Share
Embed
Kotlin beyond Android
Guillermo Orellana
June 14, 2018
Transcript
64 slides
-
–Guillermo Orellana “I am a strong, independent programmer and I
need no designer.” Things I regret -
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" } -
webpackBundle { publicPath = "/frontend/" port = 8080 proxyUrl =
"http: //localhost:9090/" sourceMapEnabled = true stats = "errors-only" } -
./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 -
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={{}} /> -
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" } } } } } -
fun fetchUserProfileFromId(userId: String) = promise { val user = userProfile(userId)
setState { userProfile = user } } .catch { console.error(it) } -
fun main(args: Array<String>) { embeddedServer(Netty, 8080) { routing { get("/")
{ call.respondText("My Example Blog", ContentType.Text.Html) } } }.start(wait = true) } http://ktor.io/ -
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)) } } -
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") } } } -
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) } } } } -
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)) } } } -
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() } -
common-android android Platform specific module common common-android common-jvm common-js common-native
expectedBy android jvm js native compile -
val submissionResponse = ProtoBuf.load(resBytes) call.respond( ProtoBuf.dump( SubmissionResponse() ) ) Protocol
Buffers Serialise Deserialise