Skip to content

Instantly share code, notes, and snippets.

@dimsuz
Created December 2, 2022 16:41
Show Gist options
  • Save dimsuz/bb2540c753c710a23a76eb9e39d57382 to your computer and use it in GitHub Desktop.
Save dimsuz/bb2540c753c710a23a76eb9e39d57382 to your computer and use it in GitHub Desktop.
package ru.kode.appyxplayground
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import com.bumble.appyx.core.composable.Children
import com.bumble.appyx.core.integration.NodeHost
import com.bumble.appyx.core.integrationpoint.ActivityIntegrationPoint
import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.node.ParentNode
import com.bumble.appyx.core.node.node
import com.bumble.appyx.core.plugin.NodeLifecycleAware
import com.bumble.appyx.navmodel.backstack.BackStack
import com.bumble.appyx.navmodel.backstack.operation.push
import com.bumble.appyx.navmodel.backstack.operation.singleTop
import com.bumble.appyx.navmodel.backstack.transitionhandler.rememberBackstackSlider
sealed class AppFlowNavTarget {
object Login : AppFlowNavTarget()
object Main : AppFlowNavTarget()
}
class AppFlowNode internal constructor(
buildContext: BuildContext,
private val backStack: BackStack<AppFlowNavTarget> = BackStack(
initialElement = AppFlowNavTarget.Login,
savedStateMap = buildContext.savedStateMap
)
) : ParentNode<AppFlowNavTarget>(
navModel = backStack,
buildContext = buildContext,
) {
override fun resolve(
navTarget: AppFlowNavTarget,
buildContext: BuildContext
): Node {
return when (navTarget) {
AppFlowNavTarget.Login -> {
LoginFlowNode(buildContext, onReset = { backStack.singleTop(AppFlowNavTarget.Main) })
}
AppFlowNavTarget.Main -> {
MainFlowNode(buildContext)
}
}
}
@Composable
override fun View(modifier: Modifier) {
Children(navModel = backStack)
}
}
class PermissionsFlowNode internal constructor(
buildContext: BuildContext,
private val onReset: () -> Unit,
private val backStack: BackStack<NavTarget> = BackStack(
initialElement = NavTarget.P1,
savedStateMap = buildContext.savedStateMap
)
) : ParentNode<PermissionsFlowNode.NavTarget>(
navModel = backStack,
buildContext = buildContext,
plugins = listOf(FlowDIComponentPlugin("Permissions"))
) {
enum class NavTarget { P1, P2 }
override fun resolve(
navTarget: NavTarget,
buildContext: BuildContext
): Node {
return when (navTarget) {
NavTarget.P1 -> {
node(buildContext) {
Column {
Text("Permissions1")
Button(onClick = { backStack.push(NavTarget.P2) }) { Text("Go to P2") }
}
}
}
NavTarget.P2 -> {
node(buildContext) {
Column {
Text("Permissions2")
Button(onClick = onReset) { Text(text = "Reset") }
}
}
}
}
}
@Composable
override fun View(modifier: Modifier) {
Children(navModel = backStack, transitionHandler = rememberBackstackSlider())
}
}
class LoginFlowNode internal constructor(
buildContext: BuildContext,
private val onReset: () -> Unit,
private val backStack: BackStack<NavTarget> = BackStack(
initialElement = NavTarget.L1,
savedStateMap = buildContext.savedStateMap
)
) : ParentNode<LoginFlowNode.NavTarget>(
navModel = backStack,
buildContext = buildContext,
plugins = listOf(FlowDIComponentPlugin("Login"))
) {
enum class NavTarget { L1, P }
override fun resolve(
navTarget: NavTarget,
buildContext: BuildContext
): Node {
return when (navTarget) {
NavTarget.L1 -> {
node(buildContext) {
Column {
Text("Login1")
Button(onClick = { backStack.push(NavTarget.P) }) { Text("Go to P") }
}
}
}
NavTarget.P -> {
PermissionsFlowNode(buildContext, onReset)
}
}
}
@Composable
override fun View(modifier: Modifier) {
Children(navModel = backStack, transitionHandler = rememberBackstackSlider())
}
}
class MainFlowNode internal constructor(
buildContext: BuildContext,
private val backStack: BackStack<NavTarget> = BackStack(
initialElement = NavTarget.M1,
savedStateMap = buildContext.savedStateMap
)
) : ParentNode<MainFlowNode.NavTarget>(
navModel = backStack,
buildContext = buildContext,
plugins = listOf(FlowDIComponentPlugin("Main"))
) {
enum class NavTarget { M1 }
override fun resolve(
navTarget: NavTarget,
buildContext: BuildContext
): Node {
return when (navTarget) {
NavTarget.M1 -> node(buildContext) {
Button(onClick = { }) { Text("Hey there, I'm Main") }
}
}
}
@Composable
override fun View(modifier: Modifier) {
Children(navModel = backStack, transitionHandler = rememberBackstackSlider())
}
}
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MaterialTheme {
Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colors.background) {
NodeHost(integrationPoint = ActivityIntegrationPoint(this, savedInstanceState)) {
AppFlowNode(it)
}
}
}
}
}
}
class FlowDIComponentPlugin(val name: String) : NodeLifecycleAware {
override fun onCreate(lifecycle: Lifecycle) {
lifecycle.addObserver(object : DefaultLifecycleObserver {
override fun onCreate(owner: LifecycleOwner) {
super.onCreate(owner)
Log.d("Appyx-Playground", "[$name] node onCreate")
}
override fun onDestroy(owner: LifecycleOwner) {
super.onDestroy(owner)
Log.d("Appyx-Playground", "[$name] node onDestroy")
}
override fun onStart(owner: LifecycleOwner) {
super.onStart(owner)
Log.d("Appyx-Playground", "[$name] node onStart")
}
override fun onStop(owner: LifecycleOwner) {
super.onStop(owner)
Log.d("Appyx-Playground", "[$name] node onStop")
}
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment