@momo-kits/native-kits 0.152.4-beta.7 → 0.152.4-maxapi

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.
@@ -1,6 +1,6 @@
1
1
  Pod::Spec.new do |spec|
2
2
  spec.name = 'MoMoComposeKits'
3
- spec.version = '0.152.4'
3
+ spec.version = '0.0.1'
4
4
  spec.homepage = 'MoMoComposeKits'
5
5
  spec.source = { :http=> ''}
6
6
  spec.authors = 'M_SERVICE'
@@ -76,7 +76,7 @@ kotlin {
76
76
  implementation(libs.coil.multiplatform.network.ktor)
77
77
  implementation(libs.jetbrains.serialization.json)
78
78
  implementation(libs.kotlinx.datetime)
79
- api(project(":NativeMaxApi"))
79
+ api(libs.native.max.api)
80
80
  }
81
81
  }
82
82
  val androidMain by getting {
@@ -1,8 +1,6 @@
1
1
  package vn.momo.kits.application
2
2
 
3
- import androidx.compose.animation.core.Animatable
4
3
  import androidx.compose.animation.core.animateFloatAsState
5
- import androidx.compose.animation.core.tween
6
4
  import androidx.compose.foundation.ScrollState
7
5
  import androidx.compose.foundation.background
8
6
  import androidx.compose.foundation.gestures.detectTapGestures
@@ -15,23 +13,14 @@ import androidx.compose.foundation.layout.asPaddingValues
15
13
  import androidx.compose.foundation.layout.aspectRatio
16
14
  import androidx.compose.foundation.layout.fillMaxSize
17
15
  import androidx.compose.foundation.layout.fillMaxWidth
18
- import androidx.compose.foundation.layout.height
19
16
  import androidx.compose.foundation.layout.ime
20
17
  import androidx.compose.foundation.layout.imePadding
21
- import androidx.compose.foundation.layout.offset
22
18
  import androidx.compose.foundation.layout.padding
23
19
  import androidx.compose.foundation.layout.systemBars
24
20
  import androidx.compose.foundation.rememberScrollState
25
21
  import androidx.compose.foundation.verticalScroll
26
22
  import androidx.compose.runtime.Composable
27
- import androidx.compose.runtime.CompositionLocalProvider
28
- import androidx.compose.runtime.DisposableEffect
29
- import androidx.compose.runtime.LaunchedEffect
30
23
  import androidx.compose.runtime.getValue
31
- import androidx.compose.runtime.mutableStateOf
32
- import androidx.compose.runtime.remember
33
- import androidx.compose.runtime.setValue
34
- import androidx.compose.runtime.staticCompositionLocalOf
35
24
  import androidx.compose.ui.Alignment
36
25
  import androidx.compose.ui.Modifier
37
26
  import androidx.compose.ui.graphics.Color
@@ -41,24 +30,15 @@ import androidx.compose.ui.layout.onGloballyPositioned
41
30
  import androidx.compose.ui.platform.LocalDensity
42
31
  import androidx.compose.ui.platform.LocalSoftwareKeyboardController
43
32
  import androidx.compose.ui.unit.Dp
44
- import androidx.compose.ui.unit.IntOffset
45
33
  import androidx.compose.ui.unit.dp
46
34
  import androidx.compose.ui.unit.min
47
35
  import androidx.compose.ui.zIndex
48
- import kotlinx.coroutines.CoroutineScope
49
- import kotlinx.coroutines.Dispatchers
50
- import kotlinx.coroutines.SupervisorJob
51
- import kotlinx.coroutines.cancel
52
- import kotlinx.coroutines.delay
53
- import kotlinx.coroutines.launch
54
36
  import vn.momo.kits.components.InputSearchProps
55
- import vn.momo.kits.const.AppNavigationBar
56
37
  import vn.momo.kits.const.AppTheme
57
38
  import vn.momo.kits.const.Colors
58
39
  import vn.momo.kits.const.Spacing
59
40
  import vn.momo.kits.modifier.conditional
60
41
  import vn.momo.kits.modifier.shadow
61
- import vn.momo.kits.navigation.component.SnackBar
62
42
  import vn.momo.kits.platform.getAndroidBuildVersion
63
43
  import vn.momo.kits.utils.getAppStatusBarHeight
64
44
 
@@ -122,134 +102,97 @@ fun Screen(
122
102
  animatedHeader?.composable?.invoke(scrollState.value)
123
103
  }
124
104
  }
