Migrate Preferences to new architecture

This commit is contained in:
ganfra 2023-01-09 19:27:28 +01:00
parent 9e211b5e04
commit ae273bd4ea
26 changed files with 399 additions and 174 deletions

View file

@ -1,3 +1,5 @@
// TODO: Remove once https://youtrack.jetbrains.com/issue/KTIJ-19369 is fixed
@Suppress("DSL_SCOPE_VIOLATION")
plugins {
id("io.element.android-compose-library")
alias(libs.plugins.molecule)

View file

@ -5,8 +5,17 @@ import androidx.compose.runtime.MutableState
sealed interface Async<out T> {
object Uninitialized : Async<Nothing>
data class Loading<out T>(val prevState: T? = null) : Async<T>
data class Failure<out T>(val error: Throwable) : Async<T>
data class Failure<out T>(val error: Throwable, val prevState: T? = null) : Async<T>
data class Success<out T>(val state: T) : Async<T>
fun dataOrNull(): T? {
return when (this) {
is Failure -> prevState
is Loading -> prevState
is Success -> state
Uninitialized -> null
}
}
}
suspend fun <T> (suspend () -> T).execute(state: MutableState<Async<T>>) {

View file

@ -6,24 +6,21 @@ import app.cash.molecule.AndroidUiDispatcher
import app.cash.molecule.RecompositionClock
import app.cash.molecule.launchMolecule
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asSharedFlow
inline fun <reified State, reified Event> LifecycleOwner.presenterConnector(presenter: Presenter<State, Event>): LifecyclePresenterConnector<State, Event> =
LifecyclePresenterConnector(lifecycleOwner = this, presenter = presenter)
class LifecyclePresenterConnector<State, Event>(lifecycleOwner: LifecycleOwner, presenter: Presenter<State, Event>) {
private val moleculeScope = CoroutineScope(lifecycleOwner.lifecycleScope.coroutineContext + AndroidUiDispatcher.Main)
private val mutableEventFlow: MutableSharedFlow<Event> = MutableSharedFlow(extraBufferCapacity = 64)
private val eventFlow = SharedFlowHolder<Event>()
val stateFlow: StateFlow<State> = moleculeScope.launchMolecule(RecompositionClock.Immediate) {
presenter.present(events = mutableEventFlow)
presenter.present(events = eventFlow.asSharedFlow())
}
fun emitEvent(event: Event) {
mutableEventFlow.tryEmit(event)
eventFlow.emit(event)
}
}

View file

@ -0,0 +1,12 @@
package io.element.android.x.architecture
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.asSharedFlow
class SharedFlowHolder<Data>(capacity: Int = 64) {
private val mutableFlow: MutableSharedFlow<Data> = MutableSharedFlow(extraBufferCapacity = capacity)
fun asSharedFlow() = mutableFlow.asSharedFlow()
fun emit(data: Data) = mutableFlow.tryEmit(data)
}

View file

@ -45,7 +45,7 @@ import androidx.compose.ui.unit.sp
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun PreferenceScreen(
fun PreferenceView(
title: String,
modifier: Modifier = Modifier,
onBackPressed: () -> Unit = {},
@ -113,7 +113,7 @@ fun PreferenceTopAppBar(
@Composable
@Preview(showBackground = false)
fun PreferenceScreenPreview() {
PreferenceScreen(
PreferenceView(
title = "Preference screen"
) {
PreferenceCategoryPreview()