@momo-kits/native-kits 0.113.1-beta.2 → 0.113.1-beta.4

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.
@@ -12,6 +12,7 @@ import androidx.compose.foundation.layout.Row
12
12
  import androidx.compose.foundation.layout.Spacer
13
13
  import androidx.compose.foundation.layout.fillMaxWidth
14
14
  import androidx.compose.foundation.layout.height
15
+ import androidx.compose.foundation.layout.offset
15
16
  import androidx.compose.foundation.layout.padding
16
17
  import androidx.compose.foundation.layout.size
17
18
  import androidx.compose.foundation.layout.width
@@ -35,6 +36,7 @@ import androidx.compose.ui.platform.LocalDensity
35
36
  import androidx.compose.ui.semantics.semantics
36
37
  import androidx.compose.ui.semantics.testTag
37
38
  import androidx.compose.ui.text.style.TextAlign
39
+ import androidx.compose.ui.unit.Dp
38
40
  import androidx.compose.ui.unit.dp
39
41
  import androidx.compose.ui.zIndex
40
42
  import kotlinx.coroutines.flow.distinctUntilChanged
@@ -48,9 +50,11 @@ import vn.momo.kits.components.Text
48
50
  import vn.momo.kits.const.AppStatusBar
49
51
  import vn.momo.kits.const.AppTheme
50
52
  import vn.momo.kits.const.Colors
53
+ import vn.momo.kits.const.Radius
51
54
  import vn.momo.kits.const.Spacing
52
55
  import vn.momo.kits.const.Typography
53
56
  import vn.momo.kits.modifier.setAutomationId
57
+ import vn.momo.kits.platform.getScreenDimensions
54
58
  import vn.momo.kits.platform.getStatusBarHeight
55
59
  import vn.momo.kits.utils.bottomBorder
56
60
 
@@ -58,6 +62,8 @@ enum class TitlePosition {
58
62
  LEFT, CENTER,
59
63
  }
60
64
 
65
+ private const val SCREEN_PADDING = 12
66
+ private const val BACK_WIDTH = 28
61
67
 
