forked from ikarenkov/Modo
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathStackScreen.kt
More file actions
95 lines (88 loc) · 3.05 KB
/
Copy pathStackScreen.kt
File metadata and controls
95 lines (88 loc) · 3.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package com.github.terrakok.modo.stack
import android.os.Parcelable
import androidx.activity.compose.BackHandler
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogWindowProvider
import com.github.terrakok.modo.ContainerScreen
import com.github.terrakok.modo.DialogScreen
import com.github.terrakok.modo.ExperimentalModoApi
import com.github.terrakok.modo.NavigationReducer
import com.github.terrakok.modo.RendererContent
import com.github.terrakok.modo.Screen
import com.github.terrakok.modo.defaultRendererContent
abstract class StackScreen(
navigationModel: StackNavModel
) : ContainerScreen<StackState>(navigationModel), Parcelable {
override val reducer: NavigationReducer<StackState> = StackReducer()
open val defaultBackHandler: Boolean = true
/**
* Default implementation last screen from stack.
*/
@Composable
override fun Content() {
TopScreenContent()
}
/**
* Renders last screen from stack.
*/
@OptIn(ExperimentalModoApi::class)
@Composable
protected fun TopScreenContent(
content: RendererContent<StackState> = defaultRendererContent
) {
val screensToRender: Pair<Screen?, DialogScreen?> by remember {
derivedStateOf {
val stack = navigationState.stack
val topScreen = stack.lastOrNull()
if (topScreen is DialogScreen) {
val screen = stack.findLast { it !is DialogScreen }!!
screen to topScreen
} else {
topScreen to null
}
}
}
val (screen, dialog) = screensToRender
if (screen != null) {
Content(screen, content)
}
if (dialog != null) {
val dialogConfig = remember(dialog) {
dialog.provideDialogConfig()
}
Dialog(
onDismissRequest = { back() },
properties = dialogConfig.dialogProperties
) {
val parent = LocalView.current.parent
LaunchedEffect(key1 = parent) {
if (!dialogConfig.useSystemDim) {
(parent as? DialogWindowProvider)?.window?.setDimAmount(0f)
}
}
Content(dialog, content)
}
}
}
@Composable
protected fun Content(
screen: Screen,
content: RendererContent<StackState> = defaultRendererContent
) {
val isBackHandlerEnabled by remember {
derivedStateOf {
defaultBackHandler && navigationState.getChildScreens().size > 1
}
}
BackHandler(enabled = isBackHandlerEnabled) {
back()
}
super.InternalContent(screen, content)
}
}