@momo-kits/foundation 0.164.1-beta.2 → 0.164.1-beta.4

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.
@@ -374,14 +374,28 @@ const getSwipeGestureValue = (
374
374
  * one light tick once the swipe back has travelled far enough to read as
375
375
  * recognised. iOS only, mirroring `gestureEnabled` in getStackOptions.
376
376
  *
377
- * the listener is scoped to the `swiping === 1` window on purpose: the same
378
- * animated value also drives the programmatic push and pop animations, so an
379
- * unscoped listener would buzz on every navigation.
377
+ * both listeners are installed on mount and never lazily inside the gesture:
378
+ * on the New Architecture `addListener` queues `startListeningToAnimatedNodeValue`
379
+ * via `queueOperationBlock`, and that queue is only drained by a React mount
380
+ * commit — which never happens during a native driven pan. subscribing when the
381
+ * swipe starts installs an observer that the release flush tears down again
382
+ * before a single frame is delivered, so it must stay on mount.
383
+ *
384
+ * `gesture` also drives the programmatic push and pop animations, so it is the
385
+ * JS `isSwiping` flag, not the subscription lifetime, that keeps the tick
386
+ * exclusive to a real finger drag.
380
387
  */
381
388
  const useSwipeBackHaptic = () => {
382
389
  const { navigator } = useContext<any>(ApplicationContext);
383
390
  const animation = useContext(CardAnimationContext);
384
391
 
392
+ /**
393
+ * the latch has to outlive the effect. `animation` identity changes on every
394
+ * navigator render, so a `hasFired` local re-arms several times per drag and
395
+ * the tick then repeats on every frame past the threshold
396
+ */
397
+ const hasFired = useRef(false);
398
+
385
399
  useEffect(() => {
386
400
  if (Platform.OS !== 'ios' || !animation) {
387
401
  return;
@@ -393,47 +407,44 @@ const useSwipeBackHaptic = () => {
393
407
  return;
394
408
  }
395
409
 
396
- let hasFired = false;
397
- let gestureListener: string | undefined;
410
+ /**
411
+ * `animation` identity is not stable, so this effect can re-run mid swipe.
412
+ * seed from the live value instead of waiting for a 0 -> 1 transition that
413
+ * has already been missed
414
+ */
415
+ let isSwiping = readAnimatedValue(swiping, 0) === 1;
398
416
 
399
- const detachGesture = () => {
400
- if (gestureListener !== undefined) {
401
- gesture.removeListener(gestureListener);
402
- gestureListener = undefined;
403
- }
404
- hasFired = false;
405
- };
417
+ /**
418
+ * sign, not magnitude: a leftward overdrag reports a negative
419
+ * translation and must not count as progress toward dismissal
420
+ */
421
+ const direction = readAnimatedValue(inverted, 1);
406
422
 
407
423
  const swipingListener = swiping.addListener(({ value }) => {
408
- if (value !== 1) {
409
- detachGesture();
424
+ isSwiping = value === 1;
425
+ if (!isSwiping) {
426
+ hasFired.current = false;
427
+ }
428
+ });
429
+
430
+ const gestureListener = gesture.addListener(({ value: translation }) => {
431
+ if (!isSwiping) {
410
432
  return;
411
433
  }
412
434
 
413
- if (gestureListener !== undefined) {
435
+ if (translation * direction < SWIPE_BACK_HAPTIC_THRESHOLD) {
436
+ hasFired.current = false;
414
437
  return;
415
438
  }
416
439
 
417
- /**
418
- * sign, not magnitude: a leftward overdrag reports a negative
419
- * translation and must not count as progress toward dismissal
420
- */
421
- const direction = readAnimatedValue(inverted, 1);
422
- gestureListener = gesture.addListener(({ value: translation }) => {
423
- if (translation * direction < SWIPE_BACK_HAPTIC_THRESHOLD) {
424
- hasFired = false;
425
- return;
426
- }
427
-
428
- if (!hasFired) {
429
- hasFired = true;
430
- navigator?.maxApi?.triggerEventVibration?.('light');
431
- }
432
- });
440
+ if (!hasFired.current) {
441
+ hasFired.current = true;
442
+ navigator?.maxApi?.triggerEventVibration?.('light');
443
+ }
433
444
  });
434
445
 
435
446
  return () => {
436
- detachGesture();
447
+ gesture.removeListener(gestureListener);
437
448
  swiping.removeListener(swipingListener);
438
449
  };
439
450
  }, [animation, navigator]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/foundation",
3
- "version": "0.164.1-beta.2",
3
+ "version": "0.164.1-beta.4",
4
4
  "description": "React Native Component Kits",
5
5
  "main": "index.ts",
6
6
  "scripts": {},