62
68
  data class AnimatedHeader(
63
69
  val type: HeaderType = HeaderType.DEFAULT,
@@ -66,20 +72,55 @@ data class AnimatedHeader(
66
72
 
67
73
  @Composable
68
74
  fun HeaderBackground(
75
+ isBack: Boolean = true,
69
76
  headerType: HeaderType = HeaderType.DEFAULT,
70
- scrollState: Int
77
+ scrollState: Int,
78
+ inputSearchProps: InputSearchProps? = null,
79
+ headerRightWidth: Dp = 0.dp,
80
+ useAnimationSearch: Boolean = false
71
81
  ) {
72
82
  val statusBarHeight = AppStatusBar.current ?: getStatusBarHeight()
83
+ val screenWidth = getScreenDimensions().width
84
+ val leftPosition = if (isBack) (BACK_WIDTH + 20).dp else 20.dp
85
+ val searchWidth = screenWidth - (SCREEN_PADDING * 2)
86
+
73
87
  val opacityAni by animateFloatAsState(
74
- targetValue = (1 - (scrollState / 200f)).coerceIn(0f, 1f),
88
+ targetValue = (1 - (scrollState / 52f)).coerceIn(0f, 1f),
75
89
  )
76
90
 
77
- val backgroundColor = if (scrollState == 0) {
78
- Color.Transparent
79
- } else {
80
- AppTheme.current.colors.background.surface
81
- }
91
+ val backgroundColor by animateColorAsState(
92
+ targetValue = animateColor(
93
+ Color.Transparent,
94
+ AppTheme.current.colors.background.surface,
95
+ opacityAni
96
+ ),
97
+ )
98
+
99
+ val backgroundSearch by animateColorAsState(
100
+ targetValue = animateColor(
101
+ AppTheme.current.colors.background.default,
102
+ Colors.black_01,
103
+ opacityAni
104
+ ),
105
+ )
106
+
107
+ val animatedTranslateX by animateFloatAsState(
108
+ targetValue = (scrollState / 52f).coerceIn(0f, 1f) * (leftPosition.value - 12) + 12,
109
+ )
82
110
 
111
+ val animatedWidth by animateFloatAsState(
112
+ targetValue = (scrollState / 52f).coerceIn(
113
+ 0f,
114
+ 1f
115
+ ) * ((searchWidth - leftPosition.value - headerRightWidth.value + 12) - searchWidth) + searchWidth,
116
+ )
117
+
118
+ val animatedHeight by animateFloatAsState(
119
+ targetValue = (1 - (scrollState / 52f).coerceIn(
120
+ 0f,
121
+ 1f
122
+ )) * (statusBarHeight.value + 94 - (statusBarHeight.value + 52)) + (statusBarHeight.value + 52),
123
+ )
83
124
 
84
125
  when (headerType) {
85
126
  HeaderType.DEFAULT -> {
@@ -119,38 +160,71 @@ fun HeaderBackground(
119
160
  )
120
161
  }
121
162
  }
122
-
123
163
  }
124
164
 
125
165
  HeaderType.EXTENDED -> {
126
-
127
166
  Box(
128
- modifier = Modifier.fillMaxWidth().height(154.dp)
129
- .alpha(opacityAni)
130
- .background(
131
- Brush.linearGradient(
132
- colors = listOf(
133
- Color(0xFFFDCADE),
134
- Color(0x00FDCADE)
135
- ),
136
- start = Offset(0f, 0f),
137
- end = Offset(0f, with(LocalDensity.current) { 154.dp.toPx() })
138
- )
139
- )
167
+ modifier = Modifier.fillMaxWidth().height(animatedHeight.dp)
140
168
  ) {
141
- if (AppTheme.current.assets.headerBackground != null) {
169
+ Box(
170
+ modifier = Modifier
171
+ .fillMaxWidth()
172
+ .height(154.dp)
173
+ .alpha(opacityAni)
174
+ .background(
175
+ Brush.linearGradient(
176
+ colors = listOf(
177
+ Color(0xFFFDCADE),
178
+ Color(0x00FDCADE)
179
+ ),
180
+ start = Offset(0f, 0f),
181
+ end = Offset(0f, with(LocalDensity.current) { 154.dp.toPx() })
182
+ )
183
+ )
184
+ ) {
185
+ if (AppTheme.current.assets.headerBackground != null) {
186
+ Box(
187
+ modifier = Modifier
188
+ .fillMaxWidth()
189
+ .background(backgroundColor)
190
+ ) {
191
+ Image(
192
+ loading = false,
193
+ source = AppTheme.current.assets.headerBackground!!,
194
+ modifier = Modifier.fillMaxWidth().height(154.dp),
195
+ options = Options(
196
+ contentScale = ContentScale.FillWidth
197
+ )
198
+ )
199
+ }
200
+ }
201
+ }
202
+
203
+ if (inputSearchProps != null && useAnimationSearch) {
142
204
  Box(
143
- modifier = Modifier.fillMaxWidth()
144
- .background(backgroundColor)
205
+ modifier = Modifier
206
+ .height(52.dp)
207
+ .offset(
208
+ x = animatedTranslateX.dp
209
+ )
210
+ .padding(vertical = Spacing.S)
211
+ .align(Alignment.BottomStart)
145
212
  ) {
146
- Image(
147
- loading = false,
148
- source = AppTheme.current.assets.headerBackground!!,
149
- modifier = Modifier.fillMaxWidth().height(154.dp),
150
- options = Options(
151
- contentScale = ContentScale.FillWidth
213
+ Box(
214
+ modifier = Modifier
215
+ .width(animatedWidth.dp)
216
+ .background(
217
+ color = backgroundSearch,
218
+ shape = RoundedCornerShape(Radius.XL)
219
+ )
220
+ ) {
221
+ InputSearch(
222
+ inputSearchProps = inputSearchProps.copy(
223
+ showButtonText = false,
224
+ backgroundColor = Color.Transparent
225
+ )
152
226
  )
153
- )
227
+ }
154
228
  }
155
229
  }
156
230
  }
@@ -160,7 +234,6 @@ fun HeaderBackground(
160
234
  Box(modifier = Modifier.fillMaxWidth())
161
235
  }
162
236
  }
163
-
164
237
  }
165
238
 
166
239
  @Composable
@@ -173,11 +246,13 @@ fun Header(
173
246
  opacity: Float? = null,
174
247
  animatedHeader: AnimatedHeader? = null,
175
248
  scrollState: Int = 0,
176
- inputSearchProps: InputSearchProps?
249
+ inputSearchProps: InputSearchProps? = null,
250
+ useAnimationSearch: Boolean = false
177
251
  ) {
178
252
  val statusBarHeight = AppStatusBar.current ?: getStatusBarHeight()
179
253
  val tintIconColor = AppTheme.current.colors.text.default
180
254
  val backgroundButton = Colors.black_01.copy(alpha = 0.6f)
255
+ val miniAppContext = ApplicationContext.current
181
256
 
182
257
  var colorFraction by remember { mutableStateOf(0f) }
183
258
 
@@ -188,14 +263,6 @@ fun Header(
188
263
  .collect { fraction -> colorFraction = fraction }
189
264
  }
190
265
 
191
- val backgroundSearch by animateColorAsState(
192
- targetValue = animateColor(
193
- Colors.black_01,
194
- AppTheme.current.colors.background.default,
195
- colorFraction
196
- )
197
- )
198
-
199
266
  if (headerType != HeaderType.NONE) {
200
267
  BoxWithConstraints(
201
268
  Modifier.height(statusBarHeight + 52.dp)
@@ -242,10 +309,12 @@ fun Header(
242
309
  }
243
310
  }
244
311
 
245
- Box(Modifier.graphicsLayer {
246
- alpha = if (animatedHeader !== null) opacity ?: 1f else 1f
247
- }) {
248
- headerRight?.invoke()
312
+ if (inputSearchProps == null && miniAppContext != null) {
313
+ Box(Modifier.graphicsLayer {
314
+ alpha = if (animatedHeader !== null) opacity ?: 1f else 1f
315
+ }) {
316
+ headerRight?.invoke()
317
+ }
249
318
  }
250
319
  }
251
320
 
@@ -258,13 +327,14 @@ fun Header(
258
327
  ) {
259
328
  if (goBack != null && titlePosition == TitlePosition.LEFT) {
260
329
  Spacer(Modifier.width(40.dp))
261
- }
262
- if (inputSearchProps != null) {
263
- InputSearch(inputSearchProps = inputSearchProps.copy(backgroundColor = backgroundSearch))
264
330
  } else {
265
331
  Box(
266
332
  Modifier.weight(1f).graphicsLayer {
267
- alpha = if (animatedHeader !== null) opacity ?: 1f else 1f
333
+ alpha = if (useAnimationSearch && inputSearchProps != null) {
334
+ 1f - (opacity ?: 1f)
335
+ } else {
336
+ if (animatedHeader !== null) opacity ?: 1f else 1f
337
+ }
268
338
  },
269
339
  contentAlignment = if (titlePosition == TitlePosition.LEFT) Alignment.TopStart else Alignment.Center
270
340
  ) {
@@ -306,4 +376,4 @@ fun animateColor(start: Color, stop: Color, fraction: Float): Color {
306
376
  blue = start.blue + fraction * (stop.blue - start.blue),
307
377
  alpha = start.alpha + fraction * (stop.alpha - start.alpha)
308
378
  )
309
- }
379
+ }
@@ -0,0 +1,261 @@
1
+ package vn.momo.kits.application
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.Box
8
+ import androidx.compose.foundation.layout.Row
9
+ import androidx.compose.foundation.layout.height
10
+ import androidx.compose.foundation.layout.offset
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.runtime.Composable
17
+ import androidx.compose.runtime.getValue
18
+ import androidx.compose.runtime.mutableStateOf
19
+ import androidx.compose.runtime.remember
20
+ import androidx.compose.runtime.setValue
21
+ import androidx.compose.ui.Alignment
22
+ import androidx.compose.ui.Modifier
23
+ import androidx.compose.ui.draw.clip
24
+ import androidx.compose.ui.graphics.Color
25
+ import androidx.compose.ui.unit.dp
26
+ import vn.momo.kits.components.BadgeDot
27
+ import vn.momo.kits.components.DotSize
28
+ import vn.momo.kits.components.Icon
29
+ import vn.momo.kits.const.Colors
30
+ import kotlinx.serialization.json.Json
31
+ import kotlinx.serialization.json.jsonObject
32
+ import kotlinx.serialization.json.jsonPrimitive
33
+
34
+ data class HeaderRightData(
35
+ val useShortcut: Boolean = false,
36
+ val useMore: Boolean = false,
37
+ val tools: List<ToolGroup> = emptyList(),
38
+ val toolCallback: ((String) -> Unit)? = { _ -> }
39
+ )
40
+
41
+ data class Tool(
42
+ val key: String,
43
+ val icon: String,
44
+ val showBadge: Boolean = false,
45
+ val name: Map<String, String> = emptyMap()
46
+ ) {
47
+ fun toMap(): Map<String, Any> {
48
+ return mapOf(
49
+ "key" to key,
50
+ "icon" to icon,
51
+ "showBadge" to showBadge,
52
+ "name" to name
53
+ )
54
+ }
55
+ }
56
+
57
+ data class ToolGroup(
58
+ val title: Map<String, String> = emptyMap(),
59
+ val items: List<Tool>
60
+ ) {
61
+ fun toMap(): Map<String, Any> {
62
+ return mapOf(
63
+ "title" to title,
64
+ "items" to items.map { it.toMap() }
65
+ )
66
+ }
67
+ }
68
+
69
+ data class NavigationButtonConfig(
70
+ val icon: String,
71
+ val onPress: () -> Unit
72
+ )
73
+
74
+ object Spacing {
75
+ val M = 16.dp
76
+ val S = 8.dp
77
+ val XXS = 2.dp
78
+ }
79
+
80
+ @Composable
81
+ fun HeaderRight(
82
+ headerRight: HeaderRightData? = null,
83
+ ) {
84
+ Row(
85
+ verticalAlignment = Alignment.CenterVertically,
86
+ ) {
87
+ ToolkitHeaderRight(headerRight = headerRight)
88
+ }
89
+ }
90
+
91
+ @Composable
92
+ fun ToolkitHeaderRight(headerRight: HeaderRightData? = null) {
93
+ var isFavorite by remember { mutableStateOf(false) }
94
+ val isLoading by remember { mutableStateOf(false) }
95
+ val api = PlatformApi.current as? ComposeApi
96
+ val context = ApplicationContext.current
97
+
98
+ fun onPressShortcut() {
99
+ api?.request("onToolAction", mapOf("item" to mapOf("key" to "onFavorite"))) {
100
+ isFavorite = !isFavorite
101
+ }
102
+ }
103
+
104
+ fun onPressHelpCenter() {
105
+ val paramMap = mapOf(
106
+ "appId" to context?.appId,
107
+ "code" to context?.appCode,
108
+ "name" to context?.appName,
109
+ "icon" to context?.appIcon,
110
+ "description" to context?.description
111
+ )
112
+ api?.request("showHelpCenter", paramMap) {
113
+
114
+ }
115
+ }
116
+
117
+ fun onPressClose() {
118
+ api?.request("dismiss", "", {_ -> })
119
+ }
120
+
121
+ fun onPressMore() {
122
+ api?.request("showTools",
123
+ mapOf(
124
+ "tools" to headerRight?.tools?.map { it.toMap() },
125
+ "context" to mapOf(
126
+ "appId" to context?.appId,
127
+ "code" to context?.appCode,
128
+ "name" to context?.appName,
129
+ "icon" to context?.appIcon,
130
+ "description" to context?.description
131
+ )
132
+ )
133
+ ) { response ->
134
+ try {
135
+ val json = Json.parseToJsonElement(response).jsonObject
136
+ val toolResponse = json["response"]?.jsonPrimitive?.content
137
+ if (toolResponse != null) {
138
+ headerRight?.toolCallback?.invoke(toolResponse)
139
+ }
140
+ } catch (e: Exception) {
141
+ println("Error parsing response: $e")
142
+ }
143
+ }
144
+ }
145
+
146
+ fun getNavigationButtonConfig(
147
+ tools: List<ToolGroup>? = emptyList(),
148
+ useMore: Boolean? = false,
149
+ isFavorite: Boolean = false,
150
+ onPressShortcut: () -> Unit,
151
+ onPressMore: () -> Unit
152
+ ): NavigationButtonConfig {
153
+ val totalTools = tools?.sumOf { it.items.size } ?: 0
154
+ var icon = if (isFavorite) "pin_star_checked" else "pin_star"
155
+ var onClickHandler = onPressShortcut
156
+ if (totalTools > 1 || useMore == true) {
157
+ icon = "navigation_more_icon"
158
+ onClickHandler = onPressMore
159
+ } else if (totalTools == 1 && !tools.isNullOrEmpty()) {
160
+ val singleTool = tools.first().items.firstOrNull()
161
+ if (singleTool != null) {
162
+ icon = singleTool.icon
163
+ onClickHandler = {
164
+ headerRight?.toolCallback?.invoke(singleTool.key)
165
+ }
166
+ }
167
+ }
168
+ return NavigationButtonConfig(icon, onClickHandler)
169
+ }
170
+
171
+ val navButtonConfig = getNavigationButtonConfig(
172
+ headerRight?.tools,
173
+ headerRight?.useMore,
174
+ isFavorite,
175
+ ::onPressShortcut,
176
+ ::onPressMore
177
+ )
178
+
179
+ val showBadge = headerRight?.tools?.any { group ->
180
+ group.items.any { it.showBadge }
181
+ }
182
+
183
+ Row(
184
+ verticalAlignment = Alignment.CenterVertically
185
+ ) {
186
+ if (headerRight?.useShortcut == true) {
187
+ NavigationButton(
188
+ disabled = isLoading,
189
+ icon = navButtonConfig.icon,
190
+ showBadge = showBadge,
191
+ onClick = navButtonConfig.onPress
192
+ )
193
+ }
194
+ Row(
195
+ verticalAlignment = Alignment.CenterVertically,
196
+ horizontalArrangement = Arrangement.Center,
197
+ modifier = Modifier
198
+ .padding(start = Spacing.S)
199
+ .border(0.2.dp, Color(0x33000000), shape = RoundedCornerShape(14.dp))
200
+ .width(65.dp)
201
+ .height(28.dp)
202
+ .clip(shape = RoundedCornerShape(14.dp))
203
+ .background(Color(0x99FFFFFF))
204
+ ) {
205
+ Icon(source = "help_center", size = 20.dp, modifier = Modifier.padding(4.dp).clickable {
206
+ onPressHelpCenter()
207
+ })
208
+ Box(
209
+ modifier = Modifier
210
+ .width(0.5.dp)
211
+ .height(12.dp)
212
+ .background(Colors.black_20)
213
+ )
214
+ Icon(
215
+ source = "16_navigation_close_circle",
216
+ size = 20.dp,
217
+ modifier = Modifier.padding(4.dp).clickable { onPressClose() }
218
+ )
219
+ }
220
+ }
221
+ }
222
+
223
+ @Composable
224
+ fun NavigationButton(
225
+ disabled: Boolean,
226
+ icon: String,
227
+ showBadge: Boolean? = false,
228
+ onClick: () -> Unit
229
+ ) {
230
+ Box(
231
+ modifier = Modifier
232
+ .size(28.dp)
233
+ .clickable(enabled = !disabled, onClick = onClick)
234
+ ) {
235
+ Box(
236
+ modifier = Modifier
237
+ .matchParentSize()
238
+ .clip(CircleShape)
239
+ .background(Color(0x99FFFFFF))
240
+ .border(0.2.dp, Color(0x33000000), CircleShape)
241
+ )
242
+ Box(
243
+ modifier = Modifier.matchParentSize(),
244
+ contentAlignment = Alignment.Center
245
+ ) {
246
+ Icon(
247
+ source = icon,
248
+ size = 16.dp
249
+ )
250
+ }
251
+
252
+ if (showBadge == true) {
253
+ BadgeDot(
254
+ size = DotSize.Small,
255
+ modifier = Modifier
256
+ .align(Alignment.TopEnd)
257
+ .offset(x = -Spacing.XXS, y = -Spacing.XXS)
258
+ )
259
+ }
260
+ }
261
+ }
@@ -6,14 +6,10 @@ import androidx.compose.runtime.LaunchedEffect
6
6
  import androidx.compose.runtime.getValue
7
7
  import androidx.compose.runtime.mutableStateOf
8
8
  import androidx.compose.runtime.remember
9
- import androidx.compose.runtime.rememberCoroutineScope
10
9
  import androidx.compose.runtime.setValue
11
10
  import androidx.compose.runtime.staticCompositionLocalOf
12
11
  import androidx.compose.ui.unit.Dp
13
- import kotlinx.coroutines.launch
14
- import kotlinx.serialization.json.Json
15
- import kotlinx.serialization.json.jsonObject
16
- import kotlinx.serialization.json.jsonPrimitive
12
+ import vn.momo.kits.components.TrustBannerData
17
13
  import vn.momo.kits.const.AppStatusBar
18
14
  import vn.momo.kits.const.AppTheme
19
15
  import vn.momo.kits.const.Theme
@@ -22,40 +18,20 @@ import vn.momo.kits.const.defaultTheme
22
18
  import vn.momo.kits.platform.disableOverscroll
23
19
  import vn.momo.kits.platform.getStatusBarHeight
24
20
 
25
- val PlatformApi = staticCompositionLocalOf<Any?> { null }
26
-
27
21
  interface ComposeApi {
28
- fun request(funcName: String, params: String?): String
29
- fun request(funcName: String, params: String?, onResponse: ((String) -> Unit)?): String
30
- fun requestCallback(funcName: String, params: String?, onResponse: ((String) -> Unit)?)
22
+ fun request(funcName: String, params: Any?): String
23
+ fun request(funcName: String, params: Any?, onResponse: ((String) -> Unit)?): String
24
+ fun requestCallback(funcName: String, params: Any?, onResponse: ((String) -> Unit)?)
31
25
  fun removeCallback(id: String)
32
26
  }
33
27
 
34
- val AppNavigator = staticCompositionLocalOf<Navigator> {
35
- error("no navigator provided!")
36
- }
37
-
38
28
  class Navigator {
39
- fun push(content: @Composable () -> Unit) {
40
- }
41
-
42
- fun present(content: @Composable () -> Unit) {
43
-
44
- }
45
-
46
- fun reset(content: @Composable () -> Unit) {
47
-
48
- }
49
-
50
- fun pop() {
51
- }
52
-
53
- fun replace(content: @Composable () -> Unit) {
54
- }
55
-
56
- fun popToTop() {
57
- }
58
-
29
+ fun push(content: @Composable () -> Unit) {}
30
+ fun present(content: @Composable () -> Unit) {}
31
+ fun reset(content: @Composable () -> Unit) {}
32
+ fun pop() {}
33
+ fun replace(content: @Composable () -> Unit) {}
34
+ fun popToTop() {}
59
35
  fun showModal(
60
36
  onClose: () -> Unit = {},
61
37
  canBackgroundClose: Boolean = true,
@@ -63,52 +39,73 @@ class Navigator {
63
39
  ) {
64
40
  }
65
41
 
66
- fun showBottomSheet(content: @Composable () -> Unit) {
67
- }
42
+ fun showBottomSheet(content: @Composable () -> Unit) {}
68
43
  }
69
44
 
45
+ data class MiniAppContext(
46
+ val appIcon: String = "",
47
+ val appName: Any? = null,
48
+ val appId: String = "",
49
+ val appCode: String = "",
50
+ val description: Any? = null,
51
+ )
52
+
53
+ val PlatformApi = staticCompositionLocalOf<Any?> { null }
54
+
55
+ val AppNavigator = staticCompositionLocalOf<Navigator> {
56
+ error("no navigator provided!")
57
+ }
58
+
59
+ val ApplicationContext = staticCompositionLocalOf<MiniAppContext?> {
60
+ null
61
+ }
62
+
63
+ val AppConfig = staticCompositionLocalOf<KitConfig?> {
64
+ null
65
+ }
66
+
67
+ data class KitConfig(
68
+ val trustBanner: TrustBannerData? = null,
69
+ val headerBar: String? = null,
70
+ val headerGradient: String? = null
71
+ )
72
+
70
73
  @Composable
71
74
  fun ApplicationContainer(
72
75
  theme: Theme = defaultTheme,
73
76
  composeApi: ComposeApi? = null,
74
- statusBarHeight: Dp? = AppStatusBar.current ?: getStatusBarHeight(),
75
- content: @Composable () -> Unit
77
+ statusBarHeight: Dp? = null,
78
+ applicationContext: MiniAppContext? = null,
79
+ config: KitConfig? = null,
80
+ content: @Composable () -> Unit,
76
81
  ) {
77
82
  var appTheme by remember { mutableStateOf(theme) }
78
- val coroutineScope = rememberCoroutineScope()
79
83
 
80
84
  LaunchedEffect(Unit) {
81
85
  try {
82
- composeApi?.request("getConfig", "DESIGN_SYSTEM") {
83
- val json = Json { ignoreUnknownKeys = true }
84
- val response = json.parseToJsonElement(it).jsonObject["response"]
85
- val headerBar = response
86
- ?.jsonObject
87
- ?.get("headerBar")
88
- ?.jsonPrimitive
89
- ?.content
90
- if (headerBar != null && appTheme.assets.headerBackground == null) {
91
- coroutineScope.launch {
92
- appTheme = appTheme.copy(
93
- assets = ThemeAssets(
94
- headerBackground = headerBar
95
- )
96
- )
97
- }
98
- }
86
+ val headerBar = config?.headerBar
87
+ if (headerBar != null && appTheme.assets.headerBackground == null) {
88
+ appTheme = appTheme.copy(
89
+ assets = ThemeAssets(
90
+ headerBackground = headerBar
91
+ )
92
+ )
99
93
  }
100
- }
101
- catch (e: Exception) {
102
- print("@@ == NavigationContainer fetch config error $e")
94
+ } catch (e: Exception) {
95
+ print("@@ == NavigationContainer get config error $e")
103
96
  }
104
97
  }
105
98
 
99
+ val appStatusBarHeight = statusBarHeight ?: getStatusBarHeight()
100
+
106
101
  disableOverscroll()
107
102
  CompositionLocalProvider(
108
103
  AppTheme provides appTheme,
109
104
  PlatformApi provides composeApi,
110
105
  AppNavigator provides Navigator(),
111
- AppStatusBar provides statusBarHeight,
106
+ AppStatusBar provides appStatusBarHeight,
107
+ ApplicationContext provides applicationContext,
108
+ AppConfig provides config
112
109
  ) {
113
110
  content()
114
111
  }