@momo-kits/native-kits 0.162.7-debug → 0.162.8-debug

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.
@@ -40,7 +40,7 @@ kotlin {
40
40
  }
41
41
 
42
42
  cocoapods {
43
- version = "0.162.7-debug"
43
+ version = "0.162.8-debug"
44
44
  summary = "IOS Shared module"
45
45
  homepage = "https://momo.vn"
46
46
  ios.deploymentTarget = "15.0"
@@ -77,6 +77,7 @@ kotlin {
77
77
  implementation(libs.kotlinx.datetime)
78
78
  api(libs.native.max.api)
79
79
  implementation(libs.compottie)
80
+ implementation(libs.gif.image)
80
81
  }
81
82
  androidMain.dependencies {
82
83
  implementation(libs.ktor.client.okhttp)
@@ -77,6 +77,7 @@ kotlin {
77
77
  implementation(libs.kotlinx.datetime)
78
78
  api(libs.native.max.api)
79
79
  implementation(libs.compottie)
80
+ implementation(libs.gif.image)
80
81
  }
81
82
  androidMain.dependencies {
82
83
  implementation(libs.ktor.client.okhttp)
@@ -1,7 +1,9 @@
1
1
  package vn.momo.kits.components
2
2
 
3
3
  import androidx.compose.foundation.border
4
+ import androidx.compose.foundation.layout.Box
4
5
  import androidx.compose.foundation.layout.BoxWithConstraints
6
+ import androidx.compose.foundation.layout.fillMaxSize
5
7
  import androidx.compose.runtime.Composable
6
8
  import androidx.compose.runtime.getValue
7
9
  import androidx.compose.runtime.mutableStateOf
@@ -17,10 +19,12 @@ import androidx.compose.ui.semantics.contentDescription
17
19
  import androidx.compose.ui.semantics.semantics
18
20
  import androidx.compose.ui.platform.LocalDensity
19
21
  import androidx.compose.ui.unit.dp
20
- import coil3.compose.AsyncImage
22
+ import coil3.compose.AsyncImage as CoilAsyncImage
21
23
  import vn.momo.kits.application.IsShowBaseLineDebug
22
24
  import vn.momo.kits.const.AppTheme
23
25
  import vn.momo.kits.const.Colors
26
+ import vn.momo.kits.gifimage.GifImage
27
+ import vn.momo.kits.gifimage.GifImageState
24
28
  import vn.momo.kits.modifier.conditional
25
29
 
26
30
  data class Options(
@@ -73,6 +77,19 @@ private fun getHostFromUrl(url: String): String? {
73
77
  }
74
78
  }
75
79
 
80
+ private fun isGifUrl(url: String): Boolean {
81
+ val path = url.substringBefore('#').substringBefore('?')
82
+ return path.endsWith(".gif", ignoreCase = true)
83
+ }
84
+
85
+ private fun GifImageState.toImageState(): ImageState {
86
+ return when (this) {
87
+ GifImageState.Success -> ImageState.Success
88
+ GifImageState.Error -> ImageState.Error
89
+ GifImageState.Loading -> ImageState.Loading
90
+ }
91
+ }
92
+
76
93
  // Optimized query parameter appending
77
94
  private fun appendSizeQueryParam(url: String, value: String): String {
78
95
  val fragmentIndex = url.indexOf('#')
@@ -95,12 +112,12 @@ fun Image(
95
112
  modifier: Modifier = Modifier,
96
113
  options: Options? = null,
97
114
  loading: Boolean = true,
115
+ onStateChanged: (ImageState) -> Unit = {},
98
116
  ) {
99
117
  val imageOptions = remember(options) {
100
118
  options ?: Options()
101
119
  }
102
120
 
103
- var imageState by remember { mutableStateOf(ImageState.Loading) }
104
121
  val density = LocalDensity.current
105
122
 
106
123
  BoxWithConstraints(
@@ -121,34 +138,46 @@ fun Image(
121
138
  processedUrl
122
139
  }
123
140
  }
124
- else -> source
141
+ else -> source.toString()
125
142
  }
126
143
  }
127
144
 
128
- AsyncImage(
129
- modifier = Modifier.matchParentSize(),
130
- model = urlToLoad,
131
- contentDescription = null,
132
- contentScale = imageOptions.contentScale,
133
- alignment = imageOptions.alignment,
134
- colorFilter = imageOptions.colorFilter,
135
- alpha = imageOptions.alpha,
136
- onLoading = { imageState = ImageState.Loading },
137
- onSuccess = { imageState = ImageState.Success },
138
- onError = { imageState = ImageState.Error },
139
- )
145
+ var imageState by remember(urlToLoad) { mutableStateOf(ImageState.Loading) }
146
+ fun updateImageState(state: ImageState) {
147
+ imageState = state
148
+ onStateChanged(state)
149
+ }
150
+
151
+ if (isGifUrl(urlToLoad)) {
152
+ GifImage(
153
+ modifier = Modifier.matchParentSize(),
154
+ url = urlToLoad,
155
+ contentDescription = null,
156
+ contentScale = imageOptions.contentScale,
157
+ alignment = imageOptions.alignment,
158
+ colorFilter = imageOptions.colorFilter,
159
+ alpha = imageOptions.alpha,
160
+ onStateChanged = { updateImageState(it.toImageState()) },
161
+ )
162
+ } else {
163
+ CoilAsyncImage(
164
+ modifier = Modifier.matchParentSize(),
165
+ model = urlToLoad,
166
+ contentDescription = null,
167
+ contentScale = imageOptions.contentScale,
168
+ alignment = imageOptions.alignment,
169
+ colorFilter = imageOptions.colorFilter,
170
+ alpha = imageOptions.alpha,
171
+ onLoading = { updateImageState(ImageState.Loading) },
172
+ onSuccess = { updateImageState(ImageState.Success) },
173
+ onError = { updateImageState(ImageState.Error) },
174
+ )
175
+ }
140
176
 
141
177
  when (imageState) {
142
- ImageState.Loading -> if (loading) Skeleton()
143
- ImageState.Error -> {
144
- val theme = AppTheme.current
145
- Icon(
146
- source = "media_fail",
147
- color = theme.colors.text.disable,
148
- modifier = Modifier.align(Alignment.Center)
149
- )
150
- }
151
178
  ImageState.Success -> {}
179
+ ImageState.Error -> ImageError()
180
+ ImageState.Loading -> if (loading) Skeleton()
152
181
  }
153
182
  }
154
183
  }
@@ -156,7 +185,7 @@ fun Image(
156
185
  // Extracted URL processing logic for better performance
157
186
  private fun processImageUrl(url: String, maxWidth: androidx.compose.ui.unit.Dp, density: androidx.compose.ui.unit.Density): String {
158
187
  val host = getHostFromUrl(url)
159
- return if (host != null && supportedDomains.contains(host)) {
188
+ return if (!isGifUrl(url) && host != null && supportedDomains.contains(host)) {
160
189
  val widthPx = with(density) { maxWidth.roundToPx() }
161
190
  val pixelRatio = density.density
162
191
  val pixelFitForWidth = widthPx * pixelRatio
@@ -167,6 +196,20 @@ private fun processImageUrl(url: String, maxWidth: androidx.compose.ui.unit.Dp,
167
196
  }
168
197
  }
169
198
 
199
+ @Composable
200
+ private fun ImageError() {
201
+ val theme = AppTheme.current
202
+ Box(
203
+ modifier = Modifier.fillMaxSize(),
204
+ contentAlignment = Alignment.Center
205
+ ) {
206
+ Icon(
207
+ source = "media_fail",
208
+ color = theme.colors.text.disable,
209
+ )
210
+ }
211
+ }
212
+
170
213
  @Composable
171
214
  fun Image(
172
215
  source: Painter,
@@ -185,4 +228,4 @@ fun Image(
185
228
  colorFilter = colorFilter,
186
229
  alpha = alpha,
187
230
  )
188
- }
231
+ }
@@ -23,7 +23,6 @@ import vn.momo.kits.navigation.LocalNavigator
23
23
  import vn.momo.kits.navigation.NavigationOptions
24
24
  import vn.momo.kits.navigation.StackScreen
25
25
  import vn.momo.kits.navigation.component.HeaderType
26
- import vn.momo.kits.platform.getScreenHeight
27
26
 
28
27
  private var bottomTabOptionItems : MutableList<NavigationOptions?> = mutableListOf()
29
28
  internal fun setBottomTabOption(index: Int, options: NavigationOptions){
@@ -45,6 +44,8 @@ fun BottomTab(
45
44
  val navigation = LocalNavigation.current
46
45
  val navigator = LocalNavigator.current
47
46
  val navController = rememberNavController()
47
+ val keyboardBottomPadding = WindowInsets.ime.asPaddingValues().calculateBottomPadding()
48
+ val shouldShowBottomTab = keyboardBottomPadding == 0.dp
48
49
 
49
50
  bottomTabOptionItems = items.mapIndexed { index, item ->
50
51
  item.options ?: NavigationOptions()
@@ -57,10 +58,16 @@ fun BottomTab(
57
58
  )
58
59
  }
59
60
 
60
- Box(modifier = Modifier.fillMaxWidth().height(getScreenHeight()), contentAlignment = Alignment.BottomCenter) {
61
+ Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.BottomCenter) {
61
62
  Box(modifier = Modifier
62
63
  .fillMaxSize()
63
- .padding(bottom = BOTTOM_TAB_BAR_HEIGHT.dp + AppNavigationBar.current)
64
+ .padding(
65
+ bottom = if (shouldShowBottomTab) {
66
+ BOTTOM_TAB_BAR_HEIGHT.dp + AppNavigationBar.current
67
+ } else {
68
+ 0.dp
69
+ }
70
+ )
64
71
  ) {
65
72
  NavHost(
66
73
  navController = navController,
@@ -119,20 +126,22 @@ fun BottomTab(
119
126
  }
120
127
  }
121
128
  }
122
- Column {
123
- BottomTabBar(
124
- items = items,
125
- floatingButton = floatingButton,
126
- navController = navController,
127
- onTabSelected = {
128
- val currentRoute = navController.currentBackStackEntry?.destination?.route
129
- val targetRoute = "option$it"
130
- if (currentRoute != targetRoute){
131
- navController.navigate(targetRoute)
129
+ if (shouldShowBottomTab) {
130
+ Column {
131
+ BottomTabBar(
132
+ items = items,
133
+ floatingButton = floatingButton,
134
+ navController = navController,
135
+ onTabSelected = {
136
+ val currentRoute = navController.currentBackStackEntry?.destination?.route
137
+ val targetRoute = "option$it"
138
+ if (currentRoute != targetRoute) {
139
+ navController.navigate(targetRoute)
140
+ }
132
141
  }
133
- }
134
- )
135
- Spacer(modifier = Modifier.fillMaxWidth().height(AppNavigationBar.current + Spacing.S).background(AppTheme.current.colors.background.surface))
142
+ )
143
+ Spacer(modifier = Modifier.fillMaxWidth().height(AppNavigationBar.current + Spacing.S).background(AppTheme.current.colors.background.surface))
144
+ }
136
145
  }
137
146
  }
138
147
  }
@@ -21,6 +21,7 @@ maxapi = "0.1.1"
21
21
  vanniktechMavenPublish = "0.34.0"
22
22
  kits = "0.159.1-beta.7"
23
23
  nativemaxapi = "0.0.6"
24
+ gif-image = "0.1.2"
24
25
 
25
26
  [libraries]
26
27
  ktor-client-core = { group = "io.ktor", name = "ktor-client-core", version.ref = "ktor-version" }
@@ -53,6 +54,7 @@ androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "a
53
54
  androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activity" }
54
55
  material = { module = "com.google.android.material:material", version.ref = "material" }
55
56
 
57
+ gif-image = { module = "vn.momo.kits:gif-image", version.ref = "gif-image" }
56
58
  [plugins]
57
59
  jetbrains-kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
58
60
  jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
package/gradle.properties CHANGED
@@ -18,7 +18,7 @@ kotlin.apple.xcodeCompatibility.nowarn=true
18
18
  name="ComposeKits"
19
19
  group=vn.momo.kits
20
20
  artifact.id=kits
21
- version=0.162.7
21
+ version=0.162.8
22
22
 
23
23
  repo=GitLab
24
24
  url=https://gitlab.mservice.com.vn/api/v4/projects/5400/packages/maven
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/native-kits",
3
- "version": "0.162.7-debug",
3
+ "version": "0.162.8-debug",
4
4
  "private": false,
5
5
  "dependencies": {},
6
6
  "devDependencies": {},