@momo-kits/native-kits 0.168.1-beta.10-debug → 0.168.1-beta.11-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.
package/CLAUDE.md CHANGED
@@ -82,6 +82,7 @@ Publishing is automated (`publish.sh` + GitLab CI on `[ci build]` / `main`). Do
82
82
  - Quick return header: glass headers and Animated headers (with a `ScrollState`) on the Duo side bar layout slide out with the content and back in on a reverse scroll; a half-shown header settles in or out once the scroll stops. The side bar is drawn apart from the header, so it stays put.
83
83
  - Overlays on Duo: popups cap at 440pt wide and the room between `duoTopInset` and the bottom inset (body scrolls, actions stay); modal centers inside that room; bottom sheet uses the window height, centers at width ≥ 600 and pads by side insets in landscape.
84
84
  - Font scale deliberately uses the short side (`min(w, h)`), unlike RN which reads the window width — landscape must not inflate every font.
85
+ - Font scale measures the **window**, never `UIScreen.main`: on iPhone Duo the main screen stays on one display while the window follows the one in use. Compose iOS `getScreenDimensions()` reads `LocalWindowInfo.containerSize` (recomposes on fold/unfold); SwiftUI `DesignSystemKits` KVO-observes each `UIWindowScene.effectiveGeometry` and republishes `windowShortSide`.
85
86
  - `StackScreen` pads content/footer/search/FAB by the side insets and provides an inset-consumed layout to its content; a bottom-tab root stays full width (tab bar + each tab's StackScreen handle insets). Grid columns use `contentWidth`.
86
87
 
87
88
  ## i18n / Localize (port of RN `Localize`)
@@ -40,7 +40,7 @@ kotlin {
40
40
  }
41
41
 
42
42
  cocoapods {
43
- version = "0.168.1-beta.10-debug"
43
+ version = "0.168.1-beta.11-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-beta.22-debug'
3
+ spec.version = '0.168.1-beta.11-debug'
4
4
  spec.homepage = 'https://momo.vn'
5
5
  spec.source = { :http=> ''}
6
6
  spec.authors = ''
@@ -21,6 +21,8 @@ import androidx.compose.ui.backhandler.BackHandler as ComposeBackHandler
21
21
  import androidx.compose.ui.graphics.Color
22
22
  import androidx.compose.ui.graphics.NativePaint
23
23
  import androidx.compose.ui.graphics.toArgb
24
+ import androidx.compose.ui.platform.LocalDensity
25
+ import androidx.compose.ui.platform.LocalWindowInfo
24
26
  import androidx.compose.ui.unit.Dp
25
27
  import androidx.compose.ui.unit.dp
26
28
  import androidx.compose.ui.viewinterop.UIKitInteropProperties
@@ -29,8 +31,6 @@ import cocoapods.lottie_ios.CompatibleAnimation
29
31
  import cocoapods.lottie_ios.CompatibleAnimationKeypath
30
32
  import cocoapods.lottie_ios.CompatibleAnimationView
31
33
  import kotlinx.cinterop.ExperimentalForeignApi
32
- import kotlinx.cinterop.get
33
- import kotlinx.cinterop.memScoped
34
34
  import androidx.navigationevent.NavigationEventDispatcher
35
35
  import androidx.navigationevent.NavigationEventDispatcherOwner
36
36
  import org.jetbrains.skia.FilterBlurMode
@@ -38,7 +38,6 @@ import org.jetbrains.skia.MaskFilter
38
38
  import platform.Foundation.NSBundle
39
39
  import platform.UIKit.UIColor
40
40
  import platform.UIKit.UIDevice
41
- import platform.UIKit.UIScreen
42
41
  import platform.UIKit.UIUserInterfaceIdiomPhone
43
42
  import vn.momo.kits.navigation.AttachHostBackGesture
44
43
  import vn.momo.kits.navigation.Navigator
@@ -48,15 +47,17 @@ actual fun getPlatformName(): String = "iOS"
48
47
  actual fun isPhoneIdiom(): Boolean =
49
48
  UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPhone
50
49
 
51
- @OptIn(ExperimentalForeignApi::class)
50
+ // AI-GENERATED START: window size, not UIScreen.main (stays on one display on iPhone Duo); recomposes on fold/unfold
52
51
  @Composable
53
- actual fun getScreenDimensions(): ScreenDimension = memScoped {
54
- val config = UIScreen.mainScreen.bounds.ptr[0]
52
+ actual fun getScreenDimensions(): ScreenDimension {
53
+ val density = LocalDensity.current
54
+ val size = LocalWindowInfo.current.containerSize
55
55
  return ScreenDimension(
56
- config.size.width.toInt(),
57
- config.size.height.toInt()
56
+ (size.width / density.density).toInt(),
57
+ (size.height / density.density).toInt()
58
58
  )
59
59
  }
60
+ // AI-GENERATED END: window size, not UIScreen.main (stays on one display on iPhone Duo); recomposes on fold/unfold
60
61
 
61
62
  actual fun NativePaint.setMaskFilter(blurRadius: Float) {
62
63
  this.maskFilter = MaskFilter.makeBlur(FilterBlurMode.NORMAL, blurRadius / 2, true)
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.167.1-beta.22
21
+ version=0.168.1-beta.11
22
22
 
23
23
  repo=GitLab
24
24
  url=https://gitlab.mservice.com.vn/api/v4/projects/5400/packages/maven
@@ -36,6 +36,10 @@ public final class DesignSystemKits: ObservableObject {
36
36
 
37
37
  @Published private var configs = DesignSystemKitsConfigs()
38
38
  @Published public private(set) var osFontScale: CGFloat = DesignSystemKits.currentOsFontScale()
39
+ // AI-GENERATED START: republish the font scale when the window scene is resized (iPhone Duo fold/unfold)
40
+ @Published public private(set) var windowShortSide: CGFloat = DesignSystemKits.currentWindowShortSide()
41
+ private var geometryObservations: [ObjectIdentifier: NSKeyValueObservation] = [:]
42
+ // AI-GENERATED END: republish the font scale when the window scene is resized (iPhone Duo fold/unfold)
39
43
 
40
44
  private init() {
41
45
  NotificationCenter.default.addObserver(
@@ -44,6 +48,19 @@ public final class DesignSystemKits: ObservableObject {
44
48
  name: UIContentSizeCategory.didChangeNotification,
45
49
  object: nil
46
50
  )
51
+ // AI-GENERATED START: republish the font scale when the window scene is resized (iPhone Duo fold/unfold)
52
+ NotificationCenter.default.addObserver(
53
+ self,
54
+ selector: #selector(sceneDidActivate(_:)),
55
+ name: UIScene.didActivateNotification,
56
+ object: nil
57
+ )
58
+ onMain {
59
+ UIApplication.shared.connectedScenes
60
+ .compactMap { $0 as? UIWindowScene }
61
+ .forEach(self.observeGeometry(of:))
62
+ }
63
+ // AI-GENERATED END: republish the font scale when the window scene is resized (iPhone Duo fold/unfold)
47
64
  }
48
65
 
49
66
  public func setConfigs(_ configs: DesignSystemKitsConfigs) {
@@ -62,7 +79,10 @@ public final class DesignSystemKits: ObservableObject {
62
79
  FontScale(
63
80
  userScaleRate: configs.userScaleRate,
64
81
  useOSScaleRate: configs.useOSScaleRate,
65
- osFontScale: osFontScale
82
+ osFontScale: osFontScale,
83
+ // AI-GENERATED START: republish the font scale when the window scene is resized (iPhone Duo fold/unfold)
84
+ windowShortSide: windowShortSide
85
+ // AI-GENERATED END: republish the font scale when the window scene is resized (iPhone Duo fold/unfold)
66
86
  )
67
87
  }
68
88
 
@@ -72,6 +92,49 @@ public final class DesignSystemKits: ObservableObject {
72
92
  osFontScale = next
73
93
  }
74
94
 
95
+ // AI-GENERATED START: republish the font scale when the window scene is resized (iPhone Duo fold/unfold)
96
+ @objc private func sceneDidActivate(_ notification: Notification) {
97
+ guard let scene = notification.object as? UIWindowScene else { return }
98
+ observeGeometry(of: scene)
99
+ refreshWindowShortSide()
100
+ }
101
+
102
+ private func observeGeometry(of scene: UIWindowScene) {
103
+ guard #available(iOS 16.0, *) else { return }
104
+ let key = ObjectIdentifier(scene)
105
+ guard geometryObservations[key] == nil else { return }
106
+ geometryObservations[key] = scene.observe(\.effectiveGeometry, options: [.new]) { [weak self] _, _ in
107
+ // The window is resized after the scene geometry, so read it on the next turn.
108
+ DispatchQueue.main.async { self?.refreshWindowShortSide() }
109
+ }
110
+ }
111
+
112
+ private func refreshWindowShortSide() {
113
+ let next = Self.currentWindowShortSide()
114
+ guard next > 0, next != windowShortSide else { return }
115
+ windowShortSide = next
116
+ }
117
+
118
+ /// UIScreen.main stays on one display on iPhone Duo, so measure the foreground window instead.
119
+ static func currentWindowShortSide() -> CGFloat {
120
+ guard Thread.isMainThread else {
121
+ return min(UIScreen.main.bounds.width, UIScreen.main.bounds.height)
122
+ }
123
+ let scenes = UIApplication.shared.connectedScenes.compactMap { $0 as? UIWindowScene }
124
+ let scene = scenes.first { $0.activationState == .foregroundActive } ?? scenes.first
125
+ let window = scene?.windows.first { $0.isKeyWindow } ?? scene?.windows.first
126
+ let size: CGSize
127
+ if let window, window.bounds.width > 0 {
128
+ size = window.bounds.size
129
+ } else if let scene {
130
+ size = scene.coordinateSpace.bounds.size
131
+ } else {
132
+ size = UIScreen.main.bounds.size
133
+ }
134
+ return min(size.width, size.height)
135
+ }
136
+ // AI-GENERATED END: republish the font scale when the window scene is resized (iPhone Duo fold/unfold)
137
+
75
138
  /// Same factor Compose's iOS `ProvideOsFontScale` derives from
76
139
  /// `UIFont.preferredFont(forTextStyle: .body).pointSize / 17`, so both iOS surfaces scale alike.
77
140
  static func currentOsFontScale() -> CGFloat {
@@ -19,11 +19,19 @@ public struct FontScale: Equatable {
19
19
  public let useOSScaleRate: Bool
20
20
  /// OS Dynamic Type factor at the time the snapshot was taken.
21
21
  public let osFontScale: CGFloat
22
+ // AI-GENERATED START: device scale from the app window, not UIScreen.main (fixed to one display on iPhone Duo)
23
+ public let windowShortSide: CGFloat
22
24
 
23
- public init(userScaleRate: CGFloat = 1, useOSScaleRate: Bool = true, osFontScale: CGFloat = 1) {
25
+ public init(
26
+ userScaleRate: CGFloat = 1,
27
+ useOSScaleRate: Bool = true,
28
+ osFontScale: CGFloat = 1,
29
+ windowShortSide: CGFloat? = nil
30
+ ) {
24
31
  self.userScaleRate = userScaleRate
25
32
  self.useOSScaleRate = useOSScaleRate
26
33
  self.osFontScale = osFontScale
34
+ self.windowShortSide = windowShortSide ?? DesignSystemKits.currentWindowShortSide()
27
35
  }
28
36
 
29
37
  /// `callAsFunction` so call sites keep reading like Compose's `scaleSize(16)`.
@@ -31,8 +39,8 @@ public struct FontScale: Equatable {
31
39
  guard useOSScaleRate else { return size * userScaleRate }
32
40
 
33
41
  // Short side, not width: landscape must not inflate every font (and so every popup's height).
34
- let bounds = UIScreen.main.bounds.size
35
- let deviceScale = min(bounds.width, bounds.height) / Self.defaultScreenSize
42
+ let deviceScale = windowShortSide / Self.defaultScreenSize
43
+ // AI-GENERATED END: device scale from the app window, not UIScreen.main (fixed to one display on iPhone Duo)
36
44
 
37
45
  var deviceScaled = size
38
46
  var osScaled = size
@@ -58,7 +66,10 @@ public struct FontScale: Equatable {
58
66
  return FontScale(
59
67
  userScaleRate: userScaleRate ?? self.userScaleRate,
60
68
  useOSScaleRate: useOSScaleRate ?? self.useOSScaleRate,
61
- osFontScale: osFontScale
69
+ osFontScale: osFontScale,
70
+ // AI-GENERATED START: keep the window size through context overrides
71
+ windowShortSide: windowShortSide
72
+ // AI-GENERATED END: keep the window size through context overrides
62
73
  )
63
74
  }
64
75
  }
@@ -1,6 +1,6 @@
1
1
  Pod::Spec.new do |s|
2
2
  s.name = 'MoMoUIKits'
3
- s.version = '0.167.1-beta.22'
3
+ s.version = '0.168.1-beta.11'
4
4
  s.summary = 'MoMoUIKits for iOS'
5
5
  s.homepage = 'https://momo.vn'
6
6
  s.license = { :type => 'MIT' }
@@ -1,6 +1,6 @@
1
1
  Pod::Spec.new do |s|
2
2
  s.name = 'MoMoUIKitsDemo'
3
- s.version = '0.167.1-beta.22'
3
+ s.version = '0.168.1-beta.11'
4
4
  s.summary = 'Demo browser for MoMoUIKits SwiftUI components'
5
5
  s.homepage = 'https://momo.vn'
6
6
  s.license = { :type => 'MIT' }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/native-kits",
3
- "version": "0.168.1-beta.10-debug",
3
+ "version": "0.168.1-beta.11-debug",
4
4
  "private": false,
5
5
  "dependeNavigationncies": {},
6
6
  "devDependencies": {},