@momo-kits/native-kits 0.163.1-sp.8-debug → 0.163.2-beta.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 (48) hide show
  1. package/.codegraph/.gitignore +5 -0
  2. package/CLAUDE.md +0 -10
  3. package/compose/build.gradle.kts +1 -1
  4. package/compose/compose.podspec +1 -1
  5. package/example/ios/Example.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/Example.xcscheme +32 -0
  6. package/example/ios/Example.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/xcschememanagement.plist +14 -0
  7. package/example/ios/Example.xcworkspace/xcuserdata/sonnguyen.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  8. package/example/ios/Example.xcworkspace/xcuserdata/sonnguyen.xcuserdatad/WorkspaceSettings.xcsettings +16 -0
  9. package/example/ios/Example.xcworkspace/xcuserdata/sonnguyen.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +6 -0
  10. package/example/ios/Example.xcworkspace/xcuserdata/sonnguyen.xcuserdatad/xcschemes/xcschememanagement.plist +5 -0
  11. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/MoMoUIKits.xcscheme +58 -0
  12. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/Pods-Example.xcscheme +58 -0
  13. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/SDWebImage.xcscheme +58 -0
  14. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/SDWebImageSwiftUI.xcscheme +58 -0
  15. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/SkeletonUI.xcscheme +58 -0
  16. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/lottie-ios-LottiePrivacyInfo.xcscheme +58 -0
  17. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/lottie-ios.xcscheme +58 -0
  18. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/xcschememanagement.plist +60 -0
  19. package/gradle.properties +1 -1
  20. package/ios/Application/ApplicationEnvironment.swift +4 -6
  21. package/ios/Application/HeaderRight.swift +17 -1
  22. package/ios/Application/Localize.swift +4 -73
  23. package/ios/Application/Navigation/NavigationContainer.swift +18 -25
  24. package/ios/Application/Navigation/Navigator.swift +29 -91
  25. package/ios/Application/StackScreen.swift +21 -18
  26. package/ios/Badge/BadgeRibbon.swift +1 -4
  27. package/ios/Button/Button.swift +61 -41
  28. package/ios/Icon/Icon.swift +4 -13
  29. package/ios/native-kits.podspec +1 -2
  30. package/ios-demo/MoMoUIKitsDemo.podspec +1 -1
  31. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ButtonDemo.swift +8 -8
  32. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CheckboxDemo.swift +2 -3
  33. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/Home.swift +12 -5
  34. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/LocalizeDemo.swift +4 -51
  35. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/NavigationDemo.swift +2 -14
  36. package/ios-demo/Sources/MoMoUIKitsDemo/SwiftUIDemoBrowserView.swift +1 -3
  37. package/local.properties +2 -2
  38. package/package.json +1 -1
  39. package/.claude/settings.local.json +0 -158
  40. package/ios/Application/LanguageSource.swift +0 -93
  41. package/ios/Application/LocalizeModifier.swift +0 -30
  42. package/ios/Application/Navigation/NavigatorManager.swift +0 -49
  43. package/ios/Application/Navigation/component/NavigationFooter.swift +0 -90
  44. package/ios/Layout/GridContext.swift +0 -30
  45. package/ios/Layout/Item.swift +0 -42
  46. package/ios/Layout/Section.swift +0 -134
  47. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/IconDemo.swift +0 -104
  48. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SectionDemo.swift +0 -100
@@ -26,24 +26,17 @@ let iconSources: [String: IconSource] = loadIconSources()
26
26
  // Icons that must never be tinted (mirror Compose `noThemeIcons`)
27
27
  let noThemeIcons: [String] = ["ic_round_momo_tiny"]
28
28
 
29
- // Compose defaults `color` to the theme text color while `color = null` means "no tint".
30
- // Swift can't tell an omitted argument from an explicit `nil`, so the default is this
31
- // unrepresentable sentinel: omitted -> theme text color, `nil` -> untinted.
32
- public let iconThemeColor = Color(.sRGB, red: -1, green: -1, blue: -1, opacity: -1)
33
-
34
29
  // Icon ViewModel
