@momo-kits/native-kits 0.167.1-duo.1-debug → 0.167.1-sizescale.1-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.
Files changed (49) hide show
  1. package/CLAUDE.md +0 -7
  2. package/compose/build.gradle.kts +1 -1
  3. package/compose/compose.podspec +1 -1
  4. package/compose/src/androidMain/kotlin/vn/momo/kits/platform/Platform.android.kt +4 -1
  5. package/compose/src/commonMain/kotlin/vn/momo/kits/application/NavigationContainer.kt +3 -3
  6. package/compose/src/commonMain/kotlin/vn/momo/kits/application/WidgetContainer.kt +2 -2
  7. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Divider.kt +1 -1
  8. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupNotify.kt +0 -6
  9. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupPromotion.kt +0 -1
  10. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Slider.kt +3 -3
  11. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tooltip.kt +1 -1
  12. package/compose/src/commonMain/kotlin/vn/momo/kits/const/KitSizeScale.kt +56 -0
  13. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Spacing.kt +15 -11
  14. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Typography.kt +6 -4
  15. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/NavigationContainer.kt +7 -4
  16. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackScreen.kt +3 -4
  17. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/Header.kt +0 -2
  18. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Utils.kt +0 -10
  19. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/OsFontScale.ios.kt +3 -1
  20. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/Platform.ios.kt +11 -6
  21. package/example/ios/Example.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/Example.xcscheme +32 -0
  22. package/example/ios/Example.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/xcschememanagement.plist +14 -0
  23. package/example/ios/Example.xcworkspace/xcuserdata/sonnguyen.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  24. package/example/ios/Example.xcworkspace/xcuserdata/sonnguyen.xcuserdatad/WorkspaceSettings.xcsettings +16 -0
  25. package/example/ios/Example.xcworkspace/xcuserdata/sonnguyen.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +6 -0
  26. package/example/ios/Example.xcworkspace/xcuserdata/sonnguyen.xcuserdatad/xcschemes/xcschememanagement.plist +5 -0
  27. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/MoMoUIKits.xcscheme +58 -0
  28. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/Pods-Example.xcscheme +58 -0
  29. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/SDWebImage.xcscheme +58 -0
  30. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/SDWebImageSwiftUI.xcscheme +58 -0
  31. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/SkeletonUI.xcscheme +58 -0
  32. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/lottie-ios-LottiePrivacyInfo.xcscheme +58 -0
  33. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/lottie-ios.xcscheme +58 -0
  34. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/xcschememanagement.plist +60 -0
  35. package/gradle.properties +1 -1
  36. package/ios/Application/Navigation/Overplay/ModalScreen.swift +0 -3
  37. package/ios/Popup/PopupDisplay.swift +0 -1
  38. package/ios/Popup/PopupNotify.swift +1 -8
  39. package/ios/Popup/PopupPromotion.swift +3 -3
  40. package/ios/Typography/FontScale.swift +3 -3
  41. package/ios/native-kits.podspec +1 -1
  42. package/ios-demo/MoMoUIKitsDemo.podspec +1 -1
  43. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/Home.swift +0 -1
  44. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupDisplayDemo.swift +0 -1
  45. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupNotifyDemo.swift +2 -2
  46. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupPromotionDemo.swift +0 -2
  47. package/local.properties +2 -2
  48. package/package.json +1 -1
  49. package/.claude/settings.local.json +0 -185
package/CLAUDE.md CHANGED
@@ -97,10 +97,3 @@ Prefer one tight line at the surprising spot over a paragraph. Match the (low) c
97
97
  - **Resource qualifier drift:** the generated Compose `Res` namespace is `vn.momo.uikits.resources`, but `utils/Resources.kt` and `platform/Platform.ios.kt` reference `vn.momo.compose.resources`. Keep bundled strings/dictionaries as plain Kotlin (the `defaultLanguage` map in `Localize.kt`), not `composeResources/values`, to avoid iOS framework resource-loading issues.
98
98
  - Prefer `NavigationContainer` over the deprecated `ApplicationContainer`; prefer `IMaxApi`/`LocalMaxApi` over the deprecated `PlatformApi`.
99
99
  - iOS strings/maps must survive Kotlin/Native framework packaging — keep them compiled-in, not loaded from resource bundles.
