react-native-reanimated 4.4.1 → 4.4.3

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 (95) hide show
  1. package/Common/cpp/reanimated/CSS/interpolation/transforms/TransformOperationInterpolator.cpp +12 -5
  2. package/Common/cpp/reanimated/CSS/misc/ViewStylesRepository.cpp +63 -36
  3. package/Common/cpp/reanimated/CSS/misc/ViewStylesRepository.h +6 -8
  4. package/Common/cpp/reanimated/CSS/svg/values/SVGStrokeDashArray.cpp +5 -0
  5. package/Common/cpp/reanimated/Fabric/ReanimatedMountHook.cpp +25 -12
  6. package/Common/cpp/reanimated/Fabric/ReanimatedMountHook.h +3 -0
  7. package/Common/cpp/reanimated/Fabric/updates/AnimatedPropsRegistry.cpp +54 -24
  8. package/Common/cpp/reanimated/Fabric/updates/AnimatedPropsRegistry.h +13 -6
  9. package/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxyCommon.cpp +6 -2
  10. package/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxyCommon.h +44 -1
  11. package/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Experimental.cpp +125 -43
  12. package/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Legacy.cpp +228 -102
  13. package/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Legacy.h +4 -0
  14. package/Common/cpp/reanimated/LayoutAnimations/SharedTransitions.cpp +8 -3
  15. package/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.cpp +7 -21
  16. package/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.h +0 -16
  17. package/android/CMakeLists.txt +6 -0
  18. package/android/build.gradle.kts +21 -1
  19. package/android/src/main/java/com/swmansion/reanimated/NativeProxy.kt +46 -2
  20. package/android/src/main/java/com/swmansion/reanimated/keyboard/KeyboardAnimationCallback.kt +8 -1
  21. package/apple/reanimated/apple/ReanimatedModule.mm +12 -1
  22. package/compatibility.json +1 -1
  23. package/lib/module/PropsRegistryGarbageCollector.js +3 -6
  24. package/lib/module/PropsRegistryGarbageCollector.js.map +1 -1
  25. package/lib/module/animation/styleAnimation.js +4 -3
  26. package/lib/module/animation/styleAnimation.js.map +1 -1
  27. package/lib/module/common/constants/platform.js +4 -4
  28. package/lib/module/common/constants/platform.js.map +1 -1
  29. package/lib/module/createAnimatedComponent/AnimatedComponent.js +1 -1
  30. package/lib/module/createAnimatedComponent/AnimatedComponent.js.map +1 -1
  31. package/lib/module/createAnimatedComponent/getViewInfo.js +3 -1
  32. package/lib/module/createAnimatedComponent/getViewInfo.js.map +1 -1
  33. package/lib/module/css/component/AnimatedComponent.js +0 -2
  34. package/lib/module/css/component/AnimatedComponent.js.map +1 -1
  35. package/lib/module/css/native/managers/CSSManager.js +5 -5
  36. package/lib/module/css/native/managers/CSSManager.js.map +1 -1
  37. package/lib/module/css/native/managers/CSSTransitionsManager.js +8 -1
  38. package/lib/module/css/native/managers/CSSTransitionsManager.js.map +1 -1
  39. package/lib/module/css/svg/native/processors/stroke.js +9 -5
  40. package/lib/module/css/svg/native/processors/stroke.js.map +1 -1
  41. package/lib/module/layoutReanimation/animationBuilder/ComplexAnimationBuilder.js +6 -3
  42. package/lib/module/layoutReanimation/animationBuilder/ComplexAnimationBuilder.js.map +1 -1
  43. package/lib/module/layoutReanimation/animationsManager.js +39 -11
  44. package/lib/module/layoutReanimation/animationsManager.js.map +1 -1
  45. package/lib/module/mappers.js +1 -1
  46. package/lib/module/mappers.js.map +1 -1
  47. package/lib/module/platform-specific/findHostInstance.js +8 -5
  48. package/lib/module/platform-specific/findHostInstance.js.map +1 -1
  49. package/lib/module/platform-specific/jsVersion.js +1 -1
  50. package/lib/module/updateProps/updateProps.js +3 -2
  51. package/lib/module/updateProps/updateProps.js.map +1 -1
  52. package/lib/module/valueSetter.js +6 -7
  53. package/lib/module/valueSetter.js.map +1 -1
  54. package/lib/typescript/PropsRegistryGarbageCollector.d.ts +0 -1
  55. package/lib/typescript/PropsRegistryGarbageCollector.d.ts.map +1 -1
  56. package/lib/typescript/animation/styleAnimation.d.ts +1 -1
  57. package/lib/typescript/animation/styleAnimation.d.ts.map +1 -1
  58. package/lib/typescript/common/constants/platform.d.ts.map +1 -1
  59. package/lib/typescript/createAnimatedComponent/AnimatedComponent.d.ts.map +1 -1
  60. package/lib/typescript/createAnimatedComponent/commonTypes.d.ts +0 -1
  61. package/lib/typescript/createAnimatedComponent/commonTypes.d.ts.map +1 -1
  62. package/lib/typescript/createAnimatedComponent/getViewInfo.d.ts.map +1 -1
  63. package/lib/typescript/css/component/AnimatedComponent.d.ts +0 -1
  64. package/lib/typescript/css/component/AnimatedComponent.d.ts.map +1 -1
  65. package/lib/typescript/css/native/managers/CSSTransitionsManager.d.ts +5 -1
  66. package/lib/typescript/css/native/managers/CSSTransitionsManager.d.ts.map +1 -1
  67. package/lib/typescript/css/svg/native/processors/stroke.d.ts.map +1 -1
  68. package/lib/typescript/layoutReanimation/animationBuilder/ComplexAnimationBuilder.d.ts +17 -14
  69. package/lib/typescript/layoutReanimation/animationBuilder/ComplexAnimationBuilder.d.ts.map +1 -1
  70. package/lib/typescript/layoutReanimation/animationsManager.d.ts.map +1 -1
  71. package/lib/typescript/platform-specific/findHostInstance.d.ts.map +1 -1
  72. package/lib/typescript/platform-specific/jsVersion.d.ts +1 -1
  73. package/lib/typescript/platform-specific/types.d.ts +1 -0
  74. package/lib/typescript/platform-specific/types.d.ts.map +1 -1
  75. package/lib/typescript/updateProps/updateProps.d.ts.map +1 -1
  76. package/package.json +3 -3
  77. package/scripts/reanimated_utils.rb +7 -0
  78. package/src/PropsRegistryGarbageCollector.ts +3 -6
  79. package/src/animation/styleAnimation.ts +5 -3
  80. package/src/common/constants/platform.ts +4 -4
  81. package/src/createAnimatedComponent/AnimatedComponent.tsx +3 -1
  82. package/src/createAnimatedComponent/commonTypes.ts +0 -1
  83. package/src/createAnimatedComponent/getViewInfo.ts +3 -1
  84. package/src/css/component/AnimatedComponent.tsx +0 -2
  85. package/src/css/native/managers/CSSManager.ts +8 -8
  86. package/src/css/native/managers/CSSTransitionsManager.ts +9 -2
  87. package/src/css/svg/native/processors/stroke.ts +9 -6
  88. package/src/layoutReanimation/animationBuilder/ComplexAnimationBuilder.ts +39 -36
  89. package/src/layoutReanimation/animationsManager.ts +41 -11
  90. package/src/mappers.ts +1 -1
  91. package/src/platform-specific/findHostInstance.ts +7 -7
  92. package/src/platform-specific/jsVersion.ts +1 -1
  93. package/src/platform-specific/types.ts +2 -0
  94. package/src/updateProps/updateProps.ts +3 -2
  95. package/src/valueSetter.ts +7 -7
