@momo-kits/native-kits 0.162.1-debug → 0.162.1-gif.1

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 (147) hide show
  1. package/ios/FPSMonitor/FPSMonitor.swift +562 -0
  2. package/package.json +1 -1
  3. package/publish.sh +2 -2
  4. package/build.gradle.kts +0 -11
  5. package/compose/build.gradle.kts +0 -186
  6. package/compose/build.gradle.kts.backup +0 -186
  7. package/compose/compose.podspec +0 -47
  8. package/compose/src/androidMain/kotlin/vn/momo/kits/navigation/ScrollToTop.android.kt +0 -6
  9. package/compose/src/androidMain/kotlin/vn/momo/kits/platform/Platform.android.kt +0 -123
  10. package/compose/src/commonMain/composeResources/font/momosignature.otf +0 -0
  11. package/compose/src/commonMain/composeResources/font/momotrustdisplay.otf +0 -0
  12. package/compose/src/commonMain/composeResources/font/sfprotext_black.otf +0 -0
  13. package/compose/src/commonMain/composeResources/font/sfprotext_black.ttf +0 -0
  14. package/compose/src/commonMain/composeResources/font/sfprotext_bold.ttf +0 -0
  15. package/compose/src/commonMain/composeResources/font/sfprotext_heavy.ttf +0 -0
  16. package/compose/src/commonMain/composeResources/font/sfprotext_light.ttf +0 -0
  17. package/compose/src/commonMain/composeResources/font/sfprotext_medium.ttf +0 -0
  18. package/compose/src/commonMain/composeResources/font/sfprotext_regular.ttf +0 -0
  19. package/compose/src/commonMain/composeResources/font/sfprotext_semibold.ttf +0 -0
  20. package/compose/src/commonMain/composeResources/font/sfprotext_thin.otf +0 -0
  21. package/compose/src/commonMain/composeResources/font/sfprotext_thin.ttf +0 -0
  22. package/compose/src/commonMain/composeResources/font/sfprotext_ultralight.otf +0 -0
  23. package/compose/src/commonMain/composeResources/font/sfprotext_ultralight.ttf +0 -0
  24. package/compose/src/commonMain/kotlin/vn/momo/kits/application/AnimationSearchInput.kt +0 -57
  25. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Context.kt +0 -109
  26. package/compose/src/commonMain/kotlin/vn/momo/kits/application/FloatingButton.kt +0 -201
  27. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Header.kt +0 -222
  28. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderAnimated.kt +0 -48
  29. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderBackground.kt +0 -86
  30. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderDefault.kt +0 -76
  31. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderExtended.kt +0 -76
  32. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderRight.kt +0 -305
  33. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderTitle.kt +0 -33
  34. package/compose/src/commonMain/kotlin/vn/momo/kits/application/LiteScreen.kt +0 -921
  35. package/compose/src/commonMain/kotlin/vn/momo/kits/application/NavigationContainer.kt +0 -121
  36. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Screen.kt +0 -403
  37. package/compose/src/commonMain/kotlin/vn/momo/kits/application/useHeaderSearchAnimation.kt +0 -69
  38. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Avatar.kt +0 -157
  39. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Badge.kt +0 -85
  40. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeDot.kt +0 -32
  41. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeRibbon.kt +0 -340
  42. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BaselineView.kt +0 -198
  43. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Button.kt +0 -357
  44. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Carousel.kt +0 -123
  45. package/compose/src/commonMain/kotlin/vn/momo/kits/components/CheckBox.kt +0 -94
  46. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Chip.kt +0 -136
  47. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Collapse.kt +0 -224
  48. package/compose/src/commonMain/kotlin/vn/momo/kits/components/CupertinoOverscroll.kt +0 -543
  49. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Divider.kt +0 -23
  50. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Icon.kt +0 -76
  51. package/compose/src/commonMain/kotlin/vn/momo/kits/components/IconButton.kt +0 -148
  52. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Image.kt +0 -188
  53. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Information.kt +0 -116
  54. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Input.kt +0 -452
  55. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputDropDown.kt +0 -172
  56. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputMoney.kt +0 -255
  57. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputOTP.kt +0 -235
  58. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputPhoneNumber.kt +0 -233
  59. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputSearch.kt +0 -259
  60. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputTextArea.kt +0 -241
  61. package/compose/src/commonMain/kotlin/vn/momo/kits/components/LazyColumnWithBouncing.kt +0 -364
  62. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Loader.kt +0 -108
  63. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationDot.kt +0 -56
  64. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationNumber.kt +0 -41
  65. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationScroll.kt +0 -92
  66. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationWhiteDot.kt +0 -40
  67. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupNotify.kt +0 -352
  68. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupPromotion.kt +0 -103
  69. package/compose/src/commonMain/kotlin/vn/momo/kits/components/ProgressInfo.kt +0 -338
  70. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Radio.kt +0 -70
  71. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Rating.kt +0 -87
  72. package/compose/src/commonMain/kotlin/vn/momo/kits/components/ScaleSizeScope.kt +0 -17
  73. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Skeleton.kt +0 -96
  74. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Slider.kt +0 -348
  75. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Stepper.kt +0 -256
  76. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Steps.kt +0 -494
  77. package/compose/src/commonMain/kotlin/vn/momo/kits/components/SuggestAction.kt +0 -131
  78. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Swipe.kt +0 -215
  79. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Switch.kt +0 -96
  80. package/compose/src/commonMain/kotlin/vn/momo/kits/components/TabView.kt +0 -531
  81. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tag.kt +0 -92
  82. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Text.kt +0 -135
  83. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Title.kt +0 -214
  84. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tooltip.kt +0 -590
  85. package/compose/src/commonMain/kotlin/vn/momo/kits/components/TrustBanner.kt +0 -177
  86. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Uploader.kt +0 -192
  87. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePicker.kt +0 -205
  88. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerTypes.kt +0 -29
  89. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerUtils.kt +0 -239
  90. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/WheelPicker.kt +0 -191
  91. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Colors.kt +0 -306
  92. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Radius.kt +0 -12
  93. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Spacing.kt +0 -16
  94. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Theme.kt +0 -188
  95. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Typography.kt +0 -285
  96. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Card.kt +0 -2
  97. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Item.kt +0 -35
  98. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Section.kt +0 -2
  99. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/AutomationId.kt +0 -57
  100. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Clickable.kt +0 -68
  101. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Conditional.kt +0 -11
  102. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/DeprecatedModifier.kt +0 -14
  103. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Shadow.kt +0 -50
  104. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Size.kt +0 -51
  105. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/BottomSheet.kt +0 -253
  106. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ModalScreen.kt +0 -133
  107. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigation.kt +0 -100
  108. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/NavigationContainer.kt +0 -145
  109. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigator.kt +0 -345
  110. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ScrollToTop.kt +0 -8
  111. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackScreen.kt +0 -556
  112. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTab.kt +0 -161
  113. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTabBar.kt +0 -243
  114. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/CurvedContainer.kt +0 -86
  115. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/FloatingButton.kt +0 -187
  116. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/Header.kt +0 -279
  117. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderBackground.kt +0 -80
  118. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderRight.kt +0 -306
  119. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderTitle.kt +0 -32
  120. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderUser.kt +0 -370
  121. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/SnackBar.kt +0 -131
  122. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/tracking/ScreenTracker.kt +0 -167
  123. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/ComposeLottieAnimation.kt +0 -72
  124. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/Platform.kt +0 -66
  125. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Icons.kt +0 -1329
  126. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Resources.kt +0 -70
  127. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Tracking.kt +0 -15
  128. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Utils.kt +0 -105
  129. package/compose/src/iosMain/kotlin/vn/momo/kits/navigation/ScrollToTop.ios.kt +0 -33
  130. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/Platform.ios.kt +0 -186
  131. package/example/ios/Example.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/xcschememanagement.plist +0 -14
  132. package/example/ios/Example.xcworkspace/xcuserdata/huynhdung.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  133. package/example/ios/Example.xcworkspace/xcuserdata/huynhdung.xcuserdatad/xcschemes/xcschememanagement.plist +0 -5
  134. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/MoMoUIKits.xcscheme +0 -58
  135. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/Pods-Example.xcscheme +0 -58
  136. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/SDWebImage.xcscheme +0 -58
  137. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/SDWebImageSwiftUI.xcscheme +0 -58
  138. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/SkeletonUI.xcscheme +0 -58
  139. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/xcschememanagement.plist +0 -46
  140. package/gradle/libs.versions.toml +0 -67
  141. package/gradle/wrapper/gradle-wrapper.jar +0 -0
  142. package/gradle/wrapper/gradle-wrapper.properties +0 -8
  143. package/gradle.properties +0 -26
  144. package/gradlew +0 -252
  145. package/gradlew.bat +0 -94
  146. package/local.properties +0 -8
  147. package/settings.gradle.kts +0 -64