100
-
101
- ## Code comments
102
- - Only comment when necessary: non-obvious logic, workarounds, or the "why" behind a decision.
103
- - Don't comment on what the code already says clearly (no "// increment i", no restating function names).
104
- - Keep comments short: one line when possible, plain and easy to understand.
105
- - No long comment blocks, no line-by-line narration, no lines that overflow the editor width.
106
- - Don't leave comments about the change itself (e.g. "// updated this", "// new logic").
@@ -40,7 +40,7 @@ kotlin {
40
40
  }
41
41
 
42
42
  cocoapods {
43
- version = "0.167.1-duo.1-debug"
43
+ version = "0.167.1-sizescale.1-debug"
44
44
  summary = "IOS Shared module"
45
45
  homepage = "https://momo.vn"
46
46
  ios.deploymentTarget = "15.0"
@@ -1,6 +1,6 @@
1
1
  Pod::Spec.new do |spec|
2
2
  spec.name = 'compose'
3
- spec.version = '0.167.1-duo.1-debug'
3
+ spec.version = '0.167.1-sizescale.1-debug'
4
4
  spec.homepage = 'https://momo.vn'
5
5
  spec.source = { :http=> ''}
6
6
  spec.authors = ''
@@ -30,6 +30,7 @@ import com.airbnb.lottie.compose.rememberLottieDynamicProperties
30
30
  import com.airbnb.lottie.compose.rememberLottieDynamicProperty
31
31
  import vn.momo.kits.const.AppNavigationBar
32
32
  import vn.momo.kits.const.AppStatusBar
33
+ import vn.momo.kits.const.LocalSizeScale
33
34
  import vn.momo.kits.navigation.Navigator
34
35
  import vn.momo.kits.utils.readJson
35
36
  import androidx.activity.compose.BackHandler as AndroidBackHandler
@@ -39,8 +40,10 @@ actual fun getPlatformName(): String = "Android"
39
40
  @Composable
40
41
  actual fun getScreenDimensions(): ScreenDimension {
41
42
  val config = LocalConfiguration.current
43
+ // Logical dp: the container size scale enlarges every dp, so the screen spans fewer of them.
44
+ val sizeScale = LocalSizeScale.current
42
45
  return ScreenDimension(
43
- config.screenWidthDp, config.screenHeightDp
46
+ (config.screenWidthDp / sizeScale).toInt(), (config.screenHeightDp / sizeScale).toInt()
44
47
  )
45
48
  }
46
49
 
@@ -7,7 +7,6 @@ import androidx.compose.ui.Modifier
7
7
  import androidx.compose.ui.unit.Dp
8
8
  import vn.momo.kits.const.*
9
9
  import vn.momo.kits.modifier.DeprecatedModifier
10
- import vn.momo.kits.platform.ProvideOsFontScale
11
10
  import vn.momo.kits.platform.getStatusBarHeight
12
11
 
13
12
  @Deprecated("Use IMaxApi instead", ReplaceWith("IMaxApi"))
@@ -92,9 +91,10 @@ fun ApplicationContainer(
92
91
  }
93
92
  }
94
93
 
95
- val appStatusBarHeight = statusBarHeight ?: getStatusBarHeight()
94
+ // Insets are measured in real units; convert to the dp of the size-scaled container.
95
+ val appStatusBarHeight = (statusBarHeight ?: getStatusBarHeight()) / pendingSizeScale()
96
96
 