35
30
  public struct Icon: View {
36
- @Environment(\.appTheme) private var theme
37
-
38
31
  var source: String
39
32
  var size: CGFloat
40
33
  var color: Color?
41
34
  var accessibilityLabel: String?
42
-
35
+
43
36
  public init(
44
37
  source: String,
45
38
  size: CGFloat = 24,
46
- color: Color? = iconThemeColor,
39
+ color: Color? = nil,
47
40
  accessibilityLabel: String? = nil
48
41
  ) {
49
42
  self.source = source
@@ -53,11 +46,9 @@ public struct Icon: View {
53
46
  }
54
47
 
55
48
  public var body: some View {
56
- // Mirror Compose: an https source is used as-is, anything else is a key into icon.json
57
- if let uri = source.contains("https") ? source : iconSources[source]?.uri {
58
- let requestedColor = color == iconThemeColor ? theme.colors.text.default : color
49
+ if let uri = iconSources[source]?.uri {
59
50
  // Mirror Compose: certain icons (e.g. branded glyphs) are never tinted
60
- let resolvedColor = noThemeIcons.contains(source) ? nil : requestedColor
51
+ let resolvedColor = noThemeIcons.contains(source) ? nil : color
61
52
  ImageView(uri, color: resolvedColor)
62
53
  .frame(width: size, height: size)
63
54
  // Mirrors Compose's auto-generated `contentDescription = "img|$iconUrl"`
@@ -1,6 +1,6 @@
1
1
  Pod::Spec.new do |s|
2
2
  s.name = 'MoMoUIKits'
3
- s.version = '0.163.1-sp.8'
3
+ s.version = '0.163.2-beta.1'
4
4
  s.summary = 'MoMoUIKits for iOS'
5
5
  s.homepage = 'https://momo.vn'
6
6
  s.license = { :type => 'MIT' }
@@ -34,7 +34,6 @@ Pod::Spec.new do |s|
34
34
  "InputDropDown/**/*.{swift,m,h}",
35
35
  "InputMoney/**/*.{swift,m,h}",
36
36
  "InputOTP/**/*.{swift,m,h}",
37
- "Layout/**/*.{swift,m,h}",
38
37
  "Loader/**/*.{swift,m,h}",
39
38
  "Lottie/**/*.{swift,m,h}",
40
39
  "OTPKeyboard/**/*.{swift,m,h}",
@@ -1,6 +1,6 @@
1
1
  Pod::Spec.new do |s|
2
2
  s.name = 'MoMoUIKitsDemo'
3
- s.version = '0.163.1-sp.8'
3
+ s.version = '0.163.2-beta.1'
4
4
  s.summary = 'Demo browser for MoMoUIKits SwiftUI components'
5
5
  s.homepage = 'https://momo.vn'
6
6
  s.license = { :type => 'MIT' }
@@ -22,19 +22,19 @@ struct ButtonDemo: View {
22
22
 
23
23
  Group {
24
24
  Button(title: "Button", action: onPress, type: disabled ? .disabled : .primary, size: .large,
25
- iconRight: "notifications_check_circle")
25
+ iconRight: AnyView(Image(systemName: "checkmark.circle")))
26
26
  Button(title: "Button", action: onPress, size: .small)
27
27
  }
28
28
 
29
29
  Group {
30
30
  Button(title: "Button", action: onPress, type: .danger,
31
- iconLeft: "notifications_check_circle")
31
+ iconLeft: AnyView(Image(systemName: "checkmark.circle")))
32
32
  Button(title: "Button", action: onPress, type: .danger, size: .medium)
33
33
  Button(title: "Button", action: onPress, type: .danger, size: .small)
34
34
  }
35
35
 
36
36
  Group {
37
- Button(title: "Button", action: onPress, type: .danger, iconLeft: "notifications_check_circle", isFull: false)
37
+ Button(title: "Button", action: onPress, type: .danger, iconLeft: AnyView(Image(systemName: "checkmark.circle")), isFull: false)
38
38
  Button(title: "Button", action: onPress, type: .danger, size: .medium, isFull: false)
39
39
  Button(title: "Button", action: onPress, type: .danger, size: .small, isFull: false)
40
40
  }
@@ -48,9 +48,9 @@ struct ButtonDemo: View {
48
48
 
49
49
  Group {
50
50
  Button(title: "Tinted icon", action: onPress, type: .primary,
51
- iconLeft: "notifications_check_circle", useTintColor: true)
51
+ iconLeft: AnyView(Image(systemName: "checkmark.circle")), useTintColor: true)
52
52
  Button(title: "Original icon", action: onPress, type: .primary,
53
- iconLeft: "notifications_check_circle", useTintColor: false)
53
+ iconLeft: AnyView(Image(systemName: "checkmark.circle")), useTintColor: false)
54
54
  }
55
55
 
56
56
  Group {
@@ -78,9 +78,9 @@ struct ButtonDemo: View {
78
78
  }
79
79
  Group {
80
80
  Button(title: "Button", action: onPress, type: .primary, size: .medium, loading: true)
81
- Button(title: "Button", action: onPress, type: .danger, size: .medium, iconLeft: "notifications_check_circle", loading: true)
82
- Button(title: "Button", action: onPress, type: .disabled, size: .medium, iconRight: "notifications_check_circle", loading: true)
83
- Button(title: "Button", action: onPress, type: .outline, size: .medium, iconLeft: "notifications_check_circle", iconRight: "notifications_check_circle", loading: true)
81
+ Button(title: "Button", action: onPress, type: .danger, size: .medium, iconLeft: AnyView(Image(systemName: "checkmark.circle")), loading: true)
82
+ Button(title: "Button", action: onPress, type: .disabled, size: .medium, iconRight: AnyView(Image(systemName: "checkmark.circle")), loading: true)
83
+ Button(title: "Button", action: onPress, type: .outline, size: .medium, iconLeft: AnyView(Image(systemName: "checkmark.circle")), iconRight: AnyView(Image(systemName: "checkmark.circle")), loading: true)
84
84
  Button(title: "Button", action: onPress, type: .secondary, size: .medium, loading: true)
85
85
  Button(title: "Button", action: onPress, type: .text, size: .medium, loading: true)
86
86
  Button(title: "Button", action: onPress, type: .tonal, size: .medium, loading: true)
@@ -12,11 +12,10 @@ struct CheckboxDemo: View {
12
12
 
13
13
  var body: some View {
14
14
  VStack(alignment: .leading, spacing: 20) {
15
- // Interactive checkbox. Checkbox toggles the binding itself;
16
- // onChange only reports the new value — don't flip state again here.
15
+ // Interactive checkbox
17
16
  Checkbox(
18
17
  $checked,
19
- onChange: { value in print("Checkbox changed: \(value)") },
18
+ onChange: { _ in checked = !checked },
20
19
  title: "Check Box"
21
20
  )
22
21
 
@@ -34,22 +34,29 @@ public func getIcon(icon: String) -> String {
34
34
  }
35
35
 
36
36
  public let ScreenUsages: [ScreenUsage] = [
37
+ // ScreenUsage(title: "ScreenUsage", destination: AnyView(ContentView()), icon: getIcon(icon: "Layout")),
37
38
  ScreenUsage(title: "Badge", destination: AnyView(BadgeDemo()), icon: getIcon(icon: "Badge")),
38
39
  ScreenUsage(title: "Button", destination: AnyView(ButtonDemo()), icon: getIcon(icon: "Button")),
39
40
  ScreenUsage(title: "CheckBox", destination: AnyView(CheckboxDemo()), icon: getIcon(icon: "Checkbox")),
40
41
  ScreenUsage(title: "Chip", destination: AnyView(ChipDemo()), icon: getIcon(icon: "Chip")),
41
- ScreenUsage(title: "Icon", destination: AnyView(IconDemo()), icon: getIcon(icon: "Icon")),
42
+ // ScreenUsage(title: "IconButton", destination: AnyView(ContentView()), icon: getIcon(icon: "Button")),
43
+ // ScreenUsage(title: "Icon", destination: AnyView(ContentView()), icon: getIcon(icon: "Icon")),
42
44
  ScreenUsage(title: "Image", destination: AnyView(ImageDemo()), icon: getIcon(icon: "Layout")),
43
45
  ScreenUsage(title: "Baseline View", destination: AnyView(BaselineViewDemo()), icon: getIcon(icon: "Layout")),
44
- ScreenUsage(title: "Section", destination: AnyView(SectionDemo()), icon: getIcon(icon: "Layout")),
46
+ // ScreenUsage(title: "InputMoney", destination: AnyView(ContentView()), icon: getIcon(icon: "FormInput")),
45
47
  ScreenUsage(title: "Input", destination: AnyView(InputDemo()), icon: getIcon(icon: "FormInput")),
46
48
  ScreenUsage(title: "Input Phone Number", destination: AnyView(InputPhoneNumberDemo()), icon: getIcon(icon: "FormInput")),
47
49
  ScreenUsage(title: "InputTextArea", destination: AnyView(InputTextAreaDemo()), icon: getIcon(icon: "FormInput")),
48
50
  ScreenUsage(title: "InputSearch", destination: AnyView(InputSearchDemo()), icon: getIcon(icon: "FormInput")),
51
+ // ScreenUsage(title: "Pagination", destination: AnyView(ContentView()), icon: getIcon(icon: "Badge")),
52
+ // ScreenUsage(title: "InputDropdown", destination: AnyView(ContentView()), icon: getIcon(icon: "FormInput")),
49
53
  ScreenUsage(title: "PopupNotify", destination: AnyView(PopupNotifyDemo()), icon: getIcon(icon: "Popup")),
50
54
  ScreenUsage(title: "PopupPromotion", destination: AnyView(PopupPromotionDemo()), icon: getIcon(icon: "Popup")),
51
55
  ScreenUsage(title: "SnackBar", destination: AnyView(SnackBarDemo()), icon: getIcon(icon: "Popup")),
56
+ // ScreenUsage(title: "Radio", destination: AnyView(ContentView()), icon: getIcon(icon: "Radio")),
57
+ // ScreenUsage(title: "Skeleton", destination: AnyView(ContentView()), icon: getIcon(icon: "Skeleton")),
52
58
  ScreenUsage(title: "Switch", destination: AnyView(SwitchDemo()), icon: getIcon(icon: "Toggle")),
59
+ // ScreenUsage(title: "Tag", destination: AnyView(ContentView()), icon: getIcon(icon: "Skeleton")),
53
60
  ScreenUsage(title: "Text", destination: AnyView(TypographyDemo()), icon: getIcon(icon: "Typography")),
54
61
  // ScreenUsage(title: "TrustBanner", destination: AnyView(TrustBanner(onPress: {_ in })), icon: getIcon(icon: "Typography")),
55
62
  ScreenUsage(title: "Information", destination: AnyView(InformationDemo()), icon: getIcon(icon: "Typography")),
@@ -127,11 +134,11 @@ public struct HomeView: View {
127
134
  headerRight: {
128
135
  HeaderRight(headerRight: HeaderRightData(useShortcut: true))
129
136
  },
130
- // footerComponent = { Button("Open SwiftUI (iOS only)") }
137
+ // footerComponent = { Button("Footer Button") }
131
138
  footer: {
132
139
  AnyView(
133
140
  MoMoUIKits.Button(
134
- title: "Open Compose",
141
+ title: "Footer Button",
135
142
  action: onOpenCompose,
136
143
  type: .primary,
137
144
  size: .large
@@ -260,7 +267,7 @@ public struct HomeItemView: View {
260
267
  Divider()
261
268
  }
262
269
  .padding(.horizontal, 16)
263
- .padding(.vertical, 16)
270
+ .padding(.vertical, 8)
264
271
  }
265
272
  }
266
273
 
@@ -24,72 +24,27 @@ private let AppTranslations = LocalizationObject(
24
24
  )
25
25
 
26
26
  struct LocalizeDemo: View {
27
- // AI-GENERATED START: observe the app language and drive it through the real platform API
28
- @Environment(\.localize) private var localize
29
- @Environment(\.applicationEnvironment) private var applicationEnvironment
30
- // AI-GENERATED END: observe the app language and drive it through the real platform API
27
+ @EnvironmentObject private var localize: Localize
31
28
 
32
29
  private var isEnglish: Bool { localize.currentLanguage == Localize.EN }
33
30
 
34
- // AI-GENERATED START: observe the app language and drive it through the real platform API
35
- private var storedLanguage: String {
36
- UserDefaults.standard.string(forKey: UserDefaultsLanguageSource.defaultKey) ?? "nil"
37
- }
38
-
39
- private func setLanguage(_ language: String) {
40
- // Platform API -> KMP LanguageApi.SetLanguage -> LocalizationProvider.set, which also
41
- // mirrors AppleLanguages. KVO then pushes the change back into Localize. The real wire.
42
- if let composeApi = applicationEnvironment.composeApi {
43
- _ = composeApi.request(funcName: "setLanguage", params: language)
44
- } else {
45
- localize.changeLanguage(language) // #Preview / sample app: no host bridge
46
- }
47
- }
48
- // AI-GENERATED END: observe the app language and drive it through the real platform API
49
-
50
31
  var body: some View {
51
32
  ScrollView {
52
33
  VStack(alignment: .leading, spacing: 0) {
53
34
 
54
35
  LocalizeSectionBox(title: "Đổi ngôn ngữ (toàn app)") {
55
36
  MomoText(
56
- "Switch gọi platform API setLanguageđổi ngôn ngữ THẬT của app. Localize observe lại "
57
- + "qua UserDefaults nên mọi màn hình đang đọc translate() đều cập nhật.",
37
+ "localize.changeLanguage(...) đổi ngôn ngữ cho cả NavigationContainer mọi màn hình đang đọc translate() sẽ cập nhật theo.",
58
38
  typography: .descriptionDefaultRegular
59
39
  )
60
40
  Switch(
61
41
  .constant(isEnglish),
62
- onChange: { _ in setLanguage(isEnglish ? Localize.VI : Localize.EN) },
42
+ onChange: { _ in localize.changeLanguage(isEnglish ? Localize.VI : Localize.EN) },
63
43
  title: "English"
64
44
  )
65
45
  MomoText("currentLanguage = \(localize.currentLanguage)", typography: .labelDefaultMedium)
66
46
  }
67
47
 
68
- // AI-GENERATED START: prove the observation loop, not kit-local state, drives updates
69
- LocalizeSectionBox(title: "Nguồn thật: UserDefaults") {
70
- MomoText(
71
- "Ghi thẳng vào UserDefaults, bỏ qua mọi API của kit — màn hình vẫn đổi, chứng minh "
72
- + "Localize đang observe ngôn ngữ app.",
73
- typography: .descriptionDefaultRegular
74
- )
75
- TranslationRow(key: UserDefaultsLanguageSource.defaultKey, value: storedLanguage)
76
- Button(
77
- title: "Ghi thẳng UserDefaults = \"en\"",
78
- action: {
79
- // Quoted on purpose: proves normalize() strips the JSON quoting
80
- // RN and KMP persist.
81
- UserDefaults.standard.set(
82
- "\"en\"",
83
- forKey: UserDefaultsLanguageSource.defaultKey
84
- )
85
- },
86
- type: .outline,
87
- size: .medium,
88
- isFull: false
89
- )
90
- }
91
- // AI-GENERATED END: prove the observation loop, not kit-local state, drives updates
92
-
93
48
  LocalizeSectionBox(title: "translate(key) — từ điển mặc định của kit") {
94
49
  TranslationRow(key: "confirm", value: localize.translate("confirm"))
95
50
  TranslationRow(key: "cancel", value: localize.translate("cancel"))
@@ -224,10 +179,8 @@ private struct TranslationRow: View {
224
179
  #Preview {
225
180
  if #available(iOS 16.0, *) {
226
181
  NavigationStack {
227
- // AI-GENERATED START: preview needs the observing provider or the toggle will not update
228
182
  LocalizeDemo()
229
- .momoLocalize(Localize())
230
- // AI-GENERATED END: preview needs the observing provider or the toggle will not update
183
+ .environmentObject(Localize())
231
184
  }
232
185
  } else {
233
186
  // Fallback on earlier versions
@@ -101,21 +101,9 @@ private struct NavigationDemoContent: View {
101
101
 
102
102
  Divider().padding(.vertical, 4)
103
103
 
104
- row("Custom Back Handler") {
105
- // The screen owns back: the header button and the edge swipe both
106
- // run this instead of popping (mirrors Compose's onBackHandler).
107
- navigator.push(
108
- { DemoLeafScreen(title: "Back is intercepted — swipe from the edge", color: Colors.blue09) },
109
- options: NavigationOptions(
110
- title: "Custom Back",
111
- onBackHandler: { print("back intercepted") }
112
- )
113
- )
114
- }
115
-
116
104
  row("Prevent Back") {
117
- // The header back button and the edge swipe both show a confirm popup
118
- // before leaving (mirrors Compose's headerBackProps.preventBack).
105
+ // Tapping the header back button shows a confirm popup before
106
+ // leaving (mirrors Compose's headerBackProps.preventBack).
119
107
  navigator.push(
120
108
  { DemoLeafScreen(title: "Tap the header back button", color: Colors.pink09) },
121
109
  options: NavigationOptions(
@@ -7,7 +7,7 @@ struct SwiftUIDemoBrowserView: View {
7
7
  @State private var searchText = ""
8
8
 
9
9
  var body: some View {
10
- ZStack {
10
+ Group {
11
11
  if #available(iOS 16.0, *) {
12
12
  HomeView(
13
13
  onOpenCompose: onOpenCompose,
@@ -16,8 +16,6 @@ struct SwiftUIDemoBrowserView: View {
16
16
  } else {
17
17
  fallbackBrowser
18
18
  }
19
-
20
- BaselineView()
21
19
  }
22
20
  .environment(\.appTheme, defaultTheme)
23
21
  }
package/local.properties CHANGED
@@ -4,5 +4,5 @@
4
4
  # Location of the SDK. This is only used by Gradle.
5
5
  # For customization when using a Version Control System, please read the
6
6
  # header note.
7
- #Tue Jun 02 17:05:32 ICT 2026
8
- sdk.dir=/Users/sophia/Library/Android/sdk
7
+ #Tue Apr 08 11:13:31 ICT 2025
8
+ sdk.dir=/Users/sonnguyen/Library/Android/sdk
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/native-kits",
3
- "version": "0.163.1-sp.8-debug",
3
+ "version": "0.163.2-beta.1-debug",
4
4
  "private": false,
5
5
  "dependencies": {},
6
6
  "devDependencies": {},
@@ -1,158 +0,0 @@
1
- {
2
- "permissions": {
3
- "allow": [
4
- "Bash(curl -s -o /dev/null -w \"%{http_code}\" \"https://repo.maven.apache.org/maven2/org/jetbrains/skiko/skiko-android/0.144.6/skiko-android-0.144.6.pom\")",
5
- "Bash(curl -s \"https://repo.maven.apache.org/maven2/org/jetbrains/skiko/skiko-android/maven-metadata.xml\")",
6
- "Bash(curl -s \"https://repo.maven.apache.org/maven2/org/jetbrains/skiko/skiko/maven-metadata.xml\")",
7
- "Bash(curl -s \"https://repo.maven.apache.org/maven2/org/jetbrains/skiko/skiko/0.144.6/skiko-0.144.6.module\")",
8
- "Bash(curl -s -o /dev/null -w '%{http_code}' https://repo.maven.apache.org/maven2/org/jetbrains/skiko/skiko-android/0.144.6/skiko-android-0.144.6.__TRACKED_VAR__)",
9
- "Bash(curl -s \"https://repo.maven.apache.org/maven2/org/jetbrains/skiko/skiko-android/0.144.6/\")",
10
- "Bash(curl -s \"https://repo.maven.apache.org/maven2/org/jetbrains/skiko/skiko-android/\")",
11
- "Bash(curl -s -o /dev/null -w \"%{http_code}\\\\n\" \"https://repo.maven.apache.org/maven2/org/jetbrains/skiko/skiko-android/0.148.1/skiko-android-0.148.1.pom\")",
12
- "Bash(curl -s -o /dev/null -w \"%{http_code}\\\\n\" \"https://repo.maven.apache.org/maven2/org/jetbrains/skiko/skiko-android/0.144.5/skiko-android-0.144.5.pom\")",
13
- "Bash(curl -s -o /dev/null -w \"%{http_code}\\\\n\" \"https://dl.google.com/dl/android/maven2/org/jetbrains/skiko/skiko-android/0.144.6/skiko-android-0.144.6.pom\")",
14
- "Bash(curl -s \"https://search.maven.org/solrsearch/select?q=a:skiko-android&rows=5&wt=json\")",
15
- "Bash(curl -sL -o /dev/null -w \"%{http_code} %{url_effective}\\\\n\" \"https://repo1.maven.org/maven2/org/jetbrains/skiko/skiko-android/0.144.6/skiko-android-0.144.6.pom\")",
16
- "Bash(curl *)",
17
- "Bash(./gradlew :sample:androidApp:dependencies --configuration debugRuntimeClasspath)",
18
- "Bash(./gradlew :sample:shared:compileDebugKotlinAndroid)",
19
- "Bash(./gradlew :sample:androidApp:compileDebugKotlin)",
20
- "Bash(ls -d *.xcodeproj)",
21
- "Bash(grep -c ChipDemo.swift __TRACKED_VAR__/project.pbxproj)",
22
- "Bash(grep -c PBXFileSystemSynchronizedRootGroup __TRACKED_VAR__/project.pbxproj)",
23
- "Bash(grep -c InformationDemo.swift __TRACKED_VAR__/project.pbxproj)",
24
- "Bash(plutil -lint project.pbxproj)",
25
- "Bash(xcode-select -p)",
26
- "Bash(/usr/bin/xcrun xcodebuild *)",
27
- "Bash(echo \"exit: $?\")",
28
- "Bash(/Applications/Xcode26.app/Contents/Developer/usr/bin/xcodebuild -version)",
29
- "Bash(./gradlew :compose:tasks --all)",
30
- "Bash(grep -n \"vanniktech\\\\|mavenPublishing\\\\|^publishing\\\\|version = gitlabVersion\\\\|namespace =\\\\|compileSdk =\\\\|minSdk =\\\\|GitLabPackages\\\\|name = \\\\\"\\\\${gitlabRepo}Packages\\\\\"\")",
31
- "Bash(git checkout *)",
32
- "Bash(./gradlew :compose:publishAllPublicationsToGitLabPackagesRepository --dry-run)",
33
- "Bash(git fetch *)",
34
- "Bash(git pull *)",
35
- "Bash(git push *)",
36
- "Bash(git branch *)",
37
- "Bash(xcodebuild -workspace iosApp.xcworkspace -list)",
38
- "Bash(xcrun simctl *)",
39
- "Bash(xcodebuild -workspace iosApp.xcworkspace -scheme iosApp -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 14 Pro' -configuration Debug build CODE_SIGNING_ALLOWED=NO)",
40
- "Bash(pod install *)",
41
- "Bash(xcodebuild -workspace iosApp.xcworkspace -scheme iosApp -sdk iphonesimulator -destination 'id=1E6F9A79-5E64-4590-BEA2-828D75D99393' -configuration Debug build CODE_SIGNING_ALLOWED=NO)",
42
- "Bash(xcrun swiftc *)",
43
- "Bash(echo \"=== exit: $? \\(1=none found\\) ===\")",
44
- "Bash(cat Radius.swift)",
45
- "Bash(cat Spacing.swift)",
46
- "Bash(echo \"exit=$?\")",
47
- "Bash(ruby *)",
48
- "Bash(xcodebuild -list -workspace iosApp.xcworkspace)",
49
- "Bash(xcodebuild -workspace iosApp.xcworkspace -scheme MoMoUIKits -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 14 Pro' build)",
50
- "Bash(xcodebuild -workspace iosApp.xcworkspace -scheme MoMoUIKits -sdk iphonesimulator -destination 'platform=iOS Simulator,id=E6A899C0-098E-473A-95B8-A2BBD2D42A92' build)",
51
- "Bash(xcodebuild -workspace iosApp.xcworkspace -scheme iosApp -sdk iphonesimulator -destination 'platform=iOS Simulator,id=E6A899C0-098E-473A-95B8-A2BBD2D42A92' build)",
52
- "Bash(xcodebuild build *)",
53
- "Bash(git stash *)",
54
- "Bash(plutil -lint sample/iosApp/iosApp.xcodeproj/project.pbxproj)",
55
- "Bash(git add *)",
56
- "Bash(git commit -m 'feat: DS-646 [ci build] *)",
57
- "Bash(git commit -q -m 'fix: DS-656 [ci build] *)",
58
- "Bash(xargs git log --oneline -1)",
59
- "Bash(git rev-list *)",
60
- "Bash(git status *)",
61
- "Bash(git rebase *)",
62
- "Bash(git merge *)",
63
- "Bash(git reset *)",
64
- "Bash(awk '/^ *)",
65
- "Bash(git ls-tree *)",
66
- "Bash(awk *)",
67
- "Read(//Users/sophia/Workspace/momo/momo-app/**)",
68
- "Bash(git log *)",
69
- "Bash(xcodebuild -version)",
70
- "Bash(xcodebuild -workspace iosApp.xcworkspace -scheme iosApp -sdk iphonesimulator -destination 'generic/platform=iOS Simulator' -configuration Debug build CODE_SIGNING_ALLOWED=NO)",
71
- "Bash(xcodebuild -workspace iosApp.xcworkspace -scheme MoMoUIKits -sdk iphonesimulator -destination 'generic/platform=iOS Simulator' -configuration Debug build CODE_SIGNING_ALLOWED=NO)",
72
- "Bash(xcodebuild -workspace iosApp.xcworkspace -scheme MoMoUIKits -sdk iphonesimulator -destination 'generic/platform=iOS Simulator' -configuration Debug clean build CODE_SIGNING_ALLOWED=NO)",
73
- "Bash(git commit *)",
74
- "Bash(npm view *)",
75
- "Bash(echo \"EXIT=$? -> not resolvable\")",
76
- "Bash(yarn install *)",
77
- "Bash(RCT_NEW_ARCH_ENABLED=1 pod install)",
78
- "Bash(xcodebuild -workspace MoMoPlatform.xcworkspace -list)",
79
- "Bash(git --no-pager diff --stat ios/Application/Localize.swift ios/Application/Navigation/NavigationContainer.swift ios/Popup/PopupDisplay.swift ios/Popup/PopupNotify.swift ios/Template/TrustBanner/TrustBanner.swift)",
80
- "Bash(git rm *)",
81
- "Bash(echo \"EXIT=$?\")",
82
- "Bash(git -C /Users/sophia/Workspace/momo/momo-native-kits diff sample/iosApp/iosApp/Demo/ButtonDemo.swift)",
83
- "Bash(python3 *)",
84
- "Bash(git -C /Users/sophia/Workspace/momo/momo-native-kits status --short)",
85
- "Bash(git -C /Users/sophia/Workspace/momo/momo-native-kits log --oneline -3)",
86
- "Bash(git -C /Users/sophia/Workspace/momo/momo-native-kits log --oneline -5 -- ios/Button/Button.swift)",
87
- "Bash(git -C /Users/sophia/Workspace/momo/momo-native-kits diff ios/native-kits.podspec compose/compose.podspec gradle.properties package.json)",
88
- "Bash(git -C /Users/sophia/Workspace/momo/momo-native-kits show HEAD:ios/Button/Button.swift)",
89
- "Bash(git -C /Users/sophia/Workspace/momo/momo-native-kits diff package.json ios/native-kits.podspec)",
90
- "Bash(grep -n \"must be a \\\\`.background\\\\` of the label\" /Users/sophia/Workspace/momo/momo-app/node_modules/@momo-kits/native-kits/ios/Button/Button.swift)",
91
- "Bash(git -C /Users/sophia/Workspace/momo/momo-native-kits show -s --format=\"%h %ci %s\" 953b234d)",
92
- "Bash(git -C /Users/sophia/Workspace/momo/momo-app show -s --format=\"%h %ci %s\" f8757a14437)",
93
- "Bash(git -C /Users/sophia/Workspace/momo/momo-app log -S '\"@momo-kits/native-kits\": \"0.163.1-beta.18\"' --format=\"%h %ci %s\" -- package.json)",
94
- "Bash(swiftc -O repro_isfull.swift -o repro_isfull)",
95
- "Bash(./repro_isfull)",
96
- "Bash(grep -n '^\\\\[32;1m$\\\\|section_start\\\\|xcodebuild.*-workspace\\\\|xcodebuild.*archive\\\\|Prebuilt\\\\|prebuilt\\\\|framework.*download\\\\|rugby\\\\|Rugby' /private/tmp/claude-503/-Users-sophia-Workspace-momo-momo-native-kits/7e2b5bd7-f8b3-42f7-b242-127fa8eabd12/scratchpad/job_trace.log)",
97
- "Bash(grep -n '\\\\[32;1m\\\\$' /private/tmp/claude-503/-Users-sophia-Workspace-momo-momo-native-kits/7e2b5bd7-f8b3-42f7-b242-127fa8eabd12/scratchpad/job_trace.log)",
98
- "Bash(npm pack *)",
99
- "Bash(mkdir -p b13 b18)",
100
- "Bash(tar xzf *)",
101
- "Bash(git *)",
102
- "Bash(tar -tzf momo-kits-native-kits-0.163.1-beta.18.tgz)",
103
- "Bash(tar -xzf momo-kits-native-kits-0.163.1-beta.18.tgz package/ios/Button/Button.swift)",
104
- "Bash(tar -xzf momo-kits-native-kits-0.162.28.tgz package/ios/Button/Button.swift -C .)",
105
- "Bash(mkdir -p old)",
106
- "Bash(tar -xzf momo-kits-native-kits-0.162.28.tgz -C old package/ios/Button/Button.swift)",
107
- "Bash(nm '/private/tmp/claude-503/-Users-sophia-Workspace-momo-momo-native-kits/7e2b5bd7-f8b3-42f7-b242-127fa8eabd12/scratchpad/ipa_extract/Payload/MoMoPlatform UAT.app/MoMoPlatform UAT')",
108
- "Bash(xcodebuild -workspace /Users/sophia/Workspace/momo/momo-native-kits/sample/iosApp/iosApp.xcworkspace -list)",
109
- "Bash(xcodebuild -workspace iosApp.xcworkspace -scheme MoMoUIKits -sdk iphonesimulator -destination 'generic/platform=iOS Simulator' build)",
110
- "Bash(xcodebuild -workspace iosApp.xcworkspace -scheme iosApp -sdk iphonesimulator -destination 'generic/platform=iOS Simulator' -derivedDataPath build-verify build)",
111
- "Bash(xcodebuild -workspace iosApp.xcworkspace -scheme MoMoUIKits -sdk iphonesimulator -destination 'generic/platform=iOS Simulator' -derivedDataPath build-verify build)",
112
- "Bash(./gradlew :sample:shared:syncComposeResourcesForIos)",
113
- "Bash(xcodebuild -workspace iosApp.xcworkspace -scheme iosApp -sdk iphonesimulator -destination 'platform=iOS Simulator,id=E6A899C0-098E-473A-95B8-A2BBD2D42A92' -derivedDataPath build-verify build)",
114
- "Bash(xcodebuild -workspace iosApp.xcworkspace -scheme MoMoUIKits -sdk iphonesimulator -destination 'generic/platform=iOS Simulator' -quiet build)",
115
- "Bash(xcodebuild -workspace sample/iosApp/iosApp.xcworkspace -list)",
116
- "Bash(xcodebuild -workspace iosApp.xcworkspace -scheme iosApp -destination 'id=0228A4B2-57E0-4E56-BFAD-DB9E95044AD9' -derivedDataPath /private/tmp/claude-503/-Users-sophia-Workspace-momo-momo-native-kits/6986983a-795d-419d-9d78-fcc100e87876/scratchpad/dd build)",
117
- "Bash(xcodebuild -workspace iosApp.xcworkspace -scheme iosApp -destination 'id=1E6F9A79-5E64-4590-BEA2-828D75D99393' -derivedDataPath /private/tmp/claude-503/-Users-sophia-Workspace-momo-momo-native-kits/6986983a-795d-419d-9d78-fcc100e87876/scratchpad/dd build)",
118
- "Bash([ -s $S/kb.png ])",
119
- "Bash(sips -g pixelWidth -g pixelHeight /private/tmp/claude-503/-Users-sophia-Workspace-momo-momo-native-kits/6986983a-795d-419d-9d78-fcc100e87876/scratchpad/kb.png)",
120
- "Bash(defaults read *)",
121
- "Bash(defaults write *)",
122
- "Bash(xcrun xcodebuild *)",
123
- "Bash(xcodebuild -workspace iosApp.xcworkspace -scheme iosApp -sdk iphonesimulator -destination 'generic/platform=iOS Simulator' -quiet build)",
124
- "Bash(xcodebuild -workspace iosApp.xcworkspace -scheme iosApp -sdk iphonesimulator -destination 'platform=iOS Simulator,id=E6A899C0-098E-473A-95B8-A2BBD2D42A92' -quiet build)",
125
- "Read(//tmp/claude-503/-Users-sophia-Workspace-momo-momo-native-kits/3e8adc08-a7e7-4169-aee6-8b22a6996f38/scratchpad/**)",
126
- "Bash(echo \"parse-exit=$?\")",
127
- "Bash(echo \"=== exit $?\")",
128
- "Bash(xcodebuild -workspace iosApp.xcworkspace -scheme iosApp -sdk iphonesimulator -destination 'generic/platform=iOS Simulator' -configuration Debug build)",
129
- "Bash(xcodebuild -workspace iosApp.xcworkspace -scheme iosApp -sdk iphonesimulator -destination 'platform=iOS Simulator,id=E6A899C0-098E-473A-95B8-A2BBD2D42A92' -configuration Debug build)",
130
- "Bash(./gradlew :sample:shared:compileCommonMainKotlinMetadata -q)",
131
- "Bash(echo \"gradle=$?\")",
132
- "Bash(xcodebuild -workspace iosApp.xcworkspace -scheme iosApp -sdk iphonesimulator -destination 'id=0228A4B2-57E0-4E56-BFAD-DB9E95044AD9' -derivedDataPath build/dd build)",
133
- "Bash(osascript *)",
134
- "Bash(screencapture -x -R253,53,452,950 win.png)",
135
- "Bash(sips -g pixelWidth -g pixelHeight win.png)",
136
- "Bash(screencapture -x -R\"253,53,452,950\" win.png)",
137
- "Bash(screencapture -x full.png)",
138
- "Bash(sips -g pixelWidth -g pixelHeight full.png)",
139
- "Bash(sips -c 1900 904 --cropOffset 106 506 full.png --out crop.png)",
140
- "Bash(swiftc -O mouse.swift -o mouse)",
141
- "Bash(./mouse click *)",
142
- "Bash(./mouse drag *)",
143
- "Bash(sips -c 900 924 --cropOffset 0 0 s12.png --out s12crop.png)",
144
- "Bash(sips -c 300 1170 --cropOffset 300 0 s12.png --out s12top.png)",
145
- "Bash(sips -c 700 1170 --cropOffset 250 0 t1.png --out t1c.png)",
146
- "Bash(sips -c 700 1170 --cropOffset 250 0 t2.png --out t2c.png)",
147
- "Bash(sips -c 700 1170 --cropOffset 150 0 t3.png --out t3c.png)",
148
- "Bash(sips -c 1200 1170 --cropOffset 600 0 t4.png --out t4c.png)",
149
- "Bash(sips -c 600 1170 --cropOffset 150 0 t5.png --out t5c.png)",
150
- "Bash(sips -c 500 1170 --cropOffset 150 0 u1.png --out u1c.png)",
151
- "Bash(cp /Users/sophia/Workspace/momo/momo-native-kits/ios/Application/Navigation/NavigationContainer.swift /Users/sophia/Workspace/momo/momo-app/node_modules/@momo-kits/native-kits/ios/Application/Navigation/NavigationContainer.swift)",
152
- "Bash(cp /Users/sophia/Workspace/momo/momo-native-kits/ios/Application/Navigation/Navigator.swift /Users/sophia/Workspace/momo/momo-app/node_modules/@momo-kits/native-kits/ios/Application/Navigation/Navigator.swift)",
153
- "Bash(cp /Users/sophia/Workspace/momo/momo-native-kits/ios/Application/Navigation/NavigatorManager.swift /Users/sophia/Workspace/momo/momo-app/node_modules/@momo-kits/native-kits/ios/Application/Navigation/NavigatorManager.swift)",
154
- "Bash(cp /Users/sophia/Workspace/momo/momo-native-kits/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/NavigationDemo.swift /Users/sophia/Workspace/momo/momo-app/node_modules/@momo-kits/native-kits/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/NavigationDemo.swift)",
155
- "Bash(xcodebuild -workspace MoMoPlatform.xcworkspace -scheme MoMoPlatform-UAT -sdk iphonesimulator -destination 'generic/platform=iOS Simulator' -derivedDataPath build/DerivedData build)"
156
- ]
157
- }
158
- }
@@ -1,93 +0,0 @@
1
- // File: ios/Application/LanguageSource.swift
2
- // Created At: 2026-07-29 10:00:00 +07:00
3
- // Created By: AI
4
- // AI Agent: Claude Code
5
- // Model: claude-opus-5[1m]
6
-
7
- // AI-GENERATED START: observe the host app's active language so Localize can follow it
8
- import Foundation
9
-
10
- /// Read-only view of the host app's active language, plus change delivery.
11
- /// Values handed to `onChange` are already normalized to `Localize.VI` / `Localize.EN`.
12
- public protocol LanguageSource: AnyObject {
13
- var currentLanguage: String { get }
14
- /// `onChange` may be invoked on any thread; `Localize` dedupes and hops to main.
15
- func startObserving(_ onChange: @escaping (String) -> Void)
16
- func stopObserving()
17
- }
18
-
19
- /// Reads the language the MoMo host app persists in `UserDefaults`. All three host writers
20
- /// (the `RNResource` RN bridge, `JSONLocalization`, and the KMP `LocalizationProvider`) write the
21
- /// same key on `UserDefaults.standard` in-process, so KVO on it sees every one of them.
22
- public final class UserDefaultsLanguageSource: NSObject, LanguageSource {
23
- public static let defaultKey = "language"
24
-
25
- private let defaults: UserDefaults
26
- private let key: String
27
- private var onChange: ((String) -> Void)?
28
- private var isObserving = false
29
- private var kvoContext = 0
30
-
31
- /// - Note: `key` must not contain `.` — `forKeyPath:` would read it as a key path.
32
- public init(
33
- defaults: UserDefaults = .standard,
34
- key: String = UserDefaultsLanguageSource.defaultKey
35
- ) {
36
- self.defaults = defaults
37
- self.key = key
38
- super.init()
39
- }
40
-
41
- public var currentLanguage: String {
42
- Localize.normalize(defaults.string(forKey: key))
43
- }
44
-
45
- public func startObserving(_ onChange: @escaping (String) -> Void) {
46
- guard !isObserving else { return }
47
- isObserving = true
48
- self.onChange = onChange
49
- defaults.addObserver(self, forKeyPath: key, options: [.new], context: &kvoContext)
50
- // Safety net for writes KVO can miss (e.g. `removeObject`). Double delivery is free:
51
- // `Localize` dedupes before touching `@Published`.
52
- NotificationCenter.default.addObserver(
53
- self,
54
- selector: #selector(emit),
55
- name: UserDefaults.didChangeNotification,
56
- object: defaults
57
- )
58
- }
59
-
60
- public func stopObserving() {
61
- guard isObserving else { return }
62
- isObserving = false
63
- defaults.removeObserver(self, forKeyPath: key, context: &kvoContext)
64
- NotificationCenter.default.removeObserver(
65
- self,
66
- name: UserDefaults.didChangeNotification,
67
- object: defaults
68
- )
69
- onChange = nil
70
- }
71
-
72
- deinit {
73
- stopObserving()
74
- }
75
-
76
- public override func observeValue(
77
- forKeyPath keyPath: String?,
78
- of object: Any?,
79
- change: [NSKeyValueChangeKey: Any]?,
80
- context: UnsafeMutableRawPointer?
81
- ) {
82
- guard context == &kvoContext else {
83
- super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
84
- return
85
- }
86
- emit()
87
- }
88
-
89
- @objc private func emit() {
90
- onChange?(currentLanguage)
91
- }
92
- }
93
- // AI-GENERATED END: observe the host app's active language so Localize can follow it
@@ -1,30 +0,0 @@
1
- // File: ios/Application/LocalizeModifier.swift
2
- // Created At: 2026-07-29 10:00:00 +07:00
3
- // Created By: AI
4
- // AI Agent: Claude Code
5
- // Model: claude-opus-5[1m]
6
-
7
- // AI-GENERATED START: inject a language-observing Localize into any SwiftUI subtree
8
- import SwiftUI
9
-
10
- public extension View {
11
- /// Injects an app-language-observing `Localize` and re-renders this subtree on change.
12
- /// Use at every `UIHostingController` root that is not inside a `NavigationContainer`.
13
- func momoLocalize(_ localize: Localize = .shared) -> some View {
14
- modifier(MomoLocalizeModifier(localize: localize))
15
- }
16
- }
17
-
18
- /// `@ObservedObject` is load-bearing: `@Environment(\.localize)` only invalidates when the boxed
19
- /// value changes, which requires *this* body to re-run on every publish. A plain helper that just
20
- /// set `\.localize` would inject a snapshot that never updates.
21
- private struct MomoLocalizeModifier: ViewModifier {
22
- @ObservedObject var localize: Localize
23
-
24
- func body(content: Content) -> some View {
25
- content
26
- .environmentObject(localize)
27
- .environment(\.localize, localize)
28
- }
29
- }
30
- // AI-GENERATED END: inject a language-observing Localize into any SwiftUI subtree