@momo-kits/native-kits 0.162.1-beta.3-debug → 0.162.1-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/build.gradle.kts +0 -11
- package/compose/build.gradle.kts +0 -189
- package/compose/build.gradle.kts.backup +0 -189
- package/compose/compose.podspec +0 -47
- package/compose/src/androidMain/kotlin/vn/momo/kits/navigation/ScrollToTop.android.kt +0 -6
- package/compose/src/androidMain/kotlin/vn/momo/kits/platform/Platform.android.kt +0 -123
- package/compose/src/commonMain/composeResources/font/momosignature.otf +0 -0
- package/compose/src/commonMain/composeResources/font/momotrustdisplay.otf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_black.otf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_black.ttf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_bold.ttf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_heavy.ttf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_light.ttf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_medium.ttf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_regular.ttf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_semibold.ttf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_thin.otf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_thin.ttf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_ultralight.otf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_ultralight.ttf +0 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/AnimationSearchInput.kt +0 -52
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Context.kt +0 -109
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/FloatingButton.kt +0 -183
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Header.kt +0 -207
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderAnimated.kt +0 -39
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderBackground.kt +0 -86
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderDefault.kt +0 -76
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderExtended.kt +0 -76
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderRight.kt +0 -294
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderTitle.kt +0 -33
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/LiteScreen.kt +0 -826
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/NavigationContainer.kt +0 -109
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Screen.kt +0 -378
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/useHeaderSearchAnimation.kt +0 -69
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Avatar.kt +0 -157
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Badge.kt +0 -80
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeDot.kt +0 -32
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeRibbon.kt +0 -338
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/BaselineView.kt +0 -175
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Button.kt +0 -354
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Carousel.kt +0 -113
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/CheckBox.kt +0 -89
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Chip.kt +0 -128
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Collapse.kt +0 -209
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/CupertinoOverscroll.kt +0 -543
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Divider.kt +0 -23
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Icon.kt +0 -76
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/IconButton.kt +0 -140
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Image.kt +0 -188
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Information.kt +0 -112
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Input.kt +0 -477
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputDropDown.kt +0 -114
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputMoney.kt +0 -214
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputOTP.kt +0 -240
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputPhoneNumber.kt +0 -216
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputSearch.kt +0 -259
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputTextArea.kt +0 -180
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/LazyColumnWithBouncing.kt +0 -343
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Loader.kt +0 -108
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationDot.kt +0 -56
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationNumber.kt +0 -41
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationScroll.kt +0 -84
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationWhiteDot.kt +0 -40
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupNotify.kt +0 -331
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupPromotion.kt +0 -97
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/ProgressInfo.kt +0 -310
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Radio.kt +0 -59
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Rating.kt +0 -87
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Skeleton.kt +0 -90
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Slider.kt +0 -323
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Stepper.kt +0 -217
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Steps.kt +0 -473
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/SuggestAction.kt +0 -122
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Swipe.kt +0 -199
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Switch.kt +0 -91
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/TabView.kt +0 -470
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tag.kt +0 -88
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Text.kt +0 -131
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Title.kt +0 -203
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tooltip.kt +0 -498
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/TrustBanner.kt +0 -177
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Uploader.kt +0 -182
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePicker.kt +0 -193
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerTypes.kt +0 -29
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerUtils.kt +0 -234
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/WheelPicker.kt +0 -188
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Colors.kt +0 -306
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Radius.kt +0 -12
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Spacing.kt +0 -16
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Theme.kt +0 -188
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Typography.kt +0 -270
- package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Card.kt +0 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Item.kt +0 -35
- package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Section.kt +0 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/AutomationId.kt +0 -52
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Clickable.kt +0 -66
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Conditional.kt +0 -11
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/DeprecatedModifier.kt +0 -104
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Shadow.kt +0 -48
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Size.kt +0 -51
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/BottomSheet.kt +0 -253
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ModalScreen.kt +0 -129
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigation.kt +0 -94
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/NavigationContainer.kt +0 -163
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/NavigationEvent.kt +0 -53
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigator.kt +0 -399
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ScrollToTop.kt +0 -8
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackScreen.kt +0 -557
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTab.kt +0 -155
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTabBar.kt +0 -223
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/CurvedContainer.kt +0 -86
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/FloatingButton.kt +0 -169
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/Header.kt +0 -319
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderBackground.kt +0 -81
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderRight.kt +0 -309
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderTitle.kt +0 -34
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderUser.kt +0 -360
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/SnackBar.kt +0 -132
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/tracking/ScreenTracker.kt +0 -128
- package/compose/src/commonMain/kotlin/vn/momo/kits/platform/ComposeLottieAnimation.kt +0 -70
- package/compose/src/commonMain/kotlin/vn/momo/kits/platform/Platform.kt +0 -58
- package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Icons.kt +0 -1329
- package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Resources.kt +0 -55
- package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Tracking.kt +0 -15
- package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Utils.kt +0 -105
- package/compose/src/iosMain/kotlin/vn/momo/kits/navigation/ScrollToTop.ios.kt +0 -32
- package/compose/src/iosMain/kotlin/vn/momo/kits/platform/Platform.ios.kt +0 -184
- package/gradle/libs.versions.toml +0 -67
- package/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/gradle/wrapper/gradle-wrapper.properties +0 -8
- package/gradle.properties +0 -26
- package/gradlew +0 -252
- package/gradlew.bat +0 -94
- package/local.properties +0 -8
- package/settings.gradle.kts +0 -64
|
@@ -1,399 +0,0 @@
|
|
|
1
|
-
package vn.momo.kits.navigation
|
|
2
|
-
|
|
3
|
-
import androidx.compose.foundation.layout.Box
|
|
4
|
-
import androidx.compose.foundation.layout.fillMaxSize
|
|
5
|
-
import androidx.compose.runtime.Composable
|
|
6
|
-
import androidx.compose.runtime.MutableState
|
|
7
|
-
import androidx.compose.runtime.mutableStateOf
|
|
8
|
-
import androidx.compose.runtime.staticCompositionLocalOf
|
|
9
|
-
import androidx.compose.ui.Alignment
|
|
10
|
-
import androidx.compose.ui.Modifier
|
|
11
|
-
import androidx.navigation.NavController
|
|
12
|
-
import androidx.navigation.toRoute
|
|
13
|
-
import kotlinx.coroutines.CoroutineScope
|
|
14
|
-
import kotlinx.coroutines.Dispatchers
|
|
15
|
-
import kotlinx.coroutines.SupervisorJob
|
|
16
|
-
import kotlinx.coroutines.cancel
|
|
17
|
-
import kotlinx.coroutines.delay
|
|
18
|
-
import kotlinx.coroutines.launch
|
|
19
|
-
import kotlinx.serialization.Serializable
|
|
20
|
-
import vn.momo.kits.components.PopupAction
|
|
21
|
-
import vn.momo.kits.components.PopupNotify
|
|
22
|
-
import vn.momo.kits.navigation.BottomHeader.*
|
|
23
|
-
import vn.momo.kits.navigation.component.SnackBar
|
|
24
|
-
import vn.momo.maxapi.IMaxApi
|
|
25
|
-
import kotlin.time.Duration.Companion.milliseconds
|
|
26
|
-
|
|
27
|
-
class Navigator(
|
|
28
|
-
private val navController: NavController,
|
|
29
|
-
private val maxApi: IMaxApi?,
|
|
30
|
-
private val registry: DynamicScreenRegistry,
|
|
31
|
-
private val onNavigationEvent: ((NavigationEvent) -> Unit)? = null
|
|
32
|
-
) {
|
|
33
|
-
private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Main)
|
|
34
|
-
|
|
35
|
-
private fun emit(event: NavigationEvent) {
|
|
36
|
-
onNavigationEvent?.invoke(event)
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* The screen currently on top of THIS container's [navController] back stack.
|
|
41
|
-
*
|
|
42
|
-
* Use this instead of [DynamicScreenRegistry.getLatestScreen], which returns the globally
|
|
43
|
-
* last-registered screen across every NavigationContainer. With multiple containers sharing
|
|
44
|
-
* the single [DynamicScreenRegistry], the global "latest" is not guaranteed to belong to this
|
|
45
|
-
* navController, so back/dismiss/overlay logic could read the wrong options or unregister the
|
|
46
|
-
* wrong screen.
|
|
47
|
-
*/
|
|
48
|
-
private fun currentScreen(): DynamicScreen? {
|
|
49
|
-
val entry = navController.currentBackStackEntry ?: return null
|
|
50
|
-
val id = runCatching { entry.toRoute<DynamicScreenRoute>().id }.getOrNull()
|
|
51
|
-
?: runCatching { entry.toRoute<DynamicDialogRoute>().id }.getOrNull()
|
|
52
|
-
?: return null
|
|
53
|
-
return registry.getScreen(id)
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
fun push(screenName: String, content: @Composable () -> Unit, options: NavigationOptions? = null) {
|
|
57
|
-
val route = registry.register(screenName, content, options)
|
|
58
|
-
emit(NavigationEvent.Push(screenName, route.id))
|
|
59
|
-
navController.navigate(DynamicScreenRoute(route.id))
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
fun replace(screenName: String, content: @Composable () -> Unit, options: NavigationOptions? = null) {
|
|
63
|
-
if (navController.previousBackStackEntry != null){
|
|
64
|
-
val replacedScreen = currentScreen()
|
|
65
|
-
emit(NavigationEvent.Replace(screenName, replacedScreen?.id ?: -1))
|
|
66
|
-
replacedScreen?.let { registry.unregisterScreen(it.id) }
|
|
67
|
-
navController.popBackStack()
|
|
68
|
-
push(screenName, content, options)
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
fun onBackSafe(callBack: (() -> Unit)? = null) {
|
|
73
|
-
val latestScreen = currentScreen()
|
|
74
|
-
val options = latestScreen?.options
|
|
75
|
-
if (options?.onBackHandler != null) {
|
|
76
|
-
options.onBackHandler.invoke()
|
|
77
|
-
return
|
|
78
|
-
}
|
|
79
|
-
val preventBack = options?.headerBackProps?.preventBack
|
|
80
|
-
if (preventBack != null) {
|
|
81
|
-
showModal(
|
|
82
|
-
content = {
|
|
83
|
-
PopupNotify(preventBack.copy(
|
|
84
|
-
primary = PopupAction(
|
|
85
|
-
title = preventBack.primary?.title ?: "",
|
|
86
|
-
onPress = {
|
|
87
|
-
preventBack.primary?.onPress?.invoke()
|
|
88
|
-
pop(2, callBack) // close popup notify, then close the screen
|
|
89
|
-
}
|
|
90
|
-
)
|
|
91
|
-
))
|
|
92
|
-
}
|
|
93
|
-
)
|
|
94
|
-
} else {
|
|
95
|
-
pop(1, callBack)
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
fun pop(count: Int = 1, callBack: (() -> Unit)? = null) {
|
|
100
|
-
emit(NavigationEvent.Pop(count, OverplayComponentRegistry.getOverplayType()))
|
|
101
|
-
scope.launch {
|
|
102
|
-
repeat(count) {
|
|
103
|
-
if (OverplayComponentRegistry.getOverplayType() == OverplayComponentType.SNACK_BAR){
|
|
104
|
-
dismissScreen()
|
|
105
|
-
OverplayComponentRegistry.hardClearAfterDismiss()
|
|
106
|
-
}
|
|
107
|
-
else if (OverplayComponentRegistry.isOverplayShowing()){
|
|
108
|
-
dismissOverplay()
|
|
109
|
-
} else {
|
|
110
|
-
dismissScreen()
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
callBack?.invoke()
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
private suspend fun dismissOverplay(isDelay: Boolean = true) {
|
|
117
|
-
OverplayComponentRegistry.clear()
|
|
118
|
-
if (isDelay) delay(300L.milliseconds)
|
|
119
|
-
OverplayComponentRegistry.hardClearAfterDismiss()
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
private suspend fun dismissScreen() {
|
|
123
|
-
if (navController.previousBackStackEntry != null){
|
|
124
|
-
// Capture the screen being dismissed BEFORE popping; after popBackStack the current
|
|
125
|
-
// entry is the revealed screen, so reading it post-pop would unregister the wrong one.
|
|
126
|
-
val dismissing = currentScreen()
|
|
127
|
-
navController.popBackStack()
|
|
128
|
-
delay(300L.milliseconds)
|
|
129
|
-
dismissing?.let { registry.unregisterScreen(it.id) }
|
|
130
|
-
} else {
|
|
131
|
-
maxApi?.dismiss { }
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
fun present(screenName: String, content: @Composable () -> Unit, options: NavigationOptions? = null) {
|
|
136
|
-
val route = registry.register(screenName, content, options)
|
|
137
|
-
emit(NavigationEvent.Present(screenName, route.id))
|
|
138
|
-
navController.navigate(DynamicDialogRoute(route.id))
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
fun reset(screenName: String, content: @Composable () -> Unit, options: NavigationOptions? = null) {
|
|
142
|
-
registry.unregisterAll()
|
|
143
|
-
|
|
144
|
-
val route = registry.register(screenName, content, options)
|
|
145
|
-
emit(NavigationEvent.Reset(screenName, route.id))
|
|
146
|
-
navController.navigate(DynamicScreenRoute(route.id)) {
|
|
147
|
-
popUpTo(0) { inclusive = true }
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
fun showModal(
|
|
152
|
-
content: @Composable () -> Unit,
|
|
153
|
-
barrierDismissible: Boolean = true,
|
|
154
|
-
onDismiss: (() -> Unit)? = null
|
|
155
|
-
){
|
|
156
|
-
val id = currentScreen()?.id ?: -1
|
|
157
|
-
emit(NavigationEvent.ShowModal(id, barrierDismissible))
|
|
158
|
-
OverplayComponentRegistry.registerOverplay(id, content, OverplayComponentType.MODAL, false, barrierDismissible, onDismiss)
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
fun showBottomSheet(
|
|
162
|
-
content: @Composable () -> Unit,
|
|
163
|
-
isSurface: Boolean = false,
|
|
164
|
-
barrierDismissible: Boolean = true,
|
|
165
|
-
onDismiss: (() -> Unit)? = null,
|
|
166
|
-
bottomSheetHeader: BottomHeader? = null
|
|
167
|
-
){
|
|
168
|
-
val id = currentScreen()?.id ?: -1
|
|
169
|
-
emit(NavigationEvent.ShowBottomSheet(id, barrierDismissible))
|
|
170
|
-
OverplayComponentRegistry.registerOverplay(id, content, OverplayComponentType.BOTTOM_SHEET, isSurface, barrierDismissible, onDismiss, bottomSheetHeader)
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
fun showSnackBar(snackBar: SnackBar, onDismiss: (() -> Unit)? = null) {
|
|
174
|
-
val id = currentScreen()?.id ?: -1
|
|
175
|
-
emit(NavigationEvent.ShowSnackBar(id))
|
|
176
|
-
scope.launch {
|
|
177
|
-
OverplayComponentRegistry.registerOverplay(
|
|
178
|
-
id = id,
|
|
179
|
-
content = {
|
|
180
|
-
SnackBar(snackBar, onDismiss)
|
|
181
|
-
},
|
|
182
|
-
type = OverplayComponentType.SNACK_BAR,
|
|
183
|
-
onDismiss = onDismiss
|
|
184
|
-
)
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
fun hideSnackBar() {
|
|
189
|
-
scope.launch {
|
|
190
|
-
OverplayComponentRegistry.clear()
|
|
191
|
-
delay(250L.milliseconds)
|
|
192
|
-
OverplayComponentRegistry.hardClearAfterDismiss()
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
fun dispose(){
|
|
197
|
-
emit(NavigationEvent.Dispose)
|
|
198
|
-
scope.cancel()
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
val LocalNavigator = staticCompositionLocalOf<Navigator> {
|
|
203
|
-
error("No NavigationStack provided")
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
@Serializable
|
|
207
|
-
data class DynamicScreenRoute(val id: Int)
|
|
208
|
-
|
|
209
|
-
@Serializable
|
|
210
|
-
data class DynamicDialogRoute(val id: Int)
|
|
211
|
-
|
|
212
|
-
data class DynamicScreen(
|
|
213
|
-
val id: Int,
|
|
214
|
-
val name: String,
|
|
215
|
-
val content: @Composable () -> Unit,
|
|
216
|
-
var options: NavigationOptions? = null
|
|
217
|
-
)
|
|
218
|
-
|
|
219
|
-
/**
|
|
220
|
-
* Per-container store of dynamic screens. Each [NavigationContainer] owns its own instance, so the
|
|
221
|
-
* number of live containers no longer matters: `getLatestScreen`/`unregisterAll` only ever see the
|
|
222
|
-
* screens of their own container.
|
|
223
|
-
*
|
|
224
|
-
* Ids are still drawn from a process-wide counter so they stay globally unique — this keeps the
|
|
225
|
-
* still-global [OverplayComponentRegistry] (which keys overlays by screen id) collision-free.
|
|
226
|
-
*/
|
|
227
|
-
class DynamicScreenRegistry {
|
|
228
|
-
private val screens = mutableMapOf<Int, DynamicScreen>()
|
|
229
|
-
|
|
230
|
-
fun register(screenName: String, content: @Composable () -> Unit, options: NavigationOptions?): DynamicScreenRoute {
|
|
231
|
-
val id = nextGlobalId()
|
|
232
|
-
screens[id] = DynamicScreen(
|
|
233
|
-
id = id,
|
|
234
|
-
name = screenName,
|
|
235
|
-
content = content,
|
|
236
|
-
options = options
|
|
237
|
-
)
|
|
238
|
-
return DynamicScreenRoute(id)
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
fun nextId(): Int = nextGlobalId()
|
|
242
|
-
|
|
243
|
-
fun bind(id: Int, screenName: String, content: @Composable () -> Unit, options: NavigationOptions?) {
|
|
244
|
-
screens[id] = DynamicScreen(
|
|
245
|
-
id = id,
|
|
246
|
-
name = screenName,
|
|
247
|
-
content = content,
|
|
248
|
-
options = options
|
|
249
|
-
)
|
|
250
|
-
advanceGlobalIdPast(id) // keep counter ahead after process-death restore
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
fun unregisterScreen(id: Int) {
|
|
254
|
-
screens.remove(id)
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
fun getLatestScreen(): DynamicScreen?{
|
|
258
|
-
return screens.entries.lastOrNull()?.value
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
fun unregisterAll(){
|
|
262
|
-
val ids = screens.keys.toList()
|
|
263
|
-
for (id in ids) {
|
|
264
|
-
unregisterScreen(id)
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
fun getScreen(id: Int): DynamicScreen? = screens[id]
|
|
269
|
-
|
|
270
|
-
fun setOptions(id: Int, options: NavigationOptions){
|
|
271
|
-
screens[id]?.options = options
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
companion object {
|
|
275
|
-
private var globalIdCounter = 1
|
|
276
|
-
|
|
277
|
-
private fun nextGlobalId(): Int = globalIdCounter++
|
|
278
|
-
|
|
279
|
-
private fun advanceGlobalIdPast(id: Int) {
|
|
280
|
-
if (id >= globalIdCounter) globalIdCounter = id + 1
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
val LocalDynamicScreenRegistry = staticCompositionLocalOf<DynamicScreenRegistry?> { null }
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
sealed class OverplayComponentParams {
|
|
289
|
-
class Modal(
|
|
290
|
-
val onDismiss: (() -> Unit)? = null,
|
|
291
|
-
val barrierDismissible: Boolean = true
|
|
292
|
-
) : OverplayComponentParams()
|
|
293
|
-
|
|
294
|
-
class BottomSheet(
|
|
295
|
-
val isSurface: Boolean = false,
|
|
296
|
-
val onDismiss: (() -> Unit)? = null,
|
|
297
|
-
val barrierDismissible: Boolean = true,
|
|
298
|
-
val bottomSheetHeader: BottomHeader? = null,
|
|
299
|
-
) : OverplayComponentParams()
|
|
300
|
-
|
|
301
|
-
class SnackBar : OverplayComponentParams()
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
data class OverplayComponent(
|
|
305
|
-
val id: Int,
|
|
306
|
-
val type: OverplayComponentType? = null,
|
|
307
|
-
val content: @Composable () -> Unit,
|
|
308
|
-
val params: OverplayComponentParams? = null
|
|
309
|
-
)
|
|
310
|
-
|
|
311
|
-
enum class OverplayComponentType {
|
|
312
|
-
MODAL, BOTTOM_SHEET, SNACK_BAR
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
object OverplayComponentRegistry {
|
|
316
|
-
private var currentOverlayComponent : MutableState<OverplayComponent?> = mutableStateOf(null)
|
|
317
|
-
private var requestClose: (() -> Unit)? = null
|
|
318
|
-
internal fun bindClose(handler: (() -> Unit)?) {
|
|
319
|
-
requestClose = handler
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
fun registerOverplay(
|
|
323
|
-
id: Int,
|
|
324
|
-
content: @Composable () -> Unit,
|
|
325
|
-
type: OverplayComponentType,
|
|
326
|
-
isSurface: Boolean = false,
|
|
327
|
-
barrierDismissible: Boolean = true,
|
|
328
|
-
onDismiss: (() -> Unit)?,
|
|
329
|
-
bottomSheetHeader: BottomHeader? = null,
|
|
330
|
-
){
|
|
331
|
-
val params = when(type){
|
|
332
|
-
OverplayComponentType.MODAL -> OverplayComponentParams.Modal(onDismiss, barrierDismissible)
|
|
333
|
-
OverplayComponentType.BOTTOM_SHEET -> OverplayComponentParams.BottomSheet(isSurface, onDismiss, barrierDismissible, bottomSheetHeader)
|
|
334
|
-
OverplayComponentType.SNACK_BAR -> OverplayComponentParams.SnackBar()
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
currentOverlayComponent.value = OverplayComponent(
|
|
338
|
-
id = id,
|
|
339
|
-
type = type,
|
|
340
|
-
content = content,
|
|
341
|
-
params = params
|
|
342
|
-
)
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
fun isOverplayShowing(): Boolean = currentOverlayComponent.value != null
|
|
346
|
-
|
|
347
|
-
fun getOverplayType(): OverplayComponentType? = currentOverlayComponent.value?.type
|
|
348
|
-
|
|
349
|
-
fun currentRootId(): Int? = currentOverlayComponent.value?.id
|
|
350
|
-
|
|
351
|
-
fun clear(){
|
|
352
|
-
if (requestClose != null) {
|
|
353
|
-
requestClose?.invoke()
|
|
354
|
-
} else {
|
|
355
|
-
currentOverlayComponent.value = null
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
internal fun hardClearAfterDismiss() {
|
|
360
|
-
currentOverlayComponent.value = null
|
|
361
|
-
requestClose = null
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
@Composable
|
|
365
|
-
internal fun OverlayComponent(){
|
|
366
|
-
val overplay = currentOverlayComponent.value ?: return
|
|
367
|
-
|
|
368
|
-
when (val params = overplay.params) {
|
|
369
|
-
is OverplayComponentParams.BottomSheet -> {
|
|
370
|
-
BottomSheet(
|
|
371
|
-
content = overplay.content,
|
|
372
|
-
header = params.bottomSheetHeader ?: Title(),
|
|
373
|
-
isSurface = params.isSurface,
|
|
374
|
-
barrierDismissible = params.barrierDismissible,
|
|
375
|
-
onDismiss = params.onDismiss
|
|
376
|
-
)
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
is OverplayComponentParams.Modal -> {
|
|
380
|
-
ModalScreen(
|
|
381
|
-
content = overplay.content,
|
|
382
|
-
barrierDismissible = params.barrierDismissible,
|
|
383
|
-
onDismiss = params.onDismiss
|
|
384
|
-
)
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
is OverplayComponentParams.SnackBar -> {
|
|
388
|
-
Box(
|
|
389
|
-
modifier = Modifier.fillMaxSize(),
|
|
390
|
-
contentAlignment = Alignment.BottomCenter
|
|
391
|
-
) {
|
|
392
|
-
overplay.content()
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
null -> {}
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
}
|