@@ -276,11 +276,10 @@ std::optional<SurfaceId> LayoutAnimationsProxy_Experimental::endLayoutAnimation(
276
276
  // one after the other, so we need to keep count of how many
277
277
  // were actually triggered, so that we don't cleanup necessary
278
278
  // structures too early
279
- if (layoutAnimation.count > 1) {
280
- layoutAnimation.count--;
279
+ if (--layoutAnimation.count > 0) {
281
280
  return {};
282
281
  }
283
- finishedAnimationTags_.push_back(tag);
282
+ maybeSettledAnimationTags_.insert(tag);
284
283
  auto surfaceId = layoutAnimation.finalView.surfaceId;
285
284
 
286
285
  if (sharedTransitionManager_->tagToName_.contains(tag)) {
@@ -397,7 +396,7 @@ void LayoutAnimationsProxy_Experimental::addOngoingAnimations(SurfaceId surfaceI
397
396
 
398
397
  const auto layoutAnimationIt = layoutAnimations_.find(tag);
399
398
 
400
- if (layoutAnimationIt == layoutAnimations_.end()) {
399
+ if (layoutAnimationIt == layoutAnimations_.end() || layoutAnimationIt->second.isSettled()) {
401
400
  continue;
402
401
  }
403
402
 
@@ -516,11 +515,10 @@ bool LayoutAnimationsProxy_Experimental::startAnimationsRecursively(
516
515
 
517
516
  if (hasExitAnimation) {
518
517
  node->state = ANIMATING;
519
- startExitingAnimation(node);
520
518
  lightNodes_[node->current.tag] = node;
519
+ startExitingAnimation(node);
521
520
  } else {
522
- // TODO (future): add proper cleanup
523
- // layoutAnimationsManager_->clearLayoutAnimationConfig(node->tag);
521
+ layoutAnimationsManager_->clearLayoutAnimationConfig(node->current.tag);
524
522
  }
525
523
 
526
524
  return wantAnimateExit;
@@ -532,10 +530,22 @@ void LayoutAnimationsProxy_Experimental::updateOngoingAnimationTarget(const int
532
530
  }
533
531
 
534
532
  void LayoutAnimationsProxy_Experimental::maybeCancelAnimation(const int tag) const {
535
- if (!layoutAnimations_.contains(tag)) {
533
+ #ifdef ANDROID
534
+ // also invalidate animation starts that are scheduled but haven't run yet,
535
+ // so they don't re-create the animation after this cancellation
536
+ if (const auto it = pendingStarts_.find(tag); it != pendingStarts_.end()) {
537
+ it->second.handle++;
538
+ }
539
+ #endif
540
+ const auto layoutAnimationIt = layoutAnimations_.find(tag);
541
+ if (layoutAnimationIt == layoutAnimations_.end()) {
542
+ return;
543
+ }
544
+ if (layoutAnimationIt->second.isSettled()) {
545
+ // Already settled - cleanupAnimations will erase it together with its updateMap entry.
536
546
  return;
537
547
  }
538
- layoutAnimations_.erase(tag);
548
+ layoutAnimations_.erase(layoutAnimationIt);
539
549
  scheduleOnUI(uiScheduler_, [weakThis = weak_from_this(), tag]() {
540
550
  auto strongThis = weakThis.lock();
541
551
  if (!strongThis) {
@@ -625,12 +635,17 @@ void LayoutAnimationsProxy_Experimental::cleanupAnimations(
625
635
  #ifdef ANDROID
626
636
  restoreOpacityInCaseOfFlakyEnteringAnimation(surfaceId);
627
637
  #endif // ANDROID
628
- for (const auto tag : finishedAnimationTags_) {
629
- auto &updateMap = surfaceManager.getUpdateMap(surfaceId);
630
- layoutAnimations_.erase(tag);
638
+ auto &updateMap = surfaceManager.getUpdateMap(surfaceId);
639
+ for (const auto tag : maybeSettledAnimationTags_) {
640
+ // Skip tags re-animated since they settled (count back above 0).
641
+ const auto layoutAnimationIt = layoutAnimations_.find(tag);
642
+ if (layoutAnimationIt == layoutAnimations_.end() || !layoutAnimationIt->second.isSettled()) {
643
+ continue;
644
+ }
645
+ layoutAnimations_.erase(layoutAnimationIt);
631
646
  updateMap.erase(tag);
632
647
  }
633
- finishedAnimationTags_.clear();
648
+ maybeSettledAnimationTags_.clear();
634
649
  }
635
650
 
636
651
  // MARK: Start Animation
@@ -676,9 +691,24 @@ void LayoutAnimationsProxy_Experimental::startEnteringAnimation(const std::share
676
691
  const auto &parent = node->parent.lock();
677
692
  react_native_assert(parent && "Parent node is nullptr");
678
693
  const auto parentTag = parent->current.tag;
694
+ #ifdef ANDROID
695
+ const auto handle = pendingStarts_[newChildShadowView.tag].handle;
696
+ pendingStarts_[newChildShadowView.tag].count++;
697
+ #endif
679
698
 
680
699
  scheduleOnUI(
681
- uiScheduler_, [weakThis = weak_from_this(), finalView, currentView, newChildShadowView, parentTag, opacity]() {
700
+ uiScheduler_,
701
+ [weakThis = weak_from_this(),
702
+ finalView,
703
+ currentView,
704
+ newChildShadowView,
705
+ parentTag,
706
+ opacity
707
+ #ifdef ANDROID
708
+ ,
709
+ handle
710
+ #endif
711
+ ]() {
682
712
  auto strongThis = weakThis.lock();
683
713
  if (!strongThis) {
684
714
  return;
@@ -688,6 +718,12 @@ void LayoutAnimationsProxy_Experimental::startEnteringAnimation(const std::share
688
718
  const auto tag = newChildShadowView.tag;
689
719
  {
690
720
  auto lock = std::unique_lock<std::recursive_mutex>(strongThis->mutex);
721
+ #ifdef ANDROID
722
+ if (consumeIsCancelled(strongThis->pendingStarts_, tag, handle)) {
723
+ // the view was removed before this start could run
724
+ return;
725
+ }
726
+ #endif
691
727
  strongThis->layoutAnimations_[tag] = {
692
728
  .finalView = newChildShadowView,
693
729
  .currentView = newChildShadowView,
@@ -721,38 +757,63 @@ void LayoutAnimationsProxy_Experimental::startExitingAnimation(const std::shared
721
757
  const auto &parent = node->parent.lock();
722
758
  react_native_assert(parent && "Parent node is nullptr");
723
759
  const auto parentTag = parent->current.tag;
760
+ #ifdef ANDROID
761
+ const auto handle = pendingStarts_[tag].handle;
762
+ pendingStarts_[tag].count++;
763
+ #endif
724
764
 
725
- scheduleOnUI(uiScheduler_, [weakThis = weak_from_this(), tag, parentTag, oldChildShadowView, surfaceId]() {
726
- auto strongThis = weakThis.lock();
727
- if (!strongThis) {
728
- return;
729
- }
765
+ scheduleOnUI(
766
+ uiScheduler_,
767
+ [weakThis = weak_from_this(),
768
+ tag,
769
+ parentTag,
770
+ oldChildShadowView,
771
+ surfaceId
772
+ #ifdef ANDROID
773
+ ,
774
+ handle
775
+ #endif
776
+ ]() {
777
+ auto strongThis = weakThis.lock();
778
+ if (!strongThis) {
779
+ return;
780
+ }
730
781
 
731
- auto oldView = oldChildShadowView;
732
- Rect window{};
733
- {
734
- auto &mutex = strongThis->mutex;
735
- auto lock = std::unique_lock<std::recursive_mutex>(mutex);
736
- oldView = strongThis->maybeCreateLayoutAnimation(oldView, oldView, parentTag);
737
- window = strongThis->surfaceManager.getWindow(surfaceId);
738
- }
782
+ auto oldView = oldChildShadowView;
783
+ Rect window{};
784
+ {
785
+ auto &mutex = strongThis->mutex;
786
+ auto lock = std::unique_lock<std::recursive_mutex>(mutex);
787
+ #ifdef ANDROID
788
+ if (consumeIsCancelled(strongThis->pendingStarts_, tag, handle)) {
789
+ // the view was removed (e.g. its subtree was force-ended by a screen
790
+ // pop) before this start could run — its Remove+Delete are already on
791
+ // their way to the mounting layer, so starting the animation now
792
+ // would emit updates for a view that's about to be deleted
793
+ strongThis->layoutAnimationsManager_->clearLayoutAnimationConfig(tag);
794
+ return;
795
+ }
796
+ #endif
797
+ oldView = strongThis->maybeCreateLayoutAnimation(oldView, oldView, parentTag);
798
+ window = strongThis->surfaceManager.getWindow(surfaceId);
799
+ }
739
800
 
740
- const Snapshot values(oldView, window);
801
+ const Snapshot values(oldView, window);
741
802
 
742
- auto &uiRuntime = strongThis->uiRuntime_;
743
- const jsi::Object yogaValues(uiRuntime);
744
- yogaValues.setProperty(uiRuntime, "currentOriginX", values.x);
745
- yogaValues.setProperty(uiRuntime, "currentGlobalOriginX", values.x);
746
- yogaValues.setProperty(uiRuntime, "currentOriginY", values.y);
747
- yogaValues.setProperty(uiRuntime, "currentGlobalOriginY", values.y);
748
- yogaValues.setProperty(uiRuntime, "currentWidth", values.width);
749
- yogaValues.setProperty(uiRuntime, "currentHeight", values.height);
750
- yogaValues.setProperty(uiRuntime, "windowWidth", values.windowWidth);
751
- yogaValues.setProperty(uiRuntime, "windowHeight", values.windowHeight);
752
- strongThis->layoutAnimationsManager_->startLayoutAnimation(
753
- uiRuntime, tag, LayoutAnimationType::EXITING, yogaValues);
754
- strongThis->layoutAnimationsManager_->clearLayoutAnimationConfig(tag);
755
- });
803
+ auto &uiRuntime = strongThis->uiRuntime_;
804
+ const jsi::Object yogaValues(uiRuntime);
805
+ yogaValues.setProperty(uiRuntime, "currentOriginX", values.x);
806
+ yogaValues.setProperty(uiRuntime, "currentGlobalOriginX", values.x);
807
+ yogaValues.setProperty(uiRuntime, "currentOriginY", values.y);
808
+ yogaValues.setProperty(uiRuntime, "currentGlobalOriginY", values.y);
809
+ yogaValues.setProperty(uiRuntime, "currentWidth", values.width);
810
+ yogaValues.setProperty(uiRuntime, "currentHeight", values.height);
811
+ yogaValues.setProperty(uiRuntime, "windowWidth", values.windowWidth);
812
+ yogaValues.setProperty(uiRuntime, "windowHeight", values.windowHeight);
813
+ strongThis->layoutAnimationsManager_->startLayoutAnimation(
814
+ uiRuntime, tag, LayoutAnimationType::EXITING, yogaValues);
815
+ strongThis->layoutAnimationsManager_->clearLayoutAnimationConfig(tag);
816
+ });
756
817
  }
757
818
 
758
819
  void LayoutAnimationsProxy_Experimental::startLayoutAnimation(const std::shared_ptr<LightNode> &node) const {
@@ -763,9 +824,24 @@ void LayoutAnimationsProxy_Experimental::startLayoutAnimation(const std::shared_
763
824
  const auto &parent = node->parent.lock();
764
825
  react_native_assert(parent && "Parent node is nullptr");
765
826
  const auto parentTag = parent->current.tag;
827
+ #ifdef ANDROID
828
+ const auto handle = pendingStarts_[tag].handle;
829
+ pendingStarts_[tag].count++;
830
+ #endif
766
831
 
767
832
  scheduleOnUI(
768
- uiScheduler_, [weakThis = weak_from_this(), surfaceId, oldChildShadowView, newChildShadowView, parentTag, tag]() {
833
+ uiScheduler_,
834
+ [weakThis = weak_from_this(),
835
+ surfaceId,
836
+ oldChildShadowView,
837
+ newChildShadowView,
838
+ parentTag,
839
+ tag
840
+ #ifdef ANDROID
841
+ ,
842
+ handle
843
+ #endif
844
+ ]() {
769
845
  auto strongThis = weakThis.lock();
770
846
  if (!strongThis) {
771
847
  return;
@@ -776,6 +852,12 @@ void LayoutAnimationsProxy_Experimental::startLayoutAnimation(const std::shared_
776
852
  {
777
853
  auto &mutex = strongThis->mutex;
778
854
  auto lock = std::unique_lock<std::recursive_mutex>(mutex);
855
+ #ifdef ANDROID
856
+ if (consumeIsCancelled(strongThis->pendingStarts_, tag, handle)) {
857
+ // the view was removed before this start could run
858
+ return;
859
+ }
860
+ #endif
779
861
  oldView = strongThis->maybeCreateLayoutAnimation(oldView, newChildShadowView, parentTag);
780
862
  window = strongThis->surfaceManager.getWindow(surfaceId);
781
863
  }