Skip to content

Instantly share code, notes, and snippets.

@molikto
Last active April 3, 2020 10:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save molikto/2451bef072b52d2a4dbe39b9bd2f2981 to your computer and use it in GitHub Desktop.
Save molikto/2451bef072b52d2a4dbe39b9bd2f2981 to your computer and use it in GitHub Desktop.
package molikto.apps.ui
import androidx.compose.*
import androidx.ui.core.Modifier
import androidx.ui.foundation.Text
import androidx.ui.foundation.TextField
import androidx.ui.layout.Column
import androidx.ui.layout.Row
import androidx.ui.layout.fillMaxHeight
import androidx.ui.material.Scaffold
import androidx.ui.material.Surface
import androidx.ui.unit.dp
import com.badoo.reaktive.observable.Observable
import com.badoo.reaktive.subject.behavior.BehaviorSubject
import kotlinx.serialization.KSerializer
import kotlinx.serialization.builtins.serializer
@Composable
fun <T> AbstractEditorScaffold(
source: Observable<T?>,
autoUpdate: Boolean = false,
topAppBar: @Composable() (Pair<T, T>?) -> Unit,
page0: @Composable() (MutableState<T>) -> Unit
) {
val backstack = backstack
val approved = state<T?>() { null }
val editing = state<T?>(StructurallyEqual) { null }
Scaffold(topAppBar = {
/* THIS IS THE VALUE READ DURING SAME FRAME */
if (editing.value == null) {
topAppBar(null)
} else {
topAppBar(Pair(approved.value!!, editing.value!!))
}
}) {
Column(Modifier.fillMaxHeight()) {
Observe(source) { so -> /* observable might fire when subscribe, then read-then-write in same frame */
/* move out directly is not stright forward, because it either change some state, or compose in-place */
if (approved.value == null) {
if (so == null) {
Banner(AppsCopy.AbstractEditor.ContentNotExist) {
SimpleTextButton(AppsCopy.Exit) {
backstack.pop()
}
}
} else {
approved.value = so
editing.value = so
}
} else {
if (so == null) {
// deleted
Banner(if (autoUpdate) AppsCopy.AbstractEditor.ContentDeleted else AppsCopy.AbstractEditor.ContentDeletedSaving) {
SimpleTextButton(AppsCopy.Exit) {
backstack.pop()
}
}
} else {
if (autoUpdate) {
approved.value = so
editing.value = so
} else if (approved.value != so) {
Banner(AppsCopy.AbstractEditor.ContentUpdated) {
SimpleTextButton(AppsCopy.Overwrite) {
approved.value = so
editing.value = so
}
}
}
}
}
}
approved.value.let { av ->
if (av != null) {
key(av) {
@Suppress("UNCHECKED_CAST")
page0(editing as MutableState<T>)
}
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment