react-native-swipeable-actions 0.1.7-canary.0 → 0.1.7-canary.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.
- package/build/Swipeable.d.ts.map +1 -1
- package/build/Swipeable.js +3 -7
- package/build/Swipeable.js.map +1 -1
- package/ios/Package.swift +1 -1
- package/ios/SwipeableView.swift +23 -61
- package/package.json +1 -1
- package/src/Swipeable.tsx +3 -6
- package/ios/OpenStateCache.swift +0 -57
package/build/Swipeable.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Swipeable.d.ts","sourceRoot":"","sources":["../src/Swipeable.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAEV,gBAAgB,EAChB,cAAc,EAGf,MAAM,mBAAmB,CAAA;AAe1B,QAAA,MAAM,SAAS,
|
|
1
|
+
{"version":3,"file":"Swipeable.d.ts","sourceRoot":"","sources":["../src/Swipeable.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAEV,gBAAgB,EAChB,cAAc,EAGf,MAAM,mBAAmB,CAAA;AAe1B,QAAA,MAAM,SAAS,0HAiJb,CAAA;AAgBF,KAAK,mBAAmB,GAAG,OAAO,SAAS,GAAG;IAC5C,IAAI,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAA;IACpC,KAAK,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;IACzD,QAAQ,EAAE,CAAC,QAAQ,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;CACvC,CAAA;AAED,QAAA,MAAM,eAAe,EAAgB,mBAAmB,CAAA;AAsBxD,eAAe,eAAe,CAAA"}
|
package/build/Swipeable.js
CHANGED
|
@@ -31,18 +31,14 @@ const Swipeable = (0, react_1.forwardRef)(function Swipeable({ children, actions
|
|
|
31
31
|
return normalizedKey != null && (0, nativeModuleUtils_1.isOpenByKey)(normalizedKey);
|
|
32
32
|
});
|
|
33
33
|
const swipeStartedRef = (0, react_1.useRef)(false);
|
|
34
|
-
const initialKeyRef = (0, react_1.useRef)(normalizedKey);
|
|
35
34
|
// When recyclingKey changes (FlatList reorder/recycle), sync hasActionsRendered
|
|
36
35
|
// with the native cached open state. FlatList reuses component instances without
|
|
37
|
-
// remounting, so useState initializer doesn't re-run.
|
|
38
|
-
// since the useState initializer already handled it.
|
|
36
|
+
// remounting, so useState initializer doesn't re-run.
|
|
39
37
|
(0, react_1.useEffect)(() => {
|
|
40
38
|
if (!normalizedKey)
|
|
41
39
|
return;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
initialKeyRef.current = normalizedKey;
|
|
45
|
-
setHasActionsRendered((0, nativeModuleUtils_1.isOpenByKey)(normalizedKey));
|
|
40
|
+
const cachedOpen = (0, nativeModuleUtils_1.isOpenByKey)(normalizedKey);
|
|
41
|
+
setHasActionsRendered(cachedOpen);
|
|
46
42
|
}, [normalizedKey]);
|
|
47
43
|
// Development-time validation
|
|
48
44
|
if (__DEV__) {
|
package/build/Swipeable.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Swipeable.js","sourceRoot":"","sources":["../src/Swipeable.tsx"],"names":[],"mappings":";;AAAA,iCAAiG;AACjG,+CAAyD;AACzD,2CAA4C;AAC5C,2DAAkF;AAQlF,yDAAqD;AACrD,mDAA+C;AAE/C,SAAS,qBAAqB,CAAC,GAAgC;IAC7D,IAAI,GAAG,IAAI,IAAI;QAAE,OAAO,SAAS,CAAA;IACjC,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAA;IACvC,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,MAAM,CAAC,GAAG,CAAC,CAAA;IAEvE,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CAAC,IAAI,CAAC,qCAAqC,GAAG,qCAAqC,CAAC,CAAA;IAC7F,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,MAAM,SAAS,GAAG,IAAA,kBAAU,EAAmC,SAAS,SAAS,CAC/E,EACE,QAAQ,EACR,OAAO,EACP,YAAY,EACZ,eAAe,GAAG,0BAAc,CAAC,gBAAgB,EACjD,QAAQ,GAAG,0BAAc,CAAC,QAAQ,EAClC,SAAS,GAAG,0BAAc,CAAC,SAAS,EACpC,cAAc,GAAG,0BAAc,CAAC,eAAe,EAC/C,kBAAkB,GAAG,0BAAc,CAAC,qBAAqB,EACzD,KAAK,EACL,MAAM,EACN,YAAY,EACZ,kBAAkB,EAClB,UAAU,EACV,UAAU,EACV,SAAS,GAAG,KAAK,EACjB,gBAAgB,GAAG,CAAC,EACpB,YAAY,EACb,EACD,GAAG;IAEH,MAAM,SAAS,GAAG,IAAA,cAAM,EAAqB,IAAI,CAAC,CAAA;IAElD,wDAAwD;IACxD,MAAM,aAAa,GAAG,qBAAqB,CAAC,YAAY,CAAC,CAAA;IACzD,MAAM,eAAe,GAAG,IAAA,cAAM,EAAqB,SAAS,CAAC,CAAA;IAC7D,eAAe,CAAC,OAAO,GAAG,aAAa,CAAA;IAEvC,2FAA2F;IAC3F,wFAAwF;IACxF,6CAA6C;IAC7C,MAAM,CAAC,kBAAkB,EAAE,qBAAqB,CAAC,GAAG,IAAA,gBAAQ,EAAC,GAAG,EAAE;QAChE,OAAO,aAAa,IAAI,IAAI,IAAI,IAAA,+BAAW,EAAC,aAAa,CAAC,CAAA;IAC5D,CAAC,CAAC,CAAA;IACF,MAAM,eAAe,GAAG,IAAA,cAAM,EAAC,KAAK,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"Swipeable.js","sourceRoot":"","sources":["../src/Swipeable.tsx"],"names":[],"mappings":";;AAAA,iCAAiG;AACjG,+CAAyD;AACzD,2CAA4C;AAC5C,2DAAkF;AAQlF,yDAAqD;AACrD,mDAA+C;AAE/C,SAAS,qBAAqB,CAAC,GAAgC;IAC7D,IAAI,GAAG,IAAI,IAAI;QAAE,OAAO,SAAS,CAAA;IACjC,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAA;IACvC,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,MAAM,CAAC,GAAG,CAAC,CAAA;IAEvE,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CAAC,IAAI,CAAC,qCAAqC,GAAG,qCAAqC,CAAC,CAAA;IAC7F,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,MAAM,SAAS,GAAG,IAAA,kBAAU,EAAmC,SAAS,SAAS,CAC/E,EACE,QAAQ,EACR,OAAO,EACP,YAAY,EACZ,eAAe,GAAG,0BAAc,CAAC,gBAAgB,EACjD,QAAQ,GAAG,0BAAc,CAAC,QAAQ,EAClC,SAAS,GAAG,0BAAc,CAAC,SAAS,EACpC,cAAc,GAAG,0BAAc,CAAC,eAAe,EAC/C,kBAAkB,GAAG,0BAAc,CAAC,qBAAqB,EACzD,KAAK,EACL,MAAM,EACN,YAAY,EACZ,kBAAkB,EAClB,UAAU,EACV,UAAU,EACV,SAAS,GAAG,KAAK,EACjB,gBAAgB,GAAG,CAAC,EACpB,YAAY,EACb,EACD,GAAG;IAEH,MAAM,SAAS,GAAG,IAAA,cAAM,EAAqB,IAAI,CAAC,CAAA;IAElD,wDAAwD;IACxD,MAAM,aAAa,GAAG,qBAAqB,CAAC,YAAY,CAAC,CAAA;IACzD,MAAM,eAAe,GAAG,IAAA,cAAM,EAAqB,SAAS,CAAC,CAAA;IAC7D,eAAe,CAAC,OAAO,GAAG,aAAa,CAAA;IAEvC,2FAA2F;IAC3F,wFAAwF;IACxF,6CAA6C;IAC7C,MAAM,CAAC,kBAAkB,EAAE,qBAAqB,CAAC,GAAG,IAAA,gBAAQ,EAAC,GAAG,EAAE;QAChE,OAAO,aAAa,IAAI,IAAI,IAAI,IAAA,+BAAW,EAAC,aAAa,CAAC,CAAA;IAC5D,CAAC,CAAC,CAAA;IACF,MAAM,eAAe,GAAG,IAAA,cAAM,EAAC,KAAK,CAAC,CAAA;IAErC,gFAAgF;IAChF,iFAAiF;IACjF,sDAAsD;IACtD,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,CAAC,aAAa;YAAE,OAAM;QAC1B,MAAM,UAAU,GAAG,IAAA,+BAAW,EAAC,aAAa,CAAC,CAAA;QAC7C,qBAAqB,CAAC,UAAU,CAAC,CAAA;IACnC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAA;IAEnB,8BAA8B;IAC9B,IAAI,OAAO,EAAE,CAAC;QACZ,IAAI,SAAS,IAAI,YAAY,IAAI,IAAI,EAAE,CAAC;YACtC,OAAO,CAAC,IAAI,CACV,gEAAgE;gBAC9D,kFAAkF,CACrF,CAAA;QACH,CAAC;IACH,CAAC;IAED,IAAA,2BAAmB,EACjB,GAAG,EACH,GAAG,EAAE,CAAC,CAAC;QACL,KAAK,EAAE,CAAC,QAAkB,EAAE,EAAE;YAC5B,MAAM,GAAG,GAAG,eAAe,CAAC,OAAO,CAAA;YACnC,IAAI,GAAG,EAAE,CAAC;gBACR,IAAA,8BAAU,EAAC,GAAG,EAAE,QAAQ,CAAC,CAAA;YAC3B,CAAC;iBAAM,IAAI,OAAO,EAAE,CAAC;gBACnB,OAAO,CAAC,IAAI,CAAC,wEAAwE,CAAC,CAAA;YACxF,CAAC;QACH,CAAC;QACD,IAAI,EAAE,GAAG,EAAE;YACT,MAAM,GAAG,GAAG,eAAe,CAAC,OAAO,CAAA;YACnC,IAAI,GAAG,EAAE,CAAC;gBACR,IAAA,6BAAS,EAAC,GAAG,CAAC,CAAA;YAChB,CAAC;iBAAM,IAAI,OAAO,EAAE,CAAC;gBACnB,OAAO,CAAC,IAAI,CAAC,uEAAuE,CAAC,CAAA;YACvF,CAAC;QACH,CAAC;KACF,CAAC,EACF,EAAE,CACH,CAAA;IAED,MAAM,gBAAgB,GAAG,IAAA,mBAAW,EAAC,GAAG,EAAE;QACxC,IAAI,CAAC,kBAAkB,EAAE,CAAC;YACxB,qBAAqB,CAAC,IAAI,CAAC,CAAA;QAC7B,CAAC;QAED,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,CAAC;YAC7B,eAAe,CAAC,OAAO,GAAG,IAAI,CAAA;YAC9B,YAAY,EAAE,EAAE,CAAA;QAClB,CAAC;IACH,CAAC,EAAE,CAAC,kBAAkB,EAAE,YAAY,CAAC,CAAC,CAAA;IAEtC,MAAM,mBAAmB,GAAG,IAAA,mBAAW,EACrC,CAAC,KAAyB,EAAE,EAAE;QAC5B,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAA;QAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAA;QACrD,UAAU,EAAE,CAAC,OAAO,CAAC,CAAA;IACvB,CAAC,EACD,CAAC,UAAU,CAAC,CACb,CAAA;IAED,MAAM,sBAAsB,GAAG,IAAA,mBAAW,EACxC,CAAC,KAAsB,EAAE,EAAE;QACzB,kBAAkB,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;IAC/C,CAAC,EACD,CAAC,kBAAkB,CAAC,CACrB,CAAA;IAED,MAAM,cAAc,GAAG,IAAA,mBAAW,EAChC,CAAC,KAAsB,EAAE,EAAE;QACzB,eAAe,CAAC,OAAO,GAAG,KAAK,CAAA;QAC/B,UAAU,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;IACvC,CAAC,EACD,CAAC,UAAU,CAAC,CACb,CAAA;IAED,OAAO,CACL,CAAC,6BAAa,CACZ,GAAG,CAAC,CAAC,SAAS,CAAC,CACf,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CACjC,YAAY,CAAC,CAAC,YAAY,CAAC,CAC3B,eAAe,CAAC,CAAC,eAAe,CAAC,CACjC,QAAQ,CAAC,CAAC,QAAQ,CAAC,CACnB,SAAS,CAAC,CAAC,SAAS,CAAC,CACrB,cAAc,CAAC,CAAC,cAAc,CAAC,CAC/B,kBAAkB,CAAC,CAAC,kBAAkB,CAAC,CACvC,SAAS,CAAC,CAAC,SAAS,CAAC,CACrB,gBAAgB,CAAC,CAAC,gBAAgB,CAAC,CACnC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAC3D,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAC/B,YAAY,CAAC,CAAC,gBAAgB,CAAC,CAC/B,eAAe,CAAC,CAAC,mBAAmB,CAAC,CACrC,kBAAkB,CAAC,CAAC,sBAAsB,CAAC,CAC3C,UAAU,CAAC,CAAC,cAAc,CAAC,CAE3B;MAAA,CAAC,kBAAkB,IAAI,CACrB,CAAC,mCAAgB,CACf,eAAe,CAAC,CAAC,eAAe,CAAC,CACjC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAEpD;UAAA,CAAC,OAAO,CACV;QAAA,EAAE,mCAAgB,CAAC,CACpB,CAED;;MAAA,CAAC,mBAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,mBAAI,CAC/C;IAAA,EAAE,6BAAa,CAAC,CACjB,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,MAAM,MAAM,GAAG,yBAAU,CAAC,MAAM,CAAC;IAC/B,SAAS,EAAE;QACT,uDAAuD;QACvD,8DAA8D;QAC9D,QAAQ,EAAE,uBAAQ,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS;KACvD;IACD,OAAO,EAAE;QACP,KAAK,EAAE,MAAM;KACd;CACF,CAAC,CAAA;AAEF,SAAS,CAAC,WAAW,GAAG,WAAW,CAAA;AASnC,MAAM,eAAe,GAAG,SAAgC,CAAA;AAExD,eAAe,CAAC,IAAI,GAAG,CAAC,YAAoB,EAAE,EAAE;IAC9C,IAAI,OAAO,IAAI,CAAC,CAAC,YAAY,IAAI,OAAO,YAAY,KAAK,QAAQ,CAAC,EAAE,CAAC;QACnE,OAAO,CAAC,IAAI,CAAC,0DAA0D,CAAC,CAAA;QACxE,OAAM;IACR,CAAC;IACD,IAAA,6BAAS,EAAC,YAAY,CAAC,CAAA;AACzB,CAAC,CAAA;AAED,eAAe,CAAC,KAAK,GAAG,CAAC,YAAoB,EAAE,QAAkB,EAAE,EAAE;IACnE,IAAI,OAAO,IAAI,CAAC,CAAC,YAAY,IAAI,OAAO,YAAY,KAAK,QAAQ,CAAC,EAAE,CAAC;QACnE,OAAO,CAAC,IAAI,CAAC,2DAA2D,CAAC,CAAA;QACzE,OAAM;IACR,CAAC;IACD,IAAA,8BAAU,EAAC,YAAY,EAAE,QAAQ,CAAC,CAAA;AACpC,CAAC,CAAA;AAED,eAAe,CAAC,QAAQ,GAAG,CAAC,QAAkB,EAAE,EAAE;IAChD,IAAA,4BAAQ,EAAC,QAAQ,CAAC,CAAA;AACpB,CAAC,CAAA;AAED,kBAAe,eAAe,CAAA"}
|
package/ios/Package.swift
CHANGED
|
@@ -17,7 +17,7 @@ let package = Package(
|
|
|
17
17
|
"SwipeableModule.swift",
|
|
18
18
|
"react-native-swipeable-actions.podspec"
|
|
19
19
|
],
|
|
20
|
-
sources: ["SwipePhysics.swift", "SwipeAnimationConfig.swift"
|
|
20
|
+
sources: ["SwipePhysics.swift", "SwipeAnimationConfig.swift"]
|
|
21
21
|
),
|
|
22
22
|
.testTarget(
|
|
23
23
|
name: "SwipeableActionsTests",
|
package/ios/SwipeableView.swift
CHANGED
|
@@ -31,23 +31,13 @@ public class SwipeableView: ExpoView {
|
|
|
31
31
|
return typeName.contains("SurfaceTouchHandler") || typeName.contains("RCTTouchHandler")
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
///
|
|
35
|
-
///
|
|
36
|
-
|
|
37
|
-
private static func isRNGHGestureHandler(_ recognizer: UIGestureRecognizer) -> Bool {
|
|
38
|
-
let typeName = String(describing: type(of: recognizer))
|
|
39
|
-
return typeName.hasPrefix("RNBetter") || typeName.hasPrefix("RNManualActivation")
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/// Walk from a hit-tested view up to (but not including) self, checking for RNGH recognizers.
|
|
43
|
-
/// Used to prevent our pan gesture from beginning when the touch landed on a RNGH-managed view.
|
|
44
|
-
private func hasRNGHGesture(from view: UIView) -> Bool {
|
|
34
|
+
/// Walk from a hit-tested view up to (but not including) self, checking for gesture recognizers.
|
|
35
|
+
/// Any child view with a gesture recognizer (RNGH, custom, etc.) takes priority over our pan.
|
|
36
|
+
private func hasChildGesture(from view: UIView) -> Bool {
|
|
45
37
|
var current: UIView? = view
|
|
46
38
|
while let v = current, v !== self {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
return true
|
|
50
|
-
}
|
|
39
|
+
if !(v.gestureRecognizers ?? []).isEmpty {
|
|
40
|
+
return true
|
|
51
41
|
}
|
|
52
42
|
current = v.superview
|
|
53
43
|
}
|
|
@@ -57,15 +47,15 @@ public class SwipeableView: ExpoView {
|
|
|
57
47
|
// MARK: - Thread-Safe Static Registry
|
|
58
48
|
|
|
59
49
|
private static let registryQueue = DispatchQueue(label: "com.swipeable.registry", qos: .userInteractive)
|
|
60
|
-
static
|
|
50
|
+
private static var _openStateCache: [String: Bool] = [:]
|
|
61
51
|
private static var _viewRegistry: [String: WeakRef<SwipeableView>] = [:]
|
|
62
52
|
|
|
63
53
|
static func getOpenState(for key: String) -> Bool {
|
|
64
|
-
|
|
54
|
+
registryQueue.sync { _openStateCache[key] ?? false }
|
|
65
55
|
}
|
|
66
56
|
|
|
67
57
|
private static func setOpenState(for key: String, isOpen: Bool) {
|
|
68
|
-
|
|
58
|
+
registryQueue.async(flags: .barrier) { _openStateCache[key] = isOpen }
|
|
69
59
|
}
|
|
70
60
|
|
|
71
61
|
private static func getView(for key: String) -> SwipeableView? {
|
|
@@ -81,7 +71,7 @@ public class SwipeableView: ExpoView {
|
|
|
81
71
|
}
|
|
82
72
|
|
|
83
73
|
private static func clearOpenState(for key: String) {
|
|
84
|
-
|
|
74
|
+
registryQueue.async(flags: .barrier) { _openStateCache.removeValue(forKey: key) }
|
|
85
75
|
}
|
|
86
76
|
|
|
87
77
|
private static func getAllViews() -> [SwipeableView] {
|
|
@@ -225,11 +215,7 @@ public class SwipeableView: ExpoView {
|
|
|
225
215
|
|
|
226
216
|
// Apply using local shouldOpen (pendingShouldOpen was cleared by close)
|
|
227
217
|
if shouldOpen {
|
|
228
|
-
|
|
229
|
-
DispatchQueue.main.async { [weak self] in
|
|
230
|
-
guard let self = self, self.recyclingKey == keyAtDispatch else { return }
|
|
231
|
-
self.snapToOpen()
|
|
232
|
-
}
|
|
218
|
+
DispatchQueue.main.async { [weak self] in self?.snapToOpen() }
|
|
233
219
|
}
|
|
234
220
|
}
|
|
235
221
|
}
|
|
@@ -305,16 +291,17 @@ public class SwipeableView: ExpoView {
|
|
|
305
291
|
currentAnimator = nil
|
|
306
292
|
isAnimating = false
|
|
307
293
|
|
|
308
|
-
//
|
|
294
|
+
// Reset layer properties to prevent corruption
|
|
295
|
+
contentView?.transform = .identity
|
|
296
|
+
contentView?.layer.zPosition = 0
|
|
297
|
+
actionsView?.transform = .identity
|
|
298
|
+
actionsView?.layer.zPosition = 0
|
|
299
|
+
|
|
300
|
+
// Unregister from static registry and clear cached state
|
|
309
301
|
if let key = recyclingKey {
|
|
310
302
|
Self.unregisterView(for: key)
|
|
303
|
+
Self.clearOpenState(for: key)
|
|
311
304
|
}
|
|
312
|
-
|
|
313
|
-
// Nil view references so didAddSubview correctly detects new children
|
|
314
|
-
// on re-insertion (wasActionsNil/wasContentNil guards).
|
|
315
|
-
// Do NOT reset transforms - Fabric DELETE+INSERT must preserve open visual state.
|
|
316
|
-
contentView = nil
|
|
317
|
-
actionsView = nil
|
|
318
305
|
}
|
|
319
306
|
super.willMove(toSuperview: newSuperview)
|
|
320
307
|
}
|
|
@@ -342,28 +329,6 @@ public class SwipeableView: ExpoView {
|
|
|
342
329
|
panGesture.view?.removeGestureRecognizer(panGesture)
|
|
343
330
|
addGestureRecognizer(panGesture)
|
|
344
331
|
}
|
|
345
|
-
|
|
346
|
-
// Restore visual state after Fabric reorder (DELETE+INSERT cycle).
|
|
347
|
-
// Fabric may reset child transforms during prop reconciliation. Re-apply
|
|
348
|
-
// on next runloop tick to ensure we run after Fabric finishes mutations.
|
|
349
|
-
if isOpen && currentTranslation != 0 {
|
|
350
|
-
DispatchQueue.main.async { [weak self] in
|
|
351
|
-
guard let self = self,
|
|
352
|
-
self.isOpen,
|
|
353
|
-
self.currentTranslation != 0,
|
|
354
|
-
!self.isDragging,
|
|
355
|
-
!self.isAnimating else { return }
|
|
356
|
-
self.contentView?.transform = CGAffineTransform(translationX: self.currentTranslation, y: 0)
|
|
357
|
-
self.contentView?.layer.zPosition = 1
|
|
358
|
-
self.actionsView?.layer.zPosition = -1
|
|
359
|
-
self.updateActionsTransform()
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
// Restart autoClose timer if it was cancelled during detach
|
|
363
|
-
if autoClose {
|
|
364
|
-
scheduleAutoClose()
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
332
|
}
|
|
368
333
|
|
|
369
334
|
public override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
|
@@ -457,9 +422,6 @@ public class SwipeableView: ExpoView {
|
|
|
457
422
|
var translation = currentTranslation
|
|
458
423
|
if isAnimating, let presentationLayer = contentView?.layer.presentation() {
|
|
459
424
|
translation = presentationLayer.transform.m41 // tx component of transform
|
|
460
|
-
// Keep currentTranslation in sync so layoutSubviews and other guards
|
|
461
|
-
// see the real position, not a stale value from before animation started.
|
|
462
|
-
currentTranslation = translation
|
|
463
425
|
// Update actions to match content position
|
|
464
426
|
let progress = min(abs(translation) / actionsWidth, 1.0)
|
|
465
427
|
let offset = isLeading ? -actionsWidth : actionsWidth
|
|
@@ -554,7 +516,7 @@ public class SwipeableView: ExpoView {
|
|
|
554
516
|
}
|
|
555
517
|
}
|
|
556
518
|
|
|
557
|
-
if
|
|
519
|
+
if currentTranslation != 0 {
|
|
558
520
|
contentView?.transform = CGAffineTransform(translationX: currentTranslation, y: 0)
|
|
559
521
|
updateActionsTransform()
|
|
560
522
|
}
|
|
@@ -913,11 +875,11 @@ extension SwipeableView: UIGestureRecognizerDelegate {
|
|
|
913
875
|
let shouldBegin = isOpen || (isLeading ? velocity.x > 0 : velocity.x < 0)
|
|
914
876
|
|
|
915
877
|
if shouldBegin {
|
|
916
|
-
// Prevent our pan from starting when the touch is on a
|
|
917
|
-
//
|
|
918
|
-
// so we
|
|
878
|
+
// Prevent our pan from starting when the touch is on a child view that has
|
|
879
|
+
// its own gesture recognizers (e.g. RNGH). Delegate-based conflict resolution
|
|
880
|
+
// doesn't work with RNGH (it overrides delegates), so we yield via hit-test.
|
|
919
881
|
let touchPoint = pan.location(in: self)
|
|
920
|
-
if let hitView = super.hitTest(touchPoint, with: nil),
|
|
882
|
+
if let hitView = super.hitTest(touchPoint, with: nil), hasChildGesture(from: hitView) {
|
|
921
883
|
return false
|
|
922
884
|
}
|
|
923
885
|
cancelFabricTouches()
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-swipeable-actions",
|
|
3
|
-
"version": "0.1.7-canary.
|
|
3
|
+
"version": "0.1.7-canary.1",
|
|
4
4
|
"description": "High-performance native swipeable row component for React Native using Expo Modules",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"types": "build/index.d.ts",
|
package/src/Swipeable.tsx
CHANGED
|
@@ -59,17 +59,14 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(function Swipeabl
|
|
|
59
59
|
return normalizedKey != null && isOpenByKey(normalizedKey)
|
|
60
60
|
})
|
|
61
61
|
const swipeStartedRef = useRef(false)
|
|
62
|
-
const initialKeyRef = useRef(normalizedKey)
|
|
63
62
|
|
|
64
63
|
// When recyclingKey changes (FlatList reorder/recycle), sync hasActionsRendered
|
|
65
64
|
// with the native cached open state. FlatList reuses component instances without
|
|
66
|
-
// remounting, so useState initializer doesn't re-run.
|
|
67
|
-
// since the useState initializer already handled it.
|
|
65
|
+
// remounting, so useState initializer doesn't re-run.
|
|
68
66
|
useEffect(() => {
|
|
69
67
|
if (!normalizedKey) return
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
setHasActionsRendered(isOpenByKey(normalizedKey))
|
|
68
|
+
const cachedOpen = isOpenByKey(normalizedKey)
|
|
69
|
+
setHasActionsRendered(cachedOpen)
|
|
73
70
|
}, [normalizedKey])
|
|
74
71
|
|
|
75
72
|
// Development-time validation
|
package/ios/OpenStateCache.swift
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import Foundation
|
|
2
|
-
|
|
3
|
-
/// Thread-safe LRU cache for tracking open/closed state of swipeable views by recycling key.
|
|
4
|
-
/// Used by the static registry in SwipeableView to persist state across list recycling.
|
|
5
|
-
public class OpenStateCache {
|
|
6
|
-
private let queue: DispatchQueue
|
|
7
|
-
private let maxSize: Int
|
|
8
|
-
private var cache: [String: Bool] = [:]
|
|
9
|
-
private var insertionOrder: [String] = []
|
|
10
|
-
|
|
11
|
-
public init(maxSize: Int = 1000, queueLabel: String = "com.swipeable.openstate") {
|
|
12
|
-
self.maxSize = maxSize
|
|
13
|
-
self.queue = DispatchQueue(label: queueLabel, qos: .userInteractive)
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/// Read the cached open state for a key. Returns false if not found.
|
|
17
|
-
public func get(_ key: String) -> Bool {
|
|
18
|
-
queue.sync { cache[key] ?? false }
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/// Set the open state for a key. Promotes existing keys to most-recently-used.
|
|
22
|
-
/// Evicts the least-recently-used entry when cache exceeds max size.
|
|
23
|
-
public func set(_ key: String, isOpen: Bool) {
|
|
24
|
-
queue.async(flags: .barrier) { [self] in
|
|
25
|
-
if cache[key] != nil {
|
|
26
|
-
insertionOrder.removeAll { $0 == key }
|
|
27
|
-
}
|
|
28
|
-
insertionOrder.append(key)
|
|
29
|
-
cache[key] = isOpen
|
|
30
|
-
if insertionOrder.count > maxSize {
|
|
31
|
-
let oldest = insertionOrder.removeFirst()
|
|
32
|
-
cache.removeValue(forKey: oldest)
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/// Remove a specific key from the cache.
|
|
38
|
-
public func clear(_ key: String) {
|
|
39
|
-
queue.async(flags: .barrier) { [self] in
|
|
40
|
-
cache.removeValue(forKey: key)
|
|
41
|
-
insertionOrder.removeAll { $0 == key }
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/// Remove all entries from the cache.
|
|
46
|
-
public func clearAll() {
|
|
47
|
-
queue.async(flags: .barrier) { [self] in
|
|
48
|
-
cache.removeAll()
|
|
49
|
-
insertionOrder.removeAll()
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/// Synchronously return the number of entries (for testing).
|
|
54
|
-
public var count: Int {
|
|
55
|
-
queue.sync { cache.count }
|
|
56
|
-
}
|
|
57
|
-
}
|