97
- ProvideOsFontScale {
97
+ ProvideKitScale {
98
98
  CompositionLocalProvider(
99
99
  AppTheme provides appTheme,
100
100
  PlatformApi provides composeApi,
@@ -7,7 +7,7 @@ import androidx.compose.runtime.remember
7
7
  import vn.momo.kits.const.AppTheme
8
8
  import vn.momo.kits.const.Theme
9
9
  import vn.momo.kits.navigation.LocalMaxApi
10
- import vn.momo.kits.platform.ProvideOsFontScale
10
+ import vn.momo.kits.const.ProvideKitScale
11
11
  import vn.momo.maxapi.IMaxApi
12
12
 
13
13
 
@@ -37,7 +37,7 @@ fun WidgetContainer(
37
37
  }
38
38
  }
39
39
 
40
- ProvideOsFontScale {
40
+ ProvideKitScale {
41
41
  CompositionLocalProvider(
42
42
  AppTheme provides resolvedTheme,
43
43
  LocalContext provides mergedContext,
@@ -18,7 +18,7 @@ import vn.momo.kits.const.Spacing
18
18
  enum class DividerType { DEFAULT, DASH }
19
19
 
20
20
  @Composable
21
- fun Divider(useMargin: Boolean = true, type: DividerType = DividerType.DEFAULT) {
21
+ fun Divider(useMargin: Boolean = false, type: DividerType = DividerType.DEFAULT) {
22
22
  val color = AppTheme.current.colors.border.default
23
23
  val margin = if (useMargin) Spacing.XS else 0.dp
24
24
  if (type == DividerType.DASH) {
@@ -20,7 +20,6 @@ import vn.momo.kits.application.LocalLocalize
20
20
  import vn.momo.kits.const.*
21
21
  import vn.momo.kits.modifier.conditional
22
22
  import vn.momo.kits.modifier.setAutomationId
23
- import vn.momo.kits.platform.getScreenDimensions
24
23
  import kotlin.math.min
25
24
 
26
25
  data class PopupAction(
@@ -34,10 +33,6 @@ enum class PopupActionDirection {
34
33
  AUTO
35
34
  }
36
35
 
37
- // Portrait width in landscape too, so aspect-ratio images don't push popups past the screen height.
38
- @Composable
39
- internal fun popupMaxWidth(): Dp = getScreenDimensions().let { minOf(it.width, it.height) }.dp
40
-
41
36
  private fun heightForLines(
42
37
  layout: TextLayoutResult,
43
38
  ): Float {
@@ -134,7 +129,6 @@ fun PopupNotify(
134
129
  ) {
135
130
  Column(
136
131
  modifier = Modifier
137
- .widthIn(max = popupMaxWidth())
138
132
  .fillMaxWidth()
139
133
  .padding(horizontal = 12.dp)
140
134
  .clip(RoundedCornerShape(Radius.L))
@@ -29,7 +29,6 @@ fun PopupPromotion(
29
29
  onClose: (() -> Unit) = {},
30
30
  ) {
31
31
  Column(Modifier
32
- .widthIn(max = popupMaxWidth())
33
32
  .padding(horizontal = Spacing.M)
34
33
  .conditional(IsShowBaseLineDebug) {
35
34
  border(1.dp, Colors.blue_03)
@@ -26,9 +26,9 @@ import kotlin.math.roundToInt
26
26
  private val THUMB_SIZE = 20.dp
27
27
  private val THUMB_BORDER = 3.dp
28
28
  private val TRACK_HEIGHT = 4.dp
29
- private val LABEL_PAD_H = Spacing.XS
30
- private val LABEL_PAD_V = Spacing.XXS
31
- private val LABEL_GAP = Spacing.XS // space between label and thumb top
29
+ private val LABEL_PAD_H get() = Spacing.XS
30
+ private val LABEL_PAD_V get() = Spacing.XXS
31
+ private val LABEL_GAP get() = Spacing.XS // space between label and thumb top
32
32
 
33
33
 
34
34
  private fun clamp(value: Float, min: Float, max: Float): Float =
@@ -67,7 +67,7 @@ class TooltipState {
67
67
  fun rememberTooltipState(): TooltipState {
68
68
  return remember { TooltipState() }
69
69
  }
70
- private val TOOLTIP_OFFSET = Spacing.S
70
+ private val TOOLTIP_OFFSET get() = Spacing.S
71
71
  private val ARROW_SIZE = 6.dp
72
72
  private class TooltipPositionProvider(
73
73
  private val placement: TooltipPlacement,
@@ -0,0 +1,56 @@
1
+ package vn.momo.kits.const
2
+
3
+ import androidx.compose.runtime.Composable
4
+ import androidx.compose.runtime.CompositionLocalProvider
5
+ import androidx.compose.runtime.getValue
6
+ import androidx.compose.runtime.mutableStateOf
7
+ import androidx.compose.runtime.setValue
8
+ import androidx.compose.runtime.staticCompositionLocalOf
9
+ import androidx.compose.ui.platform.LocalDensity
10
+ import androidx.compose.ui.unit.Density
11
+ import vn.momo.kits.platform.ProvideOsFontScale
12
+
13
+ // App-wide size scale (OS-zoom like): sizes (width/height/radius/icon…) grow by [rate] while spacing
14
+ // and text keep their original size. Seeded by the host like KitFontScale; snapshot state, so a write
15
+ // recomposes every container and relayouts without remounting screens.
16
+ //
17
+ // How: containers multiply LocalDensity.density by [rate] (every .dp grows) and divide fontScale by
18
+ // [rate] (sp text unchanged). Spacing tokens divide by [rate] so padding/margin render unchanged.
19
+ object KitSizeScale {
20
+ var rate by mutableStateOf(1f)
21
+ private set
22
+
23
+ fun update(rate: Float) {
24
+ this.rate = if (rate > 0f) rate else 1f
25
+ }
26
+ }
27
+
28
+ // Scale already applied to LocalDensity by an enclosing container (1 = none), so nested containers
29
+ // don't apply it twice and platform values in real units (screen size, OS font scale) can be converted.
30
+ internal val LocalSizeScale = staticCompositionLocalOf { 1f }
31
+
32
+ // Extra scale the next ProvideSizeScale adds on top of the current density: KitSizeScale.rate at the
33
+ // root container, 1 inside an already scaled one. Divide real-unit Dp (host-passed insets) by it.
34
+ @Composable
35
+ internal fun pendingSizeScale(): Float = KitSizeScale.rate / LocalSizeScale.current
36
+
37
+ // Root wrapper of every container: live OS font scale first, then the size scale on top of it.
38
+ @Composable
39
+ internal fun ProvideKitScale(content: @Composable () -> Unit) {
40
+ ProvideOsFontScale { ProvideSizeScale(content) }
41
+ }
42
+
43
+ @Composable
44
+ private fun ProvideSizeScale(content: @Composable () -> Unit) {
45
+ val applied = LocalSizeScale.current
46
+ val rate = KitSizeScale.rate
47
+ val density = LocalDensity.current
48
+ CompositionLocalProvider(
49
+ LocalDensity provides Density(
50
+ density = density.density / applied * rate,
51
+ fontScale = density.fontScale * applied / rate,
52
+ ),
53
+ LocalSizeScale provides rate,
54
+ content = content,
55
+ )
56
+ }
@@ -1,16 +1,20 @@
1
1
  package vn.momo.kits.const
2
2
 
3
+ import androidx.compose.ui.unit.Dp
3
4
  import androidx.compose.ui.unit.dp
4
5
 
6
+ // Divided by KitSizeScale.rate: containers scale LocalDensity for sizes, spacing must stay unscaled.
7
+ private fun spacing(value: Int): Dp = (value / KitSizeScale.rate).dp
8
+
5
9
  object Spacing {
6
- val XXS = 2.dp
7
- val XS = 4.dp
8
- val S = 8.dp
9
- val M = 12.dp
10
- val L = 16.dp
11
- val XL = 24.dp
12
- val XXL = 32.dp
13
- val Size3XL = 48.dp
14
- val Size4XL = 56.dp
15
- val Size5XL = 64.dp
16
- }
10
+ val XXS: Dp get() = spacing(2)
11
+ val XS: Dp get() = spacing(4)
12
+ val S: Dp get() = spacing(8)
13
+ val M: Dp get() = spacing(12)
14
+ val L: Dp get() = spacing(16)
15
+ val XL: Dp get() = spacing(24)
16
+ val XXL: Dp get() = spacing(32)
17
+ val Size3XL: Dp get() = spacing(48)
18
+ val Size4XL: Dp get() = spacing(56)
19
+ val Size5XL: Dp get() = spacing(64)
20
+ }
@@ -26,12 +26,13 @@ fun scaleSize(size: Float): Float {
26
26
  return size * (context?.userScaleRate ?: KitFontScale.userScaleRate)
27
27
  }
28
28
  val scaleSizeMaxRate: Float = MAX_FONT_SCALE
29
- // Short side, not width: landscape must not inflate every font.
30
- val deviceWidth = getScreenDimensions().let { minOf(it.width, it.height) }
29
+ // Real screen width / OS font scale: undo the container size scale.
30
+ val sizeScale = LocalSizeScale.current
31
+ val deviceWidth = getScreenDimensions().width * sizeScale
31
32
  val deviceScale = deviceWidth / DEFAULT_SCREEN_SIZE
32
33
 
33
34
  val density = LocalDensity.current
34
- val fontScale = density.fontScale
35
+ val fontScale = density.fontScale * sizeScale
35
36
 
36
37
  var fontSizeScaleDevice = size
37
38
  var fontSizeScaleOS = size
@@ -58,7 +59,8 @@ fun scaleSize(size: TextUnit): TextUnit {
58
59
  val density = LocalDensity.current
59
60
 
60
61
  val scaled = scaleSize(size.value)
61
- val spValue = scaled / density.fontScale
62
+ // Real OS font scale (density.fontScale is divided by the size scale inside containers).
63
+ val spValue = scaled / (density.fontScale * LocalSizeScale.current)
62
64
 
63
65
  return TextUnit(value = spValue, type = TextUnitType.Sp)
64
66
  }
@@ -30,9 +30,10 @@ import vn.momo.kits.const.AppNavigationBar
30
30
  import vn.momo.kits.const.AppStatusBar
31
31
  import vn.momo.kits.const.AppTheme
32
32
  import vn.momo.kits.const.Theme
33
+ import vn.momo.kits.const.ProvideKitScale
33
34
  import vn.momo.kits.const.defaultTheme
35
+ import vn.momo.kits.const.pendingSizeScale
34
36
  import vn.momo.kits.platform.ProvideNavigationEventDispatcherOwner
35
- import vn.momo.kits.platform.ProvideOsFontScale
36
37
  import vn.momo.kits.utils.getAppStatusBarHeight
37
38
  import vn.momo.kits.utils.getNavigationBarHeight
38
39
  import vn.momo.maxapi.IMaxApi
@@ -54,8 +55,10 @@ fun NavigationContainer(
54
55
  val navController = rememberNavController()
55
56
  val registry = remember { DynamicScreenRegistry() }
56
57
  val navigator = remember { Navigator(navController = navController, maxApi = maxApi, registry = registry) }
57
- val statusBarHeight = statusBarHeight ?: getAppStatusBarHeight()
58
- val navigationBarHeight = getNavigationBarHeight()
58
+ // Insets are measured in real units; convert to the dp of the size-scaled container.
59
+ val sizeScale = pendingSizeScale()
60
+ val statusBarHeight = (statusBarHeight ?: getAppStatusBarHeight()) / sizeScale
61
+ val navigationBarHeight = getNavigationBarHeight() / sizeScale
59
62
 
60
63
  val parentContext = LocalContext.current
61
64
  val mergedContext = MiniAppContext.merge(parentContext, miniAppContext)
@@ -92,7 +95,7 @@ fun NavigationContainer(
92
95
  registry.bind(screenId, initialScreenName, initialScreen, options)
93
96
  val startDestination = remember(screenId) { DynamicScreenRoute(screenId) }
94
97
 
95
- ProvideOsFontScale {
98
+ ProvideKitScale {
96
99
  ProvideNavigationEventDispatcherOwner(navigator) {
97
100
  CompositionLocalProvider(
98
101
  LocalNavigator provides navigator,
@@ -73,7 +73,6 @@ import vn.momo.kits.navigation.tracking.ScreenTracker
73
73
  import vn.momo.kits.navigation.tracking.ScreenTrackingState
74
74
  import kotlinx.coroutines.delay
75
75
  import vn.momo.kits.application.LocalContext
76
- import vn.momo.kits.utils.horizontalSafeAreaPadding
77
76
  import kotlin.time.Clock
78
77
  import kotlin.time.Duration.Companion.milliseconds
79
78
  import kotlin.time.ExperimentalTime
@@ -209,16 +208,16 @@ internal fun StackScreen(
209
208
  Header(onBackHandler)
210
209
  }
211
210
 
212
- Column(Modifier.zIndex(5f).horizontalSafeAreaPadding()) {
211
+ Column(Modifier.zIndex(5f)) {
213
212
  SearchAnimated(snapState = snapState)
214
213
  }
215
214
 
216
- Column(Modifier.zIndex(2f).fillMaxSize().horizontalSafeAreaPadding()) {
215
+ Column(Modifier.zIndex(2f).fillMaxSize()) {
217
216
  MainContent(content = content, isBottomTabRoot = isBottomTabRoot, isBottomTabChild = isBottomTabChild)
218
217
  FooterContent()
219
218
  }
220
219
 
221
- Box(Modifier.zIndex(6f).horizontalSafeAreaPadding()) {
220
+ Box(Modifier.zIndex(6f)) {
222
221
  FloatingContent(isBottomTabChild = isBottomTabChild)
223
222
  }
224
223
 
@@ -47,7 +47,6 @@ import vn.momo.kits.navigation.LocalNavigator
47
47
  import vn.momo.kits.navigation.LocalOptions
48
48
  import vn.momo.kits.navigation.LocalScrollState
49
49
  import vn.momo.kits.navigation.getInputSearchType
50
- import vn.momo.kits.utils.horizontalSafeAreaPadding
51
50
 
52
51
  @InternalApi
53
52
  const val HEADER_HEIGHT = 52
@@ -128,7 +127,6 @@ internal fun Header(onBackHandler: (() -> Unit)? = null) {
128
127
  Row(
129
128
  modifier = Modifier.height(HEADER_HEIGHT.dp)
130
129
  .fillMaxWidth()
131
- .horizontalSafeAreaPadding()
132
130
  .padding(horizontal = Spacing.M),
133
131
  verticalAlignment = Alignment.CenterVertically,
134
132
  horizontalArrangement = Arrangement.SpaceBetween
@@ -1,11 +1,6 @@
1
1
  package vn.momo.kits.utils
2
2
 
3
3
  import androidx.compose.foundation.layout.WindowInsets
4
- import androidx.compose.foundation.layout.WindowInsetsSides
5
- import androidx.compose.foundation.layout.displayCutout
6
- import androidx.compose.foundation.layout.only
7
- import androidx.compose.foundation.layout.union
8
- import androidx.compose.foundation.layout.windowInsetsPadding
9
4
  import androidx.compose.foundation.layout.asPaddingValues
10
5
  import androidx.compose.foundation.layout.systemBars
11
6
  import androidx.compose.runtime.Composable
@@ -95,11 +90,6 @@ fun getAppStatusBarHeight(): Dp {
95
90
  }
96
91
  }
97
92
 
98
- // Left/right safe area like SwiftUI (landscape camera/notch); consumed, so nested StackScreens don't pad twice.
99
- internal fun Modifier.horizontalSafeAreaPadding(): Modifier = composed {
100
- windowInsetsPadding(WindowInsets.systemBars.union(WindowInsets.displayCutout).only(WindowInsetsSides.Horizontal))
101
- }
102
-
103
93
  @Composable
104
94
  internal fun getNavigationBarHeight(): Dp {
105
95
  return if (AppNavigationBar.current == 0.dp) {
@@ -16,6 +16,7 @@ import platform.UIKit.UIContentSizeCategoryDidChangeNotification
16
16
  import platform.UIKit.UIFont
17
17
  import platform.UIKit.UIFontTextStyleBody
18
18
  import platform.darwin.NSObject
19
+ import vn.momo.kits.const.LocalSizeScale
19
20
 
20
21
  // Compose MP iOS reads LocalDensity.fontScale once at ComposeUIViewController creation and does not
21
22
  // recompose it when UIContentSizeCategory changes (Android tracks Configuration.fontScale live). We
@@ -59,7 +60,8 @@ actual fun ProvideOsFontScale(content: @Composable () -> Unit) {
59
60
 
60
61
  val density = LocalDensity.current
61
62
  CompositionLocalProvider(
62
- LocalDensity provides Density(density.density, osFontScale.value),
63
+ // Inside an already size-scaled container fontScale carries 1/sizeScale; keep that compensation.
64
+ LocalDensity provides Density(density.density, osFontScale.value / LocalSizeScale.current),
63
65
  ) {
64
66
  content()
65
67
  }
@@ -39,6 +39,7 @@ import platform.Foundation.NSBundle
39
39
  import platform.UIKit.UIColor
40
40
  import platform.UIKit.UIDevice
41
41
  import platform.UIKit.UIScreen
42
+ import vn.momo.kits.const.LocalSizeScale
42
43
  import vn.momo.kits.navigation.AttachHostBackGesture
43
44
  import vn.momo.kits.navigation.Navigator
44
45
 
@@ -46,12 +47,16 @@ actual fun getPlatformName(): String = "iOS"
46
47
 
47
48
  @OptIn(ExperimentalForeignApi::class)
48
49
  @Composable
49
- actual fun getScreenDimensions(): ScreenDimension = memScoped {
50
- val config = UIScreen.mainScreen.bounds.ptr[0]
51
- return ScreenDimension(
52
- config.size.width.toInt(),
53
- config.size.height.toInt()
54
- )
50
+ actual fun getScreenDimensions(): ScreenDimension {
51
+ // Logical dp: the container size scale enlarges every dp, so the screen spans fewer of them.
52
+ val sizeScale = LocalSizeScale.current
53
+ return memScoped {
54
+ val config = UIScreen.mainScreen.bounds.ptr[0]
55
+ ScreenDimension(
56
+ (config.size.width / sizeScale).toInt(),
57
+ (config.size.height / sizeScale).toInt()
58
+ )
59
+ }
55
60
  }
56
61
 
57
62
  actual fun NativePaint.setMaskFilter(blurRadius: Float) {
@@ -0,0 +1,32 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <Scheme
3
+ version = "1.3">
4
+ <BuildAction>
5
+ <BuildActionEntries>
6
+ <BuildActionEntry
7
+ buildForRunning = "YES">
8
+ <BuildableReference
9
+ BuildableIdentifier = "primary"
10
+ BlueprintIdentifier = "A6A920D22B2ADD1E00C1A11F"
11
+ BuildableName = "Example"
12
+ BlueprintName = "Example"
13
+ ReferencedContainer = "container:Example.xcodeproj">
14
+ </BuildableReference>
15
+ </BuildActionEntry>
16
+ </BuildActionEntries>
17
+ </BuildAction>
18
+ <LaunchAction
19
+ useCustomWorkingDirectory = "NO"
20
+ buildConfiguration = "Debug"
21
+ allowLocationSimulation = "YES">
22
+ <BuildableProductRunnable>
23
+ <BuildableReference
24
+ BuildableIdentifier = "primary"
25
+ BlueprintIdentifier = "A6A920D22B2ADD1E00C1A11F"
26
+ BuildableName = "Example"
27
+ BlueprintName = "Example"
28
+ ReferencedContainer = "container:Example.xcodeproj">
29
+ </BuildableReference>
30
+ </BuildableProductRunnable>
31
+ </LaunchAction>
32
+ </Scheme>
@@ -0,0 +1,14 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>SchemeUserState</key>
6
+ <dict>
7
+ <key>Example.xcscheme</key>
8
+ <dict>
9
+ <key>orderHint</key>
10
+ <integer>7</integer>
11
+ </dict>
12
+ </dict>
13
+ </dict>
14
+ </plist>
@@ -0,0 +1,16 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>BuildLocationStyle</key>
6
+ <string>UseAppPreferences</string>
7
+ <key>CustomBuildLocationType</key>
8
+ <string>RelativeToDerivedData</string>
9
+ <key>DerivedDataCustomLocation</key>
10
+ <string>DerivedData</string>
11
+ <key>DerivedDataLocationStyle</key>
12
+ <string>WorkspaceRelativePath</string>
13
+ <key>ShowSharedSchemesAutomaticallyEnabled</key>
14
+ <true/>
15
+ </dict>
16
+ </plist>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <Bucket
3
+ uuid = "6B3C387A-E951-41D1-A42C-FB6E447A46BA"
4
+ type = "0"
5
+ version = "2.0">
6
+ </Bucket>
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict />
5
+ </plist>
@@ -0,0 +1,58 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <Scheme
3
+ LastUpgradeVersion = "1600"
4
+ version = "1.3">
5
+ <BuildAction
6
+ parallelizeBuildables = "YES"
7
+ buildImplicitDependencies = "YES">
8
+ <BuildActionEntries>
9
+ <BuildActionEntry
10
+ buildForTesting = "YES"
11
+ buildForRunning = "YES"
12
+ buildForProfiling = "YES"
13
+ buildForArchiving = "YES"
14
+ buildForAnalyzing = "YES">
15
+ <BuildableReference
16
+ BuildableIdentifier = "primary"
17
+ BlueprintIdentifier = "3B6FB503A75BF5BC1FA6F30BC06B9D28"
18
+ BuildableName = "MoMoUIKits.framework"
19
+ BlueprintName = "MoMoUIKits"
20
+ ReferencedContainer = "container:Pods.xcodeproj">
21
+ </BuildableReference>
22
+ </BuildActionEntry>
23
+ </BuildActionEntries>
24
+ </BuildAction>
25
+ <TestAction
26
+ buildConfiguration = "Debug"
27
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
28
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
29
+ shouldUseLaunchSchemeArgsEnv = "YES">
30
+ <Testables>
31
+ </Testables>
32
+ </TestAction>
33
+ <LaunchAction
34
+ buildConfiguration = "Debug"
35
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
36
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
37
+ launchStyle = "0"
38
+ useCustomWorkingDirectory = "NO"
39
+ ignoresPersistentStateOnLaunch = "NO"
40
+ debugDocumentVersioning = "YES"
41
+ debugServiceExtension = "internal"
42
+ allowLocationSimulation = "YES">
43
+ </LaunchAction>
44
+ <ProfileAction
45
+ buildConfiguration = "Release"
46
+ shouldUseLaunchSchemeArgsEnv = "YES"
47
+ savedToolIdentifier = ""
48
+ useCustomWorkingDirectory = "NO"
49
+ debugDocumentVersioning = "YES">
50
+ </ProfileAction>
51
+ <AnalyzeAction
52
+ buildConfiguration = "Debug">
53
+ </AnalyzeAction>
54
+ <ArchiveAction
55
+ buildConfiguration = "Release"
56
+ revealArchiveInOrganizer = "YES">
57
+ </ArchiveAction>
58
+ </Scheme>
@@ -0,0 +1,58 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <Scheme
3
+ LastUpgradeVersion = "1600"
4
+ version = "1.3">
5
+ <BuildAction
6
+ parallelizeBuildables = "YES"
7
+ buildImplicitDependencies = "YES">
8
+ <BuildActionEntries>
9
+ <BuildActionEntry
10
+ buildForTesting = "YES"
11
+ buildForRunning = "YES"
12
+ buildForProfiling = "YES"
13
+ buildForArchiving = "YES"
14
+ buildForAnalyzing = "YES">
15
+ <BuildableReference
16
+ BuildableIdentifier = "primary"
17
+ BlueprintIdentifier = "0AEE99A309977BD12A049FF48AF9BA4B"
18
+ BuildableName = "Pods_Example.framework"
19
+ BlueprintName = "Pods-Example"
20
+ ReferencedContainer = "container:Pods.xcodeproj">
21
+ </BuildableReference>
22
+ </BuildActionEntry>
23
+ </BuildActionEntries>
24
+ </BuildAction>
25
+ <TestAction
26
+ buildConfiguration = "Debug"
27
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
28
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
29
+ shouldUseLaunchSchemeArgsEnv = "YES">
30
+ <Testables>
31
+ </Testables>
32
+ </TestAction>
33
+ <LaunchAction
34
+ buildConfiguration = "Debug"
35
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
36
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
37
+ launchStyle = "0"
38
+ useCustomWorkingDirectory = "NO"
39
+ ignoresPersistentStateOnLaunch = "NO"
40
+ debugDocumentVersioning = "YES"
41
+ debugServiceExtension = "internal"
42
+ allowLocationSimulation = "YES">
43
+ </LaunchAction>
44
+ <ProfileAction
45
+ buildConfiguration = "Release"
46
+ shouldUseLaunchSchemeArgsEnv = "YES"
47
+ savedToolIdentifier = ""
48
+ useCustomWorkingDirectory = "NO"
49
+ debugDocumentVersioning = "YES">
50
+ </ProfileAction>
51
+ <AnalyzeAction
52
+ buildConfiguration = "Debug">
53
+ </AnalyzeAction>
54
+ <ArchiveAction
55
+ buildConfiguration = "Release"
56
+ revealArchiveInOrganizer = "YES">
57
+ </ArchiveAction>
58
+ </Scheme>