Skip to content

Commit

Permalink
Use molecule
Browse files Browse the repository at this point in the history
  • Loading branch information
hfhbd committed Nov 13, 2022
1 parent 696642b commit c5890ff
Show file tree
Hide file tree
Showing 18 changed files with 201 additions and 141 deletions.
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ plugins {
id("io.gitlab.arturbosch.detekt") version "1.21.0"
}

// https://issuetracker.google.com/issues/240445963
buildscript {
dependencies {
classpath("org.apache.commons:commons-compress:1.22")
Expand Down
37 changes: 34 additions & 3 deletions clients/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ kotlin {
config()
}

watchosArm64 {
config()
}
watchosSimulatorArm64 {
config()
}

js(IR) {
browser()
}
Expand All @@ -51,7 +58,7 @@ kotlin {
dependencies {
api(projects.shared)
implementation("app.cash.sqldelight:coroutines-extensions:$sqlDelight")

api("app.cash.molecule:molecule-runtime:0.6.0")
api("io.ktor:ktor-client-logging:$ktor")
}
}
Expand All @@ -70,21 +77,45 @@ kotlin {
}
}

val iosArm64Main by getting {
val darwinMain by creating {
dependsOn(commonMain.get())
dependencies {
implementation("io.ktor:ktor-client-darwin:$ktor")
implementation("app.cash.sqldelight:native-driver:$sqlDelight")
}
}
val darwinTest by creating {
dependsOn(commonTest.get())
}

val iosArm64Main by getting {
dependsOn(darwinMain)
}
val iosSimulatorArm64Main by getting {
dependsOn(iosArm64Main)
}

val iosArm64Test by getting
val iosArm64Test by getting {
dependsOn(darwinTest)
}

val iosSimulatorArm64Test by getting {
dependsOn(iosArm64Test)
}

val watchosArm64Main by getting {
dependsOn(darwinMain)
}
val watchosArm64Test by getting {
dependsOn(darwinTest)
}
val watchosSimulatorArm64Main by getting {
dependsOn(darwinMain)
}
val watchosSimulatorArm64Test by getting {
dependsOn(darwinTest)
}

val jsMain by getting {
dependencies {
api("app.cash.sqldelight:sqljs-driver:$sqlDelight")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package app.softwork.composetodo.viewmodels

import androidx.compose.runtime.*
import app.cash.molecule.*
import app.softwork.composetodo.*
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
Expand All @@ -8,27 +10,54 @@ class LoginViewModel(
private val api: API.LoggedOut,
private val onLogin: (API.LoggedIn) -> Unit
) : ViewModel() {
val userName = MutableStateFlow("")
val password = MutableStateFlow("")
data class LoginState(
val userName: String,
val password: String,
val enableLogin: Boolean,
val error: Failure?
)

val error = MutableStateFlow<Failure?>(null)
private var userName by mutableStateOf("")
fun updateUserName(new: String) {
userName = new
}

private var password by mutableStateOf("")
fun updatePassword(new: String) {
password = new
}

private var error by mutableStateOf<Failure?>(null)
fun dismissError() {
error = null
}

fun state(
coroutineScope: CoroutineScope,
clock: RecompositionClock = RecompositionClock.ContextClock
): StateFlow<LoginState> = coroutineScope.launchMolecule(clock) {
val isError = userName.isNotEmpty() && password.isNotEmpty()

val enableLogin = userName.combine(password) { userName, password ->
userName.isNotEmpty() && password.isNotEmpty()
LoginState(
userName = userName,
password = password,
enableLogin = isError,
error = error
)
}

fun login() {
error.value = null
error = null
lifecycleScope.launch {
api.networkCall(
action = {
login(username = userName.value, password = password.value)
login(username = userName, password = password)
}, onSuccess = {
error.value = null
error = null
onLogin(it)
}
) {
error.value = it
error = it
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,16 @@ import kotlinx.coroutines.flow.*

class IosContainer(
protocol: URLProtocol,
host: String
host: String,
storage: CookiesStorage
) : AppContainer {
private val db = TodoRepository.createDatabase(NativeSqliteDriver(ComposeTodoDB.Schema, "composetodo.db"))

constructor() : this(protocol = URLProtocol.HTTPS, host = "api.todo.softwork.app")
constructor(storage: CookiesStorage) : this(protocol = URLProtocol.HTTPS, host = "api.todo.softwork.app", storage = storage)

override val client: HttpClient = HttpClient(Darwin) {
install(HttpCookies) {
storage = UserDefaultsCookieStorage()
this.storage = storage
}
install(DefaultRequest) {
url {
Expand Down
Empty file.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,28 @@ import app.softwork.composetodo.viewmodels.*

@Composable
fun Login(viewModel: LoginViewModel) {
val coroutineScope = rememberCoroutineScope()
val state by remember(viewModel, coroutineScope) { viewModel.state(coroutineScope) }.collectAsState()

Column {
val userName by remember { viewModel.userName }.collectAsState()
TextField(
label = "Username",
value = userName,
onValueChange = { viewModel.userName.value = it },
value = state.userName,
onValueChange = viewModel::updateUserName,
isPassword = false,
placeholder = "John Doe"
)
val password by remember { viewModel.password }.collectAsState()
TextField(
label = "Password",
value = password,
onValueChange = { viewModel.password.value = it },
value = state.password,
onValueChange = viewModel::updatePassword,
isPassword = true,
placeholder = ""
)

val enableLogin by remember { viewModel.enableLogin }.collectAsState(false)

Button("Login", enabled = enableLogin) { viewModel.login() }

val error by remember { viewModel.error }.collectAsState()
Button("Login", enabled = state.enableLogin) { viewModel.login() }

error?.let {
state.error?.let {
Text("ERROR: ${it.reason}")
}
}
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ org.gradle.jvmargs=-Xmx2048m
org.gradle.parallel=true

android.useAndroidX=true
android.enableJetifier=true
android.nonTransitiveRClass=true
android.disableAutomaticComponentCreation=true

kotlin.code.style=official

kotlin.native.cacheKind=none
kotlin.native.binary.objcExportSuspendFunctionLaunchThreadRestriction=none
6 changes: 3 additions & 3 deletions iosApp/Shared/AsyncStream.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ struct FlowStream<T>: AsyncSequence {
let iterator: IteratorAsync

func next() async -> T? {
return try! await withTaskCancellationHandler(handler: {
iterator.cancel()
}) {
return try! await withTaskCancellationHandler {
do {
let next = try await iterator.next()
if (next == nil) {
Expand All @@ -39,6 +37,8 @@ struct FlowStream<T>: AsyncSequence {
throw error
}
}
} onCancel: {
iterator.cancel()
}
}

Expand Down
Loading

0 comments on commit c5890ff

Please sign in to comment.