@onekeyfe/react-native-skeleton 3.0.53 → 3.0.55

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 (2) hide show
  1. package/ios/Skeleton.swift +32 -1
  2. package/package.json +1 -1
@@ -77,6 +77,9 @@ class HybridSkeleton : HybridSkeletonSpec {
77
77
  viewObserver?.invalidate()
78
78
  viewObserver = nil
79
79
 
80
+ // Stop observing app lifecycle notifications
81
+ NotificationCenter.default.removeObserver(self)
82
+
80
83
  // Cleanup must happen on main thread, but avoid deadlock
81
84
  // Use async if not on main thread to prevent blocking
82
85
  if Thread.isMainThread {
@@ -122,6 +125,16 @@ class HybridSkeleton : HybridSkeletonSpec {
122
125
  }
123
126
  }
124
127
 
128
+ // Recover the shimmer when returning from background. CoreAnimation strips the running
129
+ // CAAnimation on backgrounding and does not re-add it on foreground, which would freeze
130
+ // the gradient for the view's lifetime. Re-add the animation when the app reactivates.
131
+ NotificationCenter.default.addObserver(
132
+ self,
133
+ selector: #selector(appDidBecomeActive),
134
+ name: UIApplication.didBecomeActiveNotification,
135
+ object: nil
136
+ )
137
+
125
138
  // Start animation when view is ready
126
139
  DispatchQueue.main.async { [weak self] in
127
140
  guard let self = self, self.isActive else { return }
@@ -129,6 +142,17 @@ class HybridSkeleton : HybridSkeletonSpec {
129
142
  }
130
143
  }
131
144
 
145
+ @objc private func appDidBecomeActive() {
146
+ guard isActive else { return }
147
+ DispatchQueue.main.async { [weak self] in
148
+ guard let self = self, self.isActive else { return }
149
+ // Only restart if the shimmer should be running but its animation was stripped.
150
+ if self.isShimmerRunning, self.shimmerLayer?.animation(forKey: "shimmerAnimation") == nil {
151
+ self.restartShimmer()
152
+ }
153
+ }
154
+ }
155
+
132
156
  func startShimmer() {
133
157
  retryCount = 0 // Reset retry count when starting new shimmer
134
158
  startShimmerInternal()
@@ -238,8 +262,15 @@ class HybridSkeleton : HybridSkeletonSpec {
238
262
  // input that actually drives the animation changed (speed / colors / bounds). If the
239
263
  // shimmer is already running and nothing relevant changed, leave the existing
240
264
  // CABasicAnimation alone to avoid main-thread layer teardown/rebuild churn.
265
+ //
266
+ // Verify the CAAnimation is actually still attached rather than trusting the cached
267
+ // signature alone: on backgrounding, CoreAnimation strips the running animation (and
268
+ // does not re-add it on foreground) while the layer, isShimmerRunning, and signature
269
+ // stay unchanged. Checking the live animation lets afterUpdate() recover by restarting.
241
270
  let signature = self.currentShimmerSignature()
242
- if self.isShimmerRunning, self.shimmerLayer != nil, signature == self.lastShimmerSignature {
271
+ if self.isShimmerRunning,
272
+ self.shimmerLayer?.animation(forKey: "shimmerAnimation") != nil,
273
+ signature == self.lastShimmerSignature {
243
274
  return
244
275
  }
245
276
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onekeyfe/react-native-skeleton",
3
- "version": "3.0.53",
3
+ "version": "3.0.55",
4
4
  "description": "react-native-skeleton",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",