@momo-kits/native-kits 0.167.1-duo.11-debug → 0.167.1-duo.12-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/settings.local.json +185 -0
- package/CLAUDE.md +1 -1
- package/compose/build.gradle.kts +1 -1
- package/compose/compose.podspec +1 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/layout/ScreenLayout.kt +44 -16
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackScreen.kt +2 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderBackground.kt +17 -6
- package/gradle.properties +1 -1
- package/ios/Layout/ScreenLayout.swift +25 -10
- package/ios/Navigation/BottomSheet.swift +4 -8
- package/ios/Navigation/StackScreen.swift +22 -8
- package/ios/native-kits.podspec +1 -1
- package/ios-demo/MoMoUIKitsDemo.podspec +1 -1
- package/local.properties +8 -0
- package/package.json +1 -1
|
@@ -0,0 +1,185 @@
|
|
|
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
|
+
"Bash(cp android/gradle/libs.versions.toml /private/tmp/claude-503/-Users-sophia-Workspace-momo-momo-native-kits/bfb380ee-54cb-4a02-bc5f-d152cce4b727/scratchpad/libs.versions.toml.bak)",
|
|
157
|
+
"Bash(sed -i '' 's/kits = \"0.163.1-sp.8\"/kits = \"0.163.1-sp.7\"/' android/gradle/libs.versions.toml)",
|
|
158
|
+
"Bash(xcrun --sdk iphonesimulator --show-sdk-path)",
|
|
159
|
+
"Bash(chmod +x /private/tmp/claude-503/-Users-sophia-Workspace-momo-momo-native-kits/62b6dcd2-247f-4111-98ef-3847c8914676/scratchpad/tc.sh)",
|
|
160
|
+
"Bash(/private/tmp/claude-503/-Users-sophia-Workspace-momo-momo-native-kits/62b6dcd2-247f-4111-98ef-3847c8914676/scratchpad/tc.sh)",
|
|
161
|
+
"Bash(perl -0pi -e 's{^ static let \\(\\\\w+\\) = \\(appFont\\\\\\(size: [\\\\d.]+\\\\\\)\\(?:\\\\.weight\\\\\\(\\\\.\\\\w+\\\\\\)\\)?\\)\\(\\\\s*//.*\\)?$}{ static var $1: Font { $2 }$3}mg' ios/Typography/Typography.swift)",
|
|
162
|
+
"Bash(perl -0pi -e 's{\\(\\\\s*\\)// AI-GENERATED START: route Localize injection through the observing modifier\\\\n\\(\\\\s*\\)\\\\.momoLocalize\\\\\\(localize\\\\\\)\\\\n\\(\\\\s*\\)// AI-GENERATED END: route Localize injection through the observing modifier}{$1// AI-GENERATED START: route Localize + font-scale injection through the observing modifiers\\\\n$2.momoLocalize\\(localize\\)\\\\n$2.momoFontScale\\(\\)\\\\n$3// AI-GENERATED END: route Localize + font-scale injection through the observing modifiers}g' ios/Application/Navigation/NavigationContainer.swift)",
|
|
163
|
+
"Bash(perl -pi -e 's/Mirrors Compose.s `fontScale\\\\\\(\\\\.\\\\.\\\\.\\\\\\)`/Mirrors Compose'\"'\"'s `scaleSize\\(...\\)`/' ios/Chip/Chip.swift)",
|
|
164
|
+
"Bash(perl -pi -e 's/fontScale\\\\\\(\\(size == \\\\.small \\\\? 48 : 56\\), 1\\\\.1\\\\\\)/fontScale\\($1\\)/' ios/Input/Input.swift ios/Input/InputPhoneNumber.swift)",
|
|
165
|
+
"Bash(perl -pi -e 's/^\\(\\\\s*\\)\\\\.momoFontScale\\\\\\(\\\\\\)$/$1.momoFontScale\\(context: applicationEnvironment.applicationContext\\)/' ios/Application/Navigation/NavigationContainer.swift)",
|
|
166
|
+
"Bash(chmod +x /private/tmp/claude-503/-Users-sophia-Workspace-momo-momo-native-kits/62b6dcd2-247f-4111-98ef-3847c8914676/scratchpad/tcdemo.sh)",
|
|
167
|
+
"Bash(/private/tmp/claude-503/-Users-sophia-Workspace-momo-momo-native-kits/62b6dcd2-247f-4111-98ef-3847c8914676/scratchpad/tcdemo.sh)",
|
|
168
|
+
"Bash(\"/Users/sophia/Workspace/momo-glab/momo-agent-flows/momo-agent/scripts/repo.sh\" find *)",
|
|
169
|
+
"Read(//Users/sophia/.momo-agent/**)",
|
|
170
|
+
"Bash(xcodebuild -workspace iosApp.xcworkspace -scheme iosApp -configuration Debug -destination 'platform=iOS Simulator,name=iPhone 16 Pro' -derivedDataPath /private/tmp/claude-503/-Users-sophia-Workspace-momo-momo-native-kits/62b6dcd2-247f-4111-98ef-3847c8914676/scratchpad/dd build)",
|
|
171
|
+
"Bash(\"/Users/sophia/Workspace/momo-glab/momo-agent-flows/momo-agent/scripts/repo.sh\" prep *)",
|
|
172
|
+
"Bash(xcodebuild -workspace iosApp.xcworkspace -scheme iosApp -configuration Debug -destination id=1E6F9A79-5E64-4590-BEA2-828D75D99393 -derivedDataPath /private/tmp/claude-503/-Users-sophia-Workspace-momo-momo-native-kits/62b6dcd2-247f-4111-98ef-3847c8914676/scratchpad/dd build)",
|
|
173
|
+
"Bash(find /private/tmp/claude-503/-Users-sophia-Workspace-momo-momo-native-kits/62b6dcd2-247f-4111-98ef-3847c8914676/scratchpad/dd/Build/Products -maxdepth 2 -name *.app)",
|
|
174
|
+
"Bash(xcodebuild -workspace iosApp.xcworkspace -scheme iosApp -configuration Debug -sdk iphonesimulator -destination 'generic/platform=iOS Simulator' -derivedDataPath build/dd build)",
|
|
175
|
+
"Bash(xcodebuild -workspace iosApp.xcworkspace -scheme iosApp -configuration Debug -sdk iphonesimulator -destination 'generic/platform=iOS Simulator' -derivedDataPath build/dd ARCHS=arm64 ONLY_ACTIVE_ARCH=YES build)",
|
|
176
|
+
"Bash(./gradlew :compose:generateDummyFramework)",
|
|
177
|
+
"Bash(break)",
|
|
178
|
+
"Bash(\"/Users/sophia/Workspace/momo-glab/momo-agent-flows/momo-agent/scripts/gitlab.sh\" mr-view *)",
|
|
179
|
+
"Bash(\"/Users/sophia/Workspace/momo-glab/momo-agent-flows/momo-agent/scripts/gitlab.sh\" mr-discussions *)",
|
|
180
|
+
"Bash(command -v glab)",
|
|
181
|
+
"Bash(glab --version)",
|
|
182
|
+
"Bash(/Users/sophia/Workspace/momo-glab/momo-agent-flows/momo-agent/scripts/jira.sh transitions *)"
|
|
183
|
+
]
|
|
184
|
+
}
|
|
185
|
+
}
|
package/CLAUDE.md
CHANGED
|
@@ -68,7 +68,7 @@ Publishing is automated (`publish.sh` + GitLab CI on `[ci build]` / `main`). Do
|
|
|
68
68
|
|
|
69
69
|
- `layout/ScreenLayout.kt`: `getScreenLayout()` returns window size, raw top/bottom + side insets, `contentWidth`, header geometry, the iPhone Duo `sideBar` and `duoTopInset`. `NavigationContainer` computes it once and provides `LocalScreenLayout`; reactive to fold/unfold and rotation (window size + `WindowInsets`). Metrics (`DuoMetrics`, 72pt iPhone header floor, 20pt status-bar threshold) mirror RN `Layout/utils.ts` — change both together.
|
|
70
70
|
- iPhone-only: everything gates on `isPhoneIdiom()` (`platform/`), never on "iOS", so iPad windows keep the regular layout. Two detectors, as in RN: `isIPhoneDuo` (window aspect < 1.6 or asymmetric side insets) drives layout; `isIPhoneDuoDevice` (short side of screen or window > 440, RN `device.ts`) drives popups, modal and bottom sheet.
|
|
71
|
-
- Header height is `headerHeight` (not `AppStatusBar + HEADER_HEIGHT`); the bar row is `headerBarHeight` and starts `headerStatusBarHeight` below the window top. When the status bar is off the top edge (iPhone landscape, iPhone Duo) `headerStatusBarHeight` is 0 so the title stays centered — except on the Duo outer display in portrait
|
|
71
|
+
- Header height is `headerHeight` (not `AppStatusBar + HEADER_HEIGHT`); the bar row is `headerBarHeight` and starts `headerStatusBarHeight` below the window top. When the status bar is off the top edge (iPhone landscape, iPhone Duo) `headerStatusBarHeight` is 0 so the title stays centered — except on the Duo outer display: in portrait the header is 76pt and the row starts at 14pt so the title centers on the camera punchout; in landscape the row centers on the camera when it sits at the top end of the strip (else on the back button) and the header reaches 8pt below the back button.
|
|
72
72
|
- iPhone Duo with a side strip ≥ 60pt: back + toolkit leave the bar for `HeaderSideBar` (`navigation/component/SideBar.kt`, 48pt glass controls); custom header-right stays in the bar. `sideBar.top` is 170pt in portrait, 120pt on the inner display in landscape (height ≥ 600), 24pt on the outer display in landscape, or below the header when the status bar is on top; UIKit's `statusBarFrame` is useless on Duo. Unlike RN the column is clamped above footer (24pt gap) / rail (12pt gap).
|
|
73
73
|
- Reserved regions (iOS 27.1 `reservedRegionsOfKind:`, reached through the ObjC runtime so older SDKs still build): a probe `UIView` (`platform/ReservedRegions.ios.kt` on the Compose root view; `ReservedRegionsProbe` inside SwiftUI `momoScreenLayout()`) re-reads them in `layoutSubviews`, which UIKit re-runs when they change. They push `sideBar.top` below the status cluster as it grows for calls / Live Activities, and `sideBar.bottom` (≥ 24pt) above a camera at the bottom end of the strip.
|
|
74
74
|
- Tab bar on Duo is `bottomtab/DuoTabBar.kt`: a rail in the side strip (`sideBar.bottom` above the window bottom, QR below it) or, without a side bar, a floating bar spanning 6/8 grid columns. Both overlay the content; `duoFloatingTabBarInset` pads tab content, footer and FAB.
|
package/compose/build.gradle.kts
CHANGED
package/compose/compose.podspec
CHANGED
|
@@ -97,8 +97,10 @@ fun getScreenLayout(): ScreenLayout =
|
|
|
97
97
|
internal fun calculateScreenLayout(topInset: Dp, parent: ScreenLayout? = null): ScreenLayout {
|
|
98
98
|
val isPhone = isPhoneIdiom()
|
|
99
99
|
if (parent != null) {
|
|
100
|
+
// the parent's row center reproduces its own centered geometry
|
|
101
|
+
val titleCenterY = parent.headerStatusBarHeight + parent.headerBarHeight / 2
|
|
100
102
|
val (headerHeight, headerStatusBarHeight) =
|
|
101
|
-
headerGeometry(topInset, isPhone, parent.width, parent.height, parent.sideBar != null)
|
|
103
|
+
headerGeometry(topInset, isPhone, parent.width, parent.height, parent.sideBar != null, titleCenterY)
|
|
102
104
|
return parent.copy(headerHeight = headerHeight, headerStatusBarHeight = headerStatusBarHeight)
|
|
103
105
|
}
|
|
104
106
|
|
|
@@ -139,32 +141,53 @@ internal fun calculateScreenLayout(topInset: Dp, parent: ScreenLayout? = null):
|
|
|
139
141
|
internal fun ScreenLayout.consumeHorizontalInsets(): ScreenLayout =
|
|
140
142
|
copy(width = contentWidth, insetLeft = 0.dp, insetRight = 0.dp, sideBar = null)
|
|
141
143
|
|
|
142
|
-
|
|
144
|
+
// titleCenterY: window y the title row centers on for the outer display in landscape.
|
|
145
|
+
private fun headerGeometry(
|
|
146
|
+
topInset: Dp,
|
|
147
|
+
isPhone: Boolean,
|
|
148
|
+
width: Dp,
|
|
149
|
+
height: Dp,
|
|
150
|
+
hasSideBar: Boolean,
|
|
151
|
+
titleCenterY: Dp,
|
|
152
|
+
): Pair<Dp, Dp> {
|
|
143
153
|
val headerHeight = topInset + HEADER_HEIGHT.dp
|
|
144
154
|
if (!isPhone) return headerHeight to topInset
|
|
145
|
-
if (hasSideBar && topInset < STATUS_BAR_MIN_INSET
|
|
146
|
-
|
|
147
|
-
|
|
155
|
+
if (hasSideBar && topInset < STATUS_BAR_MIN_INSET) {
|
|
156
|
+
if (height > width && width < DuoMetrics.innerMinHeight) {
|
|
157
|
+
// outer display: the row starts below the top so the title centers on the camera
|
|
158
|
+
return DuoMetrics.outerHeaderHeight to DuoMetrics.outerCameraCenterY * 2 - DuoMetrics.outerHeaderHeight
|
|
159
|
+
}
|
|
160
|
+
if (width > height && height < DuoMetrics.innerMinHeight) {
|
|
161
|
+
// reaches 8pt below a side bar control centered on the row
|
|
162
|
+
val centered = maxOf(IPHONE_HEADER_MIN_HEIGHT, titleCenterY + DuoMetrics.controlSize / 2 + Spacing.S)
|
|
163
|
+
return centered to maxOf(0.dp, titleCenterY * 2 - centered)
|
|
164
|
+
}
|
|
148
165
|
}
|
|
149
166
|
return maxOf(headerHeight, IPHONE_HEADER_MIN_HEIGHT) to if (topInset < STATUS_BAR_MIN_INSET) 0.dp else topInset
|
|
150
167
|
}
|
|
151
168
|
|
|
152
|
-
private data class StripOcclusion(val top: Dp, val bottom: Dp)
|
|
169
|
+
private data class StripOcclusion(val top: Dp, val topCenter: Dp, val bottom: Dp)
|
|
153
170
|
|
|
154
171
|
// How far system regions reach into a side strip from its top and from its bottom end
|
|
155
|
-
// (e.g. the camera, which sits at either end depending on the rotation)
|
|
172
|
+
// (e.g. the camera, which sits at either end depending on the rotation), and the center y
|
|
173
|
+
// of the region reaching furthest from the top.
|
|
156
174
|
private fun stripOcclusion(regions: List<ReservedRegion>, stripLeft: Dp, stripRight: Dp, windowHeight: Dp): StripOcclusion {
|
|
157
175
|
var top = 0.dp
|
|
176
|
+
var topCenter = 0.dp
|
|
158
177
|
var bottom = 0.dp
|
|
159
178
|
regions.forEach { region ->
|
|
160
179
|
if (region.x >= stripRight || region.x + region.width <= stripLeft) return@forEach
|
|
161
|
-
|
|
162
|
-
|
|
180
|
+
val centerY = region.y + region.height / 2
|
|
181
|
+
if (centerY < windowHeight / 2) {
|
|
182
|
+
if (region.y + region.height > top) {
|
|
183
|
+
top = region.y + region.height
|
|
184
|
+
topCenter = centerY
|
|
185
|
+
}
|
|
163
186
|
} else {
|
|
164
187
|
bottom = maxOf(bottom, windowHeight - region.y)
|
|
165
188
|
}
|
|
166
189
|
}
|
|
167
|
-
return StripOcclusion(top, bottom)
|
|
190
|
+
return StripOcclusion(top, topCenter, bottom)
|
|
168
191
|
}
|
|
169
192
|
|
|
170
193
|
// Slab iPhones report equal side insets in landscape; iPhone Duo moves the status bar to one side.
|
|
@@ -189,9 +212,15 @@ private fun screenLayoutOf(
|
|
|
189
212
|
val isIPhoneDuo = isPhone && isIPhoneDuoWindow(width, height, asymmetricInsets)
|
|
190
213
|
|
|
191
214
|
var sideBar: SideBarLayout? = null
|
|
215
|
+
var titleCenterY = 0.dp
|
|
192
216
|
val sideInset = maxOf(insetLeft, insetRight)
|
|
193
217
|
// narrower strips cannot host a control 12pt from the inner edge
|
|
194
218
|
if (isIPhoneDuo && sideInset >= DuoMetrics.controlSize + Spacing.M) {
|
|
219
|
+
val edge = if (insetRight >= insetLeft) SideBarEdge.RIGHT else SideBarEdge.LEFT
|
|
220
|
+
val stripLeft = if (edge == SideBarEdge.RIGHT) width - sideInset else 0.dp
|
|
221
|
+
// clear of the camera and of the status bar cluster, which grows for calls and Live
|
|
222
|
+
// Activities; region frames already include the system's margin
|
|
223
|
+
val occlusion = stripOcclusion(reservedRegions, stripLeft, stripLeft + sideInset, height)
|
|
195
224
|
// UIKit reports no usable status bar frame here (a 2pt top strip), so the spot is inferred like RN
|
|
196
225
|
val top = when {
|
|
197
226
|
topInset >= STATUS_BAR_MIN_INSET -> topInset + HEADER_HEIGHT.dp + Spacing.M
|
|
@@ -200,11 +229,9 @@ private fun screenLayoutOf(
|
|
|
200
229
|
// outer display in landscape: no status bar in the strip
|
|
201
230
|
else -> DuoMetrics.edgeInset
|
|
202
231
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
// Activities; region frames already include the system's margin
|
|
207
|
-
val occlusion = stripOcclusion(reservedRegions, stripLeft, stripLeft + sideInset, height)
|
|
232
|
+
// outer display in landscape: the title row centers on the camera when it sits at the
|
|
233
|
+
// top end, otherwise on the back button
|
|
234
|
+
titleCenterY = if (occlusion.top > top) occlusion.topCenter else top + DuoMetrics.controlSize / 2
|
|
208
235
|
sideBar = SideBarLayout(
|
|
209
236
|
edge = edge,
|
|
210
237
|
width = sideInset,
|
|
@@ -212,7 +239,8 @@ private fun screenLayoutOf(
|
|
|
212
239
|
bottom = maxOf(DuoMetrics.edgeInset, occlusion.bottom),
|
|
213
240
|
)
|
|
214
241
|
}
|
|
215
|
-
val (headerHeight, headerStatusBarHeight) =
|
|
242
|
+
val (headerHeight, headerStatusBarHeight) =
|
|
243
|
+
headerGeometry(topInset, isPhone, width, height, sideBar != null, titleCenterY)
|
|
216
244
|
|
|
217
245
|
return ScreenLayout(
|
|
218
246
|
width = width,
|
|
@@ -431,9 +431,10 @@ fun Footer(
|
|
|
431
431
|
|
|
432
432
|
val backgroundColor = if (transparent) Color.Transparent else AppTheme.current.colors.background.surface
|
|
433
433
|
|
|
434
|
+
// inset as a whole, not padded inside, so the surface and its shadow stay off the iPhone Duo side bar
|
|
434
435
|
Box(Modifier.onGloballyPositioned {
|
|
435
436
|
if (footerHeightPx.intValue != it.size.height) footerHeightPx.intValue = it.size.height
|
|
436
|
-
}) {
|
|
437
|
+
}.horizontalSafeAreaPadding()) {
|
|
437
438
|
Box(
|
|
438
439
|
Modifier
|
|
439
440
|
.fillMaxWidth()
|
|
@@ -441,7 +442,6 @@ fun Footer(
|
|
|
441
442
|
.conditional(IsShowBaseLineDebug) {
|
|
442
443
|
border(1.dp, Colors.blue_03)
|
|
443
444
|
}
|
|
444
|
-
.horizontalSafeAreaPadding()
|
|
445
445
|
.padding(
|
|
446
446
|
top = if (useMargin) Spacing.S else 0.dp,
|
|
447
447
|
start = if (useMargin) Spacing.M else 0.dp,
|
|
@@ -22,6 +22,7 @@ import vn.momo.kits.layout.getScreenLayout
|
|
|
22
22
|
import vn.momo.kits.modifier.conditional
|
|
23
23
|
import vn.momo.kits.navigation.LocalOptions
|
|
24
24
|
import vn.momo.kits.navigation.LocalScrollState
|
|
25
|
+
import vn.momo.kits.navigation.getInputSearchType
|
|
25
26
|
import vn.momo.kits.navigation.usesDuoGlassHeader
|
|
26
27
|
|
|
27
28
|
enum class AnimatedHeaderRatio(val value: Float){
|
|
@@ -66,18 +67,28 @@ internal fun HeaderBackground() {
|
|
|
66
67
|
|
|
67
68
|
// iPhone Duo glass header: the gradient leaves with the content, as the quick return header does
|
|
68
69
|
val useDuoGlass = options.usesDuoGlassHeader(layout)
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
70
|
+
// RN HeaderExtendHeader with search on the side bar layout: the gradient fills the header box,
|
|
71
|
+
// which for extended shrinks from 52pt below the header over the first 100pt of scroll
|
|
72
|
+
val duoSearch = layout.sideBar != null && getInputSearchType(options) != InputSearchType.None
|
|
73
|
+
val fillsBox = useDuoGlass || duoSearch
|
|
74
|
+
val duoModifier = when {
|
|
75
|
+
useDuoGlass -> {
|
|
76
|
+
val extra = if (options.headerType is HeaderType.Extended) DUO_GRADIENT_EXTRA else 0.dp
|
|
77
|
+
Modifier.height(minHeight + extra).graphicsLayer { translationY = -scrollState.value.toFloat() }
|
|
78
|
+
}
|
|
79
|
+
duoSearch && options.headerType is HeaderType.Extended -> {
|
|
80
|
+
val progress = (with(density) { scrollState.value.toDp() } / 100.dp).coerceIn(0f, 1f)
|
|
81
|
+
Modifier.height(minHeight + DUO_GRADIENT_EXTRA * (1 - progress))
|
|
82
|
+
}
|
|
83
|
+
duoSearch -> Modifier.height(minHeight)
|
|
84
|
+
else -> Modifier.height(height)
|
|
74
85
|
}
|
|
75
86
|
|
|
76
87
|
Box(Modifier.fillMaxWidth().then(duoModifier).clipToBounds().background(backgroundColor)) {
|
|
77
88
|
// on Duo the fade spans the gradient box; a banner image keeps its 375:154 shape, clipped
|
|
78
89
|
Box(Modifier
|
|
79
90
|
.fillMaxWidth()
|
|
80
|
-
.then(if (
|
|
91
|
+
.then(if (fillsBox && !theme.isHeaderImage()) Modifier.fillMaxHeight() else Modifier.height(maxHeight))
|
|
81
92
|
.conditional(!theme.isHeaderImage()) {
|
|
82
93
|
background(Brush.verticalGradient(colors = listOf(color, backgroundColor)))
|
|
83
94
|
}
|
package/gradle.properties
CHANGED
|
@@ -110,6 +110,12 @@ extension ScreenLayout {
|
|
|
110
110
|
let sideInset = max(insets.leading, insets.trailing)
|
|
111
111
|
// narrower strips cannot host a control 12pt from the inner edge
|
|
112
112
|
if sideInset >= DuoMetrics.controlSize + Spacing.M {
|
|
113
|
+
let edge: SideBarEdge = insets.trailing >= insets.leading ? .right : .left
|
|
114
|
+
let stripLeft = edge == .right ? width - sideInset : 0
|
|
115
|
+
// clear of the camera and of the status bar cluster, which grows for calls and Live
|
|
116
|
+
// Activities; region frames already include the system's margin
|
|
117
|
+
let occlusion = stripOcclusion(reservedRegions, stripLeft: stripLeft, stripRight: stripLeft + sideInset, windowHeight: height)
|
|
118
|
+
|
|
113
119
|
var top = insets.top + HeaderMetrics.barHeight + Spacing.M
|
|
114
120
|
if insets.top < HeaderMetrics.statusBarMinInset {
|
|
115
121
|
// status bar lives in the strip: start under its cluster, as the native bar does
|
|
@@ -118,8 +124,11 @@ extension ScreenLayout {
|
|
|
118
124
|
} else if height >= DuoMetrics.innerMinHeight {
|
|
119
125
|
top = DuoMetrics.firstItemTopLandscape
|
|
120
126
|
} else {
|
|
121
|
-
// outer display in landscape: no status bar in the strip
|
|
127
|
+
// outer display in landscape: no status bar in the strip, the title row centers
|
|
128
|
+
// on the camera when it sits at the top end, otherwise on the back button
|
|
122
129
|
top = DuoMetrics.edgeInset
|
|
130
|
+
let titleCenterY = occlusion.top > top ? occlusion.topCenter : top + DuoMetrics.controlSize / 2
|
|
131
|
+
(headerHeight, headerStatusBarHeight) = centeredHeaderGeometry(centerY: titleCenterY)
|
|
123
132
|
}
|
|
124
133
|
|
|
125
134
|
if height > width && width < DuoMetrics.innerMinHeight {
|
|
@@ -129,11 +138,6 @@ extension ScreenLayout {
|
|
|
129
138
|
}
|
|
130
139
|
}
|
|
131
140
|
|
|
132
|
-
let edge: SideBarEdge = insets.trailing >= insets.leading ? .right : .left
|
|
133
|
-
let stripLeft = edge == .right ? width - sideInset : 0
|
|
134
|
-
// clear of the camera and of the status bar cluster, which grows for calls and Live
|
|
135
|
-
// Activities; region frames already include the system's margin
|
|
136
|
-
let occlusion = stripOcclusion(reservedRegions, stripLeft: stripLeft, stripRight: stripLeft + sideInset, windowHeight: height)
|
|
137
141
|
sideBar = SideBarLayout(
|
|
138
142
|
edge: edge,
|
|
139
143
|
width: sideInset,
|
|
@@ -159,18 +163,29 @@ extension ScreenLayout {
|
|
|
159
163
|
)
|
|
160
164
|
}
|
|
161
165
|
|
|
166
|
+
/// Bar row centered on a window y, at least iPhoneMinHeight tall and reaching 8pt below
|
|
167
|
+
/// a side bar control centered there.
|
|
168
|
+
private static func centeredHeaderGeometry(centerY: CGFloat) -> (CGFloat, CGFloat) {
|
|
169
|
+
let height = max(HeaderMetrics.iPhoneMinHeight, centerY + DuoMetrics.controlSize / 2 + Spacing.S)
|
|
170
|
+
return (height, max(0, centerY * 2 - height))
|
|
171
|
+
}
|
|
172
|
+
|
|
162
173
|
/// How far system regions reach into a side strip from its top and from its bottom end
|
|
163
|
-
/// (e.g. the camera, which sits at either end depending on the rotation)
|
|
174
|
+
/// (e.g. the camera, which sits at either end depending on the rotation), and the center y
|
|
175
|
+
/// of the region reaching furthest from the top.
|
|
164
176
|
private static func stripOcclusion(
|
|
165
177
|
_ regions: [CGRect],
|
|
166
178
|
stripLeft: CGFloat,
|
|
167
179
|
stripRight: CGFloat,
|
|
168
180
|
windowHeight: CGFloat
|
|
169
|
-
) -> (top: CGFloat, bottom: CGFloat) {
|
|
170
|
-
regions.reduce(into: (top: CGFloat(0), bottom: CGFloat(0))) { occlusion, region in
|
|
181
|
+
) -> (top: CGFloat, topCenter: CGFloat, bottom: CGFloat) {
|
|
182
|
+
regions.reduce(into: (top: CGFloat(0), topCenter: CGFloat(0), bottom: CGFloat(0))) { occlusion, region in
|
|
171
183
|
guard region.minX < stripRight && region.maxX > stripLeft else { return }
|
|
172
184
|
if region.midY < windowHeight / 2 {
|
|
173
|
-
|
|
185
|
+
if region.maxY > occlusion.top {
|
|
186
|
+
occlusion.top = region.maxY
|
|
187
|
+
occlusion.topCenter = region.midY
|
|
188
|
+
}
|
|
174
189
|
} else {
|
|
175
190
|
occlusion.bottom = max(occlusion.bottom, windowHeight - region.minY)
|
|
176
191
|
}
|
|
@@ -291,9 +291,8 @@ struct BottomSheetView<Content: View>: View {
|
|
|
291
291
|
}
|
|
292
292
|
}
|
|
293
293
|
|
|
294
|
-
/// Compose's `heightIn(max:)
|
|
295
|
-
///
|
|
296
|
-
/// when taller.
|
|
294
|
+
/// Compose's `heightIn(max:)`: caps the sheet but keeps it hugging its content, which
|
|
295
|
+
/// `.frame(maxHeight:)` would not — a flexible frame grows to the cap.
|
|
297
296
|
@available(iOS 16.0, *)
|
|
298
297
|
private struct CapHeight: ViewModifier {
|
|
299
298
|
let maxHeight: CGFloat
|
|
@@ -308,11 +307,8 @@ private struct CapHeightLayout: Layout {
|
|
|
308
307
|
let maxHeight: CGFloat
|
|
309
308
|
|
|
310
309
|
func sizeThatFits(proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) -> CGSize {
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
// ideal first: a scroll view would otherwise fill whatever height it is offered
|
|
314
|
-
let ideal = subview.sizeThatFits(ProposedViewSize(width: proposal.width, height: nil))
|
|
315
|
-
return subview.sizeThatFits(ProposedViewSize(width: proposal.width, height: min(ideal.height, cap)))
|
|
310
|
+
let height = min(proposal.height ?? .infinity, maxHeight)
|
|
311
|
+
return subviews.first?.sizeThatFits(ProposedViewSize(width: proposal.width, height: height)) ?? .zero
|
|
316
312
|
}
|
|
317
313
|
|
|
318
314
|
func placeSubviews(in bounds: CGRect, proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) {
|
|
@@ -431,13 +431,23 @@ public struct StackScreen<Content: View>: View {
|
|
|
431
431
|
// top-aligned: an extended band runs past the bar, under the content
|
|
432
432
|
.background(alignment: .top) {
|
|
433
433
|
ZStack(alignment: .top) {
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
434
|
+
if layout.sideBar != nil && inputSearchType != .none && !headerTransparent {
|
|
435
|
+
// RN HeaderExtendHeader with search on the side bar layout: the
|
|
436
|
+
// gradient fades out within the header box, as without the search
|
|
437
|
+
DuoScrollGradient(
|
|
438
|
+
scrollOffset: scrollOffset,
|
|
439
|
+
headerHeight: layout.headerHeight,
|
|
440
|
+
extended: headerType == .extended
|
|
441
|
+
)
|
|
442
|
+
} else {
|
|
443
|
+
NavigationHeaderBackground(
|
|
444
|
+
headerType: headerType,
|
|
445
|
+
scrollState: scrollOffset,
|
|
446
|
+
headerTransparent: headerTransparent,
|
|
447
|
+
fullScreenContent: fullScreenContent,
|
|
448
|
+
backgroundColor: backgroundColor
|
|
449
|
+
)
|
|
450
|
+
}
|
|
441
451
|
HeaderBarBackground(opacity: opacity, transparent: headerTransparent || headerType == .none)
|
|
442
452
|
}
|
|
443
453
|
.edgesIgnoringSafeArea([.top, .horizontal])
|
|
@@ -688,6 +698,7 @@ public struct NavigationFooter: View {
|
|
|
688
698
|
}
|
|
689
699
|
|
|
690
700
|
@Environment(\.appTheme) private var theme
|
|
701
|
+
@Environment(\.screenLayout) private var layout
|
|
691
702
|
|
|
692
703
|
/// Read from the window, not from an enclosing `GeometryProxy`: the proxy's bottom
|
|
693
704
|
/// inset grows to the keyboard height while the keyboard is up.
|
|
@@ -733,9 +744,10 @@ public struct NavigationFooter: View {
|
|
|
733
744
|
.padding(.bottom, Self.bottomPadding - (Spacing.S - margin))
|
|
734
745
|
// Compose paints the surface all the way to the bottom of the screen; the
|
|
735
746
|
// footer's own frame stops at the safe area, so only the fill bleeds down.
|
|
747
|
+
// With side insets (iPhone Duo) it stays inside them, off the side bar.
|
|
736
748
|
.background(
|
|
737
749
|
(transparent ? Color.clear : theme.colors.background.surface)
|
|
738
|
-
.ignoresSafeArea(.container, edges: [.bottom, .horizontal])
|
|
750
|
+
.ignoresSafeArea(.container, edges: hasSideInsets ? .bottom : [.bottom, .horizontal])
|
|
739
751
|
)
|
|
740
752
|
.overlay(alignment: .top) {
|
|
741
753
|
if !transparent { shadow }
|
|
@@ -744,6 +756,8 @@ public struct NavigationFooter: View {
|
|
|
744
756
|
}
|
|
745
757
|
}
|
|
746
758
|
|
|
759
|
+
private var hasSideInsets: Bool { layout.insetLeft > 0 || layout.insetRight > 0 }
|
|
760
|
+
|
|
747
761
|
/// Compose offsets the shadow box by -6dp, so it lands on the content above the
|
|
748
762
|
/// footer rather than on the footer surface itself.
|
|
749
763
|
private var shadow: some View {
|
package/ios/native-kits.podspec
CHANGED
package/local.properties
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
## This file must *NOT* be checked into Version Control Systems,
|
|
2
|
+
# as it contains information specific to your local configuration.
|
|
3
|
+
#
|
|
4
|
+
# Location of the SDK. This is only used by Gradle.
|
|
5
|
+
# For customization when using a Version Control System, please read the
|
|
6
|
+
# header note.
|
|
7
|
+
#Tue Jun 02 17:05:32 ICT 2026
|
|
8
|
+
sdk.dir=/Users/sophia/Library/Android/sdk
|