@momo-kits/native-kits 0.157.8-debug → 0.157.8
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 -180
- package/compose/build.gradle.kts.backup +0 -180
- package/compose/compose.podspec +0 -54
- package/compose/src/androidMain/kotlin/vn/momo/kits/platform/Platform.android.kt +0 -117
- 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 -57
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Context.kt +0 -107
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/FloatingButton.kt +0 -201
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Header.kt +0 -222
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderAnimated.kt +0 -48
- 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 -305
- 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 -720
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/NavigationContainer.kt +0 -121
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Screen.kt +0 -405
- 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 -85
- 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 -340
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/BaselineView.kt +0 -198
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Button.kt +0 -357
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Carousel.kt +0 -123
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/CheckBox.kt +0 -94
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Chip.kt +0 -136
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Collapse.kt +0 -224
- 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 -148
- 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 -116
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Input.kt +0 -448
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputDropDown.kt +0 -172
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputMoney.kt +0 -255
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputOTP.kt +0 -231
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputPhoneNumber.kt +0 -233
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputSearch.kt +0 -254
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputTextArea.kt +0 -241
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/LazyColumnWithBouncing.kt +0 -364
- 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 -92
- 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 -352
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupPromotion.kt +0 -103
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/ProgressInfo.kt +0 -338
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Radio.kt +0 -70
- 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 -17
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Skeleton.kt +0 -96
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Slider.kt +0 -348
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Stepper.kt +0 -256
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Steps.kt +0 -494
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/SuggestAction.kt +0 -131
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Swipe.kt +0 -215
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Switch.kt +0 -96
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/TabView.kt +0 -531
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tag.kt +0 -92
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Text.kt +0 -130
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Title.kt +0 -214
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tooltip.kt +0 -590
- 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 -192
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePicker.kt +0 -205
- 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 -239
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/WheelPicker.kt +0 -191
- 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 -285
- 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 -50
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Clickable.kt +0 -68
- 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 -14
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Shadow.kt +0 -50
- 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 -133
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigation.kt +0 -99
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/NavigationContainer.kt +0 -164
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigator.kt +0 -333
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackScreen.kt +0 -552
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTab.kt +0 -162
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTabBar.kt +0 -243
- 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 -187
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/Header.kt +0 -279
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderBackground.kt +0 -80
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderRight.kt +0 -306
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderTitle.kt +0 -32
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderUser.kt +0 -370
- 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 -167
- package/compose/src/commonMain/kotlin/vn/momo/kits/platform/Platform.kt +0 -46
- 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 -62
- 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 -88
- package/compose/src/iosMain/kotlin/vn/momo/kits/platform/Platform.ios.kt +0 -161
- package/gradle/libs.versions.toml +0 -57
- 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/settings.gradle.kts +0 -52
|
@@ -1,552 +0,0 @@
|
|
|
1
|
-
package vn.momo.kits.navigation
|
|
2
|
-
|
|
3
|
-
import androidx.compose.animation.animateColorAsState
|
|
4
|
-
import androidx.compose.animation.core.animateDpAsState
|
|
5
|
-
import androidx.compose.foundation.ScrollState
|
|
6
|
-
import androidx.compose.foundation.background
|
|
7
|
-
import androidx.compose.foundation.border
|
|
8
|
-
import androidx.compose.foundation.gestures.ScrollableState
|
|
9
|
-
import androidx.compose.foundation.layout.Box
|
|
10
|
-
import androidx.compose.foundation.layout.Column
|
|
11
|
-
import androidx.compose.foundation.layout.ColumnScope
|
|
12
|
-
import androidx.compose.foundation.layout.Spacer
|
|
13
|
-
import androidx.compose.foundation.layout.WindowInsets
|
|
14
|
-
import androidx.compose.foundation.layout.aspectRatio
|
|
15
|
-
import androidx.compose.foundation.layout.fillMaxSize
|
|
16
|
-
import androidx.compose.foundation.layout.fillMaxWidth
|
|
17
|
-
import androidx.compose.foundation.layout.height
|
|
18
|
-
import androidx.compose.foundation.layout.ime
|
|
19
|
-
import androidx.compose.foundation.layout.imePadding
|
|
20
|
-
import androidx.compose.foundation.layout.offset
|
|
21
|
-
import androidx.compose.foundation.layout.padding
|
|
22
|
-
import androidx.compose.foundation.lazy.LazyListState
|
|
23
|
-
import androidx.compose.foundation.lazy.rememberLazyListState
|
|
24
|
-
import androidx.compose.foundation.rememberScrollState
|
|
25
|
-
import androidx.compose.foundation.verticalScroll
|
|
26
|
-
import androidx.compose.material.ExperimentalMaterialApi
|
|
27
|
-
import androidx.compose.runtime.Composable
|
|
28
|
-
import androidx.compose.runtime.CompositionLocalProvider
|
|
29
|
-
import androidx.compose.runtime.LaunchedEffect
|
|
30
|
-
import androidx.compose.runtime.getValue
|
|
31
|
-
import androidx.compose.runtime.mutableIntStateOf
|
|
32
|
-
import androidx.compose.runtime.mutableStateOf
|
|
33
|
-
import androidx.compose.runtime.remember
|
|
34
|
-
import androidx.compose.runtime.snapshotFlow
|
|
35
|
-
import androidx.compose.runtime.staticCompositionLocalOf
|
|
36
|
-
import androidx.compose.ui.Alignment
|
|
37
|
-
import androidx.compose.ui.Modifier
|
|
38
|
-
import androidx.compose.ui.graphics.Brush
|
|
39
|
-
import androidx.compose.ui.graphics.Color
|
|
40
|
-
import androidx.compose.ui.graphics.lerp
|
|
41
|
-
import androidx.compose.ui.layout.onGloballyPositioned
|
|
42
|
-
import androidx.compose.ui.platform.LocalDensity
|
|
43
|
-
import androidx.compose.ui.unit.Dp
|
|
44
|
-
import androidx.compose.ui.unit.dp
|
|
45
|
-
import androidx.compose.ui.unit.min
|
|
46
|
-
import androidx.compose.ui.zIndex
|
|
47
|
-
import vn.momo.kits.components.InputSearch
|
|
48
|
-
import vn.momo.kits.const.AppNavigationBar
|
|
49
|
-
import vn.momo.kits.const.AppStatusBar
|
|
50
|
-
import vn.momo.kits.const.AppTheme
|
|
51
|
-
import vn.momo.kits.application.IsShowBaseLineDebug
|
|
52
|
-
import vn.momo.kits.const.Colors
|
|
53
|
-
import vn.momo.kits.const.Spacing
|
|
54
|
-
import vn.momo.kits.modifier.conditional
|
|
55
|
-
import vn.momo.kits.modifier.hideKeyboardOnTap
|
|
56
|
-
import vn.momo.kits.navigation.component.FABPosition
|
|
57
|
-
import vn.momo.kits.navigation.component.FloatingButton
|
|
58
|
-
import vn.momo.kits.navigation.component.HEADER_HEIGHT
|
|
59
|
-
import vn.momo.kits.navigation.component.Header
|
|
60
|
-
import vn.momo.kits.navigation.component.HeaderBackground
|
|
61
|
-
import vn.momo.kits.navigation.component.HeaderRight
|
|
62
|
-
import vn.momo.kits.navigation.component.HeaderType
|
|
63
|
-
import vn.momo.kits.navigation.component.InputSearchType
|
|
64
|
-
import vn.momo.kits.platform.BackHandler
|
|
65
|
-
import vn.momo.kits.platform.getAndroidBuildVersion
|
|
66
|
-
import vn.momo.kits.navigation.tracking.ScreenTracker
|
|
67
|
-
import vn.momo.kits.navigation.tracking.ScreenTrackingState
|
|
68
|
-
import kotlinx.coroutines.delay
|
|
69
|
-
import vn.momo.kits.application.ApplicationContext
|
|
70
|
-
import kotlin.time.Clock
|
|
71
|
-
import kotlin.time.ExperimentalTime
|
|
72
|
-
|
|
73
|
-
internal val LocalFooterHeightPx = staticCompositionLocalOf { mutableIntStateOf(0) }
|
|
74
|
-
internal val LocalHeaderRightWidthPx = staticCompositionLocalOf { mutableIntStateOf(0) }
|
|
75
|
-
|
|
76
|
-
@OptIn(ExperimentalMaterialApi::class, ExperimentalTime::class)
|
|
77
|
-
@Composable
|
|
78
|
-
internal fun StackScreen(
|
|
79
|
-
content: @Composable () -> Unit,
|
|
80
|
-
navigationOptions: NavigationOptions? = null,
|
|
81
|
-
id: Int = -1,
|
|
82
|
-
name: String = "",
|
|
83
|
-
bottomTabIndex: Int = -1,
|
|
84
|
-
onBackHandler: (() -> Unit)? = null,
|
|
85
|
-
) {
|
|
86
|
-
val navigator = LocalNavigator.current
|
|
87
|
-
val maxApi = LocalMaxApi.current
|
|
88
|
-
val context = ApplicationContext.current
|
|
89
|
-
val statusBar = AppStatusBar.current
|
|
90
|
-
val density = LocalDensity.current
|
|
91
|
-
val navigation = remember { Navigation(id = id, bottomTabIndex = bottomTabIndex, initOptions = navigationOptions) }
|
|
92
|
-
|
|
93
|
-
val options by navigation.currentOptions
|
|
94
|
-
|
|
95
|
-
// Auto tracking state
|
|
96
|
-
val trackingState = remember {
|
|
97
|
-
ScreenTrackingState().apply {
|
|
98
|
-
startTime = Clock.System.now().toEpochMilliseconds()
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// Determine action: push or back
|
|
103
|
-
val action = remember {
|
|
104
|
-
if (ScreenTracker.getLastScreenName() != null) "push" else "back"
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// Auto tracking effects
|
|
108
|
-
LaunchedEffect(name) {
|
|
109
|
-
// Track screen navigated immediately
|
|
110
|
-
ScreenTracker.trackScreenNavigated(
|
|
111
|
-
maxApi = maxApi,
|
|
112
|
-
context = context,
|
|
113
|
-
screenName = name,
|
|
114
|
-
action = action,
|
|
115
|
-
state = trackingState
|
|
116
|
-
)
|
|
117
|
-
|
|
118
|
-
// Track screen displayed after 2 seconds (debounce)
|
|
119
|
-
delay(2000)
|
|
120
|
-
val loadTime = Clock.System.now().toEpochMilliseconds() - trackingState.startTime
|
|
121
|
-
ScreenTracker.trackScreenDisplayed(
|
|
122
|
-
maxApi = maxApi,
|
|
123
|
-
context = context,
|
|
124
|
-
screenName = name,
|
|
125
|
-
duration = loadTime,
|
|
126
|
-
state = trackingState
|
|
127
|
-
)
|
|
128
|
-
|
|
129
|
-
// Track screen interacted after displayed
|
|
130
|
-
val interactionTime = Clock.System.now().toEpochMilliseconds() - trackingState.startTime
|
|
131
|
-
ScreenTracker.trackScreenInteracted(
|
|
132
|
-
maxApi = maxApi,
|
|
133
|
-
context = context,
|
|
134
|
-
screenName = name,
|
|
135
|
-
duration = interactionTime - loadTime,
|
|
136
|
-
totalDuration = interactionTime,
|
|
137
|
-
state = trackingState
|
|
138
|
-
)
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
val limit = with(density) {
|
|
142
|
-
(statusBar).toPx() + HEADER_HEIGHT
|
|
143
|
-
}.toInt()
|
|
144
|
-
|
|
145
|
-
val (scrollState, scrollInProcess) = if (options.scrollData.scrollState is LazyListState)
|
|
146
|
-
(options.scrollData.scrollState as? LazyListState ?: rememberLazyListState()).proxyScrollState(limit, 15)
|
|
147
|
-
else
|
|
148
|
-
(options.scrollData.scrollState as? ScrollState ?: rememberScrollState()).proxyLimitedScrollState(limit, 15)
|
|
149
|
-
|
|
150
|
-
val footerHeightPx = remember { mutableIntStateOf(0) }
|
|
151
|
-
val headerRightWidthPx = remember { mutableIntStateOf(0) }
|
|
152
|
-
|
|
153
|
-
BackHandler(true) { navigator.onBackSafe() }
|
|
154
|
-
|
|
155
|
-
CompositionLocalProvider(
|
|
156
|
-
StackScreenScrollableState provides options.scrollData.scrollState,
|
|
157
|
-
LocalNavigation provides navigation,
|
|
158
|
-
LocalScrollState provides scrollState,
|
|
159
|
-
LocalOptions provides options,
|
|
160
|
-
LocalFooterHeightPx provides footerHeightPx,
|
|
161
|
-
LocalHeaderRightWidthPx provides headerRightWidthPx
|
|
162
|
-
) {
|
|
163
|
-
Box(Modifier
|
|
164
|
-
.fillMaxSize()
|
|
165
|
-
.background(options.backgroundColor ?: AppTheme.current.colors.background.default)
|
|
166
|
-
.conditional(options.keyboardOptions.keyboardShouldPersistTaps) {
|
|
167
|
-
hideKeyboardOnTap()
|
|
168
|
-
}
|
|
169
|
-
.conditional(options.keyboardOptions.useAvoidKeyboard && getAndroidBuildVersion() > 29) {
|
|
170
|
-
imePadding()
|
|
171
|
-
}
|
|
172
|
-
) {
|
|
173
|
-
Box(Modifier.zIndex(1f)) {
|
|
174
|
-
HeaderBackground()
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
Box(Modifier.zIndex(5f)) {
|
|
178
|
-
Header(onBackHandler)
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
Column (Modifier.zIndex(6f)) {
|
|
182
|
-
SearchAnimated(isScrollInProgress = scrollInProcess)
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
Column(Modifier.zIndex(2f).fillMaxSize()) {
|
|
186
|
-
MainContent(content = content)
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
Box(Modifier.zIndex(4f).align(Alignment.BottomCenter)) {
|
|
190
|
-
FooterContent()
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
Box(Modifier.zIndex(7f)){
|
|
194
|
-
FloatingContent()
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
OverplayView(bottomTabIndex = bottomTabIndex, id = id)
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
@Composable
|
|
203
|
-
fun FloatingContent(){
|
|
204
|
-
val options = LocalOptions.current
|
|
205
|
-
val density = LocalDensity.current
|
|
206
|
-
val footerHeightPx = LocalFooterHeightPx.current
|
|
207
|
-
val scrollState = LocalScrollState.current
|
|
208
|
-
|
|
209
|
-
val fabProps = options.floatingButtonProps ?: return
|
|
210
|
-
val bottomPadding = fabProps.bottom ?:
|
|
211
|
-
(Spacing.M + if (options.footerComponent != null) with(density){ footerHeightPx.intValue.toDp() } else 0.dp)
|
|
212
|
-
|
|
213
|
-
FloatingButton(
|
|
214
|
-
scrollPosition = fabProps.scrollState?.value ?: scrollState.value,
|
|
215
|
-
onClick = fabProps.onClick,
|
|
216
|
-
containerColor = AppTheme.current.colors.primary,
|
|
217
|
-
bottom = bottomPadding,
|
|
218
|
-
icon = fabProps.icon,
|
|
219
|
-
iconColor = fabProps.iconColor,
|
|
220
|
-
text = fabProps.label,
|
|
221
|
-
size = fabProps.size,
|
|
222
|
-
position = fabProps.position ?: FABPosition.END,
|
|
223
|
-
)
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
@Composable
|
|
227
|
-
fun ColumnScope.MainContent(content: @Composable ()-> Unit){
|
|
228
|
-
val options = LocalOptions.current
|
|
229
|
-
val inputSearchType = getInputSearchType(options)
|
|
230
|
-
val density = LocalDensity.current
|
|
231
|
-
val scrollState = LocalScrollState.current
|
|
232
|
-
|
|
233
|
-
Spacer(Modifier.height(
|
|
234
|
-
if (options.headerType is HeaderType.DefaultOrExtended || (options.headerType is HeaderType.Transparent && !options.headerType.isFullScreenContent))
|
|
235
|
-
AppStatusBar.current + HEADER_HEIGHT.dp else 0.dp)
|
|
236
|
-
)
|
|
237
|
-
if (inputSearchType == InputSearchType.Animated){
|
|
238
|
-
val scrollDp = with(density) { scrollState.value.toDp() }
|
|
239
|
-
|
|
240
|
-
val animatedTopPadding by animateDpAsState(
|
|
241
|
-
targetValue = (HEADER_HEIGHT.dp - scrollDp).coerceIn(0.dp, HEADER_HEIGHT.dp),
|
|
242
|
-
label = "AnimatedTopPadding"
|
|
243
|
-
)
|
|
244
|
-
Spacer(Modifier.height(animatedTopPadding))
|
|
245
|
-
}
|
|
246
|
-
Column (Modifier
|
|
247
|
-
.fillMaxWidth()
|
|
248
|
-
.weight(1f)
|
|
249
|
-
.conditional(options.scrollData.scrollable && options.scrollData.scrollState is ScrollState) {
|
|
250
|
-
verticalScroll(scrollState)
|
|
251
|
-
}
|
|
252
|
-
) {
|
|
253
|
-
ScreenContent(content = content)
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
if (options.footerComponent != null){
|
|
257
|
-
val footerHeight = LocalFooterHeightPx.current
|
|
258
|
-
val footerHeightDp = with(density) { footerHeight.value.toDp() }
|
|
259
|
-
Spacer(Modifier.height(footerHeightDp))
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
@Composable
|
|
264
|
-
fun ScreenContent(content: @Composable () -> Unit){
|
|
265
|
-
val scrollState = LocalScrollState.current
|
|
266
|
-
val options = LocalOptions.current
|
|
267
|
-
|
|
268
|
-
if (options.headerType is HeaderType.Animated){
|
|
269
|
-
val animatedHeader = options.headerType
|
|
270
|
-
Box {
|
|
271
|
-
Box(Modifier.fillMaxWidth().aspectRatio(animatedHeader.aspectRatio.value)){
|
|
272
|
-
animatedHeader.composable.invoke(scrollState.value)
|
|
273
|
-
}
|
|
274
|
-
Box(Modifier.offset(x = 0.dp, y = AppStatusBar.current + HEADER_HEIGHT.dp + animatedHeader.layoutOffSet)){
|
|
275
|
-
content()
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
} else {
|
|
279
|
-
content()
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
@Composable
|
|
284
|
-
fun FooterContent(){
|
|
285
|
-
val options = LocalOptions.current
|
|
286
|
-
if (options.footerComponent != null){
|
|
287
|
-
val ime = WindowInsets.ime
|
|
288
|
-
val density = LocalDensity.current
|
|
289
|
-
val imeBottom = ime.getBottom(density)
|
|
290
|
-
val thresholdPx = with(density) { 50.dp.toPx() }
|
|
291
|
-
val isKeyboardVisible = imeBottom > thresholdPx
|
|
292
|
-
val bottomPadding = min(AppNavigationBar.current, if (isKeyboardVisible) 0.dp else 21.dp)
|
|
293
|
-
Footer(footerComponent = options.footerComponent, bottomPadding = bottomPadding)
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
@Composable
|
|
298
|
-
fun OverplayView(bottomTabIndex: Int, id: Int){
|
|
299
|
-
val overplayType = OverplayComponentRegistry.getOverplayType()
|
|
300
|
-
|
|
301
|
-
if (overplayType != null) {
|
|
302
|
-
Box(Modifier.zIndex(if (overplayType == OverplayComponentType.SNACK_BAR) 3f else 8f).fillMaxSize()){
|
|
303
|
-
if (bottomTabIndex != -1) return@Box
|
|
304
|
-
if (OverplayComponentRegistry.currentRootId() != id) return@Box
|
|
305
|
-
OverplayComponentRegistry.OverlayComponent()
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
@Composable
|
|
311
|
-
fun Footer(footerComponent: @Composable (() -> Unit)?, bottomPadding: Dp) {
|
|
312
|
-
if (footerComponent == null) return
|
|
313
|
-
|
|
314
|
-
val footerHeightPx = LocalFooterHeightPx.current
|
|
315
|
-
|
|
316
|
-
val shadowBrush = remember {
|
|
317
|
-
Brush.verticalGradient(
|
|
318
|
-
colors = listOf(Color.Transparent, Color.Black.copy(alpha = 0.05f))
|
|
319
|
-
)
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
Box(Modifier.onGloballyPositioned {
|
|
323
|
-
if (footerHeightPx.intValue != it.size.height) footerHeightPx.intValue = it.size.height
|
|
324
|
-
}) {
|
|
325
|
-
Box(Modifier
|
|
326
|
-
.fillMaxWidth()
|
|
327
|
-
.background(AppTheme.current.colors.background.surface)
|
|
328
|
-
.conditional(IsShowBaseLineDebug) {
|
|
329
|
-
border(1.dp, Colors.blue_03)
|
|
330
|
-
}
|
|
331
|
-
.padding(top = Spacing.S, start = Spacing.M, end = Spacing.M, bottom = bottomPadding + Spacing.S)
|
|
332
|
-
){
|
|
333
|
-
footerComponent.invoke()
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
Box(modifier = Modifier
|
|
337
|
-
.fillMaxWidth()
|
|
338
|
-
.height(6.dp)
|
|
339
|
-
.offset(x = 0.dp, y = (-6).dp)
|
|
340
|
-
.background(shadowBrush)
|
|
341
|
-
)
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
data class InputSearchLayoutParams(
|
|
346
|
-
val topPadding: Dp,
|
|
347
|
-
val startPadding: Dp,
|
|
348
|
-
val endPadding: Dp
|
|
349
|
-
)
|
|
350
|
-
@Composable
|
|
351
|
-
fun SearchAnimated(
|
|
352
|
-
isScrollInProgress: Boolean
|
|
353
|
-
) {
|
|
354
|
-
val scrollState = LocalScrollState.current
|
|
355
|
-
val options = LocalOptions.current
|
|
356
|
-
val navigator = LocalNavigator.current
|
|
357
|
-
val density = LocalDensity.current
|
|
358
|
-
|
|
359
|
-
val scrollDp = with(density) { scrollState.value.toDp() }
|
|
360
|
-
|
|
361
|
-
val inputSearchType = getInputSearchType(options)
|
|
362
|
-
val headerRightWidthPx = LocalHeaderRightWidthPx.current
|
|
363
|
-
val headerRightWidthDp = with(density) { headerRightWidthPx.intValue.toDp() }
|
|
364
|
-
|
|
365
|
-
if (inputSearchType == InputSearchType.None) return
|
|
366
|
-
val inputSearchProps = (options.headerType as? HeaderType.DefaultOrExtended)?.inputSearchProps ?: return
|
|
367
|
-
|
|
368
|
-
val minTopPadding = AppStatusBar.current
|
|
369
|
-
val maxTopPadding = AppStatusBar.current + HEADER_HEIGHT.dp
|
|
370
|
-
val minStartPadding = Spacing.M
|
|
371
|
-
val maxStartPadding = if (options.hiddenBack) Spacing.M else 52.dp
|
|
372
|
-
val minEndPadding = Spacing.M
|
|
373
|
-
val maxEndPadding = headerRightWidthDp + if (options.headerRight is HeaderRight.None) Spacing.M else Spacing.M * 2
|
|
374
|
-
|
|
375
|
-
val targetColor = lerp(
|
|
376
|
-
AppTheme.current.colors.background.surface,
|
|
377
|
-
AppTheme.current.colors.background.default,
|
|
378
|
-
(scrollDp / minTopPadding).coerceIn(0f, 1f)
|
|
379
|
-
)
|
|
380
|
-
val animatedColor by animateColorAsState(targetValue = targetColor, label = "BackgroundColor")
|
|
381
|
-
|
|
382
|
-
val layoutParams = when (inputSearchType) {
|
|
383
|
-
InputSearchType.Header -> {
|
|
384
|
-
InputSearchLayoutParams(
|
|
385
|
-
topPadding = minTopPadding,
|
|
386
|
-
startPadding = maxStartPadding,
|
|
387
|
-
endPadding = maxEndPadding
|
|
388
|
-
)
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
InputSearchType.Animated -> {
|
|
392
|
-
val animatedTopPadding by animateDpAsState(
|
|
393
|
-
targetValue = (maxTopPadding - scrollDp).coerceIn(minTopPadding, maxTopPadding),
|
|
394
|
-
label = "AnimatedTopPadding"
|
|
395
|
-
)
|
|
396
|
-
|
|
397
|
-
val animatedStartPadding by animateDpAsState(
|
|
398
|
-
targetValue = (minStartPadding + scrollDp).coerceIn(minStartPadding, maxStartPadding),
|
|
399
|
-
label = "AnimatedStartPadding"
|
|
400
|
-
)
|
|
401
|
-
|
|
402
|
-
val animatedEndPadding by animateDpAsState(
|
|
403
|
-
targetValue = (minEndPadding + scrollDp).coerceIn(minEndPadding, maxEndPadding),
|
|
404
|
-
label = "AnimatedEndPadding"
|
|
405
|
-
)
|
|
406
|
-
|
|
407
|
-
val maxPadding = remember(maxTopPadding, maxStartPadding, maxEndPadding) {
|
|
408
|
-
maxOf(maxEndPadding, maxStartPadding, maxTopPadding)
|
|
409
|
-
}
|
|
410
|
-
val snapScrollValue = with(density) { maxPadding.toPx().toInt() }
|
|
411
|
-
|
|
412
|
-
LaunchedEffect(isScrollInProgress && scrollState.value != 0 && scrollState.value != snapScrollValue) {
|
|
413
|
-
if (scrollDp < maxPadding) {
|
|
414
|
-
if (!isScrollInProgress) {
|
|
415
|
-
val midpoint = (maxTopPadding - minTopPadding) / 2
|
|
416
|
-
|
|
417
|
-
if (scrollDp < midpoint) {
|
|
418
|
-
scrollState.animateScrollTo(0)
|
|
419
|
-
} else {
|
|
420
|
-
scrollState.animateScrollTo(snapScrollValue)
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
InputSearchLayoutParams(
|
|
427
|
-
topPadding = animatedTopPadding,
|
|
428
|
-
startPadding = animatedStartPadding,
|
|
429
|
-
endPadding = animatedEndPadding
|
|
430
|
-
)
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
InputSearchType.None -> return
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
Spacer(Modifier.height(layoutParams.topPadding))
|
|
437
|
-
Box(
|
|
438
|
-
modifier = Modifier
|
|
439
|
-
.height(HEADER_HEIGHT.dp)
|
|
440
|
-
.fillMaxWidth()
|
|
441
|
-
.padding(
|
|
442
|
-
start = layoutParams.startPadding,
|
|
443
|
-
end = layoutParams.endPadding
|
|
444
|
-
),
|
|
445
|
-
contentAlignment = Alignment.Center
|
|
446
|
-
) {
|
|
447
|
-
InputSearch(
|
|
448
|
-
inputSearchProps = inputSearchProps.copy(
|
|
449
|
-
backgroundColor = animatedColor,
|
|
450
|
-
onPressButtonText = {
|
|
451
|
-
navigator.pop()
|
|
452
|
-
}
|
|
453
|
-
)
|
|
454
|
-
)
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
@Composable
|
|
459
|
-
internal fun isKeyboardVisible(): Boolean {
|
|
460
|
-
val ime = WindowInsets.ime
|
|
461
|
-
val density = LocalDensity.current
|
|
462
|
-
return ime.getBottom(density) > 0
|
|
463
|
-
}
|
|
464
|
-
private fun quantize(value: Int, stepPx: Int): Int {
|
|
465
|
-
if (stepPx <= 1) return value
|
|
466
|
-
return (value / stepPx) * stepPx
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
@Composable
|
|
470
|
-
fun LazyListState.proxyScrollState(
|
|
471
|
-
thresholdPx: Int = 200,
|
|
472
|
-
stepPx: Int = 4
|
|
473
|
-
): Pair<ScrollState, Boolean> {
|
|
474
|
-
val scrollState = rememberScrollState()
|
|
475
|
-
val locked = remember { mutableStateOf(false) }
|
|
476
|
-
|
|
477
|
-
LaunchedEffect(this, scrollState, thresholdPx, stepPx) {
|
|
478
|
-
snapshotFlow { firstVisibleItemIndex to firstVisibleItemScrollOffset }
|
|
479
|
-
.collect { (index, offset) ->
|
|
480
|
-
val rawTarget = if (index == 0) offset else SCROLLED_PAST_FIRST_ITEM_THRESHOLD
|
|
481
|
-
val shouldLock = rawTarget > thresholdPx
|
|
482
|
-
if (locked.value != shouldLock) locked.value = shouldLock
|
|
483
|
-
|
|
484
|
-
val desired = if (shouldLock) thresholdPx else quantize(rawTarget, stepPx)
|
|
485
|
-
|
|
486
|
-
if (scrollState.value != desired) {
|
|
487
|
-
scrollState.scrollTo(desired.coerceAtLeast(0))
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
val inProgress = remember { mutableStateOf(false) }
|
|
493
|
-
LaunchedEffect(this, thresholdPx) {
|
|
494
|
-
snapshotFlow { isScrollInProgress }
|
|
495
|
-
.collect { progressing ->
|
|
496
|
-
inProgress.value = if (locked.value) false else progressing
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
return scrollState to inProgress.value
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
@Composable
|
|
504
|
-
fun ScrollState.proxyLimitedScrollState(
|
|
505
|
-
thresholdPx: Int = 200,
|
|
506
|
-
stepPx: Int = 4
|
|
507
|
-
): Pair<ScrollState, Boolean> {
|
|
508
|
-
val proxy = rememberScrollState()
|
|
509
|
-
val locked = remember { mutableStateOf(false) }
|
|
510
|
-
|
|
511
|
-
LaunchedEffect(this, proxy, thresholdPx, stepPx) {
|
|
512
|
-
snapshotFlow { value }
|
|
513
|
-
.collect { rawTarget ->
|
|
514
|
-
val shouldLock = rawTarget > thresholdPx
|
|
515
|
-
if (locked.value != shouldLock) locked.value = shouldLock
|
|
516
|
-
|
|
517
|
-
val desired = if (shouldLock) thresholdPx else quantize(rawTarget, stepPx)
|
|
518
|
-
|
|
519
|
-
if (proxy.value != desired) {
|
|
520
|
-
proxy.scrollTo(desired.coerceAtLeast(0))
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
val inProgress = remember { mutableStateOf(false) }
|
|
526
|
-
LaunchedEffect(this, thresholdPx) {
|
|
527
|
-
snapshotFlow { isScrollInProgress }
|
|
528
|
-
.collect { progressing ->
|
|
529
|
-
inProgress.value = if (locked.value) false else progressing
|
|
530
|
-
}
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
return proxy to inProgress.value
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
private const val SCROLLED_PAST_FIRST_ITEM_THRESHOLD = 10_000
|
|
537
|
-
|
|
538
|
-
internal val LocalScrollState = staticCompositionLocalOf<ScrollState> { error("No Scroll State provided") }
|
|
539
|
-
internal val LocalOptions = staticCompositionLocalOf<NavigationOptions> { error("No NavigationOptions provided") }
|
|
540
|
-
|
|
541
|
-
val StackScreenScrollableState = staticCompositionLocalOf<ScrollableState?> { null }
|
|
542
|
-
|
|
543
|
-
internal fun getInputSearchType(options: NavigationOptions): InputSearchType{
|
|
544
|
-
return when (val headerType = options.headerType) {
|
|
545
|
-
is HeaderType.DefaultOrExtended -> when {
|
|
546
|
-
headerType.inputSearchProps == null -> InputSearchType.None
|
|
547
|
-
headerType.useAnimated -> InputSearchType.Animated
|
|
548
|
-
else -> InputSearchType.Header
|
|
549
|
-
}
|
|
550
|
-
else -> InputSearchType.None
|
|
551
|
-
}
|
|
552
|
-
}
|