125
- val helper = remember { ScreenHelper() }
126
105
 
127
- DisposableEffect(Unit) {
128
- onDispose { helper.dispose() }
129
- }
130
-
131
- CompositionLocalProvider(
132
- LocalScreenHelper provides helper
106
+ Box(
107
+ Modifier.fillMaxSize()
108
+ .background(backgroundColor ?: AppTheme.current.colors.background.default)
109
+ .conditional(useAvoidKeyboard && getAndroidBuildVersion() > 29) {
110
+ imePadding()
111
+ }
133
112
  ) {
134
- Box(
135
- Modifier.fillMaxSize()
136
- .background(backgroundColor ?: AppTheme.current.colors.background.default)
137
- .conditional(useAvoidKeyboard && getAndroidBuildVersion() > 29) {
138
- imePadding()
139
- }
140
- ) {
141
- val footerHeightPx = remember { mutableStateOf(0) }
142
113
 
143
- Box(Modifier.zIndex(1f)) {
144
- if (animatedHeader === null) {
145
- HeaderBackground(
146
- headerType = headerType,
147
- scrollState = scrollState.value,
148
- headerTransparent = headerTransparent
149
- )
150
- }
151
- }
114
+ if (animatedHeader === null) {
115
+ HeaderBackground(
116
+ headerType = headerType,
117
+ scrollState = scrollState.value,
118
+ headerTransparent = headerTransparent
119
+ )
120
+ }
152
121
 
153
- Box(Modifier.zIndex(5f)) {
154
- Header(
155
- headerType = headerType,
156
- title = title,
157
- titlePosition = titlePosition,
158
- headerRight = headerRight,
159
- headerRightWidth = headerRightWidth,
160
- goBack = goBack,
161
- opacity = opacity,
162
- animatedHeader = animatedHeader,
163
- inputSearchProps = inputSearchProps,
164
- scrollState = scrollState.value,
165
- useAnimationSearch = useAnimationSearch,
166
- tintColor = tintColor
167
- )
168
- }
122
+ Header(
123
+ headerType = headerType,
124
+ title = title,
125
+ titlePosition = titlePosition,
126
+ headerRight = headerRight,
127
+ headerRightWidth = headerRightWidth,
128
+ goBack = goBack,
129
+ opacity = opacity,
130
+ animatedHeader = animatedHeader,
131
+ inputSearchProps = inputSearchProps,
132
+ scrollState = scrollState.value,
133
+ useAnimationSearch = useAnimationSearch,
134
+ tintColor = tintColor
135
+ )
136
+
137
+ Column(
138
+ modifier = Modifier.fillMaxSize()
139
+ .padding( top = when {
140
+ animatedHeader != null -> 0.dp
141
+ headerType == HeaderType.NONE -> 0.dp
142
+ fullScreenContent -> 0.dp
143
+ else -> statusBarHeight + HEADER_HEIGHT.dp
144
+ })
145
+ .pointerInput(Unit) {
146
+ detectTapGestures(onTap = {
147
+ keyboardController?.hide()
148
+ })
149
+ }
150
+ .zIndex(1f),
151
+ ) {
169
152
 
170
- Box(Modifier.zIndex(2f).fillMaxSize()){
171
- Column(
172
- modifier = Modifier.fillMaxSize()
173
- .padding( top = when {
174
- animatedHeader != null -> 0.dp
175
- headerType == HeaderType.NONE -> 0.dp
176
- fullScreenContent -> 0.dp
177
- else -> statusBarHeight + HEADER_HEIGHT.dp
178
- })
179
- .pointerInput(Unit) {
180
- detectTapGestures(onTap = {
181
- keyboardController?.hide()
182
- })
153
+ Column(
154
+ modifier = Modifier
155
+ .conditional(scrollable) { weight(1f) }
156
+ .conditional(onContentLayout != null) {
157
+ onGloballyPositioned(onContentLayout ?: {})
158
+ }
159
+ .conditional(scrollable) { verticalScroll(scrollState) },
160
+ verticalArrangement = verticalArrangement,
161
+ horizontalAlignment = horizontalAlignment
162
+ ) {
163
+ Box {
164
+ if (animatedHeader !== null) headerAnimated()
165
+ Column {
166
+ if (animatedHeader !== null) {
167
+ Spacer(modifier = Modifier.padding(top = statusBarHeight + HEADER_HEIGHT.dp + layoutOffset))
183
168
  }
184
- .zIndex(1f),
185
- ) {
186
169
 
187
- Column(
188
- modifier = Modifier
189
- .conditional(scrollable) { weight(1f) }
190
- .conditional(onContentLayout != null) {
191
- onGloballyPositioned(onContentLayout ?: {})
192
- }
193
- .conditional(scrollable) { verticalScroll(scrollState) },
194
- verticalArrangement = verticalArrangement,
195
- horizontalAlignment = horizontalAlignment
196
- ) {
197
- Box {
198
- if (animatedHeader !== null) headerAnimated()
199
- Column {
200
- if (animatedHeader !== null) {
201
- Spacer(modifier = Modifier.padding(top = statusBarHeight + HEADER_HEIGHT.dp + layoutOffset))
202
- }
203
-
204
- if (useAnimationSearch && inputSearchProps != null && headerType == HeaderType.EXTENDED) {
205
- Spacer(modifier = Modifier.padding(top = (HEADER_HEIGHT.dp + Spacing.S)))
206
- }
207
- content()
208
- }
170
+ if (useAnimationSearch && inputSearchProps != null && headerType == HeaderType.EXTENDED) {
171
+ Spacer(modifier = Modifier.padding(top = (HEADER_HEIGHT.dp + Spacing.S)))
209
172
  }
210
- }
211
-
212
- footer?.let {
213
- val footerHeight = with(LocalDensity.current) { footerHeightPx.value.toDp() }
214
- Spacer(Modifier.height(footerHeight))
173
+ content()
215
174
  }
216
175
  }
217
176
  }
218
177
 
219
- Box(Modifier.zIndex(4f).align(Alignment.BottomCenter)) {
220
- footer?.let {
221
- Footer(
222
- footer = footer,
223
- bottom = bottomPadding,
224
- onFooterMeasured = { footerHeightPx.value = it }
225
- )
226
- }
227
- }
228
-
229
- Column (Modifier.zIndex(6f)) {
230
- if (fabProps != null) {
231
- FloatingButton(
232
- scrollPosition = fabProps.scrollState?.value ?: scrollState.value,
233
- onClick = fabProps.onClick,
234
- containerColor = AppTheme.current.colors.primary,
235
- bottom = fabProps.bottom
236
- ?: if (footer != null) bottomPadding + 76.dp else bottomPadding + 12.dp,
237
- icon = fabProps.icon,
238
- iconColor = fabProps.iconColor,
239
- text = fabProps.label,
240
- size = fabProps.size,
241
- position = fabProps.position ?: FABPosition.END,
242
- )
243
- }
178
+ footer?.let {
179
+ Footer(footer, bottomPadding)
244
180
  }
181
+ }
245
182
 
246
- Box(
247
- modifier = Modifier
248
- .align(Alignment.BottomCenter)
249
- .zIndex(3f)
250
- ) {
251
- ScreenSnackBarHost(footerHeightPx.value)
252
- }
183
+ if (fabProps != null) {
184
+ FloatingButton(
185
+ scrollPosition = fabProps.scrollState?.value ?: scrollState.value,
186
+ onClick = fabProps.onClick,
187
+ containerColor = AppTheme.current.colors.primary,
188
+ bottom = fabProps.bottom
189
+ ?: if (footer != null) bottomPadding + 76.dp else bottomPadding + 12.dp,
190
+ icon = fabProps.icon,
191
+ iconColor = fabProps.iconColor,
192
+ text = fabProps.label,
193
+ size = fabProps.size,
194
+ position = fabProps.position ?: FABPosition.END,
195
+ )
253
196
  }
254
197
  }
255
198
  }
@@ -263,11 +206,7 @@ internal fun isKeyboardVisible(): Boolean {
263
206
  }
264
207
 
265
208
  @Composable
266
- fun Footer(
267
- footer: @Composable (() -> Unit)? = null,
268
- bottom: Dp = 0.dp,
269
- onFooterMeasured: ((Int) -> Unit)? = null
270
- ) {
209
+ fun Footer(footer: @Composable (() -> Unit)? = null, bottom: Dp = 0.dp) {
271
210
  Box(
272
211
  Modifier
273
212
  .shadow(
@@ -277,9 +216,6 @@ fun Footer(
277
216
  offsetY = (-4).dp
278
217
  )
279
218
  .background(AppTheme.current.colors.background.surface)
280
- .onGloballyPositioned {
281
- onFooterMeasured?.invoke(it.size.height)
282
- }
283
219
  ) {
284
220
  Box(
285
221
  Modifier.fillMaxWidth()
@@ -292,98 +228,6 @@ fun Footer(
292
228
  }
293
229
 
294
230
 
295
- class ScreenHelper {
296
-
297
- private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Main)
298
-
299
- internal var snackBarState by mutableStateOf<SnackBarData?>(null)
300
-
301
- internal var requestHide by mutableStateOf(false)
302
-
303
- fun showSnackBar(snackBar: SnackBar, onDismiss: (() -> Unit)? = null) {
304
- scope.launch {
305
- requestHide = false
306
- snackBarState = SnackBarData(snackBar, onDismiss)
307
- }
308
- }
309
-
310
- fun hideSnackBar() {
311
- scope.launch {
312
- requestHide = true
313
- }
314
- }
315
-
316
- internal fun removeSnackBarNow() {
317
- snackBarState = null
318
- requestHide = false
319
- }
320
-
321
- fun dispose() {
322
- scope.cancel()
323
- }
324
- }
325
- data class SnackBarData(
326
- val type: SnackBar,
327
- val onDismiss: (() -> Unit)?
328
- )
329
-
330
- val LocalScreenHelper = staticCompositionLocalOf<ScreenHelper> {
331
- error("No Screen helper provided")
332
- }
333
-
334
- @Composable
335
- fun ScreenSnackBarHost(footerHeightPx: Int) {
336
- val helper = LocalScreenHelper.current
337
- val snackBarData = helper.snackBarState ?: return
338
-
339
-
340
- val snackBarHeight = when (snackBarData.type) {
341
- is SnackBar.Custom -> snackBarData.type.heightContent
342
- is SnackBar.Toast -> 300f
343
- }
344
-
345
- val startPosition = if (footerHeightPx > 0) 0f else snackBarHeight
346
- val targetPosition = if (footerHeightPx > 0) -footerHeightPx.toFloat() else -with(LocalDensity.current) { AppNavigationBar.current.toPx() }
347
-
348
- val offsetY = remember { Animatable(startPosition) }
349
-
350
- LaunchedEffect(snackBarData, footerHeightPx) {
351
- offsetY.snapTo(startPosition)
352
- offsetY.animateTo(targetPosition, tween(350))
353
- }
354
-
355
- LaunchedEffect(helper.requestHide) {
356
- if (helper.requestHide) {
357
- offsetY.animateTo(startPosition, tween(200))
358
- helper.removeSnackBarNow()
359
- snackBarData.onDismiss?.invoke()
360
- }
361
- }
362
-
363
- LaunchedEffect(snackBarData.type.duration) {
364
- val duration = snackBarData.type.duration
365
- if (duration != null) {
366
- delay(duration)
367
- helper.hideSnackBar()
368
- }
369
- }
370
-
371
- DisposableEffect(Unit) {
372
- onDispose { snackBarData.onDismiss?.invoke() }
373
- }
374
-
375
- Box(
376
- modifier = Modifier
377
- .offset { IntOffset(0, offsetY.value.toInt()) }
378
- .fillMaxWidth()
379
- ) {
380
- when (val type = snackBarData.type) {
381
- is SnackBar.Custom -> type.content()
382
- is SnackBar.Toast -> {}
383
- }
384
- }
385
- }
386
-
387
231
 
388
232
 
389
233
 
@@ -1,13 +1,9 @@
1
1
  package vn.momo.kits.navigation
2
2
 
3
- import androidx.compose.foundation.layout.Box
4
- import androidx.compose.foundation.layout.fillMaxSize
5
3
  import androidx.compose.runtime.Composable
6
4
  import androidx.compose.runtime.MutableState
7
5
  import androidx.compose.runtime.mutableStateOf
8
6
  import androidx.compose.runtime.staticCompositionLocalOf
9
- import androidx.compose.ui.Alignment
10
- import androidx.compose.ui.Modifier
11
7
  import androidx.navigation.NavController
12
8
  import kotlinx.coroutines.CoroutineScope
13
9
  import kotlinx.coroutines.Dispatchers
@@ -16,8 +12,6 @@ import kotlinx.coroutines.cancel
16
12
  import kotlinx.coroutines.delay
17
13
  import kotlinx.coroutines.launch
18
14
  import kotlinx.serialization.Serializable
19
- import vn.momo.kits.navigation.BottomHeader.*
20
- import vn.momo.kits.navigation.component.SnackBar
21
15
  import vn.momo.maxapi.IMaxApi
22
16
 
23
17
  class Navigator(
@@ -43,36 +37,25 @@ class Navigator(
43
37
  fun pop(count: Int = 1, callBack: (() -> Unit)? = null) {
44
38
  scope.launch {
45
39
  repeat(count) {
46
- if (OverplayComponentRegistry.getOverplayType() == OverplayComponentType.SNACK_BAR){
47
- dismissScreen()
40
+ if (OverplayComponentRegistry.isOverplayShowing()){
41
+ OverplayComponentRegistry.clear()
42
+ delay(300L)
48
43
  OverplayComponentRegistry.hardClearAfterDismiss()
49
- }
50
- else if (OverplayComponentRegistry.isOverplayShowing()){
51
- dismissOverplay()
52
44
  } else {
53
- dismissScreen()
45
+ if (navController.previousBackStackEntry != null){
46
+ navController.popBackStack()
47
+ delay(300L)
48
+ DynamicScreenRegistry.getLatestScreen()?.let { it1 ->
49
+ DynamicScreenRegistry.unregisterScreen(it1.id)
50
+ }
51
+ } else {
52
+ maxApi?.dismiss { }
53
+ }
54
54
  }
55
55
  }
56
56
  callBack?.invoke()
57
57
  }
58
58
  }
59
- private suspend fun CoroutineScope.dismissOverplay(isDelay: Boolean = true) {
60
- OverplayComponentRegistry.clear()
61
- if (isDelay) delay(300L)
62
- OverplayComponentRegistry.hardClearAfterDismiss()
63
- }
64
-
65
- private suspend fun CoroutineScope.dismissScreen() {
66
- if (navController.previousBackStackEntry != null){
67
- navController.popBackStack()
68
- delay(300L)
69
- DynamicScreenRegistry.getLatestScreen()?.let { it1 ->
70
- DynamicScreenRegistry.unregisterScreen(it1.id)
71
- }
72
- } else {
73
- maxApi?.dismiss { }
74
- }
75
- }
76
59
 
77
60
  fun present(content: @Composable () -> Unit, options: NavigationOptions? = null) {
78
61
  val route = DynamicScreenRegistry.register(content, options)
@@ -93,8 +76,7 @@ class Navigator(
93
76
  barrierDismissible: Boolean = true,
94
77
  onDismiss: (() -> Unit)? = null
95
78
  ){
96
- val id = DynamicScreenRegistry.getLatestScreen()?.id ?: -1
97
- OverplayComponentRegistry.registerOverplay(id, content, OverplayComponentType.MODAL, false, barrierDismissible, onDismiss)
79
+ OverplayComponentRegistry.registerModal(content, false, barrierDismissible, onDismiss, false)
98
80
  }
99
81
 
100
82
  fun showBottomSheet(
@@ -104,30 +86,7 @@ class Navigator(
104
86
  onDismiss: (() -> Unit)? = null,
105
87
  bottomSheetHeader: BottomHeader? = null
106
88
  ){
107
- val id = DynamicScreenRegistry.getLatestScreen()?.id ?: -1
108
- OverplayComponentRegistry.registerOverplay(id, content, OverplayComponentType.BOTTOM_SHEET, isSurface, barrierDismissible, onDismiss, bottomSheetHeader)
109
- }
110
-
111
- fun showSnackBar(snackBar: SnackBar, onDismiss: (() -> Unit)? = null) {
112
- val id = DynamicScreenRegistry.getLatestScreen()?.id ?: -1
113
- scope.launch {
114
- OverplayComponentRegistry.registerOverplay(
115
- id = id,
116
- content = {
117
- SnackBar(snackBar, onDismiss)
118
- },
119
- type = OverplayComponentType.SNACK_BAR,
120
- onDismiss = onDismiss
121
- )
122
- }
123
- }
124
-
125
- fun hideSnackBar() {
126
- scope.launch {
127
- OverplayComponentRegistry.clear()
128
- delay(250L)
129
- OverplayComponentRegistry.hardClearAfterDismiss()
130
- }
89
+ OverplayComponentRegistry.registerModal(content, isSurface, barrierDismissible, onDismiss, true, bottomSheetHeader)
131
90
  }
132
91
 
133
92
  fun dispose(){
@@ -200,21 +159,13 @@ sealed class OverplayComponentParams {
200
159
  val barrierDismissible: Boolean = true,
201
160
  val bottomSheetHeader: BottomHeader? = null,
202
161
  ) : OverplayComponentParams()
203
-
204
- class SnackBar() : OverplayComponentParams()
205
162
  }
206
163
 
207
164
  data class OverplayComponent(
208
- val id: Int,
209
- val type: OverplayComponentType? = null,
210
165
  val content: @Composable () -> Unit,
211
166
  val params: OverplayComponentParams? = null
212
167
  )
213
168
 
214
- enum class OverplayComponentType {
215
- MODAL, BOTTOM_SHEET, SNACK_BAR
216
- }
217
-
218
169
  object OverplayComponentRegistry {
219
170
  private var currentOverlayComponent : MutableState<OverplayComponent?> = mutableStateOf(null)
220
171
  private var requestClose: (() -> Unit)? = null
@@ -222,24 +173,20 @@ object OverplayComponentRegistry {
222
173
  requestClose = handler
223
174
  }
224
175
 
225
- fun registerOverplay(
226
- id: Int,
176
+ fun registerModal(
227
177
  content: @Composable () -> Unit,
228
- type: OverplayComponentType,
229
178
  isSurface: Boolean = false,
230
179
  barrierDismissible: Boolean = true,
231
180
  onDismiss: (() -> Unit)?,
181
+ isBottomSheet: Boolean = false,
232
182
  bottomSheetHeader: BottomHeader? = null,
233
183
  ){
234
- val params = when(type){
235
- OverplayComponentType.MODAL -> OverplayComponentParams.Modal(onDismiss, barrierDismissible)
236
- OverplayComponentType.BOTTOM_SHEET -> OverplayComponentParams.BottomSheet(isSurface, onDismiss, barrierDismissible, bottomSheetHeader)
237
- OverplayComponentType.SNACK_BAR -> OverplayComponentParams.SnackBar()
184
+ val params = if (isBottomSheet) {
185
+ OverplayComponentParams.BottomSheet(isSurface, onDismiss, barrierDismissible, bottomSheetHeader)
186
+ } else {
187
+ OverplayComponentParams.Modal(onDismiss, barrierDismissible)
238
188
  }
239
-
240
189
  currentOverlayComponent.value = OverplayComponent(
241
- id = id,
242
- type = type,
243
190
  content = content,
244
191
  params = params
245
192
  )
@@ -247,10 +194,6 @@ object OverplayComponentRegistry {
247
194
 
248
195
  fun isOverplayShowing(): Boolean = currentOverlayComponent.value != null
249
196
 
250
- fun getOverplayType(): OverplayComponentType? = currentOverlayComponent.value?.type
251
-
252
- fun currentRootId(): Int? = currentOverlayComponent.value?.id
253
-
254
197
  fun clear(){
255
198
  if (requestClose != null) {
256
199
  requestClose?.invoke()
@@ -268,35 +211,22 @@ object OverplayComponentRegistry {
268
211
  fun OverlayComponent(){
269
212
  val overplay = currentOverlayComponent.value ?: return
270
213
 
271
- when (val params = overplay.params) {
272
- is OverplayComponentParams.BottomSheet -> {
273
- BottomSheet(
274
- content = overplay.content,
275
- header = params.bottomSheetHeader ?: Title(),
276
- isSurface = params.isSurface,
277
- barrierDismissible = params.barrierDismissible,
278
- onDismiss = params.onDismiss
279
- )
280
- }
281
-
282
- is OverplayComponentParams.Modal -> {
283
- ModalScreen(
284
- content = overplay.content,
285
- barrierDismissible = params.barrierDismissible,
286
- onDismiss = params.onDismiss
287
- )
288
- }
289
-
290
- is OverplayComponentParams.SnackBar -> {
291
- Box(
292
- modifier = Modifier.fillMaxSize(),
293
- contentAlignment = Alignment.BottomCenter
294
- ) {
295
- overplay.content()
296
- }
297
- }
298
-
299
- null -> {}
214
+ if (overplay.params is OverplayComponentParams.BottomSheet) {
215
+ val param = overplay.params
216
+ BottomSheet(
217
+ content = overplay.content,
218
+ header = param.bottomSheetHeader ?: BottomHeader.Title(),
219
+ isSurface = param.isSurface,
220
+ barrierDismissible = param.barrierDismissible,
221
+ onDismiss = param.onDismiss
222
+ )
223
+ } else if (overplay.params is OverplayComponentParams.Modal) {
224
+ val param = overplay.params
225
+ ModalScreen(
226
+ content = overplay.content,
227
+ barrierDismissible = param.barrierDismissible,
228
+ onDismiss = param.onDismiss
229
+ )
300
230
  }
301
231
  }
302
232
  }
@@ -6,7 +6,6 @@ import androidx.compose.foundation.ScrollState
6
6
  import androidx.compose.foundation.background
7
7
  import androidx.compose.foundation.gestures.ScrollableState
8
8
  import androidx.compose.foundation.layout.Box
9
- import androidx.compose.foundation.layout.BoxScope
10
9
  import androidx.compose.foundation.layout.Column
11
10
  import androidx.compose.foundation.layout.ColumnScope
12
11
  import androidx.compose.foundation.layout.Spacer
@@ -116,11 +115,11 @@ internal fun StackScreen(
116
115
  HeaderBackground()
117
116
  }
118
117
 
119
- Box(Modifier.zIndex(5f)) {
118
+ Box(Modifier.zIndex(4f)) {
120
119
  Header()
121
120
  }
122
121
 
123
- Column (Modifier.zIndex(6f)) {
122
+ Column (Modifier.zIndex(5f)) {
124
123
  SearchAnimated(isScrollInProgress = scrollInProcess)
125
124
  }
126
125
 
@@ -128,15 +127,14 @@ internal fun StackScreen(
128
127
  MainContent(content = content)
129
128
  }
130
129
 
131
- Box(Modifier.zIndex(4f).align(Alignment.BottomCenter)) {
132
- FooterContent()
133
- }
134
-
135
- Box(Modifier.zIndex(7f)){
130
+ Box(Modifier.zIndex(5f)){
136
131
  FloatingContent()
137
132
  }
138
133
 
139
- OverplayView(bottomTabIndex = bottomTabIndex, id = id)
134
+ Box(Modifier.zIndex(6f).fillMaxSize()){
135
+ if (bottomTabIndex != -1) return@Box
136
+ OverplayComponentRegistry.OverlayComponent()
137
+ }
140
138
  }
141
139
  }
142
140
  }
@@ -193,9 +191,9 @@ fun ColumnScope.MainContent(content: @Composable ()-> Unit){
193
191
  }
194
192
 
195
193
  if (options.footerComponent != null){
196
- val footerHeight = LocalFooterHeightPx.current
197
- val footerHeightDp = with(density) { footerHeight.value.toDp() }
198
- Spacer(Modifier.height(footerHeightDp))
194
+ val isKeyboardVisible = isKeyboardVisible()
195
+ val bottomPadding = min(AppNavigationBar.current, if (isKeyboardVisible) 0.dp else 21.dp)
196
+ Footer(footerComponent = options.footerComponent, bottomPadding = bottomPadding)
199
197
  }
200
198
  }
201
199
 
@@ -219,29 +217,6 @@ fun ScreenContent(content: @Composable () -> Unit){
219
217
  }
220
218
  }
221
219
 
222
- @Composable
223
- fun FooterContent(){
224
- val options = LocalOptions.current
225
- if (options.footerComponent != null){
226
- val isKeyboardVisible = isKeyboardVisible()
227
- val bottomPadding = min(AppNavigationBar.current, if (isKeyboardVisible) 0.dp else 21.dp)
228
- Footer(footerComponent = options.footerComponent, bottomPadding = bottomPadding)
229
- }
230
- }
231
-
232
- @Composable
233
- fun OverplayView(bottomTabIndex: Int, id: Int){
234
- val overplayType = OverplayComponentRegistry.getOverplayType()
235
-
236
- if (overplayType != null) {
237
- Box(Modifier.zIndex(if (overplayType == OverplayComponentType.SNACK_BAR) 3f else 8f).fillMaxSize()){
238
- if (bottomTabIndex != -1) return@Box
239
- if (OverplayComponentRegistry.currentRootId() != id) return@Box
240
- OverplayComponentRegistry.OverlayComponent()
241
- }
242
- }
243
- }
244
-
245
220
  @Composable
246
221
  fun Footer(footerComponent: @Composable (() -> Unit)?, bottomPadding: Dp) {
247
222
  if (footerComponent == null) return
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/native-kits",
3
- "version": "0.152.4-beta.7",
3
+ "version": "0.152.4-maxapi",
4
4
  "private": false,
5
5
  "dependencies": {
6
6
  "@momo-platform/native-max-api": "1.0.18"
@@ -1,123 +0,0 @@
1
- package vn.momo.kits.navigation.component
2
-
3
- import androidx.compose.animation.core.Animatable
4
- import androidx.compose.animation.core.tween
5
- import androidx.compose.foundation.layout.Box
6
- import androidx.compose.foundation.layout.fillMaxWidth
7
- import androidx.compose.foundation.layout.offset
8
- import androidx.compose.foundation.layout.padding
9
- import androidx.compose.runtime.Composable
10
- import androidx.compose.runtime.DisposableEffect
11
- import androidx.compose.runtime.LaunchedEffect
12
- import androidx.compose.runtime.getValue
13
- import androidx.compose.runtime.mutableStateOf
14
- import androidx.compose.runtime.remember
15
- import androidx.compose.runtime.rememberCoroutineScope
16
- import androidx.compose.ui.Modifier
17
- import androidx.compose.ui.platform.LocalDensity
18
- import androidx.compose.ui.unit.IntOffset
19
- import androidx.compose.ui.unit.dp
20
- import androidx.compose.ui.unit.min
21
- import kotlinx.coroutines.delay
22
- import kotlinx.coroutines.launch
23
- import vn.momo.kits.const.AppNavigationBar
24
- import vn.momo.kits.const.Spacing
25
- import vn.momo.kits.navigation.LocalFooterHeightPx
26
- import vn.momo.kits.navigation.LocalNavigator
27
- import vn.momo.kits.navigation.LocalOptions
28
- import vn.momo.kits.navigation.OverplayComponentRegistry
29
-
30
- sealed class SnackBar(open val duration: Long? = null) {
31
- data class Custom(
32
- val content: @Composable () -> Unit,
33
- val heightContent: Float = 300f,
34
- override val duration: Long? = 3000L
35
- ) : SnackBar(duration)
36
-
37
- data class Toast(
38
- override val duration: Long? = 3000L
39
- ) : SnackBar(duration)
40
- }
41
-
42
- @Composable
43
- fun SnackBar(
44
- data: SnackBar,
45
- onDismiss: (() -> Unit)?
46
- ) {
47
- val navigator = LocalNavigator.current
48
- val options = LocalOptions.current
49
- val footerHeightPxState = LocalFooterHeightPx.current
50
-
51
- val snackBarHeight = when (data) {
52
- is SnackBar.Custom -> -data.heightContent
53
- is SnackBar.Toast -> -300f
54
- }
55
-
56
- val startPosition = if (options.footerComponent != null) 0f else -snackBarHeight
57
- val targetPosition = if (options.footerComponent != null) {
58
- footerHeightPxState.intValue.toFloat()
59
- } else {
60
- with(LocalDensity.current) { min(AppNavigationBar.current, 21.dp).toPx() }
61
- }
62
-
63
- val offsetY by remember { mutableStateOf(Animatable(startPosition)) }
64
- val coroutineScope = rememberCoroutineScope()
65
-
66
- suspend fun openEvent() {
67
- offsetY.snapTo(startPosition)
68
- offsetY.animateTo(
69
- targetValue = -targetPosition,
70
- animationSpec = tween(
71
- durationMillis = 350,
72
- )
73
- )
74
- }
75
-
76
- fun closeEvent() {
77
- coroutineScope.launch {
78
- offsetY.animateTo(
79
- targetValue = startPosition,
80
- animationSpec = tween(
81
- durationMillis = 200,
82
- )
83
- )
84
- navigator.hideSnackBar()
85
- }
86
- }
87
-
88
- LaunchedEffect(targetPosition) {
89
- openEvent()
90
- }
91
-
92
- LaunchedEffect(data.duration) {
93
- val duration = data.duration
94
- if (duration != null) {
95
- delay(duration)
96
- navigator.hideSnackBar()
97
- }
98
- }
99
-
100
- DisposableEffect(Unit) {
101
- OverplayComponentRegistry.bindClose {
102
- closeEvent()
103
- }
104
- onDispose {
105
- onDismiss?.invoke()
106
- }
107
- }
108
-
109
- Box(
110
- modifier = Modifier
111
- .offset { IntOffset(0, offsetY.value.toInt()) }
112
- .padding(bottom = Spacing.S)
113
- .fillMaxWidth()
114
- ) {
115
- when (data) {
116
- is SnackBar.Custom -> data.content()
117
- is SnackBar.Toast -> {}
118
- }
119
- }
120
- }
121
-
122
-
123
-