@momo-kits/native-kits 0.152.4-beta.9 → 0.152.4-scale.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderRight.kt +2 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/LiteScreen.kt +2 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Screen.kt +246 -78
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Badge.kt +3 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Chip.kt +21 -19
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Icon.kt +12 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Input.kt +22 -11
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputDropDown.kt +6 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputOTP.kt +4 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputPhoneNumber.kt +19 -24
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputSearch.kt +24 -19
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputTextArea.kt +25 -18
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Text.kt +3 -3
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Theme.kt +0 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Typography.kt +42 -7
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigator.kt +106 -36
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ScaleSizeScope.kt +8 -3
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackScreen.kt +34 -10
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTabBar.kt +11 -10
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderUser.kt +1 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/SnackBar.kt +125 -0
- package/ios/Badge/Badge.swift +0 -6
- package/ios/Badge/BadgeRibbon.swift +77 -9
- package/ios/Button/Button.swift +7 -7
- package/local.properties +8 -0
- package/package.json +1 -1
|
@@ -32,11 +32,12 @@ import androidx.compose.runtime.setValue
|
|
|
32
32
|
import androidx.compose.ui.Alignment
|
|
33
33
|
import androidx.compose.ui.Modifier
|
|
34
34
|
import androidx.compose.ui.focus.onFocusChanged
|
|
35
|
+
import androidx.compose.ui.text.TextStyle
|
|
35
36
|
import androidx.compose.ui.text.input.KeyboardType
|
|
36
37
|
import androidx.compose.ui.unit.dp
|
|
38
|
+
import androidx.compose.ui.unit.sp
|
|
37
39
|
import androidx.compose.ui.zIndex
|
|
38
40
|
import vn.momo.kits.const.AppTheme
|
|
39
|
-
import vn.momo.kits.const.Colors
|
|
40
41
|
import vn.momo.kits.const.Radius
|
|
41
42
|
import vn.momo.kits.const.Spacing
|
|
42
43
|
import vn.momo.kits.const.Typography
|
|
@@ -106,10 +107,12 @@ fun InputOTP(
|
|
|
106
107
|
handleChangeText("")
|
|
107
108
|
}
|
|
108
109
|
|
|
110
|
+
val fontSize = scaleSize(20.sp)
|
|
109
111
|
|
|
110
112
|
Column {
|
|
111
113
|
BasicTextField(
|
|
112
114
|
value = value,
|
|
115
|
+
textStyle = TextStyle(fontSize = fontSize),
|
|
113
116
|
onValueChange = handleChangeText,
|
|
114
117
|
singleLine = true,
|
|
115
118
|
keyboardOptions = KeyboardOptions.Default.copy(keyboardType = if (dataType == "number") KeyboardType.Number else KeyboardType.Ascii),
|
|
@@ -36,7 +36,9 @@ import vn.momo.kits.const.Colors
|
|
|
36
36
|
import vn.momo.kits.const.Radius
|
|
37
37
|
import vn.momo.kits.const.Spacing
|
|
38
38
|
import vn.momo.kits.const.Typography
|
|
39
|
+
import vn.momo.kits.const.scaleSize
|
|
39
40
|
import vn.momo.kits.modifier.setAutomationId
|
|
41
|
+
import vn.momo.kits.navigation.ScaleSizeScope
|
|
40
42
|
|
|
41
43
|
data class InputPhoneNumberSizeDetail(
|
|
42
44
|
val borderWidth: Dp,
|
|
@@ -113,18 +115,8 @@ fun InputPhoneNumber(
|
|
|
113
115
|
|
|
114
116
|
val testId = "input_phone_number"
|
|
115
117
|
|
|
116
|
-
val textStyle =
|
|
117
|
-
|
|
118
|
-
color = textColor,
|
|
119
|
-
))
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
val placeholderStyle = remember(placeholderColor) {
|
|
123
|
-
|
|
124
|
-
size.values.textStyle.merge(TextStyle(
|
|
125
|
-
color = placeholderColor
|
|
126
|
-
))
|
|
127
|
-
}
|
|
118
|
+
val textStyle = scaleSize(size.values.textStyle.copy(color = textColor))
|
|
119
|
+
val placeholderStyle = scaleSize(size.values.textStyle.copy(color = placeholderColor))
|
|
128
120
|
|
|
129
121
|
Column(modifier = modifier.setAutomationId(testId)) {
|
|
130
122
|
BasicTextField(
|
|
@@ -174,12 +166,13 @@ fun InputPhoneNumber(
|
|
|
174
166
|
alignment = Alignment.Center
|
|
175
167
|
)
|
|
176
168
|
)
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
169
|
+
ScaleSizeScope(disableScale = true) {
|
|
170
|
+
Text(
|
|
171
|
+
"+84",
|
|
172
|
+
color = textColor,
|
|
173
|
+
style = textStyle,
|
|
174
|
+
)
|
|
175
|
+
}
|
|
183
176
|
|
|
184
177
|
// Divider
|
|
185
178
|
Box(modifier = Modifier.padding(horizontal = Spacing.M)) {
|
|
@@ -193,12 +186,14 @@ fun InputPhoneNumber(
|
|
|
193
186
|
|
|
194
187
|
Box(Modifier.weight(1f)) {
|
|
195
188
|
if (text.value.isEmpty()) {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
189
|
+
ScaleSizeScope(disableScale = true) {
|
|
190
|
+
Text(
|
|
191
|
+
text = placeholder,
|
|
192
|
+
style = placeholderStyle,
|
|
193
|
+
color = placeholderColor,
|
|
194
|
+
modifier = Modifier.align(Alignment.CenterStart)
|
|
195
|
+
)
|
|
196
|
+
}
|
|
202
197
|
}
|
|
203
198
|
innerTextField()
|
|
204
199
|
}
|
|
@@ -9,10 +9,10 @@ import androidx.compose.foundation.layout.Row
|
|
|
9
9
|
import androidx.compose.foundation.layout.Spacer
|
|
10
10
|
import androidx.compose.foundation.layout.fillMaxHeight
|
|
11
11
|
import androidx.compose.foundation.layout.fillMaxWidth
|
|
12
|
-
import androidx.compose.foundation.layout.height
|
|
13
12
|
import androidx.compose.foundation.layout.padding
|
|
14
13
|
import androidx.compose.foundation.layout.size
|
|
15
14
|
import androidx.compose.foundation.layout.width
|
|
15
|
+
import androidx.compose.foundation.layout.wrapContentHeight
|
|
16
16
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
17
17
|
import androidx.compose.foundation.text.BasicTextField
|
|
18
18
|
import androidx.compose.foundation.text.KeyboardActions
|
|
@@ -39,6 +39,8 @@ import vn.momo.kits.const.Colors
|
|
|
39
39
|
import vn.momo.kits.const.Radius
|
|
40
40
|
import vn.momo.kits.const.Spacing
|
|
41
41
|
import vn.momo.kits.const.Typography
|
|
42
|
+
import vn.momo.kits.const.scaleSize
|
|
43
|
+
import vn.momo.kits.navigation.ScaleSizeScope
|
|
42
44
|
import vn.momo.kits.utils.ifTrue
|
|
43
45
|
|
|
44
46
|
@Composable
|
|
@@ -123,20 +125,25 @@ fun InputSearch(
|
|
|
123
125
|
iconTintColor = disabledColor
|
|
124
126
|
}
|
|
125
127
|
|
|
128
|
+
val fontSize = scaleSize(14.sp)
|
|
129
|
+
|
|
130
|
+
val textStyle = remember(textColor, inputSearchProps.fontWeight.value) {
|
|
131
|
+
TextStyle(
|
|
132
|
+
color = textColor,
|
|
133
|
+
fontSize = fontSize,
|
|
134
|
+
fontWeight = inputSearchProps.fontWeight.value
|
|
135
|
+
)
|
|
136
|
+
}
|
|
137
|
+
|
|
126
138
|
Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.fillMaxWidth()) {
|
|
127
139
|
BasicTextField(
|
|
128
140
|
enabled = !inputSearchProps.disabled,
|
|
129
141
|
singleLine = true,
|
|
130
142
|
value = inputSearchProps.text.value,
|
|
131
|
-
textStyle =
|
|
132
|
-
color = textColor,
|
|
133
|
-
fontSize = 14.sp,
|
|
134
|
-
lineHeight = 20.sp,
|
|
135
|
-
fontWeight = inputSearchProps.fontWeight.value
|
|
136
|
-
),
|
|
143
|
+
textStyle = textStyle,
|
|
137
144
|
keyboardOptions = inputSearchProps.keyboardOptions.copy(keyboardType = inputSearchProps.keyboardType),
|
|
138
145
|
keyboardActions = inputSearchProps.keyboardActions,
|
|
139
|
-
modifier = inputSearchProps.modifier.weight(1f).
|
|
146
|
+
modifier = inputSearchProps.modifier.weight(1f).wrapContentHeight().onFocusChanged {
|
|
140
147
|
isFocused = it.isFocused
|
|
141
148
|
if (it.isFocused) {
|
|
142
149
|
inputSearchProps.onFocus()
|
|
@@ -176,17 +183,15 @@ fun InputSearch(
|
|
|
176
183
|
)
|
|
177
184
|
Box(Modifier.weight(1f)) {
|
|
178
185
|
if (inputSearchProps.text.value.isEmpty()) {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
overflow = TextOverflow.Ellipsis
|
|
189
|
-
)
|
|
186
|
+
ScaleSizeScope(disableScale = true) {
|
|
187
|
+
Text(
|
|
188
|
+
text = inputSearchProps.placeholder,
|
|
189
|
+
style = textStyle,
|
|
190
|
+
maxLines = 1,
|
|
191
|
+
color = placeholderColor,
|
|
192
|
+
overflow = TextOverflow.Ellipsis
|
|
193
|
+
)
|
|
194
|
+
}
|
|
190
195
|
}
|
|
191
196
|
innerTextField()
|
|
192
197
|
}
|
|
@@ -36,6 +36,8 @@ import androidx.compose.ui.zIndex
|
|
|
36
36
|
import vn.momo.kits.const.AppTheme
|
|
37
37
|
import vn.momo.kits.const.Spacing
|
|
38
38
|
import vn.momo.kits.const.Typography
|
|
39
|
+
import vn.momo.kits.const.scaleSize
|
|
40
|
+
import vn.momo.kits.navigation.ScaleSizeScope
|
|
39
41
|
|
|
40
42
|
const val MAX_LENGTH = 300
|
|
41
43
|
val DEFAULT_HEIGHT = 104.dp
|
|
@@ -86,7 +88,9 @@ fun InputTextArea(
|
|
|
86
88
|
iconTintColor = disabledColor
|
|
87
89
|
}
|
|
88
90
|
|
|
89
|
-
|
|
91
|
+
val fontSize = scaleSize(16.sp)
|
|
92
|
+
val lineHeight = scaleSize(24.sp)
|
|
93
|
+
val scaleHeight = scaleSize(height)
|
|
90
94
|
|
|
91
95
|
Column {
|
|
92
96
|
BasicTextField(
|
|
@@ -95,12 +99,12 @@ fun InputTextArea(
|
|
|
95
99
|
value = text.value,
|
|
96
100
|
textStyle = TextStyle(
|
|
97
101
|
color = textColor,
|
|
98
|
-
fontSize =
|
|
99
|
-
lineHeight =
|
|
102
|
+
fontSize = fontSize,
|
|
103
|
+
lineHeight = lineHeight,
|
|
100
104
|
fontWeight = fontWeight.value
|
|
101
105
|
),
|
|
102
106
|
keyboardOptions = KeyboardOptions.Default.copy(keyboardType = keyboardType),
|
|
103
|
-
modifier = Modifier.height(
|
|
107
|
+
modifier = Modifier.height(scaleHeight).onFocusChanged {
|
|
104
108
|
isFocused = it.isFocused
|
|
105
109
|
if (it.isFocused) {
|
|
106
110
|
onFocus()
|
|
@@ -118,7 +122,7 @@ fun InputTextArea(
|
|
|
118
122
|
if (floatingValue.isNotEmpty() || floatingIcon.isNotEmpty()) {
|
|
119
123
|
Box(
|
|
120
124
|
modifier = Modifier.wrapContentSize()
|
|
121
|
-
.offset(y = (-
|
|
125
|
+
.offset(y = (-scaleHeight / 2), x = (Spacing.S))
|
|
122
126
|
.background(AppTheme.current.colors.background.surface)
|
|
123
127
|
.zIndex(10f),
|
|
124
128
|
) {
|
|
@@ -166,23 +170,27 @@ fun InputTextArea(
|
|
|
166
170
|
) {
|
|
167
171
|
Column {
|
|
168
172
|
Row(
|
|
169
|
-
modifier = Modifier.weight(
|
|
170
|
-
|
|
171
|
-
|
|
173
|
+
modifier = Modifier.weight(1f).padding(
|
|
174
|
+
start = Spacing.M,
|
|
175
|
+
end = Spacing.M,
|
|
176
|
+
top = Spacing.M
|
|
172
177
|
),
|
|
173
178
|
verticalAlignment = Alignment.Top
|
|
174
179
|
) {
|
|
175
180
|
Box(Modifier.weight(1f)) {
|
|
176
181
|
if (text.value.isEmpty()) {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
182
|
+
ScaleSizeScope(disableScale = true) {
|
|
183
|
+
Text(
|
|
184
|
+
text = placeholder,
|
|
185
|
+
style = TextStyle(
|
|
186
|
+
fontSize = fontSize,
|
|
187
|
+
lineHeight = lineHeight,
|
|
188
|
+
fontWeight = fontWeight.value
|
|
189
|
+
),
|
|
190
|
+
color = placeholderColor
|
|
191
|
+
)
|
|
192
|
+
}
|
|
193
|
+
|
|
186
194
|
}
|
|
187
195
|
innerTextField()
|
|
188
196
|
}
|
|
@@ -206,7 +214,6 @@ fun InputTextArea(
|
|
|
206
214
|
|
|
207
215
|
Box(
|
|
208
216
|
modifier = Modifier
|
|
209
|
-
.weight(1.5f)
|
|
210
217
|
.fillMaxWidth()
|
|
211
218
|
.padding(end = Spacing.M),
|
|
212
219
|
contentAlignment = Alignment.CenterEnd
|
|
@@ -10,12 +10,12 @@ import androidx.compose.ui.text.style.TextAlign
|
|
|
10
10
|
import androidx.compose.ui.text.style.TextDecoration
|
|
11
11
|
import androidx.compose.ui.text.style.TextOverflow
|
|
12
12
|
import androidx.compose.ui.unit.TextUnit
|
|
13
|
-
import androidx.compose.ui.unit.sp
|
|
14
13
|
import vn.momo.kits.const.AppTheme
|
|
15
14
|
import vn.momo.kits.const.Typography
|
|
16
15
|
import vn.momo.kits.const.getFontFamily
|
|
17
16
|
import vn.momo.kits.const.scaleSize
|
|
18
17
|
import vn.momo.kits.modifier.setAutomationId
|
|
18
|
+
import vn.momo.kits.navigation.DisableScaleSize
|
|
19
19
|
|
|
20
20
|
@Composable
|
|
21
21
|
fun Text(
|
|
@@ -38,8 +38,8 @@ fun Text(
|
|
|
38
38
|
val theme = AppTheme.current
|
|
39
39
|
|
|
40
40
|
// Call @Composable functions directly in composable context
|
|
41
|
-
val scaledFontSize = scaleSize(style.fontSize
|
|
42
|
-
val scaledLineHeight = scaleSize(style.lineHeight
|
|
41
|
+
val scaledFontSize = scaleSize(style.fontSize)
|
|
42
|
+
val scaledLineHeight = scaleSize(style.lineHeight)
|
|
43
43
|
val fontFamilyResult = getFontFamily(fontFamily ?: theme.font, style.fontWeight)
|
|
44
44
|
|
|
45
45
|
// Now memoize the results
|
|
@@ -184,8 +184,6 @@ val AppThemeController = staticCompositionLocalOf<(Theme) -> Unit> {
|
|
|
184
184
|
error("No AppTheme controller provided")
|
|
185
185
|
}
|
|
186
186
|
|
|
187
|
-
val ScaleSizeMaxRate = staticCompositionLocalOf<Float?> { null }
|
|
188
|
-
|
|
189
187
|
val AppStatusBar = staticCompositionLocalOf { 0.dp }
|
|
190
188
|
|
|
191
189
|
val AppNavigationBar = staticCompositionLocalOf { 0.dp }
|
|
@@ -8,10 +8,15 @@ import androidx.compose.ui.text.font.FontFamily
|
|
|
8
8
|
import androidx.compose.ui.text.font.FontWeight
|
|
9
9
|
import androidx.compose.ui.text.style.TextDecoration
|
|
10
10
|
import androidx.compose.ui.unit.Dp
|
|
11
|
+
import androidx.compose.ui.unit.TextUnit
|
|
12
|
+
import androidx.compose.ui.unit.TextUnitType
|
|
13
|
+
import androidx.compose.ui.unit.dp
|
|
11
14
|
import androidx.compose.ui.unit.sp
|
|
12
15
|
import org.jetbrains.compose.resources.Font
|
|
13
16
|
import org.jetbrains.compose.resources.FontResource
|
|
14
17
|
import org.jetbrains.compose.resources.InternalResourceApi
|
|
18
|
+
import vn.momo.kits.navigation.DisableScaleSize
|
|
19
|
+
import vn.momo.kits.navigation.ScaleSizeMaxRate
|
|
15
20
|
import vn.momo.kits.platform.getScreenDimensions
|
|
16
21
|
import kotlin.math.max
|
|
17
22
|
import kotlin.math.min
|
|
@@ -34,6 +39,7 @@ const val MAX_DEVICE_SCALE = 5
|
|
|
34
39
|
|
|
35
40
|
@Composable
|
|
36
41
|
fun scaleSize(size: Float): Float {
|
|
42
|
+
if (DisableScaleSize.current == true) return size
|
|
37
43
|
val scaleSizeMaxRate: Float = ScaleSizeMaxRate.current ?: MAX_FONT_SCALE
|
|
38
44
|
val deviceWidth = getScreenDimensions().width
|
|
39
45
|
val deviceScale = deviceWidth / DEFAULT_SCREEN_SIZE
|
|
@@ -41,9 +47,8 @@ fun scaleSize(size: Float): Float {
|
|
|
41
47
|
val density = LocalDensity.current
|
|
42
48
|
val fontScale = density.fontScale
|
|
43
49
|
|
|
44
|
-
|
|
45
|
-
var
|
|
46
|
-
var fontSizeScaleOS = defaultFontSize
|
|
50
|
+
var fontSizeScaleDevice = size
|
|
51
|
+
var fontSizeScaleOS = size
|
|
47
52
|
|
|
48
53
|
if (deviceScale > 1) {
|
|
49
54
|
fontSizeScaleDevice =
|
|
@@ -61,11 +66,41 @@ fun scaleSize(size: Float): Float {
|
|
|
61
66
|
}
|
|
62
67
|
|
|
63
68
|
@Composable
|
|
64
|
-
fun scaleSize(size:
|
|
69
|
+
fun scaleSize(size: TextUnit): TextUnit {
|
|
70
|
+
if (DisableScaleSize.current == true) return size
|
|
71
|
+
if (!size.isSp) return size
|
|
72
|
+
|
|
65
73
|
val density = LocalDensity.current
|
|
66
|
-
|
|
67
|
-
val
|
|
68
|
-
|
|
74
|
+
|
|
75
|
+
val scaled = scaleSize(size.value)
|
|
76
|
+
val spValue = scaled / density.fontScale
|
|
77
|
+
|
|
78
|
+
return TextUnit(value = spValue, type = TextUnitType.Sp)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
@Composable
|
|
82
|
+
fun scaleSize(size: Dp): Dp {
|
|
83
|
+
return scaleSize(size.value).toInt().dp
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
@Composable
|
|
87
|
+
fun scaleSize(textStyle: TextStyle): TextStyle {
|
|
88
|
+
return textStyle.copy(
|
|
89
|
+
fontSize = if (textStyle.fontSize != TextUnit.Unspecified)
|
|
90
|
+
scaleSize(textStyle.fontSize)
|
|
91
|
+
else
|
|
92
|
+
TextUnit.Unspecified,
|
|
93
|
+
|
|
94
|
+
lineHeight = if (textStyle.lineHeight != TextUnit.Unspecified)
|
|
95
|
+
scaleSize(textStyle.lineHeight)
|
|
96
|
+
else
|
|
97
|
+
TextUnit.Unspecified,
|
|
98
|
+
|
|
99
|
+
letterSpacing = if (textStyle.letterSpacing != TextUnit.Unspecified)
|
|
100
|
+
scaleSize(textStyle.letterSpacing)
|
|
101
|
+
else
|
|
102
|
+
TextUnit.Unspecified
|
|
103
|
+
)
|
|
69
104
|
}
|
|
70
105
|
|
|
71
106
|
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
package vn.momo.kits.navigation
|
|
2
2
|
|
|
3
|
+
import androidx.compose.foundation.layout.Box
|
|
4
|
+
import androidx.compose.foundation.layout.fillMaxSize
|
|
3
5
|
import androidx.compose.runtime.Composable
|
|
4
6
|
import androidx.compose.runtime.MutableState
|
|
5
7
|
import androidx.compose.runtime.mutableStateOf
|
|
6
8
|
import androidx.compose.runtime.staticCompositionLocalOf
|
|
9
|
+
import androidx.compose.ui.Alignment
|
|
10
|
+
import androidx.compose.ui.Modifier
|
|
7
11
|
import androidx.navigation.NavController
|
|
8
12
|
import kotlinx.coroutines.CoroutineScope
|
|
9
13
|
import kotlinx.coroutines.Dispatchers
|
|
@@ -12,6 +16,8 @@ import kotlinx.coroutines.cancel
|
|
|
12
16
|
import kotlinx.coroutines.delay
|
|
13
17
|
import kotlinx.coroutines.launch
|
|
14
18
|
import kotlinx.serialization.Serializable
|
|
19
|
+
import vn.momo.kits.navigation.BottomHeader.*
|
|
20
|
+
import vn.momo.kits.navigation.component.SnackBar
|
|
15
21
|
import vn.momo.maxapi.IMaxApi
|
|
16
22
|
|
|
17
23
|
class Navigator(
|
|
@@ -37,25 +43,36 @@ class Navigator(
|
|
|
37
43
|
fun pop(count: Int = 1, callBack: (() -> Unit)? = null) {
|
|
38
44
|
scope.launch {
|
|
39
45
|
repeat(count) {
|
|
40
|
-
if (OverplayComponentRegistry.
|
|
41
|
-
|
|
42
|
-
delay(300L)
|
|
46
|
+
if (OverplayComponentRegistry.getOverplayType() == OverplayComponentType.SNACK_BAR){
|
|
47
|
+
dismissScreen()
|
|
43
48
|
OverplayComponentRegistry.hardClearAfterDismiss()
|
|
49
|
+
}
|
|
50
|
+
else if (OverplayComponentRegistry.isOverplayShowing()){
|
|
51
|
+
dismissOverplay()
|
|
44
52
|
} else {
|
|
45
|
-
|
|
46
|
-
navController.popBackStack()
|
|
47
|
-
delay(300L)
|
|
48
|
-
DynamicScreenRegistry.getLatestScreen()?.let { it1 ->
|
|
49
|
-
DynamicScreenRegistry.unregisterScreen(it1.id)
|
|
50
|
-
}
|
|
51
|
-
} else {
|
|
52
|
-
maxApi?.dismiss { }
|
|
53
|
-
}
|
|
53
|
+
dismissScreen()
|
|
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
|
+
}
|
|
59
76
|
|
|
60
77
|
fun present(content: @Composable () -> Unit, options: NavigationOptions? = null) {
|
|
61
78
|
val route = DynamicScreenRegistry.register(content, options)
|
|
@@ -76,7 +93,8 @@ class Navigator(
|
|
|
76
93
|
barrierDismissible: Boolean = true,
|
|
77
94
|
onDismiss: (() -> Unit)? = null
|
|
78
95
|
){
|
|
79
|
-
|
|
96
|
+
val id = DynamicScreenRegistry.getLatestScreen()?.id ?: -1
|
|
97
|
+
OverplayComponentRegistry.registerOverplay(id, content, OverplayComponentType.MODAL, false, barrierDismissible, onDismiss)
|
|
80
98
|
}
|
|
81
99
|
|
|
82
100
|
fun showBottomSheet(
|
|
@@ -86,7 +104,30 @@ class Navigator(
|
|
|
86
104
|
onDismiss: (() -> Unit)? = null,
|
|
87
105
|
bottomSheetHeader: BottomHeader? = null
|
|
88
106
|
){
|
|
89
|
-
|
|
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
|
+
}
|
|
90
131
|
}
|
|
91
132
|
|
|
92
133
|
fun dispose(){
|
|
@@ -159,13 +200,21 @@ sealed class OverplayComponentParams {
|
|
|
159
200
|
val barrierDismissible: Boolean = true,
|
|
160
201
|
val bottomSheetHeader: BottomHeader? = null,
|
|
161
202
|
) : OverplayComponentParams()
|
|
203
|
+
|
|
204
|
+
class SnackBar() : OverplayComponentParams()
|
|
162
205
|
}
|
|
163
206
|
|
|
164
207
|
data class OverplayComponent(
|
|
208
|
+
val id: Int,
|
|
209
|
+
val type: OverplayComponentType? = null,
|
|
165
210
|
val content: @Composable () -> Unit,
|
|
166
211
|
val params: OverplayComponentParams? = null
|
|
167
212
|
)
|
|
168
213
|
|
|
214
|
+
enum class OverplayComponentType {
|
|
215
|
+
MODAL, BOTTOM_SHEET, SNACK_BAR
|
|
216
|
+
}
|
|
217
|
+
|
|
169
218
|
object OverplayComponentRegistry {
|
|
170
219
|
private var currentOverlayComponent : MutableState<OverplayComponent?> = mutableStateOf(null)
|
|
171
220
|
private var requestClose: (() -> Unit)? = null
|
|
@@ -173,20 +222,24 @@ object OverplayComponentRegistry {
|
|
|
173
222
|
requestClose = handler
|
|
174
223
|
}
|
|
175
224
|
|
|
176
|
-
fun
|
|
225
|
+
fun registerOverplay(
|
|
226
|
+
id: Int,
|
|
177
227
|
content: @Composable () -> Unit,
|
|
228
|
+
type: OverplayComponentType,
|
|
178
229
|
isSurface: Boolean = false,
|
|
179
230
|
barrierDismissible: Boolean = true,
|
|
180
231
|
onDismiss: (() -> Unit)?,
|
|
181
|
-
isBottomSheet: Boolean = false,
|
|
182
232
|
bottomSheetHeader: BottomHeader? = null,
|
|
183
233
|
){
|
|
184
|
-
val params =
|
|
185
|
-
OverplayComponentParams.
|
|
186
|
-
|
|
187
|
-
OverplayComponentParams.
|
|
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()
|
|
188
238
|
}
|
|
239
|
+
|
|
189
240
|
currentOverlayComponent.value = OverplayComponent(
|
|
241
|
+
id = id,
|
|
242
|
+
type = type,
|
|
190
243
|
content = content,
|
|
191
244
|
params = params
|
|
192
245
|
)
|
|
@@ -194,6 +247,10 @@ object OverplayComponentRegistry {
|
|
|
194
247
|
|
|
195
248
|
fun isOverplayShowing(): Boolean = currentOverlayComponent.value != null
|
|
196
249
|
|
|
250
|
+
fun getOverplayType(): OverplayComponentType? = currentOverlayComponent.value?.type
|
|
251
|
+
|
|
252
|
+
fun currentRootId(): Int? = currentOverlayComponent.value?.id
|
|
253
|
+
|
|
197
254
|
fun clear(){
|
|
198
255
|
if (requestClose != null) {
|
|
199
256
|
requestClose?.invoke()
|
|
@@ -211,22 +268,35 @@ object OverplayComponentRegistry {
|
|
|
211
268
|
fun OverlayComponent(){
|
|
212
269
|
val overplay = currentOverlayComponent.value ?: return
|
|
213
270
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
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 -> {}
|
|
230
300
|
}
|
|
231
301
|
}
|
|
232
302
|
}
|
|
@@ -2,16 +2,21 @@ package vn.momo.kits.navigation
|
|
|
2
2
|
|
|
3
3
|
import androidx.compose.runtime.Composable
|
|
4
4
|
import androidx.compose.runtime.CompositionLocalProvider
|
|
5
|
-
import
|
|
5
|
+
import androidx.compose.runtime.staticCompositionLocalOf
|
|
6
|
+
|
|
7
|
+
val ScaleSizeMaxRate = staticCompositionLocalOf<Float?> { null }
|
|
8
|
+
val DisableScaleSize = staticCompositionLocalOf<Boolean> { false }
|
|
6
9
|
|
|
7
10
|
@Composable
|
|
8
11
|
fun ScaleSizeScope(
|
|
12
|
+
disableScale: Boolean = false,
|
|
9
13
|
scaleSizeMaxRate: Float? = null,
|
|
10
14
|
content: @Composable () -> Unit
|
|
11
15
|
) {
|
|
12
16
|
CompositionLocalProvider(
|
|
13
|
-
ScaleSizeMaxRate provides scaleSizeMaxRate
|
|
17
|
+
ScaleSizeMaxRate provides scaleSizeMaxRate,
|
|
18
|
+
DisableScaleSize provides disableScale
|
|
14
19
|
) {
|
|
15
20
|
content()
|
|
16
21
|
}
|
|
17
|
-
}
|
|
22
|
+
}
|