Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Kotlin beyond Android

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.

Kotlin beyond Android

Avatar for Guillermo Orellana

Guillermo Orellana

June 14, 2018
Tweet

More Decks by Guillermo Orellana

Other Decks in Programming

Transcript

  1. + =

  2. Web

  3. npm { dependency "react", "16.3.1" dependency "react-dom" dependency "react-router" dependency

    "react-router-dom" devDependency "babel-loader" devDependency "babel-core" devDependency "css-loader" devDependency "style-loader" devDependency "source-map-loader" }
  4. webpackBundle { publicPath = "/frontend/" port = 8080 proxyUrl =

    "http: //localhost:9090/" sourceMapEnabled = true stats = "errors-only" }
  5. ./gradlew web:run > Task :web:nodejs-download UP-TO-DATE > Task :web:npm-preunpack UP-TO-DATE

    > Task :web:npm-configure > Task :web:npm-install UP-TO-DATE > Task :web:npm-index UP-TO-DATE > Task :web:npm-deps > Task :web:npm > Task :web:packages > Task :web:compileKotlin2Js > Task :web:compileJava NO-SOURCE > Task :web:processResources UP-TO-DATE > Task :web:classes > Task :web:compileTestKotlin2Js NO-SOURCE > Task :web:webpack-config UP-TO-DATE > Task :web:karma-config SKIPPED > Task :web:karma-start SKIPPED > Task :web:processTestResources NO-SOURCE > Task :web:runDceKotlinJs > Task :web:runDceTestKotlinJs NO-SOURCE > Task :web:webpack-run webpack started, see http: //localhost:8080/ > Task :web:run BUILD SUCCESSFUL in 9s 15 actionable tasks: 5 executed, 10 up-to-date One command to rule them all ./gradlew web:run
  6. const Submission = (props) => ( <div className={"col-md-4"}> <h4>{props.submission.title} </h4>

    <p>{props.submission.abstract} </p> <Link to={`${props.submission.submissionUrl}`} className={"btn btn-secondary btn-lg"}> {"View details"} </Link> </div> ); // Usage <Submission submission={{}} />
  7. class Submission : RComponent<SubmissionProps, RState>() { override fun RBuilder.render() {

    with(props.submission) { div("col-md-4") { h4 { +title } p { +abstract } routeLink(to = submissionUrl) { attrs { className = "btn btn-secondary btn-lg" } +"View details" } } } } }
  8. fun fetchUserProfileFromId(userId: String) = promise { val user = userProfile(userId)

    setState { userProfile = user } } .catch { console.error(it) }
  9. fun main(args: Array<String>) { embeddedServer(Netty, 8080) { routing { get("/")

    { call.respondText("My Example Blog", ContentType.Text.Html) } } }.start(wait = true) } http://ktor.io/
  10. fun Application.configureOAuth(authConf: Authentication.Configuration) = authConf.oauth("oauth") { val config = environment.config.config("keynotedex.oauth.github")

    client = HttpClient(Apache) .apply { environment.monitor.subscribe(ApplicationStopping) { close() } } providerLookup = { OAuthServerSettings.OAuth2ServerSettings( name = "github", authorizeUrl = "https: //github.com/login/oauth/authorize", accessTokenUrl = "https: //github.com/login/oauth/access_token", clientId = config.propertyOrNull("clientId") ?.getString() ?: "", clientSecret = config.propertyOrNull("clientSecret") ?.getString() ?: "" ) } urlProvider = { settings: OAuthServerSettings -> redirectString(OAuthLoginEndpoint(settings.name)) } }
  11. class ApplicationPage : Template<HTML> { val caption = Placeholder<TITLE>() val

    head = Placeholder<HEAD>() override fun HTML.apply() { head { meta { charset = "utf-8" } meta { name = "viewport" content = "width=device-width, initial-scale=1.0" } title { insert(caption) } insert(head) } body { div { id = "content" } script(src = "frontend/frontend.bundle.js") } } }
  12. class KeynotedexPageContent : Template<HTML> { val head = Placeholder<HEAD>() val

    bundle = Placeholder<SCRIPT>() override fun HTML.apply() { head { meta { charset = "utf-8" } meta { name = "viewport" content = "width=device-width, initial-scale=1.0, shrink-to-fit=no" } title { +"Keynotedex" } insert(head) link( rel = LinkRel.stylesheet, type = LinkType.textCss, href = "https: //maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" ) { attributes["integrity"] = "sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" attributes["crossorigin"] = "anonymous" } } body { div { id = "content" } script(src = "https: //code.jquery.com/jquery-3.2.1.slim.min.js") { attributes["integrity"] = "sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" attributes["crossorigin"] = "anonymous" } script(src = "https: //cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js") { attributes["integrity"] = "sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" attributes["crossorigin"] = "anonymous" } script(src = "https: //maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js") { attributes["integrity"] = "sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" attributes["crossorigin"] = "anonymous" } script { insert(bundle) } } } }
  13. fun Route.index() { static("frontend") { resource("web.bundle.js") } accept(ContentType.Text.Html) { get<IndexPage>

    { val model = mapOf( "jsbundle" to "/frontend/web.bundle.js" ) call.respond(FreeMarkerContent("index.ftl", model)) } } }
  14. Platform specific code actual class Foo actual constructor(val bar: String)

    { actual fun frob() { println("Frobbing the $bar") } } Native Common expect class Foo(bar: String) { fun frob() }