@momo-kits/native-kits 0.89.29 → 0.89.30-beta.1

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.
Files changed (31) hide show
  1. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Components.kt +73 -49
  2. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Screen.kt +10 -22
  3. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Theme.kt +3 -4
  4. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Typography.kt +24 -13
  5. package/package.json +1 -1
  6. package/android/build.gradle +0 -45
  7. package/android/proguard-rules.pro +0 -21
  8. package/android/src/main/AndroidManifest.xml +0 -4
  9. package/android/src/main/java/com/momoplatform/nativekits/foundations/Button.kt +0 -16
  10. package/android/src/main/java/com/momoplatform/nativekits/libs/Logo.kt +0 -63
  11. package/android/src/main/java/com/momoplatform/nativekits/libs/TrustBanner.kt +0 -246
  12. package/android/src/main/res/drawable/ic_launcher_background.xml +0 -170
  13. package/android/src/main/res/drawable-v24/ic_launcher_foreground.xml +0 -30
  14. package/android/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +0 -6
  15. package/android/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +0 -6
  16. package/android/src/main/res/mipmap-hdpi/ic_launcher.webp +0 -0
  17. package/android/src/main/res/mipmap-hdpi/ic_launcher_round.webp +0 -0
  18. package/android/src/main/res/mipmap-mdpi/ic_launcher.webp +0 -0
  19. package/android/src/main/res/mipmap-mdpi/ic_launcher_round.webp +0 -0
  20. package/android/src/main/res/mipmap-xhdpi/ic_launcher.webp +0 -0
  21. package/android/src/main/res/mipmap-xhdpi/ic_launcher_round.webp +0 -0
  22. package/android/src/main/res/mipmap-xxhdpi/ic_launcher.webp +0 -0
  23. package/android/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp +0 -0
  24. package/android/src/main/res/mipmap-xxxhdpi/ic_launcher.webp +0 -0
  25. package/android/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp +0 -0
  26. package/android/src/main/res/values/colors.xml +0 -10
  27. package/android/src/main/res/values/strings.xml +0 -3
  28. package/android/src/main/res/values/themes.xml +0 -3
  29. package/android/src/main/res/values-night/themes.xml +0 -3
  30. package/android/src/main/res/xml/backup_rules.xml +0 -13
  31. package/android/src/main/res/xml/data_extraction_rules.xml +0 -19
@@ -4,7 +4,6 @@ import androidx.compose.animation.animateColorAsState
4
4
  import androidx.compose.foundation.background
5
5
  import androidx.compose.foundation.border
6
6
  import androidx.compose.foundation.clickable
7
- import androidx.compose.foundation.interaction.MutableInteractionSource
8
7
  import androidx.compose.foundation.layout.Arrangement
9
8
  import androidx.compose.foundation.layout.Box
10
9
  import androidx.compose.foundation.layout.BoxWithConstraints
@@ -16,7 +15,6 @@ import androidx.compose.foundation.layout.padding
16
15
  import androidx.compose.foundation.layout.size
17
16
  import androidx.compose.foundation.layout.width
18
17
  import androidx.compose.foundation.shape.RoundedCornerShape
19
- import androidx.compose.material.ripple.rememberRipple
20
18
  import androidx.compose.runtime.Composable
21
19
  import androidx.compose.runtime.LaunchedEffect
22
20
  import androidx.compose.runtime.getValue
@@ -26,9 +24,12 @@ import androidx.compose.runtime.setValue
26
24
  import androidx.compose.runtime.snapshotFlow
27
25
  import androidx.compose.ui.Alignment
28
26
  import androidx.compose.ui.Modifier
27
+ import androidx.compose.ui.geometry.Offset
28
+ import androidx.compose.ui.graphics.Brush
29
29
  import androidx.compose.ui.graphics.Color
30
30
  import androidx.compose.ui.graphics.graphicsLayer
31
31
  import androidx.compose.ui.layout.ContentScale
32
+ import androidx.compose.ui.platform.LocalDensity
32
33
  import androidx.compose.ui.semantics.contentDescription
33
34
  import androidx.compose.ui.semantics.semantics
34
35
  import androidx.compose.ui.semantics.testTag
@@ -60,43 +61,76 @@ data class AnimatedHeader(
60
61
  )
61
62
 
62
63
  @Composable
