react-native-reanimated 3.19.1 → 3.19.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.
Files changed (48) hide show
  1. package/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy.cpp +115 -4
  2. package/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy.h +32 -3
  3. package/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.cpp +12 -1
  4. package/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.h +3 -0
  5. package/Common/cpp/reanimated/Tools/PlatformDepMethodsHolder.h +9 -1
  6. package/android/CMakeLists.txt +10 -3
  7. package/android/src/fabric/java/com/swmansion/reanimated/NativeProxy.java +19 -0
  8. package/android/src/main/cpp/reanimated/android/NativeProxy.cpp +23 -3
  9. package/android/src/main/cpp/reanimated/android/NativeProxy.h +4 -0
  10. package/lib/module/ViewDescriptorsSet.js +5 -1
  11. package/lib/module/ViewDescriptorsSet.js.map +1 -1
  12. package/lib/module/createAnimatedComponent/NativeEventsManager.js +1 -1
  13. package/lib/module/createAnimatedComponent/NativeEventsManager.js.map +1 -1
  14. package/lib/module/createAnimatedComponent/createAnimatedComponent.js +28 -11
  15. package/lib/module/createAnimatedComponent/createAnimatedComponent.js.map +1 -1
  16. package/lib/module/layoutReanimation/web/Easing.web.js +14 -0
  17. package/lib/module/layoutReanimation/web/Easing.web.js.map +1 -1
  18. package/lib/module/layoutReanimation/web/componentUtils.js +8 -4
  19. package/lib/module/layoutReanimation/web/componentUtils.js.map +1 -1
  20. package/lib/module/layoutReanimation/web/config.js.map +1 -1
  21. package/lib/module/platform-specific/jsVersion.js +1 -1
  22. package/lib/module/platformFunctions/dispatchCommand.js +10 -0
  23. package/lib/module/platformFunctions/dispatchCommand.js.map +1 -1
  24. package/lib/module/platformFunctions/scrollTo.web.js +11 -7
  25. package/lib/module/platformFunctions/scrollTo.web.js.map +1 -1
  26. package/lib/typescript/ViewDescriptorsSet.d.ts +1 -0
  27. package/lib/typescript/ViewDescriptorsSet.d.ts.map +1 -1
  28. package/lib/typescript/createAnimatedComponent/createAnimatedComponent.d.ts.map +1 -1
  29. package/lib/typescript/helperTypes.d.ts +4 -1
  30. package/lib/typescript/helperTypes.d.ts.map +1 -1
  31. package/lib/typescript/layoutReanimation/web/Easing.web.d.ts +2 -0
  32. package/lib/typescript/layoutReanimation/web/Easing.web.d.ts.map +1 -1
  33. package/lib/typescript/layoutReanimation/web/componentUtils.d.ts.map +1 -1
  34. package/lib/typescript/layoutReanimation/web/config.d.ts +3 -3
  35. package/lib/typescript/layoutReanimation/web/config.d.ts.map +1 -1
  36. package/lib/typescript/platform-specific/jsVersion.d.ts +1 -1
  37. package/lib/typescript/platformFunctions/scrollTo.web.d.ts.map +1 -1
  38. package/package.json +1 -1
  39. package/src/ViewDescriptorsSet.ts +9 -0
  40. package/src/createAnimatedComponent/NativeEventsManager.ts +1 -1
  41. package/src/createAnimatedComponent/createAnimatedComponent.tsx +35 -24
  42. package/src/helperTypes.ts +5 -1
  43. package/src/layoutReanimation/web/Easing.web.ts +32 -0
  44. package/src/layoutReanimation/web/componentUtils.ts +21 -5
  45. package/src/layoutReanimation/web/config.ts +3 -2
  46. package/src/platform-specific/jsVersion.ts +1 -1
  47. package/src/platformFunctions/dispatchCommand.ts +23 -2
  48. package/src/platformFunctions/scrollTo.web.ts +9 -3
