@momo-kits/native-kits 0.162.3-fontscale.3-debug → 0.162.3-fontscale.4-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.3-fontscale.3-debug"
43
+ version = "0.162.3-fontscale.4-debug"
44
44
  summary = "IOS Shared module"
45
45
  homepage = "https://momo.vn"
46
46
  ios.deploymentTarget = "15.0"
@@ -0,0 +1,7 @@
1
+ package vn.momo.kits.platform
2
+
3
+ import androidx.compose.runtime.Composable
4
+
5
+ // Android's LocalDensity.fontScale already tracks Configuration.fontScale live.
6
+ @Composable
7
+ actual fun ProvideOsFontScale(content: @Composable () -> Unit) = content()
@@ -7,6 +7,7 @@ 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
10
11
  import vn.momo.kits.platform.getStatusBarHeight
11
12
 
12
13
  @Deprecated("Use IMaxApi instead", ReplaceWith("IMaxApi"))
@@ -93,6 +94,7 @@ fun ApplicationContainer(
93
94
 
94
95
  val appStatusBarHeight = statusBarHeight ?: getStatusBarHeight()
95
96
 
97
+ ProvideOsFontScale {
96
98
  CompositionLocalProvider(
97
99
  AppTheme provides appTheme,
98
100
  PlatformApi provides composeApi,
@@ -103,5 +105,6 @@ fun ApplicationContainer(
103
105
  content()
104
106
  }
105
107
  }
108
+ }
106
109
 
107
110
  }
@@ -0,0 +1,22 @@
1
+ package vn.momo.kits.const
2
+
3
+ import androidx.compose.runtime.getValue
4
+ import androidx.compose.runtime.mutableStateOf
5
+ import androidx.compose.runtime.setValue
6
+
7
+ // App-wide font-scale holder. The kit is sandboxed and can't read the host cache directly, so the
8
+ // host (which sees both core and this kit) seeds this once at startup and pushes runtime updates into
9
+ // it. scaleSize() reads it as the fallback, so every screen — including direct NavigationContainer
10
+ // screens with no host-pushed MiniAppContext — scales with no per-render prop and no async flicker.
11
+ // Backed by snapshot state: writes recompose text automatically.
12
+ object KitFontScale {
13
+ var userScaleRate by mutableStateOf(1f)
14
+ private set
15
+ var useOSScaleRate by mutableStateOf(true)
16
+ private set
17
+
18
+ fun update(userScaleRate: Float, useOSScaleRate: Boolean) {
19
+ this.userScaleRate = userScaleRate
20
+ this.useOSScaleRate = useOSScaleRate
21
+ }
22
+ }
@@ -24,8 +24,10 @@ const val MAX_DEVICE_SCALE = 5
24
24
  @Composable