@@ -0,0 +1,562 @@
1
+ import UIKit
2
+ import QuartzCore
3
+ import Darwin
4
+
5
+ @objc(FPSMonitor)
6
+ public final class FPSMonitor: NSObject {
7
+ public static let shared = FPSMonitor()
8
+
9
+ public var onFPSLow: ((CGFloat) -> Void)?
10
+ public var onRamOverload: ((CGFloat) -> Void)?
11
+
12
+ @objc public private(set) var latestFPS: CGFloat = 0
13
+ @objc public private(set) var latestCPUPercent: CGFloat = 0
14
+ @objc public private(set) var latestGPUms: CGFloat = 0
15
+ @objc public private(set) var latestMemoryMB: CGFloat = 0
16
+
17
+ @objc public var ramThreshold: CGFloat
18
+ @objc public var fpsThreshold: CGFloat = 30
19
+ @objc public var updateInterval: TimeInterval = 0.2
20
+
21
+ private var overlayWindow: FPSOverlayWindow?
22
+ private var graphView: FPSGraphView?
23
+ private var displayLink: CADisplayLink?
24
+ private var lastTimestamp: CFTimeInterval = 0
25
+ private var frameCount = 0
26
+ private var lastFPSAlertTime: CFTimeInterval = 0
27
+ private var uiVisible = false
28
+
29
+ private override init() {
30
+ #if targetEnvironment(simulator)
31
+ ramThreshold = 1500
32
+ #else
33
+ ramThreshold = 500
34
+ #endif
35
+ super.init()
36
+
37
+ NotificationCenter.default.addObserver(
38
+ self,
39
+ selector: #selector(appDidBecomeActive),
40
+ name: UIApplication.didBecomeActiveNotification,
41
+ object: nil
42
+ )
43
+ NotificationCenter.default.addObserver(
44
+ self,
45
+ selector: #selector(appWillResignActive),
46
+ name: UIApplication.willResignActiveNotification,
47
+ object: nil
48
+ )
49
+ }
50
+
51
+ @objc(shared)
52
+ public class func sharedObjC() -> FPSMonitor {
53
+ shared
54
+ }
55
+
56
+ deinit {
57
+ NotificationCenter.default.removeObserver(self)
58
+ }
59
+
60
+ @objc public func startOverlay() {
61
+ runOnMain {
62
+ guard self.displayLink == nil else { return }
63
+ self.lastTimestamp = 0
64
+ self.frameCount = 0
65
+ self.uiVisible = false
66
+
67
+ let link = CADisplayLink(target: self, selector: #selector(self.tick(_:)))
68
+ link.add(to: .main, forMode: .common)
69
+ link.isPaused = false
70
+ self.displayLink = link
71
+ }
72
+ }
73
+
74
+ @objc public func stop() {
75
+ runOnMain {
76
+ self.displayLink?.invalidate()
77
+ self.displayLink = nil
78
+
79
+ self.graphView?.removeFromSuperview()
80
+ self.graphView?.isHidden = true
81
+ self.graphView = nil
82
+
83
+ self.overlayWindow?.isHidden = true
84
+ self.overlayWindow?.rootViewController = nil
85
+ self.overlayWindow = nil
86
+
87
+ self.lastTimestamp = 0
88
+ self.frameCount = 0
89
+ self.uiVisible = false
90
+ }
91
+ }
92
+
93
+ @objc public func showUI() {
94
+ runOnMain {
95
+ if self.overlayWindow == nil {
96
+ let window = FPSOverlayWindow(frame: UIScreen.main.bounds)
97
+ window.windowLevel = .statusBar + 99
98
+ window.backgroundColor = .clear
99
+ let windowScenes = UIApplication.shared.connectedScenes.compactMap { $0 as? UIWindowScene }
100
+ window.windowScene = windowScenes.first { $0.activationState == .foregroundActive } ?? windowScenes.first
101
+
102
+ let rootViewController = UIViewController()
103
+ rootViewController.view.backgroundColor = .clear
104
+ window.rootViewController = rootViewController
105
+
106
+ let graphView = self.graphView ?? FPSGraphView()
107
+ graphView.backgroundColor = .clear
108
+ window.draggableView = graphView
109
+ rootViewController.view.addSubview(graphView)
110
+
111
+ self.graphView = graphView
112
+ self.overlayWindow = window
113
+ }
114
+
115
+ if self.graphView == nil {
116
+ self.graphView = FPSGraphView(frame: CGRect(x: 10, y: 50, width: 150, height: 80))
117
+ self.overlayWindow?.draggableView = self.graphView
118
+ self.overlayWindow?.rootViewController?.view.addSubview(self.graphView!)
119
+ }
120
+
121
+ self.graphView?.frame = CGRect(x: 10, y: 50, width: 150, height: 80)
122
+ self.graphView?.isHidden = false
123
+ self.overlayWindow?.isHidden = false
124
+ self.uiVisible = true
125
+ }
126
+ }
127
+
128
+ @objc public func hideUI() {
129
+ runOnMain {
130
+ self.graphView?.isHidden = true
131
+ self.graphView?.frame = .zero
132
+ self.overlayWindow?.isHidden = true
133
+ self.uiVisible = false
134
+ }
135
+ }
136
+
137
+ @objc public func metricsSnapshot() -> [String: String] {
138
+ [
139
+ "fps": String(format: "%.2f", latestFPS),
140
+ "usedCPU": String(format: "%.2f", latestCPUPercent),
141
+ "usedGPU": String(format: "%.2f", latestGPUms),
142
+ "usedMemoryMB": String(format: "%.0f", latestMemoryMB),
143
+ ]
144
+ }
145
+
146
+ @objc private func appDidBecomeActive() {
147
+ displayLink?.isPaused = false
148
+ }
149
+
150
+ @objc private func appWillResignActive() {
151
+ displayLink?.isPaused = true
152
+ }
153
+
154
+ @objc private func tick(_ link: CADisplayLink) {
155
+ if lastTimestamp == 0 {
156
+ lastTimestamp = link.timestamp
157
+ return
158
+ }
159
+
160
+ frameCount += 1
161
+ let delta = link.timestamp - lastTimestamp
162
+ guard delta >= updateInterval else { return }
163
+
164
+ let fps = frameCount > 0 && delta > 0 ? CGFloat(Double(frameCount) / delta) : 0
165
+ let frameTime = frameCount > 0 ? delta / Double(frameCount) : 0
166
+ let baseGpuRatio: CGFloat = 0.4
167
+ let fpsVariation = (60 - min(fps, 60)) / 60
168
+ let gpuRatio = baseGpuRatio + fpsVariation * 0.3
169
+ let gpuTimePerFrameMs = CGFloat(frameTime) * gpuRatio * 1000
170
+
171
+ let cpuPercent = currentCPUPercent()
172
+ let memoryMB = currentMemoryMB()
173
+
174
+ if let onRamOverload, memoryMB > ramThreshold {
175
+ ramThreshold += 100
176
+ onRamOverload(memoryMB)
177
+ }
178
+
179
+ latestFPS = fps
180
+ latestCPUPercent = cpuPercent
181
+ latestGPUms = gpuTimePerFrameMs
182
+ latestMemoryMB = memoryMB
183
+
184
+ let now = CFAbsoluteTimeGetCurrent()
185
+ if let onFPSLow, fps < fpsThreshold, now - lastFPSAlertTime >= 0.2 {
186
+ onFPSLow(fps)
187
+ lastFPSAlertTime = now
188
+ }
189
+
190
+ if uiVisible, let graphView {
191
+ let bounds = UIScreen.main.bounds.size
192
+ let scale = UIScreen.main.scale
193
+ let resolution = CGSize(width: bounds.width * scale, height: bounds.height * scale)
194
+ let frameTimeMs = fps > 0 ? 1000 / fps : 0
195
+ let cpuTimeMs = frameTimeMs * min(max(cpuPercent, 0), 100) / 100
196
+
197
+ graphView.update(
198
+ resolution: resolution,
199
+ cpuTime: cpuTimeMs,
200
+ gpuTime: gpuTimePerFrameMs,
201
+ memory: memoryMB
202
+ )
203
+ graphView.addFPS(fps)
204
+ graphView.addCPUTime(cpuTimeMs)
205
+ graphView.addGPUTime(gpuTimePerFrameMs)
206
+ }
207
+
208
+ lastTimestamp = link.timestamp
209
+ frameCount = 0
210
+ }
211
+
212
+ private func currentMemoryMB() -> CGFloat {
213
+ var info = task_vm_info_data_t()
214
+ var count = mach_msg_type_number_t(MemoryLayout<task_vm_info_data_t>.size / MemoryLayout<natural_t>.size)
215
+
216
+ let result = withUnsafeMutablePointer(to: &info) {
217
+ $0.withMemoryRebound(to: integer_t.self, capacity: Int(count)) {
218
+ task_info(mach_task_self_, task_flavor_t(TASK_VM_INFO), $0, &count)
219
+ }
220
+ }
221
+
222
+ guard result == KERN_SUCCESS else { return 0 }
223
+ return CGFloat(info.phys_footprint) / (1024 * 1024)
224
+ }
225
+
226
+ private func currentCPUPercent() -> CGFloat {
227
+ var threadList: thread_act_array_t?
228
+ var threadCount = mach_msg_type_number_t()
229
+
230
+ guard task_threads(mach_task_self_, &threadList, &threadCount) == KERN_SUCCESS,
231
+ let threads = threadList else {
232
+ return 0
233
+ }
234
+
235
+ defer {
236
+ let byteCount = vm_size_t(Int(threadCount) * MemoryLayout<thread_t>.stride)
237
+ vm_deallocate(mach_task_self_, vm_address_t(UInt(bitPattern: threads)), byteCount)
238
+ }
239
+
240
+ var cpuUsage: Float = 0
241
+ for index in 0..<Int(threadCount) {
242
+ var info = thread_basic_info()
243
+ var infoCount = mach_msg_type_number_t(THREAD_INFO_MAX)
244
+ let result = withUnsafeMutablePointer(to: &info) {
245
+ $0.withMemoryRebound(to: integer_t.self, capacity: Int(infoCount)) {
246
+ thread_info(threads[index], thread_flavor_t(THREAD_BASIC_INFO), $0, &infoCount)
247
+ }
248
+ }
249
+
250
+ if result == KERN_SUCCESS, (info.flags & TH_FLAGS_IDLE) == 0 {
251
+ cpuUsage += Float(info.cpu_usage) / Float(TH_USAGE_SCALE) * 100
252
+ }
253
+ }
254
+
255
+ let cores = max(ProcessInfo.processInfo.activeProcessorCount, 1)
256
+ return CGFloat(cpuUsage / Float(cores))
257
+ }
258
+
259
+ private func runOnMain(_ block: @escaping () -> Void) {
260
+ if Thread.isMainThread {
261
+ block()
262
+ } else {
263
+ DispatchQueue.main.async(execute: block)
264
+ }
265
+ }
266
+ }
267
+
268
+ private final class FPSOverlayWindow: UIWindow {
269
+ weak var draggableView: UIView?
270
+
271
+ override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
272
+ guard let draggableView else { return nil }
273
+ let pointInDragView = draggableView.convert(point, from: self)
274
+ guard draggableView.point(inside: pointInDragView, with: event) else { return nil }
275
+ return super.hitTest(point, with: event)
276
+ }
277
+ }
278
+
279
+ private final class FPSGraphView: UIView {
280
+ private var fpsValues: [CGFloat] = []
281
+ private var cpuTimeValues: [CGFloat] = []
282
+ private var gpuTimeValues: [CGFloat] = []
283
+ private let maxPoints = 100
284
+ private let pointSpacing: CGFloat = 2
285
+
286
+ private var currentResolution: CGSize = .zero
287
+ private var currentCPUTime: CGFloat = 0
288
+ private var currentGPUTime: CGFloat = 0
289
+ private var currentMemory: CGFloat = 0
290
+
291
+ private var isCollapsed = false
292
+ private var fullFrame: CGRect = .zero
293
+
294
+ override init(frame: CGRect = CGRect(x: 0, y: 100, width: 150, height: 80)) {
295
+ super.init(frame: frame)
296
+ isOpaque = false
297
+ layer.cornerRadius = 8
298
+ clipsToBounds = true
299
+ fullFrame = frame
300
+ addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(handlePan(_:))))
301
+ addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(toggleCollapse)))
302
+ }
303
+
304
+ required init?(coder: NSCoder) {
305
+ super.init(coder: coder)
306
+ }
307
+
308
+ func addFPS(_ fps: CGFloat) {
309
+ append(fps, to: &fpsValues)
310
+ setNeedsDisplay()
311
+ }
312
+
313
+ func addCPUTime(_ cpuTime: CGFloat) {
314
+ append(cpuTime, to: &cpuTimeValues)
315
+ setNeedsDisplay()
316
+ }
317
+
318
+ func addGPUTime(_ gpuTime: CGFloat) {
319
+ append(gpuTime, to: &gpuTimeValues)
320
+ setNeedsDisplay()
321
+ }
322
+
323
+ func update(resolution: CGSize, cpuTime: CGFloat, gpuTime: CGFloat, memory: CGFloat) {
324
+ currentResolution = resolution
325
+ currentCPUTime = cpuTime
326
+ currentGPUTime = gpuTime
327
+ currentMemory = memory
328
+ updateFrameIfNeeded()
329
+ setNeedsDisplay()
330
+ }
331
+
332
+ @objc private func toggleCollapse() {
333
+ if isCollapsed {
334
+ UIView.animate(withDuration: 0.25, animations: {
335
+ self.frame = self.fullFrame
336
+ }, completion: { _ in
337
+ self.isCollapsed = false
338
+ self.setNeedsDisplay()
339
+ })
340
+ } else {
341
+ fullFrame = frame
342
+ isCollapsed = true
343
+ UIView.animate(withDuration: 0.25, animations: {
344
+ self.frame.size = CGSize(width: 44, height: 24)
345
+ }, completion: { _ in
346
+ self.setNeedsDisplay()
347
+ })
348
+ }
349
+ }
350
+
351
+ @objc private func handlePan(_ gesture: UIPanGestureRecognizer) {
352
+ guard let superview else { return }
353
+ let translation = gesture.translation(in: superview)
354
+ var newCenter = CGPoint(x: center.x + translation.x, y: center.y + translation.y)
355
+ let halfWidth = bounds.width / 2
356
+ let halfHeight = bounds.height / 2
357
+ let screen = UIScreen.main.bounds.size
358
+ newCenter.x = max(halfWidth, min(newCenter.x, screen.width - halfWidth))
359
+ newCenter.y = max(halfHeight, min(newCenter.y, screen.height - halfHeight))
360
+ center = newCenter
361
+ gesture.setTranslation(.zero, in: superview)
362
+ }
363
+
364
+ override func draw(_ rect: CGRect) {
365
+ if isCollapsed {
366
+ drawCollapsed(rect)
367
+ return
368
+ }
369
+ drawExpanded(rect)
370
+ }
371
+
372
+ private func drawCollapsed(_ rect: CGRect) {
373
+ guard let context = UIGraphicsGetCurrentContext() else { return }
374
+ context.clear(rect)
375
+ context.setFillColor(UIColor(white: 0, alpha: 0.6).cgColor)
376
+ context.fill(rect)
377
+
378
+ let text = String(format: "%.0f", fpsValues.last ?? 0)
379
+ let attributes: [NSAttributedString.Key: Any] = [
380
+ .font: UIFont.monospacedDigitSystemFont(ofSize: 12, weight: .medium),
381
+ .foregroundColor: UIColor.white,
382
+ ]
383
+ let size = text.size(withAttributes: attributes)
384
+ text.draw(
385
+ at: CGPoint(x: (rect.width - size.width) / 2, y: (rect.height - size.height) / 2),
386
+ withAttributes: attributes
387
+ )
388
+ }
389
+
390
+ private func drawExpanded(_ rect: CGRect) {
391
+ guard let context = UIGraphicsGetCurrentContext() else { return }
392
+ context.clear(rect)
393
+ context.setFillColor(UIColor(white: 0, alpha: 0.6).cgColor)
394
+ context.fill(rect)
395
+
396
+ let margin: CGFloat = 8
397
+ let labelAttrs = attributes(color: .white)
398
+ let fpsColor = UIColor(red: 0, green: 1, blue: 0, alpha: 1)
399
+ let cpuColor = UIColor(red: 1, green: 0.65, blue: 0, alpha: 1)
400
+ let gpuColor = UIColor(red: 0, green: 0.75, blue: 1, alpha: 1)
401
+ let memColor = UIColor(red: 1, green: 0.41, blue: 0.71, alpha: 1)
402
+
403
+ var y = margin
404
+ let deviceName = UIDevice.current.name
405
+ let resolution = String(format: "[%.0fx%.0f]", currentResolution.width, currentResolution.height)
406
+ drawSplit(left: deviceName, right: resolution, y: y, color: .white, rect: rect)
407
+ y += textHeight(labelAttrs) + 2
408
+
409
+ let scale = String(format: "%.1fx", UIScreen.main.scale)
410
+ let refreshRate = "\(UIScreen.main.maximumFramesPerSecond)Hz"
411
+ drawSplit(left: scale, right: refreshRate, y: y, color: .white, rect: rect)
412
+ y += textHeight(labelAttrs) + 6
413
+
414
+ let cpuMinMax = minMax(cpuTimeValues, fallback: currentCPUTime)
415
+ let gpuMinMax = minMax(gpuTimeValues, fallback: currentGPUTime)
416
+ let fpsMinMax = minMax(fpsValues, fallback: fpsValues.last ?? 0)
417
+
418
+ drawSplit(
419
+ left: String(format: "Pre: %.2fms", currentCPUTime),
420
+ right: String(format: "[%.2f %.2f]", cpuMinMax.min, cpuMinMax.max),
421
+ y: y,
422
+ color: cpuColor,
423
+ rect: rect
424
+ )
425
+ y += textHeight(labelAttrs) + 2
426
+
427
+ drawSplit(
428
+ left: String(format: "GPU: %.2fms", currentGPUTime),
429
+ right: String(format: "[%.2f %.2f]", gpuMinMax.min, gpuMinMax.max),
430
+ y: y,
431
+ color: gpuColor,
432
+ rect: rect
433
+ )
434
+ y += textHeight(labelAttrs) + 2
435
+
436
+ drawText(String(format: "Mem: %.1fMB", currentMemory), at: CGPoint(x: margin, y: y), color: memColor)
437
+ y += textHeight(labelAttrs) + 2
438
+
439
+ drawSplit(
440
+ left: String(format: "FPS: %.2f", fpsValues.last ?? 0),
441
+ right: String(format: "[%.2f %.2f]", fpsMinMax.min, fpsMinMax.max),
442
+ y: y,
443
+ color: fpsColor,
444
+ rect: rect
445
+ )
446
+ y += textHeight(labelAttrs) + 6
447
+
448
+ let graphTop = y
449
+ let graphHeight = rect.height - graphTop - margin
450
+ guard graphHeight > 12 else { return }
451
+
452
+ drawGrid(context: context, x: margin, y: graphTop, width: rect.width - margin * 2, height: graphHeight)
453
+ drawLine(context: context, values: fpsValues, x: margin + 2, y: graphTop, width: rect.width - margin * 2 - 4, height: graphHeight, maxScale: 60, color: fpsColor)
454
+ drawLine(context: context, values: cpuTimeValues, x: margin + 2, y: graphTop, width: rect.width - margin * 2 - 4, height: graphHeight, maxScale: 50, color: cpuColor)
455
+ }
456
+
457
+ private func updateFrameIfNeeded() {
458
+ guard !isCollapsed else { return }
459
+ let attrs = attributes(color: .white)
460
+ let lines = [
461
+ "\(UIDevice.current.name) [\(Int(currentResolution.width))x\(Int(currentResolution.height))]",
462
+ String(format: "%.1fx %dHz", UIScreen.main.scale, UIScreen.main.maximumFramesPerSecond),
463
+ "Pre: 99.99ms [99.99 99.99]",
464
+ "GPU: 99.99ms [99.99 99.99]",
465
+ "Mem: 999.9MB",
466
+ "FPS: 99.99 [99.99 99.99]",
467
+ ]
468
+ let width = lines.map { $0.size(withAttributes: attrs).width }.max() ?? 150
469
+ let finalWidth = max(150, width + 16)
470
+ let finalHeight = max(80, textHeight(attrs) * CGFloat(lines.count) + 26)
471
+
472
+ if abs(frame.width - finalWidth) > 1 || abs(frame.height - finalHeight) > 1 {
473
+ frame.size = CGSize(width: finalWidth, height: finalHeight)
474
+ fullFrame = frame
475
+ }
476
+ }
477
+
478
+ private func append(_ value: CGFloat, to values: inout [CGFloat]) {
479
+ if values.count >= maxPoints {
480
+ values.removeFirst()
481
+ }
482
+ values.append(value)
483
+ }
484
+
485
+ private func drawSplit(left: String, right: String, y: CGFloat, color: UIColor, rect: CGRect) {
486
+ let margin: CGFloat = 8
487
+ let rightSize = right.size(withAttributes: attributes(color: color))
488
+ drawText(left, at: CGPoint(x: margin, y: y), color: color)
489
+ drawText(right, at: CGPoint(x: rect.width - margin - rightSize.width, y: y), color: color)
490
+ }
491
+
492
+ private func drawText(_ text: String, at point: CGPoint, color: UIColor) {
493
+ text.draw(at: point, withAttributes: attributes(color: color))
494
+ }
495
+
496
+ private func drawGrid(context: CGContext, x: CGFloat, y: CGFloat, width: CGFloat, height: CGFloat) {
497
+ context.setStrokeColor(UIColor(white: 1, alpha: 0.1).cgColor)
498
+ context.setLineWidth(0.5)
499
+ for index in 1...3 {
500
+ let gridY = y + CGFloat(index) * (height / 4)
501
+ context.move(to: CGPoint(x: x, y: gridY))
502
+ context.addLine(to: CGPoint(x: x + width, y: gridY))
503
+ }
504
+ var gridX = x + 20
505
+ while gridX < x + width {
506
+ context.move(to: CGPoint(x: gridX, y: y))
507
+ context.addLine(to: CGPoint(x: gridX, y: y + height))
508
+ gridX += 20
509
+ }
510
+ context.strokePath()
511
+ }
512
+
513
+ private func drawLine(
514
+ context: CGContext,
515
+ values: [CGFloat],
516
+ x: CGFloat,
517
+ y: CGFloat,
518
+ width: CGFloat,
519
+ height: CGFloat,
520
+ maxScale: CGFloat,
521
+ color: UIColor
522
+ ) {
523
+ guard values.count > 1 else { return }
524
+ context.setStrokeColor(color.cgColor)
525
+ context.setLineWidth(1)
526
+
527
+ let visibleValues = Array(values.suffix(Int(width / pointSpacing)))
528
+ for index in 1..<visibleValues.count {
529
+ let previous = point(for: visibleValues[index - 1], index: index - 1, x: x, y: y, height: height, maxScale: maxScale)
530
+ let current = point(for: visibleValues[index], index: index, x: x, y: y, height: height, maxScale: maxScale)
531
+ context.move(to: previous)
532
+ context.addLine(to: current)
533
+ context.strokePath()
534
+ }
535
+ }
536
+
537
+ private func point(for value: CGFloat, index: Int, x: CGFloat, y: CGFloat, height: CGFloat, maxScale: CGFloat) -> CGPoint {
538
+ let normalized = max(0, min(value / maxScale, 1))
539
+ return CGPoint(
540
+ x: x + CGFloat(index) * pointSpacing,
541
+ y: y + height * (1 - normalized)
542
+ )
543
+ }
544
+
545
+ private func minMax(_ values: [CGFloat], fallback: CGFloat) -> (min: CGFloat, max: CGFloat) {
546
+ guard let minValue = values.min(), let maxValue = values.max() else {
547
+ return (fallback, fallback)
548
+ }
549
+ return (minValue, maxValue)
550
+ }
551
+
552
+ private func attributes(color: UIColor) -> [NSAttributedString.Key: Any] {
553
+ [
554
+ .font: UIFont.monospacedDigitSystemFont(ofSize: 10, weight: .regular),
555
+ .foregroundColor: color,
556
+ ]
557
+ }
558
+
559
+ private func textHeight(_ attributes: [NSAttributedString.Key: Any]) -> CGFloat {
560
+ "FPS".size(withAttributes: attributes).height
561
+ }
562
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/native-kits",
3
- "version": "0.162.1-debug",
3
+ "version": "0.162.1-gif.1",
4
4
  "private": false,