@@ -37,6 +37,9 @@ std::optional<MountingTransaction> LayoutAnimationsProxy::pullTransaction(
37
37
 
38
38
  addOngoingAnimations(surfaceId, filteredMutations);
39
39
 
40
+ #ifdef ANDROID
41
+ restoreOpacityInCaseOfFlakyEnteringAnimation(surfaceId);
42
+ #endif // ANDROID
40
43
  for (const auto tag : finishedAnimationTags_) {
41
44
  auto &updateMap = surfaceManager.getUpdateMap(surfaceId);
42
45
  layoutAnimations_.erase(tag);
@@ -403,7 +406,36 @@ void LayoutAnimationsProxy::addOngoingAnimations(
403
406
  SurfaceId surfaceId,
404
407
  ShadowViewMutationList &mutations) const {
405
408
  auto &updateMap = surfaceManager.getUpdateMap(surfaceId);
409
+ #ifdef ANDROID
410
+ std::vector<int> tagsToUpdate;
406
411
  for (auto &[tag, updateValues] : updateMap) {
412
+ tagsToUpdate.push_back(tag);
413
+ }
414
+
415
+ auto maybeCorrectedTags = preserveMountedTags_(tagsToUpdate);
416
+ if (!maybeCorrectedTags.has_value()) {
417
+ return;
418
+ }
419
+
420
+ auto correctedTags = maybeCorrectedTags->get();
421
+
422
+ // since the map is not updated, we can assume that the ordering of tags in
423
+ // correctedTags matches the iterator
424
+ int i = -1;
425
+ #endif
426
+ for (auto &[tag, updateValues] : updateMap) {
427
+ #ifdef ANDROID
428
+ i++;
429
+ if (correctedTags[i] == -1) {
430
+ // skip views that have not been mounted yet
431
+ // on Android we start entering animations from the JS thread
432
+ // so it might happen, that the first frame of the animation goes through
433
+ // before the view is first mounted
434
+ // https://github.com/software-mansion/react-native-reanimated/issues/7493
435
+ continue;
436
+ }
437
+ #endif
438
+
407
439
  auto layoutAnimationIt = layoutAnimations_.find(tag);
408
440
 
409
441
  if (layoutAnimationIt == layoutAnimations_.end()) {
@@ -411,7 +443,7 @@ void LayoutAnimationsProxy::addOngoingAnimations(
411
443
  }
412
444
 
413
445
  auto &layoutAnimation = layoutAnimationIt->second;
414
-
446
+ layoutAnimation.isViewAlreadyMounted = true;
415
447
  auto newView = std::make_shared<ShadowView>(*layoutAnimation.finalView);
416
448
  newView->props = updateValues.newProps;
417
449
  updateLayoutMetrics(newView->layoutMetrics, updateValues.frame);
@@ -648,11 +680,13 @@ void LayoutAnimationsProxy::createLayoutAnimation(
648
680
  #if REACT_NATIVE_MINOR_VERSION >= 78
649
681
  layoutAnimations_.insert_or_assign(
650
682
  tag,
651
- LayoutAnimation{finalView, currentView, mutation.parentTag, {}, count});
683
+ LayoutAnimation{
684
+ finalView, currentView, mutation.parentTag, {}, false, count});
652
685
  #else
653
686
  auto parentView = std::make_shared<ShadowView>(mutation.parentShadowView);
654
687
  layoutAnimations_.insert_or_assign(
655
- tag, LayoutAnimation{finalView, currentView, parentView, {}, count});
688
+ tag,
689
+ LayoutAnimation{finalView, currentView, parentView, {}, false, count});
656
690
  #endif // REACT_NATIVE_MINOR_VERSION >= 78
657
691
  }
658
692
 
@@ -870,7 +904,12 @@ void LayoutAnimationsProxy::maybeRestoreOpacity(
870
904
  if (layoutAnimation.opacity && !newStyle.hasProperty(uiRuntime_, "opacity")) {
871
905
  newStyle.setProperty(
872
906
  uiRuntime_, "opacity", jsi::Value(*layoutAnimation.opacity));
873
- layoutAnimation.opacity.reset();
907
+ if (layoutAnimation.isViewAlreadyMounted) {
908
+ // We want to reset opacity only when we are sure that this update will be
909
+ // applied to the native view. Otherwise, we want to update opacity using
910
+ // the `restoreOpacityInCaseOfFlakyEnteringAnimation` method.
911
+ layoutAnimation.opacity.reset();
912
+ }
874
913
  }
875
914
  }
876
915
 
@@ -887,6 +926,78 @@ void LayoutAnimationsProxy::maybeUpdateWindowDimensions(
887
926
  }
888
927
  }
889
928
 
929
+ #ifdef ANDROID
930
+ /*
931
+ * It is possible that we may finish the layout animation before the native view
932
+ * is mounted. If the view wasn't mounted, we wouldn't be able to restore the
933
+ * opacity of the view. To fix this, we need to schedule a React update that
934
+ * will restore the view's opacity. This is safe because we'll use the same
935
+ * queue where React has already scheduled (but not yet executed) the view
936
+ * mounting, so the opacity update will execute after the view is mounted.
937
+ */
938
+ void LayoutAnimationsProxy::restoreOpacityInCaseOfFlakyEnteringAnimation(
939
+ SurfaceId surfaceId) const {
940
+ std::vector<std::pair<double, Tag>> opacityToRestore;
941
+ for (const auto tag : finishedAnimationTags_) {
942
+ const auto &opacity = layoutAnimations_[tag].opacity;
943
+ if (opacity.has_value()) {
944
+ opacityToRestore.emplace_back(
945
+ std::pair<double, Tag>{opacity.value(), tag});
946
+ }
947
+ }
948
+ if (opacityToRestore.empty()) {
949
+ // Animation was successfully finished, and the opacity was restored, so we
950
+ // don't need to do anything. Only the Entering animation has a set opacity
951
+ // value.
952
+ return;
953
+ }
954
+ const auto weakThis = weak_from_this();
955
+ jsInvoker_->invokeAsync([=](jsi::Runtime &runtime) {
956
+ const auto self = weakThis.lock();
957
+ if (!self) {
958
+ return;
959
+ }
960
+ self->uiManager_->getShadowTreeRegistry().visit(
961
+ surfaceId, [=](ShadowTree const &shadowTree) {
962
+ shadowTree.commit(
963
+ [=](RootShadowNode const &oldRootShadowNode) {
964
+ const auto self = weakThis.lock();
965
+ if (!self) {
966
+ return cloneShadowTreeWithNewProps(oldRootShadowNode, {});
967
+ }
968
+ const auto &rootShadowNode =
969
+ static_cast<const ShadowNode &>(oldRootShadowNode);
970
+ PropsMap propsMap;
971
+ for (const auto &[opacity, tag] : opacityToRestore) {
972
+ const auto *targetShadowNode =
973
+ self->findInShadowTreeByTag(rootShadowNode, tag);
974
+ if (targetShadowNode != nullptr) {
975
+ propsMap[&targetShadowNode->getFamily()].emplace_back(
976
+ folly::dynamic::object("opacity", opacity));
977
+ }
978
+ }
979
+ return cloneShadowTreeWithNewProps(oldRootShadowNode, propsMap);
980
+ },
981
+ {});
982
+ });
983
+ });
984
+ }
985
+
986
+ const ShadowNode *LayoutAnimationsProxy::findInShadowTreeByTag(
987
+ const ShadowNode &node,
988
+ Tag tag) const {
989
+ if (node.getTag() == tag) {
990
+ return const_cast<const ShadowNode *>(&node);
991
+ }
992
+ for (auto &child : node.getChildren()) {
993
+ if (const auto result = findInShadowTreeByTag(*child, tag)) {
994
+ return result;
995
+ }
996
+ }
997
+ return nullptr;
998
+ }
999
+ #endif // ANDROID
1000
+
890
1001
  } // namespace reanimated
891
1002
 
892
1003
  #endif // RCT_NEW_ARCH_ENABLED
@@ -4,12 +4,15 @@
4
4
  #include <reanimated/Fabric/PropsRegistry.h>
5
5
  #include <reanimated/LayoutAnimations/LayoutAnimationsManager.h>
6
6
  #include <reanimated/LayoutAnimations/LayoutAnimationsUtils.h>
7
+ #include <reanimated/Tools/PlatformDepMethodsHolder.h>
7
8
 
8
9
  #include <worklets/Tools/UIScheduler.h>
9
10
 
10
11
  #include <react/renderer/componentregistry/ComponentDescriptorFactory.h>
11
12
  #include <react/renderer/mounting/MountingOverrideDelegate.h>
12
13
  #include <react/renderer/mounting/ShadowView.h>
14
+ #include <react/renderer/scheduler/Scheduler.h>
15
+ #include <react/renderer/uimanager/UIManagerBinding.h>
13
16
 
14
17
  #include <memory>
15
18
  #include <string>
@@ -31,6 +34,7 @@ struct LayoutAnimation {
31
34
  std::shared_ptr<ShadowView> finalView, currentView, parentView;
32
35
  #endif // REACT_NATIVE_MINOR_VERSION >= 78
33
36
  std::optional<double> opacity;
37
+ bool isViewAlreadyMounted = false;
34
38
  int count = 1;
35
39
  LayoutAnimation &operator=(const LayoutAnimation &other) = default;
36
40
  };
@@ -50,17 +54,38 @@ struct LayoutAnimationsProxy
50
54
  SharedComponentDescriptorRegistry componentDescriptorRegistry_;
51
55
  jsi::Runtime &uiRuntime_;
52
56
  const std::shared_ptr<UIScheduler> uiScheduler_;
57
+ #ifdef ANDROID
58
+ PreserveMountedTagsFunction preserveMountedTags_;
59
+ std::shared_ptr<UIManager> uiManager_;
60
+ std::shared_ptr<CallInvoker> jsInvoker_;
61
+ #endif
62
+
53
63
  LayoutAnimationsProxy(
54
64
  std::shared_ptr<LayoutAnimationsManager> layoutAnimationsManager,
55
65
  SharedComponentDescriptorRegistry componentDescriptorRegistry,
56
66
  ContextContainer::Shared contextContainer,
57
67
  jsi::Runtime &uiRuntime,
58
- const std::shared_ptr<UIScheduler> uiScheduler)
68
+ const std::shared_ptr<UIScheduler> uiScheduler
69
+ #ifdef ANDROID
70
+ ,
71
+ PreserveMountedTagsFunction filterUnmountedTagsFunction,
72
+ std::shared_ptr<UIManager> uiManager,
73
+ std::shared_ptr<CallInvoker> jsInvoker
74
+ #endif
75
+ )
59
76
  : layoutAnimationsManager_(layoutAnimationsManager),
