@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.
@@ -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: [StatsEvent] = []
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
- private func sendStatsWithMetadata(action: String, versionName: String?, oldVersionName: String?, metadata: [String: String]?) {
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 eventsToSend = statsQueue
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(in: view, with: event), activeTouches.count <= 3 else {
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
- self.state = self.initialSpan > 0 ? .began : .failed
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(in: view, with: event),
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.state = .changed
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
- self.state = self.state == .possible || self.state == .began ? .failed : .ended
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(in view: UIView, with event: UIEvent) -> [UITouch]? {
63
- event.touches(for: view)?.filter { touch in
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?.webView ?? self.bridge?.viewController?.view else {
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
- if recognizer.state == .ended || recognizer.state == .cancelled || recognizer.state == .failed {
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
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capgo/capacitor-updater",
3
- "version": "8.49.0",
3
+ "version": "8.49.2",
4
4
  "license": "MPL-2.0",
5
5
  "description": "Live update for capacitor apps",
6
6
  "main": "dist/plugin.cjs.js",