5
5
  "dependencies": {},
6
6
  "devDependencies": {},
package/publish.sh CHANGED
@@ -456,7 +456,7 @@ case "$PHASE" in
456
456
  ;;
457
457
  "maven")
458
458
  echo "Running PHASE 2 only: Publish to Maven"
459
- # phase_publish_maven
459
+ phase_publish_maven
460
460
  ;;
461
461
  "npm")
462
462
  echo "Running PHASE 3 only: Publish to NPM"
@@ -465,7 +465,7 @@ case "$PHASE" in
465
465
  "all")
466
466
  echo "Running ALL PHASES"
467
467
  phase_check_version
468
- # phase_publish_maven
468
+ phase_publish_maven
469
469
  phase_publish_npm
470
470
  echo ""
471
471
  echo "🎉 ALL PHASES COMPLETED SUCCESSFULLY!"
package/build.gradle.kts DELETED
@@ -1,11 +0,0 @@
1
- plugins {
2
- // this is necessary to avoid the plugins to be loaded multiple times
3
- // in each subproject's classloader
4
- alias(libs.plugins.android.application) apply false
5
- alias(libs.plugins.android.library) apply false
6
- alias(libs.plugins.compose) apply false
7
- alias(libs.plugins.kotlin.compose.compiler) apply false
8
- alias(libs.plugins.jetbrains.kotlin.multiplatform) apply false
9
- alias(libs.plugins.jetbrains.kotlin.serialization) apply false
10
- alias(libs.plugins.vanniktech.mavenPublish) apply false
11
- }