60
77
  contextContainer_(contextContainer),
61
78
  componentDescriptorRegistry_(componentDescriptorRegistry),
62
79
  uiRuntime_(uiRuntime),
63
- uiScheduler_(uiScheduler) {}
80
+ uiScheduler_(uiScheduler)
81
+ #ifdef ANDROID
82
+ ,
83
+ preserveMountedTags_(filterUnmountedTagsFunction),
84
+ uiManager_(uiManager),
85
+ jsInvoker_(jsInvoker)
86
+ #endif // ANDROID
87
+ {
88
+ }
64
89
 
65
90
  void startEnteringAnimation(const int tag, ShadowViewMutation &mutation)
66
91
  const;
@@ -132,7 +157,11 @@ struct LayoutAnimationsProxy
132
157
 
133
158
  const ComponentDescriptor &getComponentDescriptorForShadowView(
134
159
  const ShadowView &shadowView) const;
135
-
160
+ #ifdef ANDROID
161
+ void restoreOpacityInCaseOfFlakyEnteringAnimation(SurfaceId surfaceId) const;
162
+ const ShadowNode *findInShadowTreeByTag(const ShadowNode &node, Tag tag)
163
+ const;
164
+ #endif // ANDROID
136
165
  // MountingOverrideDelegate
137
166
 