25
25
  fun scaleSize(size: Float): Float {
26
26
  val context = LocalContext.current
27
- if (context?.useOSScaleRate == false) {
28
- return size * (context.userScaleRate ?: 1f)
27
+ // Host-pushed context wins; otherwise fall back to the app-wide KitFontScale holder.
28
+ val useOsScale = context?.useOSScaleRate ?: KitFontScale.useOSScaleRate
29
+ if (!useOsScale) {
30
+ return size * (context?.userScaleRate ?: KitFontScale.userScaleRate)
29
31
  }
30
32
  val scaleSizeMaxRate: Float = MAX_FONT_SCALE
31
33
  val deviceWidth = getScreenDimensions().width
@@ -12,6 +12,7 @@ import androidx.navigation.toRoute
12
12
  import vn.momo.kits.application.*
13
13
  import vn.momo.kits.const.*
14
14
  import vn.momo.kits.platform.ProvideNavigationEventDispatcherOwner
15
+ import vn.momo.kits.platform.ProvideOsFontScale
15
16
  import vn.momo.kits.utils.getAppStatusBarHeight
16
17
  import vn.momo.kits.utils.getNavigationBarHeight
17
18
  import vn.momo.maxapi.IMaxApi
@@ -57,6 +58,7 @@ fun NavigationContainer(
57
58
  registry.bind(screenId, initialScreenName, initialScreen, options)
58
59
  val startDestination = remember(screenId) { DynamicScreenRoute(screenId) }
59
60
 
61
+ ProvideOsFontScale {
60
62
  ProvideNavigationEventDispatcherOwner {
61
63
  CompositionLocalProvider(
62
64
  LocalNavigator provides navigator,
@@ -133,6 +135,7 @@ fun NavigationContainer(
133
135
  }
134
136
  }
135
137
  }
138
+ }
136
139
 
137
140
  DisposableEffect(Unit) {
138
141
  onDispose {
@@ -0,0 +1,9 @@
1
+ package vn.momo.kits.platform
2
+
3
+ import androidx.compose.runtime.Composable
4
+
5
+ // Overrides LocalDensity.fontScale with the live OS Dynamic Type scale so text re-scales while a
6
+ // screen is visible. Wrapped inside the containers so every screen is covered, not just callers of
7
+ // the app-level wrappers.
8
+ @Composable
9
+ expect fun ProvideOsFontScale(content: @Composable () -> Unit)
@@ -0,0 +1,66 @@
1
+ package vn.momo.kits.platform
2
+
3
+ import androidx.compose.runtime.Composable
4
+ import androidx.compose.runtime.CompositionLocalProvider
5
+ import androidx.compose.runtime.DisposableEffect
6
+ import androidx.compose.runtime.mutableStateOf
7
+ import androidx.compose.runtime.remember
8
+ import androidx.compose.ui.platform.LocalDensity
9
+ import androidx.compose.ui.unit.Density
10
+ import kotlinx.cinterop.ExperimentalForeignApi
11
+ import kotlinx.cinterop.ObjCAction
12
+ import platform.Foundation.NSNotification
13
+ import platform.Foundation.NSNotificationCenter
14
+ import platform.Foundation.NSSelectorFromString
15
+ import platform.UIKit.UIContentSizeCategoryDidChangeNotification
16
+ import platform.UIKit.UIFont
17
+ import platform.UIKit.UIFontTextStyleBody
18
+ import platform.darwin.NSObject
19
+
20
+ // Compose MP iOS reads LocalDensity.fontScale once at ComposeUIViewController creation and does not
21
+ // recompose it when UIContentSizeCategory changes (Android tracks Configuration.fontScale live). We
22
+ // observe the notification and override LocalDensity.fontScale so scaleSize() recomposes live. The
23
+ // formula matches the SwiftUI kit (UIFont body point size / 17) so both iOS surfaces scale alike.
24
+ private const val DEFAULT_BODY_POINT_SIZE = 17.0
25
+
26
+ private fun currentOsFontScale(): Float =
27
+ (UIFont.preferredFontForTextStyle(UIFontTextStyleBody).pointSize / DEFAULT_BODY_POINT_SIZE).toFloat()
28
+
29
+ @OptIn(ExperimentalForeignApi::class)
30
+ @Composable
31
+ actual fun ProvideOsFontScale(content: @Composable () -> Unit) {
32
+ val osFontScale = remember { mutableStateOf(currentOsFontScale()) }
33
+
34
+ val listener = remember {
35
+ object : NSObject() {
36
+ @Suppress("unused")
37
+ @ObjCAction
38
+ fun contentSizeChanged(arg: NSNotification) {
39
+ osFontScale.value = currentOsFontScale()
40
+ }
41
+ }
42
+ }
43
+
44
+ DisposableEffect(Unit) {
45
+ NSNotificationCenter.defaultCenter.addObserver(
46
+ observer = listener,
47
+ selector = NSSelectorFromString(listener::contentSizeChanged.name + ":"),
48
+ name = UIContentSizeCategoryDidChangeNotification,
49
+ `object` = null,
50
+ )
51
+ onDispose {
52
+ NSNotificationCenter.defaultCenter.removeObserver(
53
+ observer = listener,
54
+ name = UIContentSizeCategoryDidChangeNotification,
55
+ `object` = null,
56
+ )
57
+ }
58
+ }
59
+
60
+ val density = LocalDensity.current
61
+ CompositionLocalProvider(
62
+ LocalDensity provides Density(density.density, osFontScale.value),
63
+ ) {
64
+ content()
65
+ }
66
+ }
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.3-fontscale.3
21
+ version=0.162.3-fontscale.4
22
22
 
23
23
  repo=GitLab
24
24
  url=https://gitlab.mservice.com.vn/api/v4/projects/5400/packages/maven
@@ -1,17 +1,16 @@
1
- import Combine
2
1
  import CoreGraphics
3
2
 
4
- /// App-wide font-scale preference for the SwiftUI kit. Populated by the host container
5
- /// (`KitContainer`), which reads `FontScaleProvider.configFlow` the cache-backed source, same
6
- /// as RN/Compose. `scaleSize`/`appFont` read the snapshot; `MomoText` observes it for live redraw.
7
- /// When `useOSScaleRate` is false the kit applies `userScaleRate` instead of the OS Dynamic Type
8
- /// factor. `update` must be called on the main thread.
9
- public final class FontScaleStore: ObservableObject {
3
+ /// App-wide font-scale preference for the SwiftUI kit. An exported holder the host writes once at
4
+ /// app startup (from the cache-backed `FontScaleProvider`); `scaleSize`/`appFont` read the snapshot.
5
+ /// No realtime: the SwiftUI kit has no navigation container to scope reactive updates, so a startup
6
+ /// snapshot is enough. When `useOSScaleRate` is false the kit applies `userScaleRate` instead of the
7
+ /// OS Dynamic Type factor.
8
+ public final class FontScaleStore {
10
9
  public static let shared = FontScaleStore()
11
10
  private init() {}
12
11
 
13
- @Published public private(set) var userScaleRate: CGFloat = 1
14
- @Published public private(set) var useOSScaleRate: Bool = true
12
+ public private(set) var userScaleRate: CGFloat = 1
13
+ public private(set) var useOSScaleRate: Bool = true
15
14
 
16
15
  public func update(userScaleRate: CGFloat, useOSScaleRate: Bool) {
17
16
  self.userScaleRate = userScaleRate
@@ -118,7 +118,6 @@ public extension TypographyStyle {
118
118
  }
119
119
 
120
120
  public struct MomoText: View {
121
- @ObservedObject private var fontScale = FontScaleStore.shared
122
121
  private let content: String
123
122
  private let typography: TypographyStyle
124
123
  private let color: Color
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/native-kits",
3
- "version": "0.162.3-fontscale.3-debug",
3
+ "version": "0.162.3-fontscale.4-debug",
4
4
  "private": false,
5
5
  "dependencies": {},
6
6
  "devDependencies": {},