@capgo/capacitor-updater 8.49.0 → 8.49.2
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/README.md +15 -6
- package/android/src/main/java/ee/forgr/capacitor_updater/CapacitorUpdaterPlugin.java +110 -1
- package/android/src/main/java/ee/forgr/capacitor_updater/CapgoUpdater.java +44 -5
- package/android/src/main/java/ee/forgr/capacitor_updater/DeviceIdHelper.java +45 -30
- package/android/src/main/java/ee/forgr/capacitor_updater/ThreeFingerPinchDetector.java +217 -63
- package/dist/docs.json +3 -3
- package/dist/esm/definitions.d.ts +15 -6
- package/dist/esm/definitions.js.map +1 -1
- package/ios/Sources/CapacitorUpdaterPlugin/CapacitorUpdaterPlugin.swift +87 -1
- package/ios/Sources/CapacitorUpdaterPlugin/CapgoUpdater.swift +32 -6
- package/ios/Sources/CapacitorUpdaterPlugin/ShakeMenu.swift +22 -13
- package/package.json +1 -1
|
@@ -51,11 +51,16 @@ import UIKit
|
|
|
51
51
|
private static var rateLimitStatisticSent = false
|
|
52
52
|
|
|
53
53
|
// Stats batching - queue events and send max once per second
|
|
54
|
-
private var statsQueue: [
|
|
54
|
+
private var statsQueue: [QueuedStatsEvent] = []
|
|
55
55
|
private let statsQueueLock = NSLock()
|
|
56
56
|
private var statsFlushTimer: Timer?
|
|
57
57
|
private static let statsFlushInterval: TimeInterval = 1.0
|
|
58
58
|
|
|
59
|
+
private struct QueuedStatsEvent {
|
|
60
|
+
let event: StatsEvent
|
|
61
|
+
let onSent: (() -> Void)?
|
|
62
|
+
}
|
|
63
|
+
|
|
59
64
|
private static func sanitizeHeaderValue(_ value: String) -> String {
|
|
60
65
|
if value.isEmpty {
|
|
61
66
|
return "unknown"
|
|
@@ -2474,14 +2479,24 @@ import UIKit
|
|
|
2474
2479
|
}()
|
|
2475
2480
|
|
|
2476
2481
|
func sendStats(action: String, versionName: String? = nil, oldVersionName: String? = "") {
|
|
2477
|
-
sendStatsWithMetadata(action: action, versionName: versionName, oldVersionName: oldVersionName, metadata: nil)
|
|
2482
|
+
sendStatsWithMetadata(action: action, versionName: versionName, oldVersionName: oldVersionName, metadata: nil, onSent: nil)
|
|
2478
2483
|
}
|
|
2479
2484
|
|
|
2480
2485
|
func sendStats(action: String, versionName: String?, oldVersionName: String?, metadata: [String: String]) {
|
|
2481
|
-
sendStatsWithMetadata(action: action, versionName: versionName, oldVersionName: oldVersionName, metadata: metadata)
|
|
2486
|
+
sendStatsWithMetadata(action: action, versionName: versionName, oldVersionName: oldVersionName, metadata: metadata, onSent: nil)
|
|
2482
2487
|
}
|
|
2483
2488
|
|
|
2484
|
-
|
|
2489
|
+
func sendStats(action: String, versionName: String?, oldVersionName: String?, metadata: [String: String], onSent: @escaping () -> Void) {
|
|
2490
|
+
sendStatsWithMetadata(action: action, versionName: versionName, oldVersionName: oldVersionName, metadata: metadata, onSent: onSent)
|
|
2491
|
+
}
|
|
2492
|
+
|
|
2493
|
+
private func sendStatsWithMetadata(
|
|
2494
|
+
action: String,
|
|
2495
|
+
versionName: String?,
|
|
2496
|
+
oldVersionName: String?,
|
|
2497
|
+
metadata: [String: String]?,
|
|
2498
|
+
onSent: (() -> Void)?
|
|
2499
|
+
) {
|
|
2485
2500
|
if previewSession {
|
|
2486
2501
|
logger.debug("Skipping sendStats during preview session.")
|
|
2487
2502
|
return
|
|
@@ -2522,7 +2537,7 @@ import UIKit
|
|
|
2522
2537
|
)
|
|
2523
2538
|
|
|
2524
2539
|
statsQueueLock.lock()
|
|
2525
|
-
statsQueue.append(event)
|
|
2540
|
+
statsQueue.append(QueuedStatsEvent(event: event, onSent: onSent))
|
|
2526
2541
|
statsQueueLock.unlock()
|
|
2527
2542
|
|
|
2528
2543
|
ensureStatsTimerStarted()
|
|
@@ -2549,10 +2564,13 @@ import UIKit
|
|
|
2549
2564
|
statsQueueLock.unlock()
|
|
2550
2565
|
return
|
|
2551
2566
|
}
|
|
2552
|
-
let
|
|
2567
|
+
let queuedEvents = statsQueue
|
|
2553
2568
|
statsQueue.removeAll()
|
|
2554
2569
|
statsQueueLock.unlock()
|
|
2555
2570
|
|
|
2571
|
+
let eventsToSend = queuedEvents.map(\.event)
|
|
2572
|
+
let onSentCallbacks = queuedEvents.compactMap(\.onSent)
|
|
2573
|
+
|
|
2556
2574
|
operationQueue.maxConcurrentOperationCount = 1
|
|
2557
2575
|
|
|
2558
2576
|
let operation = BlockOperation {
|
|
@@ -2570,10 +2588,18 @@ import UIKit
|
|
|
2570
2588
|
return
|
|
2571
2589
|
}
|
|
2572
2590
|
|
|
2591
|
+
if let statusCode = response.response?.statusCode, !(200...299).contains(statusCode) {
|
|
2592
|
+
self.logger.error("Error sending stats batch")
|
|
2593
|
+
self.logger.debug("Response code: \(statusCode)")
|
|
2594
|
+
semaphore.signal()
|
|
2595
|
+
return
|
|
2596
|
+
}
|
|
2597
|
+
|
|
2573
2598
|
switch response.result {
|
|
2574
2599
|
case .success:
|
|
2575
2600
|
self.logger.info("Stats batch sent successfully")
|
|
2576
2601
|
self.logger.debug("Sent \(eventsToSend.count) events")
|
|
2602
|
+
onSentCallbacks.forEach { $0() }
|
|
2577
2603
|
case let .failure(error):
|
|
2578
2604
|
self.logger.error("Error sending stats batch")
|
|
2579
2605
|
self.logger.debug("Response: \(response.value?.debugDescription ?? "nil"), Error: \(error.localizedDescription)")
|
|
@@ -14,10 +14,11 @@ private let threeFingerPinchScaleDelta: CGFloat = 0.12
|
|
|
14
14
|
final class ThreeFingerPinchGestureRecognizer: UIGestureRecognizer {
|
|
15
15
|
private var initialSpan: CGFloat = 0
|
|
16
16
|
private(set) var scale: CGFloat = 1
|
|
17
|
+
var onTrackingStarted: (() -> Void)?
|
|
17
18
|
|
|
18
19
|
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
|
|
19
20
|
super.touchesBegan(touches, with: event)
|
|
20
|
-
guard let view = self.view, let activeTouches = activeTouches(
|
|
21
|
+
guard let view = self.view, let activeTouches = activeTouches(with: event), activeTouches.count <= 3 else {
|
|
21
22
|
self.state = .failed
|
|
22
23
|
return
|
|
23
24
|
}
|
|
@@ -25,14 +26,18 @@ final class ThreeFingerPinchGestureRecognizer: UIGestureRecognizer {
|
|
|
25
26
|
if activeTouches.count == 3 {
|
|
26
27
|
self.initialSpan = span(for: activeTouches, in: view)
|
|
27
28
|
self.scale = 1
|
|
28
|
-
|
|
29
|
+
if self.initialSpan > 0 {
|
|
30
|
+
self.onTrackingStarted?()
|
|
31
|
+
} else {
|
|
32
|
+
self.state = .failed
|
|
33
|
+
}
|
|
29
34
|
}
|
|
30
35
|
}
|
|
31
36
|
|
|
32
37
|
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent) {
|
|
33
38
|
super.touchesMoved(touches, with: event)
|
|
34
39
|
guard let view = self.view,
|
|
35
|
-
let activeTouches = activeTouches(
|
|
40
|
+
let activeTouches = activeTouches(with: event),
|
|
36
41
|
activeTouches.count == 3,
|
|
37
42
|
self.initialSpan > 0 else {
|
|
38
43
|
self.state = .failed
|
|
@@ -40,12 +45,16 @@ final class ThreeFingerPinchGestureRecognizer: UIGestureRecognizer {
|
|
|
40
45
|
}
|
|
41
46
|
|
|
42
47
|
self.scale = span(for: activeTouches, in: view) / self.initialSpan
|
|
43
|
-
self.
|
|
48
|
+
if abs(self.scale - 1) >= threeFingerPinchScaleDelta {
|
|
49
|
+
self.state = .recognized
|
|
50
|
+
}
|
|
44
51
|
}
|
|
45
52
|
|
|
46
53
|
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent) {
|
|
47
54
|
super.touchesEnded(touches, with: event)
|
|
48
|
-
|
|
55
|
+
if self.state == .possible {
|
|
56
|
+
self.state = .failed
|
|
57
|
+
}
|
|
49
58
|
}
|
|
50
59
|
|
|
51
60
|
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent) {
|
|
@@ -59,8 +68,8 @@ final class ThreeFingerPinchGestureRecognizer: UIGestureRecognizer {
|
|
|
59
68
|
self.scale = 1
|
|
60
69
|
}
|
|
61
70
|
|
|
62
|
-
private func activeTouches(
|
|
63
|
-
event.touches(for:
|
|
71
|
+
private func activeTouches(with event: UIEvent) -> [UITouch]? {
|
|
72
|
+
event.touches(for: self)?.filter { touch in
|
|
64
73
|
touch.phase != .ended && touch.phase != .cancelled
|
|
65
74
|
}
|
|
66
75
|
}
|
|
@@ -106,7 +115,7 @@ extension CapacitorUpdaterPlugin: UIGestureRecognizerDelegate {
|
|
|
106
115
|
let shouldInstall = self.shakeMenuGesture == Self.shakeMenuGestureThreeFingerPinch &&
|
|
107
116
|
(self.shakeMenuEnabled || self.shakeChannelSelectorEnabled)
|
|
108
117
|
|
|
109
|
-
guard shouldInstall, let targetView = self.bridge?.
|
|
118
|
+
guard shouldInstall, let targetView = self.bridge?.viewController?.view ?? self.bridge?.webView else {
|
|
110
119
|
self.removeShakeMenuGestureRecognizer()
|
|
111
120
|
return
|
|
112
121
|
}
|
|
@@ -122,6 +131,9 @@ extension CapacitorUpdaterPlugin: UIGestureRecognizerDelegate {
|
|
|
122
131
|
recognizer.delaysTouchesBegan = false
|
|
123
132
|
recognizer.delaysTouchesEnded = false
|
|
124
133
|
recognizer.delegate = self
|
|
134
|
+
recognizer.onTrackingStarted = { [weak self] in
|
|
135
|
+
self?.logger.info("Three finger pinch tracking started")
|
|
136
|
+
}
|
|
125
137
|
targetView.addGestureRecognizer(recognizer)
|
|
126
138
|
self.shakeMenuPinchGestureRecognizer = recognizer
|
|
127
139
|
self.logger.info("Three finger pinch menu gesture initialized")
|
|
@@ -138,11 +150,7 @@ extension CapacitorUpdaterPlugin: UIGestureRecognizerDelegate {
|
|
|
138
150
|
}
|
|
139
151
|
|
|
140
152
|
@objc func handleShakeMenuPinch(_ recognizer: ThreeFingerPinchGestureRecognizer) {
|
|
141
|
-
|
|
142
|
-
self.shakeMenuPinchGestureTriggered = false
|
|
143
|
-
return
|
|
144
|
-
}
|
|
145
|
-
guard recognizer.state == .changed, !self.shakeMenuPinchGestureTriggered else {
|
|
153
|
+
guard recognizer.state == .recognized, !self.shakeMenuPinchGestureTriggered else {
|
|
146
154
|
return
|
|
147
155
|
}
|
|
148
156
|
guard abs(recognizer.scale - 1) >= threeFingerPinchScaleDelta else {
|
|
@@ -156,6 +164,7 @@ extension CapacitorUpdaterPlugin: UIGestureRecognizerDelegate {
|
|
|
156
164
|
}
|
|
157
165
|
|
|
158
166
|
self.shakeMenuPinchGestureTriggered = true
|
|
167
|
+
self.logger.info("Three finger pinch detected")
|
|
159
168
|
_ = window.showCapacitorUpdaterMenu(plugin: self, bridge: bridge, gestureName: "Three finger pinch")
|
|
160
169
|
}
|
|
161
170
|
|