138
167
  bool shouldOverridePullTransaction() const override;
@@ -74,6 +74,10 @@ ReanimatedModuleProxy::ReanimatedModuleProxy(
74
74
  layoutAnimationsManager_(
75
75
  std::make_shared<LayoutAnimationsManager>(jsLogger_)),
76
76
  #ifdef RCT_NEW_ARCH_ENABLED
77
+ #ifdef ANDROID
78
+ filterUnmountedTagsFunction_(
79
+ platformDepMethodsHolder.filterUnmountedTagsFunction),
80
+ #endif // ANDROID
77
81
  propsRegistry_(std::make_shared<PropsRegistry>()),
78
82
  #else
79
83
  obtainPropFunction_(platformDepMethodsHolder.obtainPropFunction),
@@ -943,7 +947,14 @@ void ReanimatedModuleProxy::initializeLayoutAnimationsProxy() {
943
947
  componentDescriptorRegistry,
944
948
  scheduler->getContextContainer(),
945
949
  uiWorkletRuntime_->getJSIRuntime(),
946
- workletsModuleProxy_->getUIScheduler());
950
+ workletsModuleProxy_->getUIScheduler()
951
+ #ifdef ANDROID
952
+ ,
953
+ filterUnmountedTagsFunction_,
954
+ uiManager_,
955
+ jsInvoker_
956
+ #endif
957
+ );
947
958
  }
948
959
  }
949
960
 
@@ -223,6 +223,9 @@ class ReanimatedModuleProxy
223
223
  std::shared_ptr<LayoutAnimationsManager> layoutAnimationsManager_;
224
224
 
225
225
  #ifdef RCT_NEW_ARCH_ENABLED
226
+ #ifdef ANDROID
227
+ const PreserveMountedTagsFunction filterUnmountedTagsFunction_;
228
+ #endif // ANDROID
226
229
  std::unordered_set<std::string>
227
230
  animatablePropNames_; // filled by configureProps
228
231
  std::shared_ptr<UIManager> uiManager_;
@@ -6,6 +6,8 @@
6
6
  #include <react/renderer/core/ReactPrimitives.h>
7
7
  #endif
8
8
 
9
+ #include <memory>
10
+ #include <optional>
9
11
  #include <string>
10
12
  #include <utility>
11
13
  #include <vector>
@@ -53,6 +55,10 @@ using ObtainPropFunction =
53
55
 
54
56
  using RequestRenderFunction =
55
57
  std::function<void(std::function<void(const double)>)>;
58
+ #ifdef ANDROID
59
+ using PreserveMountedTagsFunction =
60
+ std::function<std::optional<std::unique_ptr<int[]>>(std::vector<int> &)>;
61
+ #endif // ANDROID
56
62
  using GetAnimationTimestampFunction = std::function<double(void)>;
57
63
 
58
64
  using ProgressLayoutAnimationFunction =
