@momo-kits/native-kits 0.163.1-sp.2-debug → 0.163.1-sp.2
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 -190
- package/compose/build.gradle.kts.backup +0 -190
- 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/OsFontScale.android.kt +0 -7
- package/compose/src/androidMain/kotlin/vn/momo/kits/platform/Platform.android.kt +0 -150
- 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 -106
- 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 -293
- 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/Localize.kt +0 -269
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/NavigationContainer.kt +0 -110
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Screen.kt +0 -378
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/WidgetContainer.kt +0 -56
- 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 -82
- 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 -356
- 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 -542
- 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 -125
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Image.kt +0 -231
- 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 -182
- 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 -328
- 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/ScaleSizeScope.kt +0 -21
- 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 -175
- 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 -325
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/KitFontScale.kt +0 -22
- 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 -276
- package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Card.kt +0 -52
- package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Item.kt +0 -36
- package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Section.kt +0 -39
- 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 -252
- 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 -100
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/NavigationContainer.kt +0 -172
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigator.kt +0 -360
- 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 -581
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTab.kt +0 -156
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTabBar.kt +0 -225
- 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 -320
- 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 -127
- package/compose/src/commonMain/kotlin/vn/momo/kits/platform/ComposeLottieAnimation.kt +0 -91
- package/compose/src/commonMain/kotlin/vn/momo/kits/platform/OsFontScale.kt +0 -9
- package/compose/src/commonMain/kotlin/vn/momo/kits/platform/Platform.kt +0 -69
- 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/OsFontScale.ios.kt +0 -66
- package/compose/src/iosMain/kotlin/vn/momo/kits/platform/Platform.ios.kt +0 -207
- package/gradle/libs.versions.toml +0 -69
- 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/ios-demo/README.md +0 -120
- package/local.properties +0 -8
- package/settings.gradle.kts +0 -64
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
package vn.momo.kits.navigation
|
|
2
|
-
|
|
3
|
-
import androidx.compose.animation.core.tween
|
|
4
|
-
import androidx.compose.animation.fadeIn
|
|
5
|
-
import androidx.compose.animation.slideInHorizontally
|
|
6
|
-
import androidx.compose.animation.slideInVertically
|
|
7
|
-
import androidx.compose.animation.slideOutHorizontally
|
|
8
|
-
import androidx.compose.animation.slideOutVertically
|
|
9
|
-
import androidx.compose.runtime.Composable
|
|
10
|
-
import androidx.compose.runtime.CompositionLocalProvider
|
|
11
|
-
import androidx.compose.runtime.DisposableEffect
|
|
12
|
-
import androidx.compose.runtime.LaunchedEffect
|
|
13
|
-
import androidx.compose.runtime.mutableStateOf
|
|
14
|
-
import androidx.compose.runtime.remember
|
|
15
|
-
import androidx.compose.runtime.saveable.rememberSaveable
|
|
16
|
-
import androidx.compose.runtime.staticCompositionLocalOf
|
|
17
|
-
import androidx.compose.ui.unit.Dp
|
|
18
|
-
import androidx.navigation.compose.NavHost
|
|
19
|
-
import androidx.navigation.compose.composable
|
|
20
|
-
import androidx.navigation.compose.rememberNavController
|
|
21
|
-
import androidx.navigation.toRoute
|
|
22
|
-
import vn.momo.kits.application.LocalContext
|
|
23
|
-
import vn.momo.kits.application.LocalLocalize
|
|
24
|
-
import vn.momo.kits.application.Localize
|
|
25
|
-
import vn.momo.kits.application.MiniAppContext
|
|
26
|
-
import vn.momo.kits.const.AppNavigationBar
|
|
27
|
-
import vn.momo.kits.const.AppStatusBar
|
|
28
|
-
import vn.momo.kits.const.AppTheme
|
|
29
|
-
import vn.momo.kits.const.Theme
|
|
30
|
-
import vn.momo.kits.const.defaultTheme
|
|
31
|
-
import vn.momo.kits.platform.ProvideNavigationEventDispatcherOwner
|
|
32
|
-
import vn.momo.kits.platform.ProvideOsFontScale
|
|
33
|
-
import vn.momo.kits.utils.getAppStatusBarHeight
|
|
34
|
-
import vn.momo.kits.utils.getNavigationBarHeight
|
|
35
|
-
import vn.momo.maxapi.IMaxApi
|
|
36
|
-
|
|
37
|
-
@Composable
|
|
38
|
-
fun NavigationContainer(
|
|
39
|
-
initialScreenName: String,
|
|
40
|
-
initialScreen: @Composable () -> Unit,
|
|
41
|
-
options: NavigationOptions? = null,
|
|
42
|
-
initialTheme: Theme = defaultTheme,
|
|
43
|
-
miniAppContext: MiniAppContext? = null,
|
|
44
|
-
maxApi: IMaxApi? = null,
|
|
45
|
-
setNavigator: ((Navigator) -> Unit)? = null,
|
|
46
|
-
statusBarHeight: Dp? = null,
|
|
47
|
-
localize: Localize? = null,
|
|
48
|
-
) {
|
|
49
|
-
val navController = rememberNavController()
|
|
50
|
-
val registry = remember { DynamicScreenRegistry() }
|
|
51
|
-
val navigator = remember { Navigator(navController = navController, maxApi = maxApi, registry = registry) }
|
|
52
|
-
val statusBarHeight = statusBarHeight ?: getAppStatusBarHeight()
|
|
53
|
-
val navigationBarHeight = getNavigationBarHeight()
|
|
54
|
-
|
|
55
|
-
val parentContext = LocalContext.current
|
|
56
|
-
val mergedContext = MiniAppContext.merge(parentContext, miniAppContext)
|
|
57
|
-
|
|
58
|
-
val theme = remember { mutableStateOf(initialTheme) }
|
|
59
|
-
val fallbackLocalize = remember { Localize() }
|
|
60
|
-
|
|
61
|
-
val resolvedLocalize = localize ?: fallbackLocalize
|
|
62
|
-
|
|
63
|
-
LaunchedEffect(maxApi, resolvedLocalize) {
|
|
64
|
-
val api = maxApi ?: return@LaunchedEffect
|
|
65
|
-
runCatching {
|
|
66
|
-
api.getLanguage(callback = { data ->
|
|
67
|
-
if (parseLanguage(data) == Localize.EN) {
|
|
68
|
-
resolvedLocalize.changeLanguage(Localize.EN)
|
|
69
|
-
}
|
|
70
|
-
})
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
val screenId = rememberSaveable { registry.nextId() }
|
|
75
|
-
registry.bind(screenId, initialScreenName, initialScreen, options)
|
|
76
|
-
val startDestination = remember(screenId) { DynamicScreenRoute(screenId) }
|
|
77
|
-
|
|
78
|
-
ProvideOsFontScale {
|
|
79
|
-
ProvideNavigationEventDispatcherOwner {
|
|
80
|
-
CompositionLocalProvider(
|
|
81
|
-
LocalNavigator provides navigator,
|
|
82
|
-
LocalDynamicScreenRegistry provides registry,
|
|
83
|
-
LocalMaxApi provides maxApi,
|
|
84
|
-
AppTheme provides theme.value,
|
|
85
|
-
AppStatusBar provides statusBarHeight,
|
|
86
|
-
AppNavigationBar provides navigationBarHeight,
|
|
87
|
-
LocalContext provides mergedContext,
|
|
88
|
-
LocalLocalize provides resolvedLocalize,
|
|
89
|
-
) {
|
|
90
|
-
LaunchedEffect(Unit) {
|
|
91
|
-
setNavigator?.invoke(navigator)
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
NavHost(navController, startDestination = startDestination) {
|
|
95
|
-
composable<DynamicScreenRoute>(
|
|
96
|
-
enterTransition = {
|
|
97
|
-
slideInHorizontally(
|
|
98
|
-
animationSpec = tween(300),
|
|
99
|
-
initialOffsetX = { it }
|
|
100
|
-
)
|
|
101
|
-
},
|
|
102
|
-
exitTransition = null,
|
|
103
|
-
popEnterTransition = { fadeIn(animationSpec = tween(0)) },
|
|
104
|
-
popExitTransition = {
|
|
105
|
-
slideOutHorizontally(
|
|
106
|
-
animationSpec = tween(300),
|
|
107
|
-
targetOffsetX = { it }
|
|
108
|
-
)
|
|
109
|
-
}
|
|
110
|
-
) { backStackEntry ->
|
|
111
|
-
val route = backStackEntry.toRoute<DynamicScreenRoute>()
|
|
112
|
-
val screen = registry.getScreen(route.id)
|
|
113
|
-
|
|
114
|
-
if (screen != null) {
|
|
115
|
-
StackScreen(
|
|
116
|
-
id = route.id,
|
|
117
|
-
name = screen.name,
|
|
118
|
-
content = screen.content,
|
|
119
|
-
navigationOptions = screen.options
|
|
120
|
-
)
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
composable<DynamicDialogRoute>(
|
|
125
|
-
enterTransition = {
|
|
126
|
-
slideInVertically(
|
|
127
|
-
animationSpec = tween(300),
|
|
128
|
-
initialOffsetY = { it }
|
|
129
|
-
)
|
|
130
|
-
},
|
|
131
|
-
exitTransition = null,
|
|
132
|
-
popEnterTransition = { fadeIn(animationSpec = tween(0)) },
|
|
133
|
-
popExitTransition = {
|
|
134
|
-
slideOutVertically(
|
|
135
|
-
animationSpec = tween(300),
|
|
136
|
-
targetOffsetY = { it }
|
|
137
|
-
)
|
|
138
|
-
}
|
|
139
|
-
) { backStackEntry ->
|
|
140
|
-
val route = backStackEntry.toRoute<DynamicDialogRoute>()
|
|
141
|
-
val screen = registry.getScreen(route.id)
|
|
142
|
-
|
|
143
|
-
if (screen != null) {
|
|
144
|
-
StackScreen(
|
|
145
|
-
id = route.id,
|
|
146
|
-
name = screen.name,
|
|
147
|
-
content = screen.content,
|
|
148
|
-
navigationOptions = screen.options
|
|
149
|
-
)
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
DisposableEffect(Unit) {
|
|
158
|
-
onDispose {
|
|
159
|
-
navigator.dispose()
|
|
160
|
-
registry.unregisterScreen(screenId)
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
val LocalMaxApi = staticCompositionLocalOf<IMaxApi?> { null }
|
|
166
|
-
|
|
167
|
-
private fun parseLanguage(raw: Map<String, Any?>?): String? {
|
|
168
|
-
val code = (raw?.get("response") as? String)?.trim()?.lowercase()
|
|
169
|
-
if (code.isNullOrEmpty()) return null
|
|
170
|
-
return if (code.startsWith(Localize.EN)) Localize.EN else Localize.VI
|
|
171
|
-
}
|
|
172
|
-
|
|
@@ -1,360 +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
|
-
) {
|
|
32
|
-
private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Main)
|
|
33
|
-
|
|
34
|
-
private fun currentScreen(): DynamicScreen? {
|
|
35
|
-
val entry = navController.currentBackStackEntry ?: return null
|
|
36
|
-
val id = runCatching { entry.toRoute<DynamicScreenRoute>().id }.getOrNull()
|
|
37
|
-
?: runCatching { entry.toRoute<DynamicDialogRoute>().id }.getOrNull()
|
|
38
|
-
?: return null
|
|
39
|
-
return registry.getScreen(id)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
fun push(screenName: String, content: @Composable () -> Unit, options: NavigationOptions? = null) {
|
|
43
|
-
val route = registry.register(screenName, content, options)
|
|
44
|
-
navController.navigate(DynamicScreenRoute(route.id))
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
fun replace(screenName: String, content: @Composable () -> Unit, options: NavigationOptions? = null) {
|
|
48
|
-
val replacedScreen = currentScreen()
|
|
49
|
-
replacedScreen?.let { registry.unregisterScreen(it.id) }
|
|
50
|
-
navController.popBackStack()
|
|
51
|
-
push(screenName, content, options)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
fun onBackSafe(callBack: (() -> Unit)? = null) {
|
|
55
|
-
val currentScreen = currentScreen()
|
|
56
|
-
val options = currentScreen?.options
|
|
57
|
-
if (options?.onBackHandler != null) {
|
|
58
|
-
options.onBackHandler.invoke()
|
|
59
|
-
return
|
|
60
|
-
}
|
|
61
|
-
val preventBack = options?.headerBackProps?.preventBack
|
|
62
|
-
if (preventBack != null) {
|
|
63
|
-
showModal(
|
|
64
|
-
content = {
|
|
65
|
-
PopupNotify(preventBack.copy(
|
|
66
|
-
primary = PopupAction(
|
|
67
|
-
title = preventBack.primary?.title ?: "",
|
|
68
|
-
onPress = {
|
|
69
|
-
preventBack.primary?.onPress?.invoke()
|
|
70
|
-
pop(2, callBack) // close popup notify, then close the screen
|
|
71
|
-
}
|
|
72
|
-
)
|
|
73
|
-
))
|
|
74
|
-
}
|
|
75
|
-
)
|
|
76
|
-
} else {
|
|
77
|
-
pop(1, callBack)
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
fun pop(count: Int = 1, callBack: (() -> Unit)? = null) {
|
|
82
|
-
scope.launch {
|
|
83
|
-
repeat(count) {
|
|
84
|
-
if (OverplayComponentRegistry.getOverplayType() == OverplayComponentType.SNACK_BAR){
|
|
85
|
-
dismissScreen()
|
|
86
|
-
OverplayComponentRegistry.hardClearAfterDismiss()
|
|
87
|
-
}
|
|
88
|
-
else if (OverplayComponentRegistry.isOverplayShowing()){
|
|
89
|
-
dismissOverplay()
|
|
90
|
-
} else {
|
|
91
|
-
dismissScreen()
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
callBack?.invoke()
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
private suspend fun dismissOverplay(isDelay: Boolean = true) {
|
|
98
|
-
OverplayComponentRegistry.clear()
|
|
99
|
-
if (isDelay) delay(300L.milliseconds)
|
|
100
|
-
OverplayComponentRegistry.hardClearAfterDismiss()
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
private suspend fun dismissScreen() {
|
|
104
|
-
if (navController.previousBackStackEntry != null){
|
|
105
|
-
val dismissing = currentScreen()
|
|
106
|
-
navController.popBackStack()
|
|
107
|
-
delay(300L.milliseconds)
|
|
108
|
-
dismissing?.let { registry.unregisterScreen(it.id) }
|
|
109
|
-
} else {
|
|
110
|
-
maxApi?.dismiss { }
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
fun present(screenName: String, content: @Composable () -> Unit, options: NavigationOptions? = null) {
|
|
115
|
-
val route = registry.register(screenName, content, options)
|
|
116
|
-
navController.navigate(DynamicDialogRoute(route.id))
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
fun reset(screenName: String, content: @Composable () -> Unit, options: NavigationOptions? = null) {
|
|
120
|
-
registry.unregisterAll()
|
|
121
|
-
|
|
122
|
-
val route = registry.register(screenName, content, options)
|
|
123
|
-
navController.navigate(DynamicScreenRoute(route.id)) {
|
|
124
|
-
popUpTo(0) { inclusive = true }
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
fun showModal(
|
|
129
|
-
content: @Composable () -> Unit,
|
|
130
|
-
barrierDismissible: Boolean = true,
|
|
131
|
-
onDismiss: (() -> Unit)? = null
|
|
132
|
-
){
|
|
133
|
-
val id = currentScreen()?.id ?: -1
|
|
134
|
-
OverplayComponentRegistry.registerOverplay(id, content, OverplayComponentType.MODAL, false, barrierDismissible, onDismiss)
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
fun showBottomSheet(
|
|
138
|
-
content: @Composable () -> Unit,
|
|
139
|
-
isSurface: Boolean = false,
|
|
140
|
-
barrierDismissible: Boolean = true,
|
|
141
|
-
onDismiss: (() -> Unit)? = null,
|
|
142
|
-
bottomSheetHeader: BottomHeader? = null
|
|
143
|
-
){
|
|
144
|
-
val id = currentScreen()?.id ?: -1
|
|
145
|
-
OverplayComponentRegistry.registerOverplay(id, content, OverplayComponentType.BOTTOM_SHEET, isSurface, barrierDismissible, onDismiss, bottomSheetHeader)
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
fun showSnackBar(snackBar: SnackBar, onDismiss: (() -> Unit)? = null) {
|
|
149
|
-
val id = currentScreen()?.id ?: -1
|
|
150
|
-
scope.launch {
|
|
151
|
-
OverplayComponentRegistry.registerOverplay(
|
|
152
|
-
id = id,
|
|
153
|
-
content = {
|
|
154
|
-
SnackBar(snackBar, onDismiss)
|
|
155
|
-
},
|
|
156
|
-
type = OverplayComponentType.SNACK_BAR,
|
|
157
|
-
onDismiss = onDismiss
|
|
158
|
-
)
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
fun hideSnackBar() {
|
|
163
|
-
scope.launch {
|
|
164
|
-
OverplayComponentRegistry.clear()
|
|
165
|
-
delay(250L.milliseconds)
|
|
166
|
-
OverplayComponentRegistry.hardClearAfterDismiss()
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
fun dispose(){
|
|
171
|
-
scope.cancel()
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
val LocalNavigator = staticCompositionLocalOf<Navigator> {
|
|
176
|
-
error("No NavigationStack provided")
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
@Serializable
|
|
180
|
-
data class DynamicScreenRoute(val id: Int)
|
|
181
|
-
|
|
182
|
-
@Serializable
|
|
183
|
-
data class DynamicDialogRoute(val id: Int)
|
|
184
|
-
|
|
185
|
-
data class DynamicScreen(
|
|
186
|
-
val id: Int,
|
|
187
|
-
val name: String,
|
|
188
|
-
val content: @Composable () -> Unit,
|
|
189
|
-
var options: NavigationOptions? = null
|
|
190
|
-
)
|
|
191
|
-
|
|
192
|
-
class DynamicScreenRegistry {
|
|
193
|
-
private val screens = mutableMapOf<Int, DynamicScreen>()
|
|
194
|
-
|
|
195
|
-
fun register(screenName: String, content: @Composable () -> Unit, options: NavigationOptions?): DynamicScreenRoute {
|
|
196
|
-
val id = nextGlobalId()
|
|
197
|
-
screens[id] = DynamicScreen(
|
|
198
|
-
id = id,
|
|
199
|
-
name = screenName,
|
|
200
|
-
content = content,
|
|
201
|
-
options = options
|
|
202
|
-
)
|
|
203
|
-
return DynamicScreenRoute(id)
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
fun nextId(): Int = nextGlobalId()
|
|
207
|
-
|
|
208
|
-
fun bind(id: Int, screenName: String, content: @Composable () -> Unit, options: NavigationOptions?) {
|
|
209
|
-
screens[id] = DynamicScreen(
|
|
210
|
-
id = id,
|
|
211
|
-
name = screenName,
|
|
212
|
-
content = content,
|
|
213
|
-
options = options
|
|
214
|
-
)
|
|
215
|
-
advanceGlobalIdPast(id) // keep counter ahead after process-death restore
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
fun unregisterScreen(id: Int) {
|
|
219
|
-
screens.remove(id)
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
fun unregisterAll(){
|
|
223
|
-
val ids = screens.keys.toList()
|
|
224
|
-
for (id in ids) {
|
|
225
|
-
unregisterScreen(id)
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
fun getScreen(id: Int): DynamicScreen? = screens[id]
|
|
230
|
-
|
|
231
|
-
fun setOptions(id: Int, options: NavigationOptions){
|
|
232
|
-
screens[id]?.options = options
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
companion object {
|
|
236
|
-
private var globalIdCounter = 1
|
|
237
|
-
|
|
238
|
-
private fun nextGlobalId(): Int = globalIdCounter++
|
|
239
|
-
|
|
240
|
-
private fun advanceGlobalIdPast(id: Int) {
|
|
241
|
-
if (id >= globalIdCounter) globalIdCounter = id + 1
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
val LocalDynamicScreenRegistry = staticCompositionLocalOf<DynamicScreenRegistry?> { null }
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
sealed class OverplayComponentParams {
|
|
250
|
-
class Modal(
|
|
251
|
-
val onDismiss: (() -> Unit)? = null,
|
|
252
|
-
val barrierDismissible: Boolean = true
|
|
253
|
-
) : OverplayComponentParams()
|
|
254
|
-
|
|
255
|
-
class BottomSheet(
|
|
256
|
-
val isSurface: Boolean = false,
|
|
257
|
-
val onDismiss: (() -> Unit)? = null,
|
|
258
|
-
val barrierDismissible: Boolean = true,
|
|
259
|
-
val bottomSheetHeader: BottomHeader? = null,
|
|
260
|
-
) : OverplayComponentParams()
|
|
261
|
-
|
|
262
|
-
class SnackBar : OverplayComponentParams()
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
data class OverplayComponent(
|
|
266
|
-
val id: Int,
|
|
267
|
-
val type: OverplayComponentType? = null,
|
|
268
|
-
val content: @Composable () -> Unit,
|
|
269
|
-
val params: OverplayComponentParams? = null
|
|
270
|
-
)
|
|
271
|
-
|
|
272
|
-
enum class OverplayComponentType {
|
|
273
|
-
MODAL, BOTTOM_SHEET, SNACK_BAR
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
object OverplayComponentRegistry {
|
|
277
|
-
private var currentOverlayComponent : MutableState<OverplayComponent?> = mutableStateOf(null)
|
|
278
|
-
private var requestClose: (() -> Unit)? = null
|
|
279
|
-
internal fun bindClose(handler: (() -> Unit)?) {
|
|
280
|
-
requestClose = handler
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
fun registerOverplay(
|
|
284
|
-
id: Int,
|
|
285
|
-
content: @Composable () -> Unit,
|
|
286
|
-
type: OverplayComponentType,
|
|
287
|
-
isSurface: Boolean = false,
|
|
288
|
-
barrierDismissible: Boolean = true,
|
|
289
|
-
onDismiss: (() -> Unit)?,
|
|
290
|
-
bottomSheetHeader: BottomHeader? = null,
|
|
291
|
-
){
|
|
292
|
-
val params = when(type){
|
|
293
|
-
OverplayComponentType.MODAL -> OverplayComponentParams.Modal(onDismiss, barrierDismissible)
|
|
294
|
-
OverplayComponentType.BOTTOM_SHEET -> OverplayComponentParams.BottomSheet(isSurface, onDismiss, barrierDismissible, bottomSheetHeader)
|
|
295
|
-
OverplayComponentType.SNACK_BAR -> OverplayComponentParams.SnackBar()
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
currentOverlayComponent.value = OverplayComponent(
|
|
299
|
-
id = id,
|
|
300
|
-
type = type,
|
|
301
|
-
content = content,
|
|
302
|
-
params = params
|
|
303
|
-
)
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
fun isOverplayShowing(): Boolean = currentOverlayComponent.value != null
|
|
307
|
-
|
|
308
|
-
fun getOverplayType(): OverplayComponentType? = currentOverlayComponent.value?.type
|
|
309
|
-
|
|
310
|
-
fun currentRootId(): Int? = currentOverlayComponent.value?.id
|
|
311
|
-
|
|
312
|
-
fun clear(){
|
|
313
|
-
if (requestClose != null) {
|
|
314
|
-
requestClose?.invoke()
|
|
315
|
-
} else {
|
|
316
|
-
currentOverlayComponent.value = null
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
internal fun hardClearAfterDismiss() {
|
|
321
|
-
currentOverlayComponent.value = null
|
|
322
|
-
requestClose = null
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
@Composable
|
|
326
|
-
internal fun OverlayComponent(){
|
|
327
|
-
val overplay = currentOverlayComponent.value ?: return
|
|
328
|
-
|
|
329
|
-
when (val params = overplay.params) {
|
|
330
|
-
is OverplayComponentParams.BottomSheet -> {
|
|
331
|
-
BottomSheet(
|
|
332
|
-
content = overplay.content,
|
|
333
|
-
header = params.bottomSheetHeader ?: Title(),
|
|
334
|
-
isSurface = params.isSurface,
|
|
335
|
-
barrierDismissible = params.barrierDismissible,
|
|
336
|
-
onDismiss = params.onDismiss
|
|
337
|
-
)
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
is OverplayComponentParams.Modal -> {
|
|
341
|
-
ModalScreen(
|
|
342
|
-
content = overplay.content,
|
|
343
|
-
barrierDismissible = params.barrierDismissible,
|
|
344
|
-
onDismiss = params.onDismiss
|
|
345
|
-
)
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
is OverplayComponentParams.SnackBar -> {
|
|
349
|
-
Box(
|
|
350
|
-
modifier = Modifier.fillMaxSize(),
|
|
351
|
-
contentAlignment = Alignment.BottomCenter
|
|
352
|
-
) {
|
|
353
|
-
overplay.content()
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
null -> {}
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
}
|