63
- fun HeaderImage(
64
- headerType: HeaderType = HeaderType.DEFAULT,
65
- headerBackground: String?,
64
+ fun HeaderBackground(
65
+ headerType: HeaderType = HeaderType.DEFAULT
66
66
  ) {
67
67
  val statusBarHeight = AppStatusBar.current ?: getStatusBarHeight()
68
68
  when (headerType) {
69
69
  HeaderType.DEFAULT -> {
70
70
  val height = statusBarHeight + 52.dp
71
- Image(
72
- source = headerBackground ?: "",
73
- modifier = Modifier.fillMaxWidth().height(height),
74
- options = Options(
75
- contentScale = ContentScale.FillWidth
71
+ Box(
72
+ modifier = Modifier.fillMaxWidth().height(height)
73
+ .bottomBorder(
74
+ strokeWidth = 1.dp,
75
+ color = AppTheme.current.colors.border.default
76
+ )
77
+ ) {
78
+ Box(
79
+ modifier = Modifier
80
+ .height(height)
81
+ .fillMaxWidth()
82
+ .background(
83
+ Brush.linearGradient(
84
+ colors = listOf(
85
+ Color(0xFFFDCACE),
86
+ Color(0x00FDCACE)
87
+ ),
88
+ start = Offset(0f, 0f),
89
+ end = Offset(0f, with(LocalDensity.current) { 154.dp.toPx() })
90
+ )
91
+ )
76
92
  )
77
- )
78
- }
93
+ if (AppTheme.current.assets.headerBackground != null) {
94
+ Image(
95
+ source = AppTheme.current.assets.headerBackground!!,
96
+ modifier = Modifier.fillMaxWidth().height(height),
97
+ options = Options(
98
+ contentScale = ContentScale.FillWidth
99
+ )
100
+ )
101
+ }
102
+ }
79
103
 
80
- HeaderType.EXTENDED -> {
81
- Image(
82
- source = headerBackground ?: "",
83
- modifier = Modifier.fillMaxWidth(),
84
- options = Options(
85
- contentScale = ContentScale.FillWidth
86
- )
87
- )
88
104
  }
89
105
 
90
- HeaderType.SURFACE -> {
91
- val height = statusBarHeight + 52.dp
106
+ HeaderType.EXTENDED -> {
92
107
  Box(
93
- modifier = Modifier.fillMaxWidth().height(height)
94
- .background(AppTheme.current.colors.background.surface)
108
+ modifier = Modifier.fillMaxWidth().height(154.dp)
109
+ .background(
110
+ Brush.linearGradient(
111
+ colors = listOf(
112
+ Color(0xFFFDCACE),
113
+ Color(0x00FDCACE)
114
+ ),
115
+ start = Offset(0f, 0f),
116
+ end = Offset(0f, with(LocalDensity.current) { 154.dp.toPx() })
117
+ )
118
+ )
95
119
  .bottomBorder(
96
- strokeWidth = 2.dp,
120
+ strokeWidth = 1.dp,
97
121
  color = AppTheme.current.colors.border.default
98
122
  )
99
- )
123
+ ) {
124
+ if (AppTheme.current.assets.headerBackground != null) {
125
+ Image(
126
+ source = AppTheme.current.assets.headerBackground!!,
127
+ modifier = Modifier.fillMaxWidth().height(154.dp),
128
+ options = Options(
129
+ contentScale = ContentScale.FillWidth
130
+ )
131
+ )
132
+ }
133
+ }
100
134
  }
101
135
 
102
136
  else -> {
@@ -118,22 +152,16 @@ fun Header(
118
152
  scrollState: Int = 0
119
153
  ) {
120
154
  val statusBarHeight = AppStatusBar.current ?: getStatusBarHeight()
121
- var tintIconColor = Colors.black_01
122
- var backgroundButton = Colors.black_20.copy(alpha = 0.4f)
123
- if (headerType == HeaderType.SURFACE) {
124
- tintIconColor = AppTheme.current.colors.text.default
125
- backgroundButton = Color.Transparent
126
- }
155
+ val tintIconColor = AppTheme.current.colors.text.default
156
+ val backgroundButton = Colors.black_01.copy(alpha = 0.2f)
127
157
 
128
158
  var colorFraction by remember { mutableStateOf(0f) }
129
159
 
130
160
  LaunchedEffect(scrollState) {
131
- if (headerType == HeaderType.SURFACE) {
132
- snapshotFlow { scrollState }
133
- .map { (it / 50f).coerceIn(0f, 1f) }
134
- .distinctUntilChanged()
135
- .collect { fraction -> colorFraction = fraction }
136
- }
161
+ snapshotFlow { scrollState }
162
+ .map { (it / 50f).coerceIn(0f, 1f) }
163
+ .distinctUntilChanged()
164
+ .collect { fraction -> colorFraction = fraction }
137
165
  }
138
166
 
139
167
  val tintIconColorAnim by animateColorAsState(
@@ -164,15 +192,11 @@ fun Header(
164
192
  modifier = Modifier
165
193
  .size(28.dp)
166
194
  .then(
167
- if (headerType == HeaderType.SURFACE) {
168
- Modifier.border(
169
- 0.5.dp,
170
- Colors.black_20.copy(alpha = 0.4f),
171
- RoundedCornerShape(100)
172
- )
173
- } else {
174
- Modifier
175
- }
195
+ Modifier.border(
196
+ 0.5.dp,
197
+ Colors.black_20.copy(alpha = 0.4f),
198
+ RoundedCornerShape(100)
199
+ )
176
200
  )
177
201
  .background(
178
202
  backgroundButton,
@@ -190,7 +214,7 @@ fun Header(
190
214
  ) {
191
215
  Icon(
192
216
  source = "ic_back_ios",
193
- color = if (headerType == HeaderType.SURFACE && animatedHeader !== null) tintIconColorAnim else tintIconColor,
217
+ color = if (animatedHeader !== null) tintIconColorAnim else tintIconColor,
194
218
  size = 20.dp,
195
219
  )
196
220
  }
@@ -221,7 +245,7 @@ fun Header(
221
245
  ) {
222
246
  HeaderTitle(
223
247
  title = title,
224
- color = if (headerType == HeaderType.SURFACE && animatedHeader !== null) tintIconColorAnim else tintIconColor,
248
+ color = if (animatedHeader !== null) tintIconColorAnim else tintIconColor,
225
249
  modifier = Modifier.semantics {
226
250
  contentDescription = "title_navigation_header"
227
251
  testTag = "title_navigation_header"
@@ -38,7 +38,6 @@ import vn.momo.kits.platform.getStatusBarHeight
38
38
 
39
39
  enum class HeaderType {
40
40
  DEFAULT,
41
- SURFACE,
42
41
  EXTENDED,
43
42
  NONE
44
43
  }
@@ -46,7 +45,6 @@ enum class HeaderType {
46
45
  @Composable
47
46
  fun Screen(
48
47
  backgroundColor: Color? = null,
49
- headerBackground: String? = null,
50
48
  isBack: Boolean = true,
51
49
  headerType: HeaderType = HeaderType.DEFAULT,
52
50
  verticalArrangement: Arrangement.Vertical = Arrangement.Top,
@@ -90,18 +88,14 @@ fun Screen(
90
88
  ) {
91
89
 
92
90
  if (animatedHeader === null) {
93
- HeaderImage(
94
- headerType,
95
- headerBackground ?: AppTheme.current.assets.headerBackground
96
- )
91
+ HeaderBackground(headerType)
97
92
  } else {
98
93
  Box(
99
- Modifier.zIndex(5f).background(Color.White.copy(alpha = opacity))
100
- .graphicsLayer { alpha = opacity }) {
101
- HeaderImage(
102
- headerType,
103
- headerBackground ?: AppTheme.current.assets.headerBackground
104
- )
94
+ Modifier.zIndex(5f)
95
+ .background(Color.White.copy(alpha = opacity))
96
+ .graphicsLayer { alpha = opacity }
97
+ ) {
98
+ HeaderBackground(headerType)
105
99
  }
106
100
  }
107
101
 
@@ -129,9 +123,7 @@ fun Screen(
129
123
  ) {
130
124
 
131
125
  Column(
132
- modifier = if (scrollable) Modifier.weight(1f).padding(bottom = keyboardSize)
133
- .verticalScroll(scrollState) else
134
- Modifier.padding(bottom = keyboardSize),
126
+ modifier = if (scrollable) Modifier.weight(1f).padding(bottom = keyboardSize).verticalScroll(scrollState) else Modifier.padding(bottom = keyboardSize),
135
127
  verticalArrangement = verticalArrangement,
136
128
  horizontalAlignment = horizontalAlignment
137
129
  ) {
@@ -156,8 +148,7 @@ fun Screen(
156
148
  scrollPosition = fabProps.scrollState?.value ?: scrollState.value,
157
149
  onClick = fabProps.onClick,
158
150
  containerColor = AppTheme.current.colors.primary,
159
- bottom = fabProps.bottom
160
- ?: if (footer != null) bottomPadding + 76.dp else bottomPadding + 12.dp,
151
+ bottom = fabProps.bottom ?: if (footer != null) bottomPadding + 76.dp else bottomPadding + 12.dp,
161
152
  icon = fabProps.icon,
162
153
  iconColor = fabProps.iconColor,
163
154
  text = fabProps.label,
@@ -186,11 +177,8 @@ fun Footer(footer: @Composable (() -> Unit)? = null, keyboardSize: Dp = 0.dp, bo
186
177
  .background(AppTheme.current.colors.background.surface)
187
178
  ) {
188
179
  Box(
189
- Modifier
190
- .fillMaxWidth()
191
- .padding(vertical = Spacing.S, horizontal = Spacing.M)
192
- )
193
- {
180
+ Modifier.fillMaxWidth().padding(vertical = Spacing.S, horizontal = Spacing.M)
181
+ ) {
194
182
  footer?.invoke()
195
183
  }
196
184
  }
@@ -106,7 +106,7 @@ val defaultTheme = Theme(
106
106
  ),
107
107
  font = "SFProText",
108
108
  assets = ThemeAssets(
109
- headerBackground = "https://static.momocdn.net/app/img/app/img/header-background.png"
109
+ headerBackground = null
110
110
  )
111
111
  )
112
112
 
@@ -168,6 +168,5 @@ val darkTheme = Theme(
168
168
 
169
169
 
170
170
  val AppTheme = staticCompositionLocalOf { defaultTheme }
171
- val AppStatusBar = staticCompositionLocalOf<Dp?> {
172
- null
173
- }
171
+
172
+ val AppStatusBar = staticCompositionLocalOf<Dp?> { null }
@@ -27,10 +27,10 @@ fun scaleSize(size: Float): Float {
27
27
 
28
28
  @OptIn(InternalResourceApi::class)
29
29
  @Composable
30
- fun getFont(font: String, ext: String = "ttf"): FontFamily {
30
+ fun getFont(font: String): FontFamily {
31
31
  val fontResource = FontResource(
32
- "font:${font}",
33
- setOf(ResourceItem(setOf(), "font/${font}.${ext}", -1, -1))
32
+ "font:${font.substringBeforeLast(".")}",
33
+ setOf(ResourceItem(setOf(), "font/${font.substringBeforeLast(".")}.${font.substringAfterLast(".")}", -1, -1))
34
34
  )
35
35
  return FontFamily(Font(fontResource))
36
36
  }
@@ -39,17 +39,28 @@ fun getFont(font: String, ext: String = "ttf"): FontFamily {
39
39
  fun getFontFamily(fontFamily: String, fontWeight: FontWeight? = FontWeight.Normal): FontFamily {
40
40
  val key = "$fontFamily-${fontWeight?.weight}"
41
41
  val fontMap = mapOf(
42
- "SFProText-100" to getFont("sfprotext_thin"),
43
- "SFProText-200" to getFont("sfprotext_ultralight"),
44
- "SFProText-300" to getFont("sfprotext_light"),
45
- "SFProText-400" to getFont("sfprotext_regular"),
46
- "SFProText-500" to getFont("sfprotext_medium"),
47
- "SFProText-600" to getFont("sfprotext_medium"),
48
- "SFProText-700" to getFont("sfprotext_semibold"),
49
- "SFProText-800" to getFont("sfprotext_bold"),
50
- "SFProText-900" to getFont("sfprotext_heavy"),
42
+ "SFProText-100" to "sfprotext_thin.ttf",
43
+ "SFProText-200" to "sfprotext_ultralight.ttf",
44
+ "SFProText-300" to "sfprotext_light.ttf",
45
+ "SFProText-400" to "sfprotext_regular.ttf",
46
+ "SFProText-500" to "sfprotext_medium.ttf",
47
+ "SFProText-600" to "sfprotext_medium.ttf",
48
+ "SFProText-700" to "sfprotext_semibold.ttf",
49
+ "SFProText-800" to "sfprotext_bold.ttf",
50
+ "SFProText-900" to "sfprotext_heavy.ttf",
51
+
52
+ "MoMoSignature-100" to "momosignature.otf",
53
+ "MoMoSignature-200" to "momosignature.otf",
54
+ "MoMoSignature-300" to "momosignature.otf",
55
+ "MoMoSignature-400" to "momosignature.otf",
56
+ "MoMoSignature-500" to "momosignature.otf",
57
+ "MoMoSignature-600" to "momosignature.otf",
58
+ "MoMoSignature-700" to "momosignature.otf",
59
+ "MoMoSignature-800" to "momosignature.otf",
60
+ "MoMoSignature-900" to "momosignature.otf",
51
61
  )
52
- return fontMap[key] ?: getFont("sfprotext_regular")
62
+ val font = fontMap[key] ?: "sfprotext_regular.ttf"
63
+ return getFont(font)
53
64
  }
54
65
 
55
66
  @Immutable
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/native-kits",
3
- "version": "0.89.29",
3
+ "version": "0.89.30-beta.1",
4
4
  "private": false,
5
5
  "dependencies": {},
6
6
  "devDependencies": {},
@@ -1,45 +0,0 @@
1
- plugins {
2
- id 'com.android.library'
3
- id 'org.jetbrains.kotlin.android'
4
- alias libs.plugins.kotlin.compose.compiler
5
- }
6
-
7
- android {
8
- namespace 'com.momoplatform.nativekits'
9
- compileSdk 34
10
-
11
- defaultConfig {
12
- minSdk 23
13
- targetSdk 34
14
- versionCode 1
15
- versionName "1.0"
16
- }
17
-
18
- compileOptions {
19
- sourceCompatibility JavaVersion.VERSION_1_8
20
- targetCompatibility JavaVersion.VERSION_1_8
21
- }
22
-
23
- kotlinOptions {
24
- jvmTarget = '1.8'
25
- }
26
-
27
- buildFeatures {
28
- compose true
29
- }
30
- }
31
-
32
- dependencies {
33
- def composeBom = platform('androidx.compose:compose-bom:2023.10.01')
34
- implementation composeBom
35
- androidTestImplementation composeBom
36
- implementation "androidx.compose.material3:material3"
37
- implementation "androidx.compose.material:material:$rootProject.materialComposeVersion"
38
- implementation "androidx.compose.foundation:foundation:$rootProject.composeVersion"
39
- implementation "androidx.compose.ui:ui:$rootProject.composeVersion"
40
- implementation "androidx.compose.ui:ui-tooling-preview:$rootProject.composeVersion"
41
- debugImplementation "androidx.compose.ui:ui-tooling:$rootProject.composeVersion"
42
- implementation("io.coil-kt:coil-compose:2.5.0")
43
- implementation 'com.google.code.gson:gson:2.8.6'
44
-
45
- }
@@ -1,21 +0,0 @@
1
- # Add project specific ProGuard rules here.
2
- # You can control the set of applied configuration files using the
3
- # proguardFiles setting in build.gradle.
4
- #
5
- # For more details, see
6
- # http://developer.android.com/guide/developing/tools/proguard.html
7
-
8
- # If your project uses WebView with JS, uncomment the following
9
- # and specify the fully qualified class name to the JavaScript interface
10
- # class:
11
- #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12
- # public *;
13
- #}
14
-
15
- # Uncomment this to preserve the line number information for
16
- # debugging stack traces.
17
- #-keepattributes SourceFile,LineNumberTable
18
-
19
- # If you keep the line number information, uncomment this to
20
- # hide the original source file name.
21
- #-renamesourcefileattribute SourceFile
@@ -1,4 +0,0 @@
1
- <?xml version="1.0" encoding="utf-8"?>
2
- <manifest xmlns:android="http://schemas.android.com/apk/res/android">
3
-
4
- </manifest>
@@ -1,16 +0,0 @@
1
- package com.momoplatform.nativekits.foundations
2
-
3
- import androidx.compose.material3.Text
4
- import androidx.compose.runtime.Composable
5
- import androidx.compose.ui.tooling.preview.Preview
6
-
7
- @Composable
8
- fun Button (){
9
- Text("Button")
10
- }
11
-
12
- @Preview
13
- @Composable
14
- fun ReviewButton (){
15
- Button()
16
- }
@@ -1,63 +0,0 @@
1
- package com.momoplatform.nativekits.libs
2
-
3
- import androidx.compose.foundation.background
4
- import androidx.compose.foundation.border
5
- import androidx.compose.foundation.layout.size
6
- import androidx.compose.foundation.shape.RoundedCornerShape
7
- import androidx.compose.runtime.Composable
8
- import androidx.compose.ui.Modifier
9
- import androidx.compose.ui.draw.clip
10
- import androidx.compose.ui.draw.shadow
11
- import androidx.compose.ui.graphics.Color
12
- import androidx.compose.ui.layout.ContentScale
13
- import androidx.compose.ui.tooling.preview.Preview
14
- import androidx.compose.ui.unit.dp
15
- import coil.compose.AsyncImage
16
-
17
- @Composable
18
- fun Logo(
19
- type: String = "image",
20
- useShadow:Boolean = true,
21
- useBorder:Boolean = true,
22
- useBackground:Boolean = true,
23
- backgroundColor: Color = Color(0xffd8d8d8),
24
- shadowColor: Color = Color(0xffd8d8d8),
25
- borderColor: Color = Color(0xffe2e2e2),
26
- source: String = ""
27
- ) {
28
- val radius = if (type == "image") 9.dp else 0.dp
29
-
30
- var logoModifier = Modifier
31
- .size(28.dp)
32
- .clip(RoundedCornerShape(radius))
33
-
34
- if (useBackground) {
35
- logoModifier = logoModifier.background(color = backgroundColor)
36
- }
37
-
38
- if (useBorder && type != "icon") {
39
- logoModifier = logoModifier.border(width = 2.dp, color = borderColor, shape = RoundedCornerShape(9.dp))
40
- }
41
-
42
- if (useShadow) {
43
- logoModifier = logoModifier.shadow(2.dp, ambientColor = shadowColor)
44
- }
45
-
46
- AsyncImage(
47
- model = source,
48
- contentDescription = null,
49
- modifier = logoModifier,
50
- contentScale = ContentScale.Fit
51
- )
52
- }
53
-
54
- @Composable
55
- @Preview
56
- fun LogoPreview() {
57
- Logo(
58
- source = "https://static.momocdn.net/app/img/paylater/static/ic_service_vts_30kb.png",
59
- useShadow = false,
60
- shadowColor = Color.Green,
61
- type = "icon"
62
- )
63
- }
@@ -1,246 +0,0 @@
1
- package com.momoplatform.nativekits.libs
2
-
3
- import androidx.compose.foundation.background
4
- import androidx.compose.foundation.border
5
- import androidx.compose.foundation.clickable
6
- import androidx.compose.foundation.layout.Arrangement
7
- import androidx.compose.foundation.layout.Column
8
- import androidx.compose.foundation.layout.Row
9
- import androidx.compose.foundation.layout.fillMaxWidth
10
- import androidx.compose.foundation.layout.height
11
- import androidx.compose.foundation.layout.padding
12
- import androidx.compose.foundation.layout.size
13
- import androidx.compose.foundation.layout.width
14
- import androidx.compose.foundation.shape.CircleShape
15
- import androidx.compose.foundation.shape.RoundedCornerShape
16
- import androidx.compose.material.Text
17
- import androidx.compose.runtime.Composable
18
- import androidx.compose.runtime.mutableStateOf
19
- import androidx.compose.ui.Alignment
20
- import androidx.compose.ui.Modifier
21
- import androidx.compose.ui.draw.clip
22
- import androidx.compose.ui.graphics.Color
23
- import androidx.compose.ui.layout.ContentScale
24
- import androidx.compose.ui.unit.dp
25
- import androidx.compose.ui.unit.sp
26
- import coil.compose.AsyncImage
27
- import okhttp3.OkHttpClient
28
- import okhttp3.Request
29
- import kotlinx.coroutines.*
30
- import androidx.compose.runtime.*
31
- import com.google.gson.Gson
32
- import com.google.gson.annotations.SerializedName
33
-
34
- val defaultBanner = TrustBanner(
35
- content = mapOf(
36
- "vi" to "Bảo mật thông tin & An toàn tài sản của bạn là ưu tiên hàng đầu của MoMo.",
37
- "en" to "Your data security and money safety are MoMo's top priorities."
38
- ),
39
- pciImage = "https://static.momocdn.net/app/img/kits/trustBanner/pci.png",
40
- sslImage = "https://static.momocdn.net/app/img/kits/trustBanner/ssl.png",
41
- urlConfig = "https://momo.vn/an-toan-bao-mat",
42
- featureCode = "login_and_security",
43
- icons = listOf(
44
- "https://static.momocdn.net/app/img/kits/trustBanner/ic_viettinbank.png",
45
- "https://static.momocdn.net/app/img/kits/trustBanner/ic_agribank.png",
46
- "https://static.momocdn.net/app/img/kits/trustBanner/ic_vietcombank.png",
47
- "https://static.momocdn.net/app/img/kits/trustBanner/ic_bidv.png"
48
- ),
49
- momoImage = "https://static.momocdn.net/app/img/kits/trustBanner/ic_momo_secu.png"
50
- )
51
-
52
- val defaultData = TrustBannerData(trustBanner = defaultBanner)
53
-
54
- const val borderColor = 0xFFE8E8E8
55
- const val tonalColor = 0xFFFDEAF4
56
- const val backgroundBlue = 0xFFF2F8FF
57
- const val contentColor = 0xFF484848
58
- const val primaryColor = 0xFFEB2F96
59
- const val jsonUrl = "https://static.momocdn.net/app/json/component-kits/design_system.json"
60
-
61
- data class TrustBannerData(
62
- val trustBanner: TrustBanner
63
- )
64
-
65
- data class TrustBanner (
66
- val content: Map<String, String>,
67
-
68
- val pciImage: String,
69
- val sslImage: String,
70
- val icons: List<String>,
71
- val momoImage: String,
72
-
73
- @SerializedName("url_config")
74
- val urlConfig: String,
75
-
76
- @SerializedName("feature_code")
77
- val featureCode: String,
78
- )
79
-
80
- fun fetchJsonData(url: String, onFailure: (Exception) -> Unit) {
81
- val client = OkHttpClient()
82
-
83
- CoroutineScope(Dispatchers.IO).launch {
84
- try {
85
- val request = Request.Builder().url(url).build()
86
- val response = client.newCall(request).execute()
87
-
88
- if (!response.isSuccessful) {
89
- onFailure(Exception("Unexpected code $response"))
90
- } else {
91
- response.body?.string()?.let { jsonString ->
92
- withContext(Dispatchers.Main) {
93
- Gson().fromJson(jsonString, TrustBannerData::class.java)
94
- }
95
- }
96
- }
97
- } catch (e: Exception) {
98
- withContext(Dispatchers.Main) {
99
- onFailure(e)
100
- }
101
- }
102
- }
103
- }
104
-
105
- @Composable
106
- fun Avatar(iconURL: String) {
107
- AsyncImage(
108
- model = iconURL,
109
- contentDescription = null,
110
- modifier = Modifier
111
- .size(24.dp)
112
- .background(Color.White, CircleShape)
113
- .border(width = 1.dp, color = Color(borderColor), CircleShape),
114
- contentScale = ContentScale.Fit
115
- )
116
- }
117
-
118
- @Composable
119
- fun TrustBannerView(serviceName: String = "", screenName: String = "",onPress: ((Map<String, String>)->Unit)?, trackEvent: ((String, Map<String, String>)->Unit)?, language: String = "vi") {
120
- var trustBannerData by remember { mutableStateOf<TrustBannerData?>(defaultData) }
121
- var error by remember { mutableStateOf<String?>(null) }
122
-
123
- LaunchedEffect(Unit) {
124
- if (trackEvent != null) {
125
- trackEvent("service_component_displayed",mapOf(
126
- "service_name" to serviceName,
127
- "screen_name" to screenName,
128
- "component_name" to "logo_trust"
129
- ))
130
- }
131
- fetchJsonData(
132
- url = jsonUrl,
133
- onFailure = { exception ->
134
- error = exception.message
135
- }
136
- )
137
- }
138
-
139
- when {
140
- trustBannerData != null -> {
141
- if (onPress != null) {
142
- TrustBannerContent(trustBannerData!!.trustBanner,serviceName, screenName,onPress,trackEvent,language)
143
- }
144
- }
145
- }
146
- }
147
-
148
- @Composable
149
- fun TrustBannerContent(
150
- trustBanner: TrustBanner,
151
- serviceName: String,
152
- screenName: String,
153
- onPress: ((Map<String, String>) -> Unit)?,
154
- trackEvent: ((String,Map<String, String>) -> Unit)?,
155
- language: String
156
- ) {
157
- Row(
158
- modifier = Modifier
159
- .clip(RoundedCornerShape(12.dp))
160
- .background(color = Color(backgroundBlue))
161
- .padding(12.dp)
162
- .clickable {
163
- if (trackEvent != null) {
164
- trackEvent("service_component_clicked",mapOf(
165
- "service_name" to serviceName,
166
- "screen_name" to screenName,
167
- "component_name" to "logo_trust",
168
- "url_config" to trustBanner.urlConfig
169
- ))
170
- }
171
- if (onPress != null) {
172
- onPress(mapOf(
173
- "service_name" to serviceName,
174
- "screen_name" to screenName,
175
- "url_config" to trustBanner.urlConfig,
176
- "feature_code" to trustBanner.featureCode
177
- ))
178
- }
179
- }
180
- ) {
181
- AsyncImage(
182
- model = trustBanner.momoImage,
183
- contentDescription = "Momo mascot",
184
- modifier = Modifier
185
- .width(64.dp)
186
- .height(64.dp)
187
- .padding(end = 8.dp)
188
- )
189
- Column {
190
- Text(
191
- text = trustBanner.content[language] ?: "",
192
- modifier = Modifier.padding(bottom = 8.dp),
193
- lineHeight = 16.sp,
194
- fontSize = 12.sp,
195
- color = Color(contentColor),
196
- maxLines = 2
197
- )
198
- Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
199
- Row {
200
- AsyncImage(
201
- model = trustBanner.pciImage, contentDescription = "PCI image", modifier = Modifier
202
- .padding(end = 4.dp)
203
- .width(52.dp)
204
- .height(20.dp)
205
- )
206
- AsyncImage(
207
- model = trustBanner.sslImage, contentDescription = "PCI image", modifier = Modifier
208
- .width(52.dp)
209
- .height(20.dp)
210
- )
211
- }
212
- Row(
213
- modifier = Modifier
214
- .width(96.dp)
215
- .height(24.dp),
216
- horizontalArrangement = Arrangement.spacedBy((-6).dp)
217
- ) {
218
- trustBanner.icons.forEach { iconURL ->
219
- Avatar(iconURL = iconURL)
220
- }
221
- Row(
222
- modifier = Modifier
223
- .size(24.dp)
224
- .background(color = Color(tonalColor), CircleShape)
225
- .border(width = 1.dp, color = Color(borderColor), CircleShape),
226
- verticalAlignment = Alignment.CenterVertically,
227
- horizontalArrangement = Arrangement.Center
228
- ) {
229
- Text(
230
- text = "36+",
231
- color = Color(primaryColor),
232
- lineHeight = 14.sp,
233
- fontSize = 10.sp
234
- )
235
- }
236
- }
237
- }
238
- }
239
- }
240
- }
241
-
242
- //@Preview
243
- //@Composable
244
- //fun TrustBannerPreview() {
245
- //// TrustBannerView()
246
- //}
@@ -1,170 +0,0 @@
1
- <?xml version="1.0" encoding="utf-8"?>
2
- <vector xmlns:android="http://schemas.android.com/apk/res/android"
3
- android:width="108dp"
4
- android:height="108dp"
5
- android:viewportWidth="108"
6
- android:viewportHeight="108">
7
- <path
8
- android:fillColor="#3DDC84"
9
- android:pathData="M0,0h108v108h-108z" />
10
- <path
11
- android:fillColor="#00000000"
12
- android:pathData="M9,0L9,108"
13
- android:strokeWidth="0.8"
14
- android:strokeColor="#33FFFFFF" />
15
- <path
16
- android:fillColor="#00000000"
17
- android:pathData="M19,0L19,108"
18
- android:strokeWidth="0.8"
19
- android:strokeColor="#33FFFFFF" />
20
- <path
21
- android:fillColor="#00000000"
22
- android:pathData="M29,0L29,108"
23
- android:strokeWidth="0.8"
24
- android:strokeColor="#33FFFFFF" />
25
- <path
26
- android:fillColor="#00000000"
27
- android:pathData="M39,0L39,108"
28
- android:strokeWidth="0.8"
29
- android:strokeColor="#33FFFFFF" />
30
- <path
31
- android:fillColor="#00000000"
32
- android:pathData="M49,0L49,108"
33
- android:strokeWidth="0.8"
34
- android:strokeColor="#33FFFFFF" />
35
- <path
36
- android:fillColor="#00000000"
37
- android:pathData="M59,0L59,108"
38
- android:strokeWidth="0.8"
39
- android:strokeColor="#33FFFFFF" />
40
- <path
41
- android:fillColor="#00000000"
42
- android:pathData="M69,0L69,108"
43
- android:strokeWidth="0.8"
44
- android:strokeColor="#33FFFFFF" />
45
- <path
46
- android:fillColor="#00000000"
47
- android:pathData="M79,0L79,108"
48
- android:strokeWidth="0.8"
49
- android:strokeColor="#33FFFFFF" />
50
- <path
51
- android:fillColor="#00000000"
52
- android:pathData="M89,0L89,108"
53
- android:strokeWidth="0.8"
54
- android:strokeColor="#33FFFFFF" />
55
- <path
56
- android:fillColor="#00000000"
57
- android:pathData="M99,0L99,108"
58
- android:strokeWidth="0.8"
59
- android:strokeColor="#33FFFFFF" />
60
- <path
61
- android:fillColor="#00000000"
62
- android:pathData="M0,9L108,9"
63
- android:strokeWidth="0.8"
64
- android:strokeColor="#33FFFFFF" />
65
- <path
66
- android:fillColor="#00000000"
67
- android:pathData="M0,19L108,19"
68
- android:strokeWidth="0.8"
69
- android:strokeColor="#33FFFFFF" />
70
- <path
71
- android:fillColor="#00000000"
72
- android:pathData="M0,29L108,29"
73
- android:strokeWidth="0.8"
74
- android:strokeColor="#33FFFFFF" />
75
- <path
76
- android:fillColor="#00000000"
77
- android:pathData="M0,39L108,39"
78
- android:strokeWidth="0.8"
79
- android:strokeColor="#33FFFFFF" />
80
- <path
81
- android:fillColor="#00000000"
82
- android:pathData="M0,49L108,49"
83
- android:strokeWidth="0.8"
84
- android:strokeColor="#33FFFFFF" />
85
- <path
86
- android:fillColor="#00000000"
87
- android:pathData="M0,59L108,59"
88
- android:strokeWidth="0.8"
89
- android:strokeColor="#33FFFFFF" />
90
- <path
91
- android:fillColor="#00000000"
92
- android:pathData="M0,69L108,69"
93
- android:strokeWidth="0.8"
94
- android:strokeColor="#33FFFFFF" />
95
- <path
96
- android:fillColor="#00000000"
97
- android:pathData="M0,79L108,79"
98
- android:strokeWidth="0.8"
99
- android:strokeColor="#33FFFFFF" />
100
- <path
101
- android:fillColor="#00000000"
102
- android:pathData="M0,89L108,89"
103
- android:strokeWidth="0.8"
104
- android:strokeColor="#33FFFFFF" />
105
- <path
106
- android:fillColor="#00000000"
107
- android:pathData="M0,99L108,99"
108
- android:strokeWidth="0.8"
109
- android:strokeColor="#33FFFFFF" />
110
- <path
111
- android:fillColor="#00000000"
112
- android:pathData="M19,29L89,29"
113
- android:strokeWidth="0.8"
114
- android:strokeColor="#33FFFFFF" />
115
- <path
116
- android:fillColor="#00000000"
117
- android:pathData="M19,39L89,39"
118
- android:strokeWidth="0.8"
119
- android:strokeColor="#33FFFFFF" />
120
- <path
121
- android:fillColor="#00000000"
122
- android:pathData="M19,49L89,49"
123
- android:strokeWidth="0.8"
124
- android:strokeColor="#33FFFFFF" />
125
- <path
126
- android:fillColor="#00000000"
127
- android:pathData="M19,59L89,59"
128
- android:strokeWidth="0.8"
129
- android:strokeColor="#33FFFFFF" />
130
- <path
131
- android:fillColor="#00000000"
132
- android:pathData="M19,69L89,69"
133
- android:strokeWidth="0.8"
134
- android:strokeColor="#33FFFFFF" />
135
- <path
136
- android:fillColor="#00000000"
137
- android:pathData="M19,79L89,79"
138
- android:strokeWidth="0.8"
139
- android:strokeColor="#33FFFFFF" />
140
- <path
141
- android:fillColor="#00000000"
142
- android:pathData="M29,19L29,89"
143
- android:strokeWidth="0.8"
144
- android:strokeColor="#33FFFFFF" />
145
- <path
146
- android:fillColor="#00000000"
147
- android:pathData="M39,19L39,89"
148
- android:strokeWidth="0.8"
149
- android:strokeColor="#33FFFFFF" />
150
- <path
151
- android:fillColor="#00000000"
152
- android:pathData="M49,19L49,89"
153
- android:strokeWidth="0.8"
154
- android:strokeColor="#33FFFFFF" />
155
- <path
156
- android:fillColor="#00000000"
157
- android:pathData="M59,19L59,89"
158
- android:strokeWidth="0.8"
159
- android:strokeColor="#33FFFFFF" />
160
- <path
161
- android:fillColor="#00000000"
162
- android:pathData="M69,19L69,89"
163
- android:strokeWidth="0.8"
164
- android:strokeColor="#33FFFFFF" />
165
- <path
166
- android:fillColor="#00000000"
167
- android:pathData="M79,19L79,89"
168
- android:strokeWidth="0.8"
169
- android:strokeColor="#33FFFFFF" />
170
- </vector>
@@ -1,30 +0,0 @@
1
- <vector xmlns:android="http://schemas.android.com/apk/res/android"
2
- xmlns:aapt="http://schemas.android.com/aapt"
3
- android:width="108dp"
4
- android:height="108dp"
5
- android:viewportWidth="108"
6
- android:viewportHeight="108">
7
- <path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
8
- <aapt:attr name="android:fillColor">
9
- <gradient
10
- android:endX="85.84757"
11
- android:endY="92.4963"
12
- android:startX="42.9492"
13
- android:startY="49.59793"
14
- android:type="linear">
15
- <item
16
- android:color="#44000000"
17
- android:offset="0.0" />
18
- <item
19
- android:color="#00000000"
20
- android:offset="1.0" />
21
- </gradient>
22
- </aapt:attr>
23
- </path>
24
- <path
25
- android:fillColor="#FFFFFF"
26
- android:fillType="nonZero"
27
- android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
28
- android:strokeWidth="1"
29
- android:strokeColor="#00000000" />
30
- </vector>
@@ -1,6 +0,0 @@
1
- <?xml version="1.0" encoding="utf-8"?>
2
- <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
3
- <background android:drawable="@drawable/ic_launcher_background" />
4
- <foreground android:drawable="@drawable/ic_launcher_foreground" />
5
- <monochrome android:drawable="@drawable/ic_launcher_foreground" />
6
- </adaptive-icon>
@@ -1,6 +0,0 @@
1
- <?xml version="1.0" encoding="utf-8"?>
2
- <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
3
- <background android:drawable="@drawable/ic_launcher_background" />
4
- <foreground android:drawable="@drawable/ic_launcher_foreground" />
5
- <monochrome android:drawable="@drawable/ic_launcher_foreground" />
6
- </adaptive-icon>
@@ -1,10 +0,0 @@
1
- <?xml version="1.0" encoding="utf-8"?>
2
- <resources>
3
- <color name="purple_200">#FFBB86FC</color>
4
- <color name="purple_500">#FF6200EE</color>
5
- <color name="purple_700">#FF3700B3</color>
6
- <color name="teal_200">#FF03DAC5</color>
7
- <color name="teal_700">#FF018786</color>
8
- <color name="black">#FF000000</color>
9
- <color name="white">#FFFFFFFF</color>
10
- </resources>
@@ -1,3 +0,0 @@
1
- <resources>
2
- <string name="app_name">nativekits</string>
3
- </resources>
@@ -1,3 +0,0 @@
1
- <resources xmlns:tools="http://schemas.android.com/tools">
2
-
3
- </resources>
@@ -1,3 +0,0 @@
1
- <resources xmlns:tools="http://schemas.android.com/tools">
2
-
3
- </resources>
@@ -1,13 +0,0 @@
1
- <?xml version="1.0" encoding="utf-8"?><!--
2
- Sample backup rules file; uncomment and customize as necessary.
3
- See https://developer.android.com/guide/topics/data/autobackup
4
- for details.
5
- Note: This file is ignored for devices older that API 31
6
- See https://developer.android.com/about/versions/12/backup-restore
7
- -->
8
- <full-backup-content>
9
- <!--
10
- <include domain="sharedpref" path="."/>
11
- <exclude domain="sharedpref" path="device.xml"/>
12
- -->
13
- </full-backup-content>
@@ -1,19 +0,0 @@
1
- <?xml version="1.0" encoding="utf-8"?><!--
2
- Sample data extraction rules file; uncomment and customize as necessary.
3
- See https://developer.android.com/about/versions/12/backup-restore#xml-changes
4
- for details.
5
- -->
6
- <data-extraction-rules>
7
- <cloud-backup>
8
- <!-- TODO: Use <include> and <exclude> to control what is backed up.
9
- <include .../>
10
- <exclude .../>
11
- -->
12
- </cloud-backup>
13
- <!--
14
- <device-transfer>
15
- <include .../>
16
- <exclude .../>
17
- </device-transfer>
18
- -->
19
- </data-extraction-rules>