@@ -75,7 +81,9 @@ using MaybeFlushUIUpdatesQueueFunction = std::function<void()>;
75
81
  struct PlatformDepMethodsHolder {
76
82
  RequestRenderFunction requestRender;
77
83
  #ifdef RCT_NEW_ARCH_ENABLED
78
- // nothing
84
+ #ifdef ANDROID
85
+ PreserveMountedTagsFunction filterUnmountedTagsFunction;
86
+ #endif // ANDROID
79
87
  #else
80
88
  UpdatePropsFunction updatePropsFunction;
81
89
  ScrollToFunction scrollToFunction;
@@ -15,9 +15,16 @@ string(APPEND CMAKE_CXX_FLAGS
15
15
  " -DREACT_NATIVE_MINOR_VERSION=${REACT_NATIVE_MINOR_VERSION}\
16
16
  -DREANIMATED_VERSION=${REANIMATED_VERSION}")
17
17
 
18
- string(APPEND CMAKE_CXX_FLAGS
19
- " -fexceptions -fno-omit-frame-pointer -frtti -fstack-protector-all\
20
- -std=c++${CMAKE_CXX_STANDARD} -Wall -Werror")
18
+ string(APPEND CMAKE_CXX_FLAGS " -fno-omit-frame-pointer -fstack-protector-all")
19
+
20
+ if(ReactAndroid_VERSION_MINOR GREATER_EQUAL 80)
21
+ include("${REACT_NATIVE_DIR}/ReactCommon/cmake-utils/\
22
+ react-native-flags.cmake")
23
+ target_compile_reactnative_options(reanimated PUBLIC)
24
+ else()
25
+ string(APPEND CMAKE_CXX_FLAGS
26
+ " -fexceptions -frtti -std=c++${CMAKE_CXX_STANDARD} -Wall -Werror")
27
+ endif()
21
28
 
22
29
  if(${IS_NEW_ARCHITECTURE_ENABLED})
23
30
  string(APPEND CMAKE_CXX_FLAGS " -DRCT_NEW_ARCH_ENABLED")
@@ -4,6 +4,7 @@ import androidx.annotation.OptIn;
4
4
  import com.facebook.jni.HybridData;
5
5
  import com.facebook.proguard.annotations.DoNotStrip;
6
6
  import com.facebook.react.bridge.ReactApplicationContext;
7
+ import com.facebook.react.bridge.UiThreadUtil;
7
8
  import com.facebook.react.common.annotations.FrameworkAPI;
8
9
  import com.facebook.react.fabric.FabricUIManager;
9
10
  import com.facebook.react.turbomodule.core.CallInvokerHolderImpl;
@@ -32,6 +33,8 @@ public class NativeProxy extends NativeProxyCommon {
32
33
  */
33
34
  private final AtomicBoolean mInvalidated = new AtomicBoolean(false);
34
35
 
36
+ private final FabricUIManager mFabricUIManager;
37
+
35
38
  public @OptIn(markerClass = FrameworkAPI.class) NativeProxy(
36
39
  ReactApplicationContext context, WorkletsModule workletsModule) {
37
40
  super(context);
@@ -39,6 +42,7 @@ public class NativeProxy extends NativeProxyCommon {
39
42
 
40
43
  FabricUIManager fabricUIManager =
41
44
  (FabricUIManager) UIManagerHelper.getUIManager(context, UIManagerType.FABRIC);
45
+ mFabricUIManager = fabricUIManager;
42
46
 
43
47
  LayoutAnimations LayoutAnimations = new LayoutAnimations(context);
44
48
 
@@ -72,6 +76,21 @@ public class NativeProxy extends NativeProxyCommon {
72
76
 
73
77
  public native void performOperations();
74
78
 
79
+ @DoNotStrip
80
+ public boolean preserveMountedTags(int[] tags) {
81
+ if (!UiThreadUtil.isOnUiThread()) {
82
+ return false;
83
+ }
84
+
85
+ for (int i = 0; i < tags.length; i++) {
86
+ if (mFabricUIManager.resolveView(tags[i]) == null) {
87
+ tags[i] = -1;
88
+ }
89
+ }
90
+
91
+ return true;
92
+ }
93
+
75
94
  @Override
76
95
  protected HybridData getHybridData() {
77
96
  return mHybridData;
@@ -220,7 +220,26 @@ void NativeProxy::maybeFlushUIUpdatesQueue() {
220
220
  }
221
221
 
222
222
  #ifdef RCT_NEW_ARCH_ENABLED
223
- // nothing
223
+ std::optional<std::unique_ptr<int[]>> NativeProxy::preserveMountedTags(
224
+ std::vector<int> &tags) {
225
+ if (tags.empty()) {
226
+ return {};
227
+ }
228
+
229
+ static const auto method =
230
+ getJniMethod<jboolean(jni::alias_ref<jni::JArrayInt>)>(
231
+ "preserveMountedTags");
232
+ auto jArrayInt = jni::JArrayInt::newArray(tags.size());
233
+ jArrayInt->setRegion(0, tags.size(), tags.data());
234
+
235
+ if (!method(javaPart_.get(), jArrayInt)) {
236
+ return {};
237
+ }
238
+
239
+ auto region = jArrayInt->getRegion(0, tags.size());
240
+ return region;
241
+ }
242
+
224
243
  #else
225
244
  jsi::Value NativeProxy::obtainProp(
226
245
  jsi::Runtime &rt,
@@ -434,7 +453,8 @@ PlatformDepMethodsHolder NativeProxy::getPlatformDependentMethods() {
434
453
  auto requestRender = bindThis(&NativeProxy::requestRender);
435
454
 
436
455
  #ifdef RCT_NEW_ARCH_ENABLED
437
- // nothing
456
+ auto preserveMountedTags = bindThis(&NativeProxy::preserveMountedTags);
457
+
438
458
  #else
439
459
  auto configurePropsFunction = bindThis(&NativeProxy::configureProps);
440
460
  #endif
@@ -468,7 +488,7 @@ PlatformDepMethodsHolder NativeProxy::getPlatformDependentMethods() {
468
488
  return {
469
489
  requestRender,
470
490
  #ifdef RCT_NEW_ARCH_ENABLED
471
- // nothing
491
+ preserveMountedTags,
472
492
  #else
473
493
  updatePropsFunction,
474
494
  scrollToFunction,
@@ -183,6 +183,10 @@ class NativeProxy : public jni::HybridClass<NativeProxy> {
183
183
  // std::shared_ptr<EventListener> eventListener_;
184
184
  #endif // RCT_NEW_ARCH_ENABLED
185
185
  void installJSIBindings();
186
+ #ifdef RCT_NEW_ARCH_ENABLED
187
+ std::optional<std::unique_ptr<int[]>> preserveMountedTags(
188
+ std::vector<int> &tags);
189
+ #endif // RCT_NEW_ARCH_ENABLED
186
190
  PlatformDepMethodsHolder getPlatformDependentMethods();
187
191
  void setupLayoutAnimations();
188
192
 
@@ -3,9 +3,11 @@
3
3
  import { makeMutable } from "./core.js";
4
4
  export function makeViewDescriptorsSet() {
5
5
  const shareableViewDescriptors = makeMutable([]);
6
+ const viewTags = new Set();
6
7
  const data = {
7
8
  shareableViewDescriptors,
8
9
  add: item => {
10
+ viewTags.add(item.tag);
9
11
  shareableViewDescriptors.modify(descriptors => {
10
12
  'worklet';
11
13
 
@@ -19,6 +21,7 @@ export function makeViewDescriptorsSet() {
19
21
  }, false);
20
22
  },
21
23
  remove: viewTag => {
24
+ viewTags.delete(viewTag);
22
25
  shareableViewDescriptors.modify(descriptors => {
23
26
  'worklet';
24
27
 
@@ -28,7 +31,8 @@ export function makeViewDescriptorsSet() {
28
31
  }
29
32
  return descriptors;
30
33
  }, false);
31
- }
34
+ },
35
+ has: viewTag => viewTags.has(viewTag)
32
36
  };
33
37
  return data;
34
38
  }
@@ -1 +1 @@
1
- {"version":3,"names":["makeMutable","makeViewDescriptorsSet","shareableViewDescriptors","data","add","item","modify","descriptors","index","findIndex","descriptor","tag","push","remove","viewTag","splice"],"sourceRoot":"../../src","sources":["ViewDescriptorsSet.ts"],"mappings":"AAAA,YAAY;;AAEZ,SAASA,WAAW,QAAQ,WAAQ;AASpC,OAAO,SAASC,sBAAsBA,CAAA,EAAuB;EAC3D,MAAMC,wBAAwB,GAAGF,WAAW,CAAe,EAAE,CAAC;EAC9D,MAAMG,IAAwB,GAAG;IAC/BD,wBAAwB;IACxBE,GAAG,EAAGC,IAAgB,IAAK;MACzBH,wBAAwB,CAACI,MAAM,CAAEC,WAAW,IAAK;QAC/C,SAAS;;QACT,MAAMC,KAAK,GAAGD,WAAW,CAACE,SAAS,CAChCC,UAAU,IAAKA,UAAU,CAACC,GAAG,KAAKN,IAAI,CAACM,GAC1C,CAAC;QACD,IAAIH,KAAK,KAAK,CAAC,CAAC,EAAE;UAChBD,WAAW,CAACC,KAAK,CAAC,GAAGH,IAAI;QAC3B,CAAC,MAAM;UACLE,WAAW,CAACK,IAAI,CAACP,IAAI,CAAC;QACxB;QACA,OAAOE,WAAW;MACpB,CAAC,EAAE,KAAK,CAAC;IACX,CAAC;IAEDM,MAAM,EAAGC,OAAe,IAAK;MAC3BZ,wBAAwB,CAACI,MAAM,CAAEC,WAAW,IAAK;QAC/C,SAAS;;QACT,MAAMC,KAAK,GAAGD,WAAW,CAACE,SAAS,CAChCC,UAAU,IAAKA,UAAU,CAACC,GAAG,KAAKG,OACrC,CAAC;QACD,IAAIN,KAAK,KAAK,CAAC,CAAC,EAAE;UAChBD,WAAW,CAACQ,MAAM,CAACP,KAAK,EAAE,CAAC,CAAC;QAC9B;QACA,OAAOD,WAAW;MACpB,CAAC,EAAE,KAAK,CAAC;IACX;EACF,CAAC;EACD,OAAOJ,IAAI;AACb","ignoreList":[]}
1
+ {"version":3,"names":["makeMutable","makeViewDescriptorsSet","shareableViewDescriptors","viewTags","Set","data","add","item","tag","modify","descriptors","index","findIndex","descriptor","push","remove","viewTag","delete","splice","has"],"sourceRoot":"../../src","sources":["ViewDescriptorsSet.ts"],"mappings":"AAAA,YAAY;;AAEZ,SAASA,WAAW,QAAQ,WAAQ;AAUpC,OAAO,SAASC,sBAAsBA,CAAA,EAAuB;EAC3D,MAAMC,wBAAwB,GAAGF,WAAW,CAAe,EAAE,CAAC;EAC9D,MAAMG,QAAQ,GAAG,IAAIC,GAAG,CAAS,CAAC;EAElC,MAAMC,IAAwB,GAAG;IAC/BH,wBAAwB;IAExBI,GAAG,EAAGC,IAAgB,IAAK;MACzBJ,QAAQ,CAACG,GAAG,CAACC,IAAI,CAACC,GAAa,CAAC;MAChCN,wBAAwB,CAACO,MAAM,CAAEC,WAAW,IAAK;QAC/C,SAAS;;QACT,MAAMC,KAAK,GAAGD,WAAW,CAACE,SAAS,CAChCC,UAAU,IAAKA,UAAU,CAACL,GAAG,KAAKD,IAAI,CAACC,GAC1C,CAAC;QACD,IAAIG,KAAK,KAAK,CAAC,CAAC,EAAE;UAChBD,WAAW,CAACC,KAAK,CAAC,GAAGJ,IAAI;QAC3B,CAAC,MAAM;UACLG,WAAW,CAACI,IAAI,CAACP,IAAI,CAAC;QACxB;QACA,OAAOG,WAAW;MACpB,CAAC,EAAE,KAAK,CAAC;IACX,CAAC;IAEDK,MAAM,EAAGC,OAAe,IAAK;MAC3Bb,QAAQ,CAACc,MAAM,CAACD,OAAO,CAAC;MACxBd,wBAAwB,CAACO,MAAM,CAAEC,WAAW,IAAK;QAC/C,SAAS;;QACT,MAAMC,KAAK,GAAGD,WAAW,CAACE,SAAS,CAChCC,UAAU,IAAKA,UAAU,CAACL,GAAG,KAAKQ,OACrC,CAAC;QACD,IAAIL,KAAK,KAAK,CAAC,CAAC,EAAE;UAChBD,WAAW,CAACQ,MAAM,CAACP,KAAK,EAAE,CAAC,CAAC;QAC9B;QACA,OAAOD,WAAW;MACpB,CAAC,EAAE,KAAK,CAAC;IACX,CAAC;IAEDS,GAAG,EAAGH,OAAe,IAAKb,QAAQ,CAACgB,GAAG,CAACH,OAAO;EAChD,CAAC;EAED,OAAOX,IAAI;AACb","ignoreList":[]}
@@ -80,7 +80,7 @@ export class NativeEventsManager {
80
80
  // On the first render of a component, we may already receive a resolved view tag.
81
81
  return this.#managedComponent.getComponentViewTag();
82
82
  }
83
- if (componentAnimatedRef.__nativeTag || componentAnimatedRef._nativeTag) {
83
+ if (componentAnimatedRef?.__nativeTag || componentAnimatedRef?._nativeTag) {
84
84
  /*
85
85
  Fast path for native refs,
86
86
  _nativeTag is used by Paper components,
@@ -1 +1 @@
1
- {"version":3,"names":["findNodeHandle","WorkletEventHandler","has","NativeEventsManager","managedComponent","componentOptions","eventViewTag","constructor","component","options","getEventViewTag","attachEvents","executeForEachEventHandler","props","key","handler","registerForEvents","detachEvents","_key","unregisterFromEvents","updateEvents","prevProps","computedEventTag","prevHandler","newProp","isWorkletEventHandler","workletEventHandler","componentUpdate","componentAnimatedRef","_componentRef","getScrollableNode","scrollableNode","setNativeProps","getComponentViewTag","__nativeTag","_nativeTag","prop","callback"],"sourceRoot":"../../../src","sources":["createAnimatedComponent/NativeEventsManager.ts"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["findNodeHandle","WorkletEventHandler","has","NativeEventsManager","managedComponent","componentOptions","eventViewTag","constructor","component","options","getEventViewTag","attachEvents","executeForEachEventHandler","props","key","handler","registerForEvents","detachEvents","_key","unregisterFromEvents","updateEvents","prevProps","computedEventTag","prevHandler","newProp","isWorkletEventHandler","workletEventHandler","componentUpdate","componentAnimatedRef","_componentRef","getScrollableNode","scrollableNode","setNativeProps","getComponentViewTag","__nativeTag","_nativeTag","prop","callback"],"sourceRoot":"../../../src","sources":["createAnimatedComponent/NativeEventsManager.ts"],"mappings":"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","ignoreList":[]}
@@ -108,10 +108,15 @@ export function createAnimatedComponent(Component, options) {
108
108
  if (this.props.exiting && this._componentDOMRef) {
109
109
  saveSnapshot(this._componentDOMRef);
110
110
  }
111
- if (!this.props.entering || getReducedMotionFromConfig(this.props.entering)) {
111
+ if (!this.props.entering) {
112
112
  this._isFirstRender = false;
113
113
  return;
114
114
  }
115
+ if (getReducedMotionFromConfig(this.props.entering)) {
116
+ this._isFirstRender = false;
117
+ this.props.entering.callbackV?.(true);
118
+ return;
119
+ }
115
120
  const skipEntering = this.context?.current;
116
121
  if (!skipEntering) {
117
122
  startWebLayoutAnimation(this.props, this._componentDOMRef, LayoutAnimationType.ENTERING);
@@ -135,7 +140,11 @@ export function createAnimatedComponent(Component, options) {
135
140
  }
136
141
  this._sharedElementTransition?.unregisterTransition(this.getComponentViewTag(), true);
137
142
  const exiting = this.props.exiting;
138
- if (IS_WEB && this._componentDOMRef && exiting && !getReducedMotionFromConfig(exiting)) {
143
+ if (IS_WEB && this._componentDOMRef && exiting) {
144
+ if (getReducedMotionFromConfig(exiting)) {
145
+ exiting.callbackV?.(true);
146
+ return;
147
+ }
139
148
  addHTMLMutationObserver();
140
149
  startWebLayoutAnimation(this.props, this._componentDOMRef, LayoutAnimationType.EXITING);
141
150
  } else if (exiting && !IS_WEB && !isFabric()) {
@@ -238,18 +247,22 @@ export function createAnimatedComponent(Component, options) {
238
247
  if (hasReanimated2Props && viewConfig) {
239
248
  adaptViewConfig(viewConfig);
240
249
  }
250
+ const newStyles = new Set(styles);
251
+ const isStyleAttached = style => style.viewDescriptors.has(viewTag);
241
252
 
242
253
  // remove old styles
243
254
  if (prevStyles) {
244
255
  // in most of the cases, views have only a single animated style and it remains unchanged
245
256
  const hasOneSameStyle = styles.length === 1 && prevStyles.length === 1 && styles[0] === prevStyles[0];
246
- if (!hasOneSameStyle) {
247
- // otherwise, remove each style that is not present in new styles
248
- for (const prevStyle of prevStyles) {
249
- const isPresent = styles.some(style => style === prevStyle);
250
- if (!isPresent) {
251
- prevStyle.viewDescriptors.remove(viewTag);
252
- }
257
+ if (hasOneSameStyle && isStyleAttached(prevStyles[0])) {
258
+ return;
259
+ }
260
+
261
+ // otherwise, remove each style that is not present in new styles
262
+ for (const prevStyle of prevStyles) {
263
+ const isPresent = styles.some(style => style === prevStyle);
264
+ if (!isPresent && isStyleAttached(prevStyle)) {
265
+ prevStyle.viewDescriptors.remove(viewTag);
253
266
  }
254
267
  }
255
268
  }
@@ -262,7 +275,7 @@ export function createAnimatedComponent(Component, options) {
262
275
  animatedProps.jestAnimatedValues.current = this.jestAnimatedProps;
263
276
  }
264
277
  }
265
- styles.forEach(style => {
278
+ newStyles.forEach(style => {
266
279
  style.viewDescriptors.add({
267
280
  tag: viewTag,
268
281
  name: viewName,
@@ -310,7 +323,11 @@ export function createAnimatedComponent(Component, options) {
310
323
  if (IS_WEB && this.props.exiting && this._componentDOMRef) {
311
324
  saveSnapshot(this._componentDOMRef);
312
325
  }
313
- if (IS_WEB && snapshot && this.props.layout && !getReducedMotionFromConfig(this.props.layout)) {
326
+ if (IS_WEB && snapshot && this.props.layout) {
327
+ if (getReducedMotionFromConfig(this.props.layout)) {
328
+ this.props.layout.callbackV?.(true);
329
+ return;
330
+ }
314
331
  tryActivateLayoutTransition(this.props, this._componentDOMRef, snapshot);
315
332
  }
316
333
  }