@momo-kits/native-kits 0.113.2-beta.5 → 0.113.3-beta.10
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/androidMain/kotlin/vn/momo/kits/platform/Platform.android.kt +6 -5
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/AnimationSearchInput.kt +58 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Header.kt +33 -38
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderBackground.kt +36 -34
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderDefault.kt +5 -5
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderExtended.kt +44 -71
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderRight.kt +36 -17
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderTitle.kt +0 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/NavigationContainer.kt +6 -4
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Screen.kt +15 -21
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/useHeaderSearchAnimation.kt +23 -19
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupNotify.kt +11 -20
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Text.kt +1 -1
- package/ios/Image/Image.swift +1 -1
- package/ios/Popup/PopupDisplay.swift +15 -6
- package/local.properties +2 -2
- package/package.json +1 -1
|
@@ -3,12 +3,9 @@ package vn.momo.kits.platform
|
|
|
3
3
|
import android.annotation.SuppressLint
|
|
4
4
|
import android.content.res.Resources
|
|
5
5
|
import android.graphics.BlurMaskFilter
|
|
6
|
-
import androidx.compose.foundation.layout.WindowInsets
|
|
7
|
-
import androidx.compose.foundation.layout.statusBars
|
|
8
6
|
import androidx.compose.runtime.Composable
|
|
9
7
|
import androidx.compose.ui.graphics.NativePaint
|
|
10
8
|
import androidx.compose.ui.platform.LocalConfiguration
|
|
11
|
-
import androidx.compose.ui.platform.LocalDensity
|
|
12
9
|
import androidx.compose.ui.unit.Dp
|
|
13
10
|
import androidx.compose.ui.unit.dp
|
|
14
11
|
|
|
@@ -31,6 +28,10 @@ actual fun NativePaint.setMaskFilter(blurRadius: Float) {
|
|
|
31
28
|
@SuppressLint("InternalInsetResource")
|
|
32
29
|
@Composable
|
|
33
30
|
actual fun getStatusBarHeight(): Dp {
|
|
34
|
-
val
|
|
35
|
-
|
|
31
|
+
val resourceId = Resources.getSystem().getIdentifier(
|
|
32
|
+
"status_bar_height",
|
|
33
|
+
"dimen",
|
|
34
|
+
"android"
|
|
35
|
+
)
|
|
36
|
+
return if(resourceId > 0) Resources.getSystem().getDimensionPixelSize(resourceId).dp else 0.dp
|
|
36
37
|
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
package vn.momo.kits.application
|
|
2
|
+
|
|
3
|
+
import androidx.compose.foundation.background
|
|
4
|
+
import androidx.compose.foundation.layout.Box
|
|
5
|
+
import androidx.compose.foundation.layout.fillMaxWidth
|
|
6
|
+
import androidx.compose.foundation.layout.height
|
|
7
|
+
import androidx.compose.foundation.layout.offset
|
|
8
|
+
import androidx.compose.foundation.layout.padding
|
|
9
|
+
import androidx.compose.foundation.layout.width
|
|
10
|
+
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
11
|
+
import androidx.compose.runtime.Composable
|
|
12
|
+
import androidx.compose.ui.Modifier
|
|
13
|
+
import androidx.compose.ui.graphics.Color
|
|
14
|
+
import androidx.compose.ui.unit.dp
|
|
15
|
+
import androidx.compose.ui.zIndex
|
|
16
|
+
import vn.momo.kits.components.InputSearch
|
|
17
|
+
import vn.momo.kits.components.InputSearchProps
|
|
18
|
+
import vn.momo.kits.const.Radius
|
|
19
|
+
import vn.momo.kits.const.Spacing
|
|
20
|
+
|
|
21
|
+
@Composable
|
|
22
|
+
fun AnimationSearchInput(
|
|
23
|
+
animations: HeaderAnimations,
|
|
24
|
+
inputSearchProps: InputSearchProps
|
|
25
|
+
) {
|
|
26
|
+
Box(
|
|
27
|
+
modifier = Modifier
|
|
28
|
+
.fillMaxWidth()
|
|
29
|
+
.offset(
|
|
30
|
+
x = animations.translateX.dp,
|
|
31
|
+
y = animations.translateY.dp
|
|
32
|
+
)
|
|
33
|
+
) {
|
|
34
|
+
Box(
|
|
35
|
+
modifier = Modifier
|
|
36
|
+
.height(HEADER_HEIGHT.dp)
|
|
37
|
+
.padding(vertical = Spacing.S)
|
|
38
|
+
.zIndex(1f)
|
|
39
|
+
) {
|
|
40
|
+
Box(
|
|
41
|
+
modifier = Modifier
|
|
42
|
+
.width(animations.width.dp)
|
|
43
|
+
.background(
|
|
44
|
+
color = animations.backgroundSearch,
|
|
45
|
+
shape = RoundedCornerShape(Radius.XL)
|
|
46
|
+
)
|
|
47
|
+
) {
|
|
48
|
+
InputSearch(
|
|
49
|
+
inputSearchProps = inputSearchProps.copy(
|
|
50
|
+
showButtonText = false,
|
|
51
|
+
backgroundColor = Color.Transparent
|
|
52
|
+
)
|
|
53
|
+
)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
package vn.momo.kits.application
|
|
2
2
|
|
|
3
|
-
import androidx.compose.animation.animateColorAsState
|
|
4
3
|
import androidx.compose.foundation.background
|
|
5
4
|
import androidx.compose.foundation.border
|
|
6
5
|
import androidx.compose.foundation.clickable
|
|
@@ -24,10 +23,10 @@ import androidx.compose.runtime.setValue
|
|
|
24
23
|
import androidx.compose.runtime.snapshotFlow
|
|
25
24
|
import androidx.compose.ui.Alignment
|
|
26
25
|
import androidx.compose.ui.Modifier
|
|
27
|
-
import androidx.compose.ui.graphics.Color
|
|
28
26
|
import androidx.compose.ui.graphics.graphicsLayer
|
|
29
27
|
import androidx.compose.ui.semantics.semantics
|
|
30
28
|
import androidx.compose.ui.semantics.testTag
|
|
29
|
+
import androidx.compose.ui.unit.Dp
|
|
31
30
|
import androidx.compose.ui.unit.dp
|
|
32
31
|
import androidx.compose.ui.zIndex
|
|
33
32
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
|
@@ -42,15 +41,6 @@ import vn.momo.kits.const.Spacing
|
|
|
42
41
|
import vn.momo.kits.modifier.setAutomationId
|
|
43
42
|
import vn.momo.kits.platform.getStatusBarHeight
|
|
44
43
|
|
|
45
|
-
enum class TitlePosition {
|
|
46
|
-
LEFT, CENTER,
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
data class AnimatedHeader(
|
|
50
|
-
val type: HeaderType = HeaderType.DEFAULT,
|
|
51
|
-
val composable: @Composable (scrollState: Int) -> Unit = {}
|
|
52
|
-
)
|
|
53
|
-
|
|
54
44
|
@Composable
|
|
55
45
|
fun Header(
|
|
56
46
|
headerType: HeaderType = HeaderType.DEFAULT,
|
|
@@ -58,16 +48,16 @@ fun Header(
|
|
|
58
48
|
title: String,
|
|
59
49
|
headerRight: @Composable (() -> Unit)? = null,
|
|
60
50
|
goBack: (() -> Unit)? = null,
|
|
61
|
-
opacity: Float
|
|
51
|
+
opacity: Float = 1f,
|
|
62
52
|
animatedHeader: AnimatedHeader? = null,
|
|
63
53
|
scrollState: Int = 0,
|
|
64
54
|
inputSearchProps: InputSearchProps? = null,
|
|
55
|
+
headerRightWidth: Dp = 0.dp,
|
|
65
56
|
useAnimationSearch: Boolean = false
|
|
66
57
|
) {
|
|
67
58
|
val statusBarHeight = AppStatusBar.current ?: getStatusBarHeight()
|
|
68
59
|
val tintIconColor = AppTheme.current.colors.text.default
|
|
69
60
|
val backgroundButton = Colors.black_01.copy(alpha = 0.6f)
|
|
70
|
-
val miniAppContext = ApplicationContext.current
|
|
71
61
|
|
|
72
62
|
var colorFraction by remember { mutableStateOf(0f) }
|
|
73
63
|
|
|
@@ -77,24 +67,31 @@ fun Header(
|
|
|
77
67
|
.distinctUntilChanged()
|
|
78
68
|
.collect { fraction -> colorFraction = fraction }
|
|
79
69
|
}
|
|
70
|
+
val animations = useHeaderSearchAnimation(
|
|
71
|
+
opacityAni = opacity,
|
|
72
|
+
scrollState = scrollState,
|
|
73
|
+
headerRightWidth = headerRightWidth,
|
|
74
|
+
isBack = goBack != null
|
|
75
|
+
)
|
|
80
76
|
|
|
81
|
-
val backgroundSearch
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
colorFraction
|
|
86
|
-
)
|
|
77
|
+
val backgroundSearch = animateColor(
|
|
78
|
+
Colors.black_01,
|
|
79
|
+
AppTheme.current.colors.background.default,
|
|
80
|
+
colorFraction
|
|
87
81
|
)
|
|
88
82
|
|
|
83
|
+
val searchAnimationEnable =
|
|
84
|
+
inputSearchProps != null && useAnimationSearch && headerType == HeaderType.EXTENDED
|
|
85
|
+
|
|
89
86
|
if (headerType != HeaderType.NONE) {
|
|
90
87
|
BoxWithConstraints(
|
|
91
|
-
Modifier.height(statusBarHeight +
|
|
88
|
+
Modifier.height(statusBarHeight + HEADER_HEIGHT.dp)
|
|
92
89
|
.fillMaxWidth()
|
|
93
90
|
.zIndex(10f),
|
|
94
91
|
contentAlignment = Alignment.BottomCenter
|
|
95
92
|
) {
|
|
96
93
|
Row(
|
|
97
|
-
modifier = Modifier.height(
|
|
94
|
+
modifier = Modifier.height(HEADER_HEIGHT.dp)
|
|
98
95
|
.fillMaxWidth()
|
|
99
96
|
.padding(horizontal = Spacing.M),
|
|
100
97
|
verticalAlignment = Alignment.CenterVertically,
|
|
@@ -132,9 +129,9 @@ fun Header(
|
|
|
132
129
|
}
|
|
133
130
|
}
|
|
134
131
|
|
|
135
|
-
if (
|
|
132
|
+
if (useAnimationSearch || inputSearchProps == null) {
|
|
136
133
|
Box(Modifier.graphicsLayer {
|
|
137
|
-
alpha = if (
|
|
134
|
+
alpha = if (animatedHeader !== null) opacity else 1f
|
|
138
135
|
}) {
|
|
139
136
|
headerRight?.invoke()
|
|
140
137
|
}
|
|
@@ -143,7 +140,7 @@ fun Header(
|
|
|
143
140
|
|
|
144
141
|
// Title
|
|
145
142
|
Row(
|
|
146
|
-
modifier = Modifier.height(
|
|
143
|
+
modifier = Modifier.height(HEADER_HEIGHT.dp)
|
|
147
144
|
.fillMaxWidth()
|
|
148
145
|
.padding(horizontal = Spacing.M),
|
|
149
146
|
verticalAlignment = Alignment.CenterVertically,
|
|
@@ -156,14 +153,15 @@ fun Header(
|
|
|
156
153
|
} else {
|
|
157
154
|
Box(
|
|
158
155
|
Modifier.weight(1f).graphicsLayer {
|
|
159
|
-
alpha = if (useAnimationSearch
|
|
160
|
-
1f - (opacity
|
|
156
|
+
alpha = if (useAnimationSearch) {
|
|
157
|
+
1f - (opacity)
|
|
161
158
|
} else {
|
|
162
|
-
if (animatedHeader !== null) opacity
|
|
159
|
+
if (animatedHeader !== null) opacity else 1f
|
|
163
160
|
}
|
|
164
161
|
},
|
|
165
162
|
contentAlignment = if (titlePosition == TitlePosition.LEFT) Alignment.TopStart else Alignment.Center
|
|
166
163
|
) {
|
|
164
|
+
|
|
167
165
|
HeaderTitle(
|
|
168
166
|
title = title,
|
|
169
167
|
color = tintIconColor,
|
|
@@ -174,16 +172,13 @@ fun Header(
|
|
|
174
172
|
}
|
|
175
173
|
}
|
|
176
174
|
}
|
|
175
|
+
|
|
176
|
+
if (searchAnimationEnable) {
|
|
177
|
+
AnimationSearchInput(
|
|
178
|
+
animations = animations,
|
|
179
|
+
inputSearchProps = inputSearchProps!!
|
|
180
|
+
)
|
|
181
|
+
}
|
|
177
182
|
}
|
|
178
183
|
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
fun animateColor(start: Color, stop: Color, fraction: Float): Color {
|
|
183
|
-
return Color(
|
|
184
|
-
red = start.red + fraction * (stop.red - start.red),
|
|
185
|
-
green = start.green + fraction * (stop.green - start.green),
|
|
186
|
-
blue = start.blue + fraction * (stop.blue - start.blue),
|
|
187
|
-
alpha = start.alpha + fraction * (stop.alpha - start.alpha)
|
|
188
|
-
)
|
|
189
|
-
}
|
|
184
|
+
}
|
|
@@ -1,66 +1,68 @@
|
|
|
1
1
|
package vn.momo.kits.application
|
|
2
2
|
|
|
3
|
+
import androidx.compose.animation.animateColorAsState
|
|
4
|
+
import androidx.compose.animation.core.animateFloatAsState
|
|
3
5
|
import androidx.compose.foundation.layout.Box
|
|
4
6
|
import androidx.compose.foundation.layout.fillMaxWidth
|
|
5
7
|
import androidx.compose.runtime.Composable
|
|
8
|
+
import androidx.compose.runtime.getValue
|
|
6
9
|
import androidx.compose.ui.Modifier
|
|
7
10
|
import androidx.compose.ui.graphics.Color
|
|
8
|
-
import androidx.compose.ui.unit.Dp
|
|
9
|
-
import androidx.compose.ui.unit.dp
|
|
10
|
-
import vn.momo.kits.components.InputSearchProps
|
|
11
11
|
import vn.momo.kits.const.AppStatusBar
|
|
12
12
|
import vn.momo.kits.const.AppTheme
|
|
13
|
-
import vn.momo.kits.platform.getScreenDimensions
|
|
14
13
|
import vn.momo.kits.platform.getStatusBarHeight
|
|
15
14
|
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
enum class TitlePosition {
|
|
16
|
+
LEFT, CENTER,
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
data class AnimatedHeader(
|
|
20
|
+
val type: HeaderType = HeaderType.DEFAULT,
|
|
21
|
+
val composable: @Composable (scrollState: Int) -> Unit = {}
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
fun animateColor(start: Color, stop: Color, fraction: Float): Color {
|
|
25
|
+
return Color(
|
|
26
|
+
red = start.red + fraction * (stop.red - start.red),
|
|
27
|
+
green = start.green + fraction * (stop.green - start.green),
|
|
28
|
+
blue = start.blue + fraction * (stop.blue - start.blue),
|
|
29
|
+
alpha = start.alpha + fraction * (stop.alpha - start.alpha)
|
|
30
|
+
)
|
|
31
|
+
}
|
|
18
32
|
|
|
19
33
|
@Composable
|
|
20
34
|
fun HeaderBackground(
|
|
21
|
-
isBack: Boolean = true,
|
|
22
35
|
headerType: HeaderType = HeaderType.DEFAULT,
|
|
23
36
|
scrollState: Int,
|
|
24
|
-
inputSearchProps: InputSearchProps? = null,
|
|
25
|
-
headerRightWidth: Dp = 0.dp,
|
|
26
|
-
useAnimationSearch: Boolean = false
|
|
27
37
|
) {
|
|
28
38
|
val statusBarHeight = AppStatusBar.current ?: getStatusBarHeight()
|
|
29
|
-
val screenWidth = getScreenDimensions().width
|
|
30
|
-
val leftPosition = if (isBack) (BACK_WIDTH + 20).dp else 20.dp
|
|
31
|
-
val searchWidth = screenWidth - (SCREEN_PADDING * 2)
|
|
32
39
|
|
|
33
|
-
val
|
|
34
|
-
|
|
35
|
-
statusBarHeight = statusBarHeight,
|
|
36
|
-
leftPosition = leftPosition,
|
|
37
|
-
searchWidth = searchWidth,
|
|
38
|
-
headerRightWidth = headerRightWidth
|
|
40
|
+
val opacityAni by animateFloatAsState(
|
|
41
|
+
targetValue = (1 - (scrollState / HEADER_HEIGHT*1f)).coerceIn(0f, 1f),
|
|
39
42
|
)
|
|
40
43
|
|
|
41
|
-
val backgroundColor
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
val backgroundColor by animateColorAsState(
|
|
45
|
+
targetValue = animateColor(
|
|
46
|
+
Color.Transparent,
|
|
47
|
+
AppTheme.current.colors.background.surface,
|
|
48
|
+
opacityAni
|
|
49
|
+
),
|
|
50
|
+
)
|
|
46
51
|
|
|
47
52
|
when (headerType) {
|
|
48
53
|
HeaderType.DEFAULT -> {
|
|
49
|
-
val height = statusBarHeight + 52.dp
|
|
50
54
|
HeaderDefault(
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
backgroundColor = backgroundColor
|
|
55
|
+
opacityAni = opacityAni,
|
|
56
|
+
statusBarHeight = statusBarHeight,
|
|
54
57
|
)
|
|
55
58
|
}
|
|
56
59
|
|
|
57
60
|
HeaderType.EXTENDED -> {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
)
|
|
61
|
+
HeaderExtended(
|
|
62
|
+
opacityAni = opacityAni,
|
|
63
|
+
statusBarHeight = statusBarHeight,
|
|
64
|
+
backgroundColor = backgroundColor,
|
|
65
|
+
)
|
|
64
66
|
}
|
|
65
67
|
|
|
66
68
|
else -> {
|
|
@@ -21,13 +21,13 @@ import vn.momo.kits.utils.bottomBorder
|
|
|
21
21
|
|
|
22
22
|
@Composable
|
|
23
23
|
fun HeaderDefault(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
animations: HeaderAnimations
|
|
24
|
+
opacityAni: Float,
|
|
25
|
+
statusBarHeight: Dp,
|
|
27
26
|
) {
|
|
27
|
+
val height = statusBarHeight + HEADER_HEIGHT.dp
|
|
28
28
|
Box(
|
|
29
29
|
modifier = Modifier.fillMaxWidth().height(height)
|
|
30
|
-
.background(
|
|
30
|
+
.background(AppTheme.current.colors.background.surface)
|
|
31
31
|
.bottomBorder(
|
|
32
32
|
strokeWidth = 1.dp,
|
|
33
33
|
color = AppTheme.current.colors.border.default
|
|
@@ -37,7 +37,7 @@ fun HeaderDefault(
|
|
|
37
37
|
modifier = Modifier
|
|
38
38
|
.height(height)
|
|
39
39
|
.fillMaxWidth()
|
|
40
|
-
.alpha(
|
|
40
|
+
.alpha(opacityAni)
|
|
41
41
|
.background(
|
|
42
42
|
Brush.linearGradient(
|
|
43
43
|
colors = listOf(
|
|
@@ -4,12 +4,7 @@ import androidx.compose.foundation.background
|
|
|
4
4
|
import androidx.compose.foundation.layout.Box
|
|
5
5
|
import androidx.compose.foundation.layout.fillMaxWidth
|
|
6
6
|
import androidx.compose.foundation.layout.height
|
|
7
|
-
import androidx.compose.foundation.layout.offset
|
|
8
|
-
import androidx.compose.foundation.layout.padding
|
|
9
|
-
import androidx.compose.foundation.layout.width
|
|
10
|
-
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
11
7
|
import androidx.compose.runtime.Composable
|
|
12
|
-
import androidx.compose.ui.Alignment
|
|
13
8
|
import androidx.compose.ui.Modifier
|
|
14
9
|
import androidx.compose.ui.draw.alpha
|
|
15
10
|
import androidx.compose.ui.geometry.Offset
|
|
@@ -17,86 +12,64 @@ import androidx.compose.ui.graphics.Brush
|
|
|
17
12
|
import androidx.compose.ui.graphics.Color
|
|
18
13
|
import androidx.compose.ui.layout.ContentScale
|
|
19
14
|
import androidx.compose.ui.platform.LocalDensity
|
|
15
|
+
import androidx.compose.ui.unit.Dp
|
|
20
16
|
import androidx.compose.ui.unit.dp
|
|
21
17
|
import vn.momo.kits.components.Image
|
|
22
|
-
import vn.momo.kits.components.InputSearch
|
|
23
|
-
import vn.momo.kits.components.InputSearchProps
|
|
24
18
|
import vn.momo.kits.components.Options
|
|
25
19
|
import vn.momo.kits.const.AppTheme
|
|
26
|
-
import vn.momo.kits.
|
|
27
|
-
import vn.momo.kits.const.Spacing
|
|
20
|
+
import vn.momo.kits.utils.bottomBorder
|
|
28
21
|
|
|
29
22
|
@Composable
|
|
30
23
|
fun HeaderExtended(
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
){
|
|
24
|
+
opacityAni: Float,
|
|
25
|
+
statusBarHeight: Dp,
|
|
26
|
+
backgroundColor: Color
|
|
27
|
+
) {
|
|
36
28
|
Box(
|
|
37
|
-
modifier = Modifier
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
.
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
),
|
|
50
|
-
start = Offset(0f, 0f),
|
|
51
|
-
end = Offset(0f, with(LocalDensity.current) { 154.dp.toPx() })
|
|
52
|
-
)
|
|
29
|
+
modifier = Modifier
|
|
30
|
+
.fillMaxWidth()
|
|
31
|
+
.height(154.dp)
|
|
32
|
+
.alpha(opacityAni)
|
|
33
|
+
.background(
|
|
34
|
+
Brush.linearGradient(
|
|
35
|
+
colors = listOf(
|
|
36
|
+
Color(0xFFFDCADE),
|
|
37
|
+
Color(0x00FDCADE)
|
|
38
|
+
),
|
|
39
|
+
start = Offset(0f, 0f),
|
|
40
|
+
end = Offset(0f, with(LocalDensity.current) { 154.dp.toPx() })
|
|
53
41
|
)
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
modifier = Modifier
|
|
58
|
-
.fillMaxWidth()
|
|
59
|
-
.background(backgroundColor)
|
|
60
|
-
) {
|
|
61
|
-
Image(
|
|
62
|
-
loading = false,
|
|
63
|
-
source = AppTheme.current.assets.headerBackground!!,
|
|
64
|
-
modifier = Modifier.fillMaxWidth().height(154.dp),
|
|
65
|
-
options = Options(
|
|
66
|
-
contentScale = ContentScale.FillWidth
|
|
67
|
-
)
|
|
68
|
-
)
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
if (inputSearchProps != null && useAnimationSearch) {
|
|
42
|
+
)
|
|
43
|
+
) {
|
|
44
|
+
if (AppTheme.current.assets.headerBackground != null) {
|
|
74
45
|
Box(
|
|
75
46
|
modifier = Modifier
|
|
76
|
-
.
|
|
77
|
-
.
|
|
78
|
-
x = animations.translateX.dp
|
|
79
|
-
)
|
|
80
|
-
.padding(vertical = Spacing.S)
|
|
81
|
-
.align(Alignment.BottomStart)
|
|
47
|
+
.fillMaxWidth()
|
|
48
|
+
.background(backgroundColor)
|
|
82
49
|
) {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
)
|
|
90
|
-
) {
|
|
91
|
-
InputSearch(
|
|
92
|
-
inputSearchProps = inputSearchProps.copy(
|
|
93
|
-
showButtonText = false,
|
|
94
|
-
backgroundColor = Color.Transparent
|
|
95
|
-
)
|
|
50
|
+
Image(
|
|
51
|
+
loading = false,
|
|
52
|
+
source = AppTheme.current.assets.headerBackground!!,
|
|
53
|
+
modifier = Modifier.fillMaxWidth().height(154.dp),
|
|
54
|
+
options = Options(
|
|
55
|
+
contentScale = ContentScale.FillWidth
|
|
96
56
|
)
|
|
97
|
-
|
|
57
|
+
)
|
|
98
58
|
}
|
|
99
59
|
}
|
|
100
60
|
}
|
|
101
|
-
}
|
|
102
61
|
|
|
62
|
+
Box(
|
|
63
|
+
modifier = Modifier
|
|
64
|
+
.fillMaxWidth()
|
|
65
|
+
.alpha(1f - opacityAni)
|
|
66
|
+
.height(statusBarHeight + HEADER_HEIGHT.dp)
|
|
67
|
+
.background(
|
|
68
|
+
AppTheme.current.colors.background.surface
|
|
69
|
+
)
|
|
70
|
+
.bottomBorder(
|
|
71
|
+
strokeWidth = 1.dp,
|
|
72
|
+
color = AppTheme.current.colors.border.default
|
|
73
|
+
)
|
|
74
|
+
)
|
|
75
|
+
}
|
|
@@ -78,13 +78,13 @@ object Spacing {
|
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
@Composable
|
|
81
|
-
fun HeaderRight(
|
|
82
|
-
|
|
81
|
+
internal fun HeaderRight(
|
|
82
|
+
headerRight: HeaderRightData? = null,
|
|
83
83
|
) {
|
|
84
84
|
Row(
|
|
85
85
|
verticalAlignment = Alignment.CenterVertically,
|
|
86
86
|
) {
|
|
87
|
-
ToolkitHeaderRight(headerRight =
|
|
87
|
+
ToolkitHeaderRight(headerRight = headerRight)
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
90
|
|
|
@@ -115,11 +115,12 @@ fun ToolkitHeaderRight(headerRight: HeaderRightData? = null) {
|
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
fun onPressClose() {
|
|
118
|
-
api?.request("dismiss", "", {_ -> })
|
|
118
|
+
api?.request("dismiss", "", { _ -> })
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
fun onPressMore() {
|
|
122
|
-
api?.request(
|
|
122
|
+
api?.request(
|
|
123
|
+
"showTools",
|
|
123
124
|
mapOf(
|
|
124
125
|
"tools" to headerRight?.tools?.map { it.toMap() },
|
|
125
126
|
"context" to mapOf(
|
|
@@ -127,7 +128,11 @@ fun ToolkitHeaderRight(headerRight: HeaderRightData? = null) {
|
|
|
127
128
|
"code" to context?.appCode,
|
|
128
129
|
"name" to context?.appName,
|
|
129
130
|
"icon" to context?.appIcon,
|
|
130
|
-
"description" to context?.description
|
|
131
|
+
"description" to context?.description,
|
|
132
|
+
"support" to context?.support,
|
|
133
|
+
"toolkitConfig" to context?.toolkitConfig,
|
|
134
|
+
"providerId" to context?.providerId,
|
|
135
|
+
"permissions" to context?.permissions
|
|
131
136
|
)
|
|
132
137
|
)
|
|
133
138
|
) { response ->
|
|
@@ -180,10 +185,18 @@ fun ToolkitHeaderRight(headerRight: HeaderRightData? = null) {
|
|
|
180
185
|
group.items.any { it.showBadge }
|
|
181
186
|
}
|
|
182
187
|
|
|
188
|
+
val toolkitWidth = if (context !== null) 65.dp else 28.dp
|
|
189
|
+
|
|
190
|
+
var isShowShortcut = headerRight?.useShortcut == true
|
|
191
|
+
//backup case context null of more icon
|
|
192
|
+
if (headerRight?.useMore == true && context == null) {
|
|
193
|
+
isShowShortcut = false
|
|
194
|
+
}
|
|
195
|
+
|
|
183
196
|
Row(
|
|
184
197
|
verticalAlignment = Alignment.CenterVertically
|
|
185
198
|
) {
|
|
186
|
-
if (
|
|
199
|
+
if (isShowShortcut) {
|
|
187
200
|
NavigationButton(
|
|
188
201
|
disabled = isLoading,
|
|
189
202
|
icon = navButtonConfig.icon,
|
|
@@ -197,20 +210,26 @@ fun ToolkitHeaderRight(headerRight: HeaderRightData? = null) {
|
|
|
197
210
|
modifier = Modifier
|
|
198
211
|
.padding(start = Spacing.S)
|
|
199
212
|
.border(0.2.dp, Color(0x33000000), shape = RoundedCornerShape(14.dp))
|
|
200
|
-
.width(
|
|
213
|
+
.width(toolkitWidth)
|
|
201
214
|
.height(28.dp)
|
|
202
215
|
.clip(shape = RoundedCornerShape(14.dp))
|
|
203
216
|
.background(Color(0x99FFFFFF))
|
|
204
217
|
) {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
218
|
+
if (context != null) {
|
|
219
|
+
Icon(
|
|
220
|
+
source = "help_center",
|
|
221
|
+
size = 20.dp,
|
|
222
|
+
modifier = Modifier.padding(4.dp).clickable {
|
|
223
|
+
onPressHelpCenter()
|
|
224
|
+
})
|
|
225
|
+
Box(
|
|
226
|
+
modifier = Modifier
|
|
227
|
+
.width(0.5.dp)
|
|
228
|
+
.height(12.dp)
|
|
229
|
+
.background(Colors.black_20)
|
|
230
|
+
)
|
|
231
|
+
}
|
|
232
|
+
|
|
214
233
|
Icon(
|
|
215
234
|
source = "16_navigation_close_circle",
|
|
216
235
|
size = 20.dp,
|
|
@@ -9,7 +9,7 @@ import androidx.compose.runtime.remember
|
|
|
9
9
|
import androidx.compose.runtime.setValue
|
|
10
10
|
import androidx.compose.runtime.staticCompositionLocalOf
|
|
11
11
|
import androidx.compose.ui.unit.Dp
|
|
12
|
-
import
|
|
12
|
+
import kotlinx.serialization.Serializable
|
|
13
13
|
import vn.momo.kits.components.TrustBannerData
|
|
14
14
|
import vn.momo.kits.const.AppStatusBar
|
|
15
15
|
import vn.momo.kits.const.AppTheme
|
|
@@ -49,6 +49,10 @@ data class MiniAppContext(
|
|
|
49
49
|
val appId: String = "",
|
|
50
50
|
val appCode: String = "",
|
|
51
51
|
val description: Any? = null,
|
|
52
|
+
val support: Map<String, Any?> = emptyMap(),
|
|
53
|
+
val toolkitConfig: Map<String, Any?> = emptyMap(),
|
|
54
|
+
val providerId: String = "",
|
|
55
|
+
val permissions: List<Map<String, Any>>? = emptyList()
|
|
52
56
|
)
|
|
53
57
|
|
|
54
58
|
val PlatformApi = staticCompositionLocalOf<Any?> { null }
|
|
@@ -75,7 +79,7 @@ data class KitConfig(
|
|
|
75
79
|
fun ApplicationContainer(
|
|
76
80
|
theme: Theme = defaultTheme,
|
|
77
81
|
composeApi: ComposeApi? = null,
|
|
78
|
-
statusBarHeight: Dp? =
|
|
82
|
+
statusBarHeight: Dp? = AppStatusBar.current,
|
|
79
83
|
applicationContext: MiniAppContext? = null,
|
|
80
84
|
config: KitConfig? = null,
|
|
81
85
|
content: @Composable () -> Unit,
|
|
@@ -99,8 +103,6 @@ fun ApplicationContainer(
|
|
|
99
103
|
|
|
100
104
|
val appStatusBarHeight = statusBarHeight ?: getStatusBarHeight()
|
|
101
105
|
|
|
102
|
-
println("appStatusBarHeight ${appStatusBarHeight.value}")
|
|
103
|
-
|
|
104
106
|
disableOverscroll()
|
|
105
107
|
CompositionLocalProvider(
|
|
106
108
|
AppTheme provides appTheme,
|
|
@@ -47,6 +47,8 @@ enum class HeaderType {
|
|
|
47
47
|
NONE
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
+
const val HEADER_HEIGHT = 52
|
|
51
|
+
|
|
50
52
|
@Composable
|
|
51
53
|
fun Screen(
|
|
52
54
|
backgroundColor: Color? = null,
|
|
@@ -62,12 +64,13 @@ fun Screen(
|
|
|
62
64
|
onContentLayout: ((LayoutCoordinates) -> Unit)? = null,
|
|
63
65
|
useAvoidKeyboard: Boolean = true,
|
|
64
66
|
footer: @Composable (() -> Unit)? = null,
|
|
65
|
-
headerRight: @Composable (() -> Unit)? =
|
|
67
|
+
headerRight: @Composable (() -> Unit)? = null,
|
|
66
68
|
fabProps: FabProps? = null,
|
|
67
69
|
animatedHeader: AnimatedHeader? = null,
|
|
68
70
|
layoutOffset: Dp = 56.dp,
|
|
69
71
|
inputSearchProps: InputSearchProps? = null,
|
|
70
72
|
useAnimationSearch: Boolean = false,
|
|
73
|
+
headerRightWidth: Dp = 0.dp,
|
|
71
74
|
content: @Composable () -> Unit,
|
|
72
75
|
) {
|
|
73
76
|
val statusBarHeight = AppStatusBar.current ?: getStatusBarHeight()
|
|
@@ -84,7 +87,7 @@ fun Screen(
|
|
|
84
87
|
val bottomPadding = min(indicator, 21.dp)
|
|
85
88
|
|
|
86
89
|
val opacity by animateFloatAsState(
|
|
87
|
-
targetValue = ((scrollState.value /
|
|
90
|
+
targetValue = ((scrollState.value / HEADER_HEIGHT*1f)).coerceIn(0f, 1f),
|
|
88
91
|
)
|
|
89
92
|
|
|
90
93
|
val headerAnimated =
|
|
@@ -94,15 +97,13 @@ fun Screen(
|
|
|
94
97
|
|
|
95
98
|
Box(
|
|
96
99
|
Modifier.fillMaxSize()
|
|
97
|
-
.background(AppTheme.current.colors.background.
|
|
100
|
+
.background(backgroundColor ?: AppTheme.current.colors.background.default)
|
|
98
101
|
) {
|
|
99
102
|
|
|
100
103
|
if (animatedHeader === null) {
|
|
101
104
|
HeaderBackground(
|
|
102
105
|
headerType = headerType,
|
|
103
|
-
scrollState = scrollState.value
|
|
104
|
-
inputSearchProps = inputSearchProps,
|
|
105
|
-
useAnimationSearch = useAnimationSearch
|
|
106
|
+
scrollState = scrollState.value
|
|
106
107
|
)
|
|
107
108
|
} else {
|
|
108
109
|
Box(
|
|
@@ -111,31 +112,28 @@ fun Screen(
|
|
|
111
112
|
.graphicsLayer { alpha = opacity }
|
|
112
113
|
) {
|
|
113
114
|
HeaderBackground(
|
|
114
|
-
isBack = isBack,
|
|
115
115
|
headerType = headerType,
|
|
116
|
-
scrollState = scrollState.value
|
|
117
|
-
inputSearchProps = inputSearchProps,
|
|
118
|
-
useAnimationSearch = useAnimationSearch
|
|
116
|
+
scrollState = scrollState.value
|
|
119
117
|
)
|
|
120
118
|
}
|
|
121
119
|
}
|
|
122
|
-
|
|
123
120
|
Header(
|
|
124
121
|
headerType = headerType,
|
|
125
122
|
title = title,
|
|
126
123
|
titlePosition = titlePosition,
|
|
127
124
|
headerRight = headerRight,
|
|
125
|
+
headerRightWidth = headerRightWidth,
|
|
128
126
|
goBack = goBack,
|
|
129
127
|
opacity = opacity,
|
|
130
128
|
animatedHeader = animatedHeader,
|
|
131
129
|
inputSearchProps = inputSearchProps,
|
|
132
130
|
scrollState = scrollState.value,
|
|
133
|
-
useAnimationSearch = useAnimationSearch
|
|
131
|
+
useAnimationSearch = useAnimationSearch,
|
|
134
132
|
)
|
|
135
133
|
|
|
136
134
|
Column(
|
|
137
135
|
modifier = Modifier.fillMaxSize()
|
|
138
|
-
.padding(top = if (animatedHeader === null && headerType !== HeaderType.NONE) statusBarHeight +
|
|
136
|
+
.padding(top = if (animatedHeader === null && headerType !== HeaderType.NONE) statusBarHeight + HEADER_HEIGHT.dp else 0.dp)
|
|
139
137
|
.pointerInput(Unit) {
|
|
140
138
|
detectTapGestures(onTap = {
|
|
141
139
|
keyboardController?.hide()
|
|
@@ -155,19 +153,15 @@ fun Screen(
|
|
|
155
153
|
verticalArrangement = verticalArrangement,
|
|
156
154
|
horizontalAlignment = horizontalAlignment
|
|
157
155
|
) {
|
|
158
|
-
Box
|
|
159
|
-
modifier = Modifier.background(
|
|
160
|
-
backgroundColor ?: AppTheme.current.colors.background.default
|
|
161
|
-
)
|
|
162
|
-
) {
|
|
156
|
+
Box {
|
|
163
157
|
headerAnimated()
|
|
164
158
|
Column {
|
|
165
159
|
if (animatedHeader !== null) {
|
|
166
|
-
Spacer(modifier = Modifier.padding(top = statusBarHeight +
|
|
160
|
+
Spacer(modifier = Modifier.padding(top = statusBarHeight + HEADER_HEIGHT.dp + layoutOffset))
|
|
167
161
|
}
|
|
168
162
|
|
|
169
|
-
if (useAnimationSearch && inputSearchProps != null) {
|
|
170
|
-
Spacer(modifier = Modifier.padding(top =
|
|
163
|
+
if (useAnimationSearch && inputSearchProps != null && headerType == HeaderType.EXTENDED) {
|
|
164
|
+
Spacer(modifier = Modifier.padding(top = (HEADER_HEIGHT.dp + Spacing.M)))
|
|
171
165
|
}
|
|
172
166
|
content()
|
|
173
167
|
}
|
|
@@ -3,59 +3,63 @@ package vn.momo.kits.application
|
|
|
3
3
|
import androidx.compose.animation.animateColorAsState
|
|
4
4
|
import androidx.compose.animation.core.animateFloatAsState
|
|
5
5
|
import androidx.compose.runtime.Composable
|
|
6
|
+
import androidx.compose.runtime.getValue
|
|
6
7
|
import androidx.compose.ui.graphics.Color
|
|
7
8
|
import androidx.compose.ui.unit.Dp
|
|
9
|
+
import androidx.compose.ui.unit.dp
|
|
8
10
|
import vn.momo.kits.const.AppTheme
|
|
9
11
|
import vn.momo.kits.const.Colors
|
|
10
|
-
import
|
|
12
|
+
import vn.momo.kits.platform.getScreenDimensions
|
|
11
13
|
|
|
12
14
|
data class HeaderAnimations(
|
|
13
15
|
val opacity: Float,
|
|
14
16
|
val backgroundSearch: Color,
|
|
15
17
|
val translateX: Float,
|
|
16
18
|
val width: Float,
|
|
17
|
-
val
|
|
19
|
+
val translateY: Float
|
|
18
20
|
)
|
|
19
21
|
|
|
22
|
+
private const val SCREEN_PADDING = 12
|
|
23
|
+
private const val BACK_WIDTH = 28
|
|
24
|
+
|
|
20
25
|
@Composable
|
|
21
26
|
fun useHeaderSearchAnimation(
|
|
27
|
+
opacityAni: Float,
|
|
22
28
|
scrollState: Int,
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
searchWidth: Int,
|
|
26
|
-
headerRightWidth: Dp
|
|
29
|
+
headerRightWidth: Dp,
|
|
30
|
+
isBack: Boolean
|
|
27
31
|
): HeaderAnimations {
|
|
28
|
-
val
|
|
29
|
-
|
|
30
|
-
)
|
|
32
|
+
val screenWidth = getScreenDimensions().width
|
|
33
|
+
val leftPosition = if (isBack) (BACK_WIDTH + 20).dp else 12.dp
|
|
34
|
+
val searchWidth = screenWidth - (SCREEN_PADDING * 2)
|
|
31
35
|
|
|
32
36
|
val backgroundSearch by animateColorAsState(
|
|
33
37
|
targetValue = animateColor(
|
|
34
|
-
AppTheme.current.colors.background.default,
|
|
35
38
|
Colors.black_01,
|
|
39
|
+
AppTheme.current.colors.background.default,
|
|
36
40
|
opacityAni
|
|
37
|
-
)
|
|
41
|
+
),
|
|
38
42
|
)
|
|
39
43
|
|
|
40
44
|
val animatedTranslateX by animateFloatAsState(
|
|
41
|
-
targetValue = (scrollState /
|
|
45
|
+
targetValue = (scrollState / HEADER_HEIGHT*1f).coerceIn(0f, 1f) * (leftPosition.value - 12) + 12,
|
|
42
46
|
)
|
|
43
47
|
|
|
44
48
|
val animatedWidth by animateFloatAsState(
|
|
45
|
-
targetValue = (scrollState /
|
|
46
|
-
|
|
49
|
+
targetValue = (scrollState / HEADER_HEIGHT*1f).coerceIn(
|
|
50
|
+
0f,
|
|
51
|
+
1f
|
|
52
|
+
) * ((searchWidth - leftPosition.value - headerRightWidth.value + 12) - searchWidth) + searchWidth,
|
|
47
53
|
)
|
|
48
54
|
|
|
49
|
-
val
|
|
50
|
-
targetValue = (1 - (scrollState /
|
|
51
|
-
(statusBarHeight.value + 94 - (statusBarHeight.value + 52)) + (statusBarHeight.value + 52)
|
|
55
|
+
val animatedTranslateY by animateFloatAsState(
|
|
56
|
+
targetValue = (1 - (scrollState / HEADER_HEIGHT* 1f).coerceIn(0f, 1f)) * HEADER_HEIGHT
|
|
52
57
|
)
|
|
53
|
-
|
|
54
58
|
return HeaderAnimations(
|
|
55
59
|
opacity = opacityAni,
|
|
56
60
|
backgroundSearch = backgroundSearch,
|
|
57
61
|
translateX = animatedTranslateX,
|
|
58
62
|
width = animatedWidth,
|
|
59
|
-
|
|
63
|
+
translateY = animatedTranslateY
|
|
60
64
|
)
|
|
61
65
|
}
|
|
@@ -35,6 +35,7 @@ import vn.momo.kits.const.AppTheme
|
|
|
35
35
|
import vn.momo.kits.const.Radius
|
|
36
36
|
import vn.momo.kits.const.Spacing
|
|
37
37
|
import vn.momo.kits.const.Typography
|
|
38
|
+
import vn.momo.kits.modifier.setAutomationId
|
|
38
39
|
import vn.momo.kits.utils.ifNotNull
|
|
39
40
|
|
|
40
41
|
data class PopupAction(
|
|
@@ -95,12 +96,12 @@ fun PopupNotify(
|
|
|
95
96
|
callback?.invoke()
|
|
96
97
|
}
|
|
97
98
|
|
|
98
|
-
Box(Modifier.
|
|
99
|
-
|
|
100
|
-
}, contentAlignment = Alignment.TopEnd) {
|
|
99
|
+
Box(Modifier.setAutomationId("popup_notify")
|
|
100
|
+
, contentAlignment = Alignment.TopEnd) {
|
|
101
101
|
Column(
|
|
102
102
|
modifier = Modifier
|
|
103
103
|
.fillMaxWidth()
|
|
104
|
+
.padding(horizontal = 12.dp)
|
|
104
105
|
.clip(RoundedCornerShape(Radius.L))
|
|
105
106
|
.background(
|
|
106
107
|
AppTheme.current.colors.background.surface,
|
|
@@ -115,7 +116,7 @@ fun PopupNotify(
|
|
|
115
116
|
)
|
|
116
117
|
|
|
117
118
|
Column(modifier = Modifier.padding(Spacing.XL)) {
|
|
118
|
-
Text(style = Typography.titleXs, maxLines = 2, text = title)
|
|
119
|
+
Text(style = Typography.titleXs, maxLines = 2, text = title, modifier = Modifier.setAutomationId("title_popup_permission"))
|
|
119
120
|
content(Modifier.padding(top = Spacing.S))
|
|
120
121
|
if (error.isNotEmpty()) {
|
|
121
122
|
Text(
|
|
@@ -142,7 +143,7 @@ fun PopupNotify(
|
|
|
142
143
|
Modifier
|
|
143
144
|
.width(22.dp)
|
|
144
145
|
.height(22.dp)
|
|
145
|
-
.offset(x = Spacing.
|
|
146
|
+
.offset(x = Spacing.M / 2, y = -Spacing.M)
|
|
146
147
|
.background(
|
|
147
148
|
color = AppTheme.current.colors.text.default,
|
|
148
149
|
shape = RoundedCornerShape(Radius.M)
|
|
@@ -164,9 +165,7 @@ fun PopupNotify(
|
|
|
164
165
|
source = "navigation_close",
|
|
165
166
|
color = AppTheme.current.colors.background.surface,
|
|
166
167
|
size = 16.dp,
|
|
167
|
-
modifier = Modifier.
|
|
168
|
-
testTag = "ic_popup_close"
|
|
169
|
-
}
|
|
168
|
+
modifier = Modifier.setAutomationId("ic_popup_close")
|
|
170
169
|
)
|
|
171
170
|
}
|
|
172
171
|
}
|
|
@@ -233,9 +232,7 @@ fun renderRow(
|
|
|
233
232
|
},
|
|
234
233
|
title = it.title,
|
|
235
234
|
type = ButtonType.TEXT,
|
|
236
|
-
modifier = Modifier.
|
|
237
|
-
testTag = "btn_popup_cancel"
|
|
238
|
-
}
|
|
235
|
+
modifier = Modifier.setAutomationId("btn_popup_cancel")
|
|
239
236
|
)
|
|
240
237
|
}
|
|
241
238
|
Spacer(modifier = Modifier.width(Spacing.S))
|
|
@@ -248,9 +245,7 @@ fun renderRow(
|
|
|
248
245
|
onAction(primary?.onPress)
|
|
249
246
|
},
|
|
250
247
|
title = primary?.title ?: "",
|
|
251
|
-
modifier = Modifier.
|
|
252
|
-
testTag = "btn_popup_allow"
|
|
253
|
-
}
|
|
248
|
+
modifier = Modifier.setAutomationId("btn_popup_allow")
|
|
254
249
|
)
|
|
255
250
|
}
|
|
256
251
|
}
|
|
@@ -271,9 +266,7 @@ fun renderColumn(
|
|
|
271
266
|
onAction(primary?.onPress)
|
|
272
267
|
},
|
|
273
268
|
title = primary?.title ?: "",
|
|
274
|
-
modifier = Modifier.
|
|
275
|
-
testTag = "btn_popup_allow"
|
|
276
|
-
}
|
|
269
|
+
modifier = Modifier.setAutomationId("btn_popup_allow")
|
|
277
270
|
)
|
|
278
271
|
secondary?.let {
|
|
279
272
|
Spacer(modifier = Modifier.height(Spacing.S))
|
|
@@ -286,9 +279,7 @@ fun renderColumn(
|
|
|
286
279
|
},
|
|
287
280
|
title = it.title,
|
|
288
281
|
type = ButtonType.TEXT,
|
|
289
|
-
modifier = Modifier.
|
|
290
|
-
testTag = "btn_popup_cancel"
|
|
291
|
-
}
|
|
282
|
+
modifier = Modifier.setAutomationId("btn_popup_cancel")
|
|
292
283
|
)
|
|
293
284
|
}
|
|
294
285
|
}
|
|
@@ -37,7 +37,7 @@ fun Text(
|
|
|
37
37
|
modifier = modifier.setAutomationId(accessibilityId?:text, text),
|
|
38
38
|
text = text,
|
|
39
39
|
color = color ?: AppTheme.current.colors.text.default,
|
|
40
|
-
style = style,
|
|
40
|
+
style = style.copy(fontWeight = null),
|
|
41
41
|
textAlign = textAlign,
|
|
42
42
|
fontSize = fontSize,
|
|
43
43
|
fontFamily = font,
|
package/ios/Image/Image.swift
CHANGED
|
@@ -46,8 +46,10 @@ public struct PopupDisplay: View {
|
|
|
46
46
|
.overlay(RoundedRectangle(cornerRadius: Radius.L).stroke(Colors.black01, lineWidth: 1))
|
|
47
47
|
}.foregroundColor(Colors.black20)
|
|
48
48
|
.background(Colors.black01.cornerRadius(15))
|
|
49
|
-
.
|
|
49
|
+
.padding(.trailing, -Spacing.M )
|
|
50
|
+
.padding(.top, -Spacing.M)
|
|
50
51
|
.zIndex(1)
|
|
52
|
+
.accessibility(identifier: "ic_popup_close")
|
|
51
53
|
|
|
52
54
|
VStack {
|
|
53
55
|
if(!url.isEmpty) {
|
|
@@ -70,6 +72,7 @@ public struct PopupDisplay: View {
|
|
|
70
72
|
.padding(.top, 16)
|
|
71
73
|
.padding(.bottom, 8)
|
|
72
74
|
.lineLimit(2)
|
|
75
|
+
.accessibility(identifier: "title_popup_permission")
|
|
73
76
|
|
|
74
77
|
Text(description)
|
|
75
78
|
.foregroundColor(.black)
|
|
@@ -77,7 +80,9 @@ public struct PopupDisplay: View {
|
|
|
77
80
|
.opacity(0.6)
|
|
78
81
|
.multilineTextAlignment(.leading)
|
|
79
82
|
.padding(.bottom, 20)
|
|
80
|
-
}
|
|
83
|
+
}
|
|
84
|
+
.frame(maxWidth: .infinity, alignment: .leading)
|
|
85
|
+
.padding(.horizontal, 24)
|
|
81
86
|
|
|
82
87
|
if buttonDirection == .row {
|
|
83
88
|
if buttonType == .text {
|
|
@@ -97,7 +102,9 @@ public struct PopupDisplay: View {
|
|
|
97
102
|
}
|
|
98
103
|
}
|
|
99
104
|
.background(Color.white.cornerRadius(15))
|
|
100
|
-
.padding(.horizontal,
|
|
105
|
+
.padding(.horizontal, 12)
|
|
106
|
+
.accessibilityElement(children: .ignore)
|
|
107
|
+
.accessibility(identifier: "popup_notify")
|
|
101
108
|
}
|
|
102
109
|
|
|
103
110
|
// MARK: Internal
|
|
@@ -150,8 +157,9 @@ public struct PopupDisplay: View {
|
|
|
150
157
|
|
|
151
158
|
var RowButtons: some View {
|
|
152
159
|
HStack {
|
|
153
|
-
Button(title: closeButtonTitle, action: onPressCloseButton, type: .secondary, size: .medium)
|
|
160
|
+
Button(title: closeButtonTitle, action: onPressCloseButton, type: .secondary, size: .medium).accessibility(identifier: "btn_popup_cancel")
|
|
154
161
|
Button(title: actionButtonTitle, action: onPressAction, size: .medium)
|
|
162
|
+
.accessibility(identifier: "btn_popup_allow")
|
|
155
163
|
}
|
|
156
164
|
.frame(maxWidth: .infinity, alignment: .center)
|
|
157
165
|
.padding(.horizontal, 24)
|
|
@@ -164,8 +172,9 @@ public struct PopupDisplay: View {
|
|
|
164
172
|
title: actionButtonTitle,
|
|
165
173
|
action: onPressAction,
|
|
166
174
|
size: .medium
|
|
167
|
-
)
|
|
168
|
-
Button(title: closeButtonTitle, action: onPressCloseButton, type: .secondary, size: .medium)
|
|
175
|
+
).accessibility(identifier: "btn_popup_allow")
|
|
176
|
+
Button(title: closeButtonTitle, action: onPressCloseButton, type: .secondary, size: .medium).accessibility(identifier: "btn_popup_cancel")
|
|
177
|
+
|
|
169
178
|
}
|
|
170
179
|
.frame(maxWidth: .infinity, alignment: .trailing)
|
|
171
180
|
.padding(.horizontal, 24)
|
package/local.properties
CHANGED
|
@@ -4,5 +4,5 @@
|
|
|
4
4
|
# Location of the SDK. This is only used by Gradle.
|
|
5
5
|
# For customization when using a Version Control System, please read the
|
|
6
6
|
# header note.
|
|
7
|
-
#
|
|
8
|
-
sdk.dir=/Users/
|
|
7
|
+
#Sun Mar 02 11:30:14 ICT 2025
|
|
8
|
+
sdk.dir=/Users/nguyenhoangson/Library/Android/sdk
|