@react-native-ohos/react-native-reanimated 4.0.1 → 4.0.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 (235) hide show
  1. package/compatibility.json +161 -161
  2. package/harmony/reanimated/BuildProfile.ets +1 -1
  3. package/harmony/reanimated/build-profile.json5 +18 -18
  4. package/harmony/reanimated/hvigorfile.ts +4 -4
  5. package/harmony/reanimated/index.ets +4 -4
  6. package/harmony/reanimated/oh-package-lock.json5 +39 -0
  7. package/harmony/reanimated/oh-package.json5 +12 -12
  8. package/harmony/reanimated/src/main/cpp/CMakeLists.txt +62 -62
  9. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/AnimatedSensor/AnimatedSensorModule.cpp +81 -81
  10. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/AnimatedSensor/AnimatedSensorModule.h +46 -46
  11. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/InterpolatorRegistry.cpp +390 -390
  12. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/InterpolatorRegistry.h +16 -16
  13. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/definitions.h +30 -30
  14. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/filters/FilterOp.cpp +46 -46
  15. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/filters/FilterOp.h +23 -23
  16. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/transforms/Quaternion.cpp +53 -53
  17. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/transforms/Quaternion.h +21 -21
  18. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/transforms/TransformMatrix.cpp +166 -166
  19. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/transforms/TransformMatrix.h +71 -71
  20. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/transforms/TransformMatrix2D.cpp +368 -368
  21. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/transforms/TransformMatrix2D.h +53 -53
  22. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/transforms/TransformMatrix3D.cpp +594 -594
  23. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/transforms/TransformMatrix3D.h +67 -67
  24. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/transforms/TransformOp.cpp +52 -52
  25. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/transforms/TransformOp.h +26 -26
  26. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/transforms/vectors.cpp +156 -156
  27. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/transforms/vectors.h +76 -76
  28. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/CSSAngle.cpp +94 -94
  29. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/CSSAngle.h +33 -33
  30. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/CSSBoolean.cpp +48 -48
  31. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/CSSBoolean.h +31 -31
  32. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/CSSColor.cpp +135 -135
  33. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/CSSColor.h +61 -61
  34. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/CSSDiscreteArray.cpp +100 -100
  35. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/CSSDiscreteArray.h +45 -45
  36. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/CSSKeyword.cpp +81 -81
  37. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/CSSKeyword.h +53 -53
  38. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/CSSLength.cpp +122 -122
  39. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/CSSLength.h +38 -38
  40. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/CSSNumber.cpp +82 -82
  41. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/CSSNumber.h +63 -63
  42. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/CSSValue.h +118 -118
  43. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/CSSValueVariant.cpp +174 -174
  44. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/CSSValueVariant.h +111 -111
  45. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/complex/CSSBoxShadow.cpp +196 -196
  46. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/complex/CSSBoxShadow.h +66 -66
  47. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/complex/CSSDropShadow.cpp +134 -134
  48. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/common/values/complex/CSSDropShadow.h +44 -44
  49. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/configs/CSSAnimationConfig.cpp +174 -174
  50. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/configs/CSSAnimationConfig.h +49 -49
  51. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/configs/CSSKeyframesConfig.cpp +45 -45
  52. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/configs/CSSKeyframesConfig.h +26 -26
  53. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/configs/CSSTransitionConfig.cpp +90 -90
  54. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/configs/CSSTransitionConfig.h +43 -43
  55. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/configs/common.cpp +17 -17
  56. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/configs/common.h +13 -13
  57. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/core/CSSAnimation.cpp +127 -127
  58. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/core/CSSAnimation.h +51 -51
  59. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/core/CSSTransition.cpp +145 -145
  60. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/core/CSSTransition.h +47 -47
  61. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/easing/EasingFunctions.cpp +69 -69
  62. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/easing/EasingFunctions.h +22 -22
  63. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/easing/cubicBezier.cpp +66 -66
  64. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/easing/cubicBezier.h +15 -15
  65. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/easing/linear.cpp +28 -28
  66. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/easing/linear.h +15 -15
  67. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/easing/steps.cpp +13 -13
  68. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/easing/steps.h +12 -12
  69. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/InterpolatorFactory.cpp +157 -157
  70. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/InterpolatorFactory.h +189 -189
  71. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/PropertyInterpolator.cpp +76 -76
  72. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/PropertyInterpolator.h +66 -66
  73. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/configs.h +20 -20
  74. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/filters/FilterOperation.cpp +136 -136
  75. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/filters/FilterOperation.h +40 -40
  76. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/filters/FilterOperationInterpolator.cpp +38 -38
  77. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/filters/FilterOperationInterpolator.h +24 -24
  78. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/filters/FilterStyleInterpolator.cpp +58 -58
  79. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/filters/FilterStyleInterpolator.h +24 -24
  80. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/filters/operations/blur.h +14 -14
  81. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/filters/operations/brightness.h +14 -14
  82. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/filters/operations/contrast.h +14 -14
  83. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/filters/operations/dropShadow.h +17 -17
  84. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/filters/operations/grayscale.h +14 -14
  85. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/filters/operations/hueRotate.h +14 -14
  86. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/filters/operations/invert.h +14 -14
  87. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/filters/operations/opacity.h +14 -14
  88. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/filters/operations/saturate.h +14 -14
  89. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/filters/operations/sepia.h +14 -14
  90. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/groups/ArrayPropertiesInterpolator.cpp +95 -95
  91. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/groups/ArrayPropertiesInterpolator.h +36 -36
  92. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/groups/GroupPropertiesInterpolator.cpp +41 -41
  93. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/groups/GroupPropertiesInterpolator.h +32 -32
  94. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/groups/RecordPropertiesInterpolator.cpp +99 -99
  95. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/groups/RecordPropertiesInterpolator.h +37 -37
  96. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/operations/OperationsStyleInterpolator.cpp +308 -308
  97. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/operations/OperationsStyleInterpolator.h +100 -100
  98. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/operations/StyleOperation.cpp +19 -19
  99. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/operations/StyleOperation.h +94 -94
  100. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/operations/StyleOperationInterpolator.cpp +18 -18
  101. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/operations/StyleOperationInterpolator.h +43 -43
  102. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/styles/AnimationStyleInterpolator.h +26 -26
  103. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/styles/TransitionStyleInterpolator.cpp +103 -103
  104. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/styles/TransitionStyleInterpolator.h +42 -42
  105. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/transforms/TransformOperation.cpp +224 -224
  106. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/transforms/TransformOperation.h +52 -52
  107. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/transforms/TransformOperationInterpolator.cpp +218 -218
  108. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/transforms/TransformOperationInterpolator.h +89 -89
  109. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/transforms/TransformsStyleInterpolator.cpp +149 -149
  110. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/transforms/TransformsStyleInterpolator.h +33 -33
  111. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/transforms/operations/matrix.cpp +208 -208
  112. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/transforms/operations/matrix.h +56 -56
  113. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/transforms/operations/perspective.cpp +42 -42
  114. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/transforms/operations/perspective.h +20 -20
  115. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/transforms/operations/rotate.cpp +41 -41
  116. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/transforms/operations/rotate.h +39 -39
  117. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/transforms/operations/scale.cpp +28 -28
  118. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/transforms/operations/scale.h +25 -25
  119. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/transforms/operations/skew.cpp +14 -14
  120. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/transforms/operations/skew.h +20 -20
  121. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/transforms/operations/translate.cpp +39 -39
  122. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/transforms/operations/translate.h +25 -25
  123. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/values/ResolvableValueInterpolator.cpp +47 -47
  124. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/values/ResolvableValueInterpolator.h +43 -43
  125. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/values/SimpleValueInterpolator.cpp +70 -70
  126. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/values/SimpleValueInterpolator.h +40 -40
  127. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/values/ValueInterpolator.cpp +146 -146
  128. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/interpolation/values/ValueInterpolator.h +71 -71
  129. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/misc/ViewStylesRepository.cpp +155 -155
  130. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/misc/ViewStylesRepository.h +53 -53
  131. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/progress/AnimationProgressProvider.cpp +170 -170
  132. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/progress/AnimationProgressProvider.h +67 -67
  133. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/progress/KeyframeProgressProvider.h +12 -12
  134. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/progress/RawProgressProvider.cpp +41 -41
  135. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/progress/RawProgressProvider.h +31 -31
  136. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/progress/TransitionProgressProvider.cpp +193 -193
  137. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/progress/TransitionProgressProvider.h +77 -77
  138. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/registries/CSSAnimationsRegistry.cpp +340 -340
  139. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/registries/CSSAnimationsRegistry.h +80 -80
  140. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/registries/CSSKeyframesRegistry.cpp +45 -45
  141. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/registries/CSSKeyframesRegistry.h +29 -29
  142. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/registries/CSSTransitionsRegistry.cpp +167 -167
  143. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/registries/CSSTransitionsRegistry.h +51 -51
  144. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/registries/StaticPropsRegistry.cpp +61 -61
  145. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/registries/StaticPropsRegistry.h +33 -33
  146. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/svg/values/SVGBrush.cpp +80 -80
  147. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/svg/values/SVGBrush.h +39 -39
  148. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/svg/values/SVGLength.cpp +93 -93
  149. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/svg/values/SVGLength.h +36 -36
  150. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/svg/values/SVGStrokeDashArray.cpp +111 -111
  151. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/svg/values/SVGStrokeDashArray.h +33 -33
  152. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/utils/DelayedItemsManager.cpp +75 -75
  153. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/utils/DelayedItemsManager.h +45 -45
  154. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/utils/algorithms.cpp +12 -12
  155. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/utils/algorithms.h +10 -10
  156. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/utils/interpolators.cpp +36 -36
  157. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/utils/interpolators.h +23 -23
  158. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/utils/props.cpp +149 -149
  159. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/CSS/utils/props.h +32 -32
  160. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Fabric/ReanimatedCommitHook.cpp +113 -113
  161. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Fabric/ReanimatedCommitHook.h +49 -49
  162. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Fabric/ReanimatedCommitShadowNode.h +46 -46
  163. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Fabric/ReanimatedMountHook.cpp +56 -56
  164. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Fabric/ReanimatedMountHook.h +37 -37
  165. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Fabric/ShadowTreeCloner.cpp +104 -104
  166. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Fabric/ShadowTreeCloner.h +22 -22
  167. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Fabric/updates/AnimatedPropsRegistry.cpp +72 -72
  168. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Fabric/updates/AnimatedPropsRegistry.h +25 -25
  169. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Fabric/updates/UpdatesRegistry.cpp +160 -160
  170. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Fabric/updates/UpdatesRegistry.h +71 -71
  171. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Fabric/updates/UpdatesRegistryManager.cpp +161 -161
  172. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Fabric/updates/UpdatesRegistryManager.h +65 -65
  173. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationType.h +11 -11
  174. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsManager.cpp +137 -137
  175. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsManager.h +82 -82
  176. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxyCommon.cpp +79 -79
  177. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxyCommon.h +81 -81
  178. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Experimental.cpp +864 -864
  179. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Experimental.h +214 -214
  180. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Legacy.cpp +897 -897
  181. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Legacy.h +220 -220
  182. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsUtils.cpp +31 -31
  183. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsUtils.h +146 -146
  184. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/LayoutAnimations/PropsDiffer.cpp +456 -456
  185. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/LayoutAnimations/PropsDiffer.h +102 -102
  186. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/LayoutAnimations/SharedTransitions.cpp +544 -544
  187. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/NativeModules/PropValueProcessor.cpp +119 -119
  188. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/NativeModules/PropValueProcessor.h +39 -39
  189. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.cpp +1380 -1380
  190. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.h +230 -230
  191. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxySpec.cpp +183 -183
  192. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxySpec.h +93 -93
  193. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/RuntimeDecorators/RNRuntimeDecorator.cpp +54 -54
  194. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/RuntimeDecorators/RNRuntimeDecorator.h +28 -28
  195. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/RuntimeDecorators/UIRuntimeDecorator.cpp +58 -58
  196. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/RuntimeDecorators/UIRuntimeDecorator.h +31 -31
  197. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Tools/FeatureFlags.cpp +18 -18
  198. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Tools/FeatureFlags.h +44 -44
  199. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Tools/PlatformDepMethodsHolder.h +67 -67
  200. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Tools/ReanimatedSystraceSection.h +114 -114
  201. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Tools/ReanimatedVersion.cpp +46 -46
  202. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Tools/ReanimatedVersion.h +18 -18
  203. package/harmony/reanimated/src/main/cpp/ReanimatedModule.cpp +246 -233
  204. package/harmony/reanimated/src/main/cpp/ReanimatedModule.h +23 -23
  205. package/harmony/reanimated/src/main/cpp/ReanimatedNodesManager.cpp +56 -56
  206. package/harmony/reanimated/src/main/cpp/ReanimatedNodesManager.h +30 -30
  207. package/harmony/reanimated/src/main/cpp/ReanimatedPackage.cpp +44 -44
  208. package/harmony/reanimated/src/main/cpp/ReanimatedPackage.h +16 -16
  209. package/harmony/reanimated/src/main/cpp/ReanimatedSensor.cpp +265 -265
  210. package/harmony/reanimated/src/main/cpp/ReanimatedSensor.h +36 -36
  211. package/harmony/reanimated/src/main/cpp/ReanimatedSensorContainer.cpp +35 -35
  212. package/harmony/reanimated/src/main/cpp/ReanimatedSensorContainer.h +23 -23
  213. package/harmony/reanimated/src/main/cpp/ReanimatedUIScheduler.cpp +23 -23
  214. package/harmony/reanimated/src/main/cpp/ReanimatedUIScheduler.h +19 -19
  215. package/harmony/reanimated/src/main/cpp/TransformParser.h +93 -93
  216. package/harmony/reanimated/src/main/ets/AnimationManager.ts +60 -60
  217. package/harmony/reanimated/src/main/ets/ReanimatedModule.ts +62 -51
  218. package/harmony/reanimated/src/main/ets/ReanimatedPackage.ts +25 -25
  219. package/harmony/reanimated/src/main/module.json5 +12 -12
  220. package/harmony/reanimated/src/main/resources/base/element/color.json +7 -7
  221. package/harmony/reanimated/src/main/resources/base/element/string.json +15 -15
  222. package/harmony/reanimated/src/main/resources/base/profile/main_pages.json +5 -5
  223. package/harmony/reanimated/src/main/resources/en_US/element/string.json +15 -15
  224. package/harmony/reanimated/src/main/resources/zh_CN/element/string.json +15 -15
  225. package/harmony/reanimated/ts.ts +6 -6
  226. package/harmony/reanimated.har +0 -0
  227. package/package.json +70 -69
  228. package/scripts/deploy.js +191 -191
  229. package/scripts/set-reanimated-version.js +37 -37
  230. package/scripts/update-version.js +119 -119
  231. package/scripts/validate-react-native-version.js +46 -46
  232. package/scripts/validate-worklets-build.js +17 -17
  233. package/scripts/validate-worklets-version.js +84 -84
  234. package/scripts/worklets-version.json +4 -4
  235. package/src/index.ts +9 -9
@@ -1,864 +1,864 @@
1
- #include <glog/logging.h>
2
- #include <react/renderer/animations/utils.h>
3
- #include <react/renderer/core/ConcreteState.h>
4
- #include <react/renderer/mounting/ShadowViewMutation.h>
5
- #include <reanimated/LayoutAnimations/LayoutAnimationsProxy_Experimental.h>
6
- #include <reanimated/LayoutAnimations/PropsDiffer.h>
7
- #include <reanimated/NativeModules/ReanimatedModuleProxy.h>
8
- #include <reanimated/Tools/ReanimatedSystraceSection.h>
9
-
10
- #include <algorithm>
11
- #include <memory>
12
- #include <ranges>
13
- #include <string>
14
- #include <unordered_set>
15
- #include <utility>
16
- #include <vector>
17
-
18
- namespace reanimated {
19
- using enum LayoutAnimationType;
20
- using enum ExitingState;
21
-
22
- // MARK: MountingOverrideDelegate
23
-
24
- std::optional<MountingTransaction> LayoutAnimationsProxy_Experimental::pullTransaction(
25
- SurfaceId surfaceId,
26
- MountingTransaction::Number transactionNumber,
27
- const TransactionTelemetry &telemetry,
28
- ShadowViewMutationList mutations) const {
29
- ReanimatedSystraceSection d("pullTransaction");
30
- auto lock = std::unique_lock<std::recursive_mutex>(mutex);
31
- const PropsParserContext propsParserContext{surfaceId, *contextContainer_};
32
- ShadowViewMutationList filteredMutations;
33
- auto rootChildCount = static_cast<int>(lightNodes_[surfaceId]->children.size());
34
- const std::vector<std::shared_ptr<MutationNode>> roots;
35
- const bool isInTransition = transitionState_;
36
-
37
- if (isInTransition) {
38
- updateLightTree(propsParserContext, mutations, filteredMutations);
39
- handleProgressTransition(filteredMutations, mutations, propsParserContext, surfaceId);
40
- } else if (!synchronized_) {
41
- auto actualTop = topScreen[surfaceId];
42
- updateLightTree(propsParserContext, mutations, filteredMutations);
43
- auto reactTop = findTopScreen(lightNodes_[surfaceId]);
44
- if (reactTop == actualTop) {
45
- synchronized_ = true;
46
- }
47
- } else if (!mutations.empty()) {
48
- auto root = lightNodes_[surfaceId];
49
- react_native_assert(root && "Root node not found");
50
- auto beforeTopScreen = topScreen[surfaceId];
51
- if (beforeTopScreen) {
52
- ReanimatedSystraceSection s("find before elements");
53
- findSharedElementsOnScreen(beforeTopScreen, BEFORE, propsParserContext);
54
- }
55
-
56
- updateLightTree(propsParserContext, mutations, filteredMutations);
57
-
58
- auto afterTopScreen = findTopScreen(root);
59
- topScreen[surfaceId] = afterTopScreen;
60
- if (afterTopScreen) {
61
- ReanimatedSystraceSection s("find after elements");
62
- findSharedElementsOnScreen(afterTopScreen, AFTER, propsParserContext);
63
- #ifdef __APPLE__
64
- forceScreenSnapshot_(afterTopScreen->current.tag);
65
- #endif
66
- }
67
- const bool hasScreenChanged = beforeTopScreen && afterTopScreen && beforeTopScreen != afterTopScreen;
68
-
69
- if (hasScreenChanged) {
70
- // We want to add mutations to hide the views that will start their transitions.
71
- // To keep things simple, we put mutations related to source views before all muatations
72
- // and mutations to hide target views after all mutations.
73
- std::vector<ShadowViewMutation> mergedMutations;
74
- hideTransitioningViews(BEFORE, mergedMutations, propsParserContext);
75
- mergedMutations.insert(mergedMutations.end(), filteredMutations.begin(), filteredMutations.end());
76
- hideTransitioningViews(AFTER, mergedMutations, propsParserContext);
77
- std::swap(filteredMutations, mergedMutations);
78
- }
79
-
80
- handleSharedTransitionsStart(
81
- afterTopScreen, beforeTopScreen, filteredMutations, mutations, propsParserContext, surfaceId);
82
- }
83
-
84
- for (auto &node : entering_) {
85
- startEnteringAnimation(node);
86
- }
87
- for (auto &node : layout_) {
88
- startLayoutAnimation(node);
89
- }
90
- entering_.clear();
91
- layout_.clear();
92
-
93
- handleRemovals(filteredMutations, exiting_);
94
- exiting_.clear();
95
-
96
- addOngoingAnimations(surfaceId, filteredMutations);
97
-
98
- cleanupAnimations(filteredMutations, propsParserContext, surfaceId);
99
-
100
- transitionMap_.clear();
101
- transitions_.clear();
102
-
103
- insertContainers(filteredMutations, rootChildCount, surfaceId);
104
-
105
- return MountingTransaction{surfaceId, transactionNumber, std::move(filteredMutations), telemetry};
106
- }
107
-
108
- bool LayoutAnimationsProxy_Experimental::shouldOverridePullTransaction() const {
109
- // we need to listen to every possible mutation to keep the light tree updated
110
- return true;
111
- }
112
-
113
- // MARK: Light Tree
114
-
115
- void LayoutAnimationsProxy_Experimental::updateLightTree(
116
- const PropsParserContext &propsParserContext,
117
- const ShadowViewMutationList &mutations,
118
- ShadowViewMutationList &filteredMutations) const {
119
- ReanimatedSystraceSection s("updateLightTree");
120
- std::unordered_set<Tag> inserted, moved, deleted;
121
- for (auto it = mutations.rbegin(); it != mutations.rend(); it++) {
122
- const auto &mutation = *it;
123
- switch (mutation.type) {
124
- case ShadowViewMutation::Delete: {
125
- deleted.insert(mutation.oldChildShadowView.tag);
126
- break;
127
- }
128
- case ShadowViewMutation::Insert: {
129
- inserted.insert(mutation.newChildShadowView.tag);
130
- break;
131
- }
132
- case ShadowViewMutation::Remove: {
133
- const auto tag = mutation.oldChildShadowView.tag;
134
- if (inserted.contains(tag)) {
135
- moved.insert(tag);
136
- }
137
- break;
138
- }
139
- default: {
140
- // Skip other mutation types. We are only interested in moves and deletions here.
141
- break;
142
- }
143
- }
144
- }
145
-
146
- for (const auto &mutation : mutations) {
147
- maybeUpdateWindowDimensions(mutation);
148
- switch (mutation.type) {
149
- case ShadowViewMutation::Update: {
150
- auto &node = lightNodes_[mutation.newChildShadowView.tag];
151
- react_native_assert(node && "LightNode not found");
152
- node->previous = mutation.oldChildShadowView;
153
- #ifdef ANDROID
154
- // TODO (future): We don't merge the root view as the currently stored version might not be accurate, because of the inconsequential initialization order of proxy and the surface
155
- if (!isRoot(node) && node->current.props) {
156
- // On android rawProps are used to store the diffed props so we need to merge them
157
- // This should soon be replaced in RN with Props 2.0 (the diffing will be done at the end of the pipeline)
158
- auto &currentRawProps = node->current.props->rawProps;
159
- auto mergedRawProps = folly::dynamic::merge(currentRawProps, mutation.newChildShadowView.props->rawProps);
160
- node->current = mutation.newChildShadowView;
161
- node->current.props =
162
- getComponentDescriptorForShadowView(node->current)
163
- .cloneProps(propsParserContext, mutation.newChildShadowView.props, RawProps(mergedRawProps));
164
- } else {
165
- node->current = mutation.newChildShadowView;
166
- }
167
- #else
168
- node->current = mutation.newChildShadowView;
169
- #endif // ANDROID
170
- auto tag = mutation.newChildShadowView.tag;
171
- if (layoutAnimationsManager_->hasLayoutAnimation(tag, LAYOUT)) {
172
- layout_.push_back(node);
173
- } else {
174
- filteredMutations.push_back(mutation);
175
- }
176
- break;
177
- }
178
- case ShadowViewMutation::Create: {
179
- const auto &node = std::make_shared<LightNode>();
180
- node->current = mutation.newChildShadowView;
181
- react_native_assert(!lightNodes_.contains(mutation.newChildShadowView.tag) && "LightNode already exists");
182
-
183
- lightNodes_[mutation.newChildShadowView.tag] = node;
184
- filteredMutations.push_back(mutation);
185
- break;
186
- }
187
- case ShadowViewMutation::Delete: {
188
- lightNodes_.erase(mutation.oldChildShadowView.tag);
189
- break;
190
- }
191
- case ShadowViewMutation::Insert: {
192
- transferConfigFromNativeID(mutation.newChildShadowView.props->nativeId, mutation.newChildShadowView.tag);
193
- auto &node = lightNodes_[mutation.newChildShadowView.tag];
194
- auto &parent = lightNodes_[mutation.parentTag];
195
- parent->children.insert(parent->children.begin() + mutation.index, node);
196
- node->parent = parent;
197
- const auto tag = mutation.newChildShadowView.tag;
198
- if (moved.contains(tag) && layoutAnimationsManager_->hasLayoutAnimation(tag, LAYOUT)) {
199
- filteredMutations.push_back(
200
- ShadowViewMutation::InsertMutation(mutation.parentTag, node->previous, mutation.index));
201
- } else if (layoutAnimationsManager_->hasLayoutAnimation(tag, ENTERING)) {
202
- entering_.push_back(node);
203
- filteredMutations.push_back(mutation);
204
- } else {
205
- filteredMutations.push_back(mutation);
206
- }
207
- break;
208
- }
209
- case ShadowViewMutation::Remove: {
210
- const auto &node = lightNodes_[mutation.oldChildShadowView.tag];
211
- const auto tag = node->current.tag;
212
- const auto parentTag = mutation.parentTag;
213
- const auto &parent = lightNodes_[parentTag];
214
- react_native_assert(
215
- parent->children[mutation.index]->current.tag == mutation.oldChildShadowView.tag &&
216
- "Indicies are wrong in Remove mutation");
217
-
218
- if (deleted.contains(tag) && !deleted.contains(parentTag)) {
219
- exiting_.push_back(node);
220
- filteredMutations.push_back(mutation);
221
- parent->children.erase(parent->children.begin() + mutation.index);
222
- } else if (!deleted.contains(tag)) {
223
- filteredMutations.push_back(mutation);
224
- parent->children.erase(parent->children.begin() + mutation.index);
225
- }
226
- break;
227
- }
228
- default: {
229
- react_native_assert(false && "Unsupported mutation type");
230
- break;
231
- }
232
- }
233
- }
234
- }
235
-
236
- // MARK: Layout Animation Updates
237
-
238
- std::optional<SurfaceId> LayoutAnimationsProxy_Experimental::progressLayoutAnimation(
239
- int tag,
240
- const jsi::Object &newStyle) {
241
- ReanimatedSystraceSection s("progressLayoutAnimation");
242
- const auto lock = std::unique_lock<std::recursive_mutex>(mutex);
243
- const auto layoutAnimationIt = layoutAnimations_.find(tag);
244
-
245
- if (layoutAnimationIt == layoutAnimations_.end()) {
246
- return {};
247
- }
248
-
249
- auto &layoutAnimation = layoutAnimationIt->second;
250
-
251
- maybeRestoreOpacity(layoutAnimation, newStyle);
252
-
253
- auto rawProps = std::make_shared<RawProps>(uiRuntime_, jsi::Value(uiRuntime_, newStyle));
254
-
255
- const PropsParserContext propsParserContext{layoutAnimation.finalView.surfaceId, *contextContainer_};
256
- #ifdef RN_SERIALIZABLE_STATE
257
- rawProps = std::make_shared<RawProps>(
258
- folly::dynamic::merge(layoutAnimation.finalView.props->rawProps, (folly::dynamic)*rawProps));
259
- #endif
260
- auto newProps = getComponentDescriptorForShadowView(layoutAnimation.finalView)
261
- .cloneProps(propsParserContext, layoutAnimation.finalView.props, std::move(*rawProps));
262
- auto &updateMap = surfaceManager.getUpdateMap(layoutAnimation.finalView.surfaceId);
263
- updateMap.insert_or_assign(tag, UpdateValues{newProps, Frame(uiRuntime_, newStyle)});
264
-
265
- return layoutAnimation.finalView.surfaceId;
266
- }
267
-
268
- std::optional<SurfaceId> LayoutAnimationsProxy_Experimental::endLayoutAnimation(int tag, bool shouldRemove) {
269
- auto lock = std::unique_lock<std::recursive_mutex>(mutex);
270
- auto layoutAnimationIt = layoutAnimations_.find(tag);
271
-
272
- if (layoutAnimationIt == layoutAnimations_.end()) {
273
- return {};
274
- }
275
-
276
- auto &layoutAnimation = layoutAnimationIt->second;
277
-
278
- // multiple layout animations can be triggered for a view
279
- // one after the other, so we need to keep count of how many
280
- // were actually triggered, so that we don't cleanup necessary
281
- // structures too early
282
- if (layoutAnimation.count > 1) {
283
- layoutAnimation.count--;
284
- return {};
285
- }
286
- finishedAnimationTags_.push_back(tag);
287
- auto surfaceId = layoutAnimation.finalView.surfaceId;
288
-
289
- if (sharedTransitionManager_->tagToName_.contains(tag)) {
290
- auto sharedTag = sharedTransitionManager_->tagToName_[tag];
291
- sharedTransitionManager_->containerTags_.erase(sharedTag);
292
-
293
- sharedContainersToRemove_.push_back(tag);
294
- tagsToRestore_.push_back(restoreMap_[tag][1]);
295
- transformForNode_.clear();
296
- }
297
- if (!shouldRemove) {
298
- return surfaceId;
299
- }
300
-
301
- auto node = lightNodes_[tag];
302
- react_native_assert(node && "LightNode not found");
303
-
304
- node->state = DEAD;
305
- lightNodes_.erase(tag);
306
- deadNodes.insert(node);
307
-
308
- return surfaceId;
309
- }
310
-
311
- void LayoutAnimationsProxy_Experimental::handleRemovals(
312
- ShadowViewMutationList &filteredMutations,
313
- std::vector<std::shared_ptr<LightNode>> &roots) const {
314
- ReanimatedSystraceSection s("handleRemovals");
315
- // iterate from the end, so that children
316
- // with higher indices appear first in the mutations list
317
- for (auto it = roots.rbegin(); it != roots.rend(); it++) {
318
- auto &node = *it;
319
-
320
- const StartAnimationsRecursivelyConfig config = {
321
- .shouldRemoveSubviewsWithoutAnimations = true,
322
- .shouldAnimate = true,
323
- .isScreenPop = false,
324
- };
325
-
326
- if (startAnimationsRecursively(node, filteredMutations, config)) {
327
- auto parent = node->parent.lock();
328
- react_native_assert(parent && "Parent node is nullptr");
329
- // TODO (future): figure out a better way to handle this
330
- // Currently we remove each view, and then if we want to animate it, reinsert it at the end.
331
- // This is nice, but introduces extra mutations (which could have some side effects, like making a snapshot in RNScreens),
332
- // and it changes the zIndex of animated views, which is different from what've had.
333
- // The biggest convenience of this approach is that it is much easier to maintain indices of animated views, and handle reparentings.
334
-
335
- auto current = node->current;
336
- if (layoutAnimations_.contains(node->current.tag)) {
337
- current = layoutAnimations_.at(node->current.tag).currentView;
338
- }
339
- filteredMutations.push_back(
340
- ShadowViewMutation::InsertMutation(parent->current.tag, current, static_cast<int>(parent->children.size())));
341
- parent->children.push_back(node);
342
- if (node->state == UNDEFINED) {
343
- node->state = WAITING;
344
- }
345
- } else {
346
- maybeCancelAnimation(node->current.tag);
347
- filteredMutations.push_back(ShadowViewMutation::DeleteMutation(node->current));
348
- }
349
- }
350
-
351
- for (const auto &node : deadNodes) {
352
- if (node->state != DELETED) {
353
- auto parent = node->parent.lock();
354
- react_native_assert(parent && "Parent node is nullptr");
355
- auto index = parent->removeChild(node);
356
- react_native_assert(index != -1 && "Dead node not found");
357
-
358
- endAnimationsRecursively(node, index, filteredMutations);
359
- maybeDropAncestors(parent, filteredMutations);
360
- }
361
- }
362
- deadNodes.clear();
363
- }
364
-
365
- void LayoutAnimationsProxy_Experimental::addOngoingAnimations(SurfaceId surfaceId, ShadowViewMutationList &mutations)
366
- const {
367
- ReanimatedSystraceSection s1("addOngoingAnimations");
368
- auto &updateMap = surfaceManager.getUpdateMap(surfaceId);
369
- #ifdef ANDROID
370
- std::vector<int> tagsToUpdate;
371
- tagsToUpdate.reserve(updateMap.size());
372
- for (auto &[tag, updateValues] : updateMap) {
373
- tagsToUpdate.push_back(tag);
374
- }
375
-
376
- auto maybeCorrectedTags = preserveMountedTags_(tagsToUpdate);
377
- if (!maybeCorrectedTags.has_value()) {
378
- return;
379
- }
380
-
381
- auto correctedTags = maybeCorrectedTags->get();
382
-
383
- // since the map is not updated, we can assume that the ordering of tags in
384
- // correctedTags matches the iterator
385
- int i = -1;
386
- #endif
387
- for (auto &[tag, updateValues] : updateMap) {
388
- #ifdef ANDROID
389
- i++;
390
- if (correctedTags[i] == -1) {
391
- // skip views that have not been mounted yet
392
- // on Android we start entering animations from the JS thread
393
- // so it might happen, that the first frame of the animation goes through
394
- // before the view is first mounted
395
- // https://github.com/software-mansion/react-native-reanimated/issues/7493
396
- continue;
397
- }
398
- #endif
399
-
400
- const auto layoutAnimationIt = layoutAnimations_.find(tag);
401
-
402
- if (layoutAnimationIt == layoutAnimations_.end()) {
403
- continue;
404
- }
405
-
406
- auto &layoutAnimation = layoutAnimationIt->second;
407
- layoutAnimation.isViewAlreadyMounted = true;
408
- auto newView = layoutAnimation.finalView;
409
- if (updateValues.newProps) {
410
- newView.props = updateValues.newProps;
411
- }
412
- updateLayoutMetrics(newView.layoutMetrics, updateValues.frame);
413
-
414
- mutations.push_back(
415
- ShadowViewMutation::UpdateMutation(layoutAnimation.currentView, newView, layoutAnimation.parentTag));
416
- layoutAnimation.currentView = newView;
417
- }
418
- updateMap.clear();
419
- }
420
-
421
- void LayoutAnimationsProxy_Experimental::endAnimationsRecursively(
422
- const std::shared_ptr<LightNode> &node,
423
- int index,
424
- ShadowViewMutationList &mutations) const {
425
- maybeCancelAnimation(node->current.tag);
426
- node->state = DELETED;
427
- // iterate from the end, so that children
428
- // with higher indices appear first in the mutations list
429
-
430
- const int childrenSize = static_cast<int>(node->children.size());
431
- for (int i = childrenSize - 1; i >= 0; i--) {
432
- auto &subNode = node->children[i];
433
- if (subNode->state != DELETED) {
434
- endAnimationsRecursively(subNode, i, mutations);
435
- }
436
- }
437
- node->children.clear();
438
-
439
- const auto &parent = node->parent.lock();
440
- react_native_assert(parent && "Parent node is nullptr");
441
- mutations.push_back(ShadowViewMutation::RemoveMutation(parent->current.tag, node->current, index));
442
- mutations.push_back(ShadowViewMutation::DeleteMutation(node->current));
443
- }
444
-
445
- void LayoutAnimationsProxy_Experimental::maybeDropAncestors(
446
- const std::shared_ptr<LightNode> &node,
447
- ShadowViewMutationList &cleanupMutations) const {
448
- if (node->children.size() != 0 || node->state == ANIMATING || node->state == UNDEFINED) {
449
- return;
450
- }
451
-
452
- auto parent = node->parent.lock();
453
- react_native_assert(parent && "Parent node is nullptr");
454
- auto index = parent->removeChild(node);
455
- react_native_assert(index != -1 && "Child node not found");
456
-
457
- node->state = DELETED;
458
- maybeCancelAnimation(node->current.tag);
459
- cleanupMutations.push_back(ShadowViewMutation::RemoveMutation(parent->current.tag, node->current, index));
460
- cleanupMutations.push_back(ShadowViewMutation::DeleteMutation(node->current));
461
- maybeDropAncestors(parent, cleanupMutations);
462
- }
463
-
464
- const ComponentDescriptor &LayoutAnimationsProxy_Experimental::getComponentDescriptorForShadowView(
465
- const ShadowView &shadowView) const {
466
- return componentDescriptorRegistry_->at(shadowView.componentHandle);
467
- }
468
-
469
- bool LayoutAnimationsProxy_Experimental::startAnimationsRecursively(
470
- const std::shared_ptr<LightNode> &node,
471
- ShadowViewMutationList &mutations,
472
- StartAnimationsRecursivelyConfig config) const {
473
- auto &[shouldRemoveSubviewsWithoutAnimations, shouldAnimate, isScreenPop] = config;
474
- if (isRNSScreenOrStack(node)) {
475
- isScreenPop = true;
476
- }
477
-
478
- shouldAnimate = !isScreenPop && layoutAnimationsManager_->shouldAnimateExiting(node->current.tag, shouldAnimate);
479
-
480
- const bool hasExitAnimation =
481
- shouldAnimate && layoutAnimationsManager_->hasLayoutAnimation(node->current.tag, LayoutAnimationType::EXITING);
482
- bool hasAnimatedChildren = false;
483
-
484
- shouldRemoveSubviewsWithoutAnimations = shouldRemoveSubviewsWithoutAnimations && !hasExitAnimation;
485
- std::vector<std::shared_ptr<LightNode>> toBeRemoved;
486
-
487
- // iterate from the end, so that children
488
- // with higher indices appear first in the mutations list
489
- auto index = static_cast<int>(node->children.size());
490
- for (auto it = node->children.rbegin(); it != node->children.rend(); it++) {
491
- index--;
492
- auto &subNode = *it;
493
- if (subNode->state != UNDEFINED) {
494
- if (shouldAnimate && subNode->state != DEAD) {
495
- hasAnimatedChildren = true;
496
- } else {
497
- endAnimationsRecursively(subNode, index, mutations);
498
- toBeRemoved.push_back(subNode);
499
- }
500
- } else if (startAnimationsRecursively(subNode, mutations, config)) {
501
- hasAnimatedChildren = true;
502
- } else if (shouldRemoveSubviewsWithoutAnimations) {
503
- maybeCancelAnimation(subNode->current.tag);
504
- mutations.push_back(ShadowViewMutation::RemoveMutation(node->current.tag, subNode->current, index));
505
- toBeRemoved.push_back(subNode);
506
- subNode->state = DELETED;
507
- mutations.push_back(ShadowViewMutation::DeleteMutation(subNode->current));
508
- } else {
509
- subNode->state = WAITING;
510
- }
511
- }
512
-
513
- for (auto &subNode : toBeRemoved) {
514
- node->removeChild(subNode);
515
- }
516
-
517
- const bool wantAnimateExit = hasExitAnimation || hasAnimatedChildren;
518
-
519
- if (hasExitAnimation) {
520
- node->state = ANIMATING;
521
- startExitingAnimation(node);
522
- lightNodes_[node->current.tag] = node;
523
- } else {
524
- // TODO (future): add proper cleanup
525
- // layoutAnimationsManager_->clearLayoutAnimationConfig(node->tag);
526
- }
527
-
528
- return wantAnimateExit;
529
- }
530
-
531
- void LayoutAnimationsProxy_Experimental::updateOngoingAnimationTarget(const int tag, const ShadowViewMutation &mutation)
532
- const {
533
- layoutAnimations_[tag].finalView = mutation.newChildShadowView;
534
- }
535
-
536
- void LayoutAnimationsProxy_Experimental::maybeCancelAnimation(const int tag) const {
537
- if (!layoutAnimations_.contains(tag)) {
538
- return;
539
- }
540
- layoutAnimations_.erase(tag);
541
- uiScheduler_->scheduleOnUI([weakThis = weak_from_this(), tag]() {
542
- auto strongThis = weakThis.lock();
543
- if (!strongThis) {
544
- return;
545
- }
546
-
547
- auto &uiRuntime = strongThis->uiRuntime_;
548
- strongThis->layoutAnimationsManager_->cancelLayoutAnimation(uiRuntime, tag);
549
- });
550
- }
551
-
552
- void LayoutAnimationsProxy_Experimental::transferConfigFromNativeID(const std::string &nativeIdString, const int tag)
553
- const {
554
- if (nativeIdString.empty() || nativeIdString.length() > 9) {
555
- return;
556
- }
557
- auto nativeId = 0;
558
- for (int i = 0; i < nativeIdString.length(); i++) {
559
- if (nativeIdString[i] < '0' || nativeIdString[i] > '9') {
560
- return;
561
- }
562
- nativeId *= 10;
563
- nativeId += nativeIdString[i] - '0';
564
- }
565
-
566
- layoutAnimationsManager_->transferConfigFromNativeID(nativeId, tag);
567
- }
568
-
569
- // When entering animations start, we temporarily set opacity to 0
570
- // so that we can immediately insert the view at the right position
571
- // and schedule the animation on the UI thread
572
- ShadowView LayoutAnimationsProxy_Experimental::cloneViewWithoutOpacity(
573
- const ShadowView &shadowView,
574
- const PropsParserContext &propsParserContext) const {
575
- auto newView = shadowView;
576
- const folly::dynamic opacity = folly::dynamic::object("opacity", 0);
577
- auto newProps =
578
- getComponentDescriptorForShadowView(newView).cloneProps(propsParserContext, newView.props, RawProps(opacity));
579
- newView.props = newProps;
580
- return newView;
581
- }
582
-
583
- ShadowView LayoutAnimationsProxy_Experimental::cloneViewWithOpacity(
584
- const ShadowView &shadowView,
585
- const PropsParserContext &propsParserContext) const {
586
- auto newView = shadowView;
587
- const auto &props = static_cast<const ViewProps &>(*newView.props);
588
- const folly::dynamic opacity = folly::dynamic::object("opacity", props.opacity);
589
- auto newProps =
590
- getComponentDescriptorForShadowView(newView).cloneProps(propsParserContext, newView.props, RawProps(opacity));
591
- newView.props = newProps;
592
- return newView;
593
- }
594
-
595
- void LayoutAnimationsProxy_Experimental::maybeRestoreOpacity(
596
- reanimated::LayoutAnimation &layoutAnimation,
597
- const jsi::Object &newStyle) const {
598
- if (layoutAnimation.opacity && !newStyle.hasProperty(uiRuntime_, "opacity")) {
599
- newStyle.setProperty(uiRuntime_, "opacity", jsi::Value(*layoutAnimation.opacity));
600
- if (layoutAnimation.isViewAlreadyMounted) {
601
- // We want to reset opacity only when we are sure that this update will be
602
- // applied to the native view. Otherwise, we want to update opacity using
603
- // the `restoreOpacityInCaseOfFlakyEnteringAnimation` method.
604
- layoutAnimation.opacity.reset();
605
- }
606
- }
607
- }
608
-
609
- void LayoutAnimationsProxy_Experimental::maybeUpdateWindowDimensions(
610
- const facebook::react::ShadowViewMutation &mutation) const {
611
- if (mutation.type == ShadowViewMutation::Update &&
612
- !std::strcmp(mutation.oldChildShadowView.componentName, RootComponentName)) {
613
- surfaceManager.updateWindow(
614
- mutation.newChildShadowView.tag,
615
- mutation.newChildShadowView.layoutMetrics.frame.size.width,
616
- mutation.newChildShadowView.layoutMetrics.frame.size.height);
617
- }
618
- }
619
-
620
- void LayoutAnimationsProxy_Experimental::cleanupAnimations(
621
- ShadowViewMutationList &filteredMutations,
622
- const PropsParserContext &propsParserContext,
623
- SurfaceId surfaceId) const {
624
- ReanimatedSystraceSection s("cleanupAnimations");
625
- cleanupSharedTransitions(filteredMutations, propsParserContext, surfaceId);
626
-
627
- #ifdef ANDROID
628
- restoreOpacityInCaseOfFlakyEnteringAnimation(surfaceId);
629
- #endif // ANDROID
630
- for (const auto tag : finishedAnimationTags_) {
631
- auto &updateMap = surfaceManager.getUpdateMap(surfaceId);
632
- layoutAnimations_.erase(tag);
633
- updateMap.erase(tag);
634
- }
635
- finishedAnimationTags_.clear();
636
- }
637
-
638
- // MARK: Start Animation
639
-
640
- ShadowView LayoutAnimationsProxy_Experimental::maybeCreateLayoutAnimation(
641
- ShadowView &before,
642
- const ShadowView &after,
643
- const Tag parentTag) const {
644
- auto count = 1;
645
- const auto tag = after.tag;
646
- auto layoutAnimationIt = layoutAnimations_.find(tag);
647
- auto &oldView = before;
648
-
649
- if (layoutAnimationIt != layoutAnimations_.end()) {
650
- auto &layoutAnimation = layoutAnimationIt->second;
651
- oldView = layoutAnimation.currentView;
652
- count = layoutAnimation.count + 1;
653
- }
654
-
655
- auto finalView = after;
656
- auto currentView = oldView;
657
- auto startView = oldView;
658
-
659
- layoutAnimations_[tag] = {
660
- .finalView = finalView,
661
- .currentView = currentView,
662
- .startView = startView,
663
- .parentTag = parentTag,
664
- .count = count,
665
- };
666
-
667
- return oldView;
668
- }
669
-
670
- void LayoutAnimationsProxy_Experimental::startEnteringAnimation(const std::shared_ptr<LightNode> &node) const {
671
- auto newChildShadowView = node->current;
672
- const auto &finalView = newChildShadowView;
673
- const auto &currentView = newChildShadowView;
674
-
675
- const auto &props = newChildShadowView.props;
676
- auto &viewProps = static_cast<const ViewProps &>(*props);
677
- const auto opacity = viewProps.opacity;
678
- const auto &parent = node->parent.lock();
679
- react_native_assert(parent && "Parent node is nullptr");
680
- const auto parentTag = parent->current.tag;
681
-
682
- uiScheduler_->scheduleOnUI(
683
- [weakThis = weak_from_this(), finalView, currentView, newChildShadowView, parentTag, opacity]() {
684
- auto strongThis = weakThis.lock();
685
- if (!strongThis) {
686
- return;
687
- }
688
-
689
- Rect window;
690
- const auto tag = newChildShadowView.tag;
691
- {
692
- auto lock = std::unique_lock<std::recursive_mutex>(strongThis->mutex);
693
- strongThis->layoutAnimations_[tag] = {
694
- .finalView = newChildShadowView,
695
- .currentView = newChildShadowView,
696
- .startView = newChildShadowView,
697
- .parentTag = parentTag,
698
- .opacity = opacity,
699
- };
700
- window = strongThis->surfaceManager.getWindow(newChildShadowView.surfaceId);
701
- }
702
-
703
- const Snapshot values(newChildShadowView, window);
704
- auto &uiRuntime = strongThis->uiRuntime_;
705
- const jsi::Object yogaValues(uiRuntime);
706
- yogaValues.setProperty(uiRuntime, "targetOriginX", values.x);
707
- yogaValues.setProperty(uiRuntime, "targetGlobalOriginX", values.x);
708
- yogaValues.setProperty(uiRuntime, "targetOriginY", values.y);
709
- yogaValues.setProperty(uiRuntime, "targetGlobalOriginY", values.y);
710
- yogaValues.setProperty(uiRuntime, "targetWidth", values.width);
711
- yogaValues.setProperty(uiRuntime, "targetHeight", values.height);
712
- yogaValues.setProperty(uiRuntime, "windowWidth", values.windowWidth);
713
- yogaValues.setProperty(uiRuntime, "windowHeight", values.windowHeight);
714
- strongThis->layoutAnimationsManager_->startLayoutAnimation(
715
- uiRuntime, tag, LayoutAnimationType::ENTERING, yogaValues);
716
- });
717
- }
718
-
719
- void LayoutAnimationsProxy_Experimental::startExitingAnimation(const std::shared_ptr<LightNode> &node) const {
720
- auto &oldChildShadowView = node->current;
721
- const auto surfaceId = oldChildShadowView.surfaceId;
722
- const auto tag = oldChildShadowView.tag;
723
- const auto &parent = node->parent.lock();
724
- react_native_assert(parent && "Parent node is nullptr");
725
- const auto parentTag = parent->current.tag;
726
-
727
- uiScheduler_->scheduleOnUI([weakThis = weak_from_this(), tag, parentTag, oldChildShadowView, surfaceId]() {
728
- auto strongThis = weakThis.lock();
729
- if (!strongThis) {
730
- return;
731
- }
732
-
733
- auto oldView = oldChildShadowView;
734
- Rect window{};
735
- {
736
- auto &mutex = strongThis->mutex;
737
- auto lock = std::unique_lock<std::recursive_mutex>(mutex);
738
- oldView = strongThis->maybeCreateLayoutAnimation(oldView, oldView, parentTag);
739
- window = strongThis->surfaceManager.getWindow(surfaceId);
740
- }
741
-
742
- const Snapshot values(oldView, window);
743
-
744
- auto &uiRuntime = strongThis->uiRuntime_;
745
- const jsi::Object yogaValues(uiRuntime);
746
- yogaValues.setProperty(uiRuntime, "currentOriginX", values.x);
747
- yogaValues.setProperty(uiRuntime, "currentGlobalOriginX", values.x);
748
- yogaValues.setProperty(uiRuntime, "currentOriginY", values.y);
749
- yogaValues.setProperty(uiRuntime, "currentGlobalOriginY", values.y);
750
- yogaValues.setProperty(uiRuntime, "currentWidth", values.width);
751
- yogaValues.setProperty(uiRuntime, "currentHeight", values.height);
752
- yogaValues.setProperty(uiRuntime, "windowWidth", values.windowWidth);
753
- yogaValues.setProperty(uiRuntime, "windowHeight", values.windowHeight);
754
- strongThis->layoutAnimationsManager_->startLayoutAnimation(
755
- uiRuntime, tag, LayoutAnimationType::EXITING, yogaValues);
756
- strongThis->layoutAnimationsManager_->clearLayoutAnimationConfig(tag);
757
- });
758
- }
759
-
760
- void LayoutAnimationsProxy_Experimental::startLayoutAnimation(const std::shared_ptr<LightNode> &node) const {
761
- auto oldChildShadowView = node->previous;
762
- auto newChildShadowView = node->current;
763
- auto surfaceId = oldChildShadowView.surfaceId;
764
- const auto tag = oldChildShadowView.tag;
765
- const auto &parent = node->parent.lock();
766
- react_native_assert(parent && "Parent node is nullptr");
767
- const auto parentTag = parent->current.tag;
768
-
769
- uiScheduler_->scheduleOnUI(
770
- [weakThis = weak_from_this(), surfaceId, oldChildShadowView, newChildShadowView, parentTag, tag]() {
771
- auto strongThis = weakThis.lock();
772
- if (!strongThis) {
773
- return;
774
- }
775
-
776
- auto oldView = oldChildShadowView;
777
- Rect window{};
778
- {
779
- auto &mutex = strongThis->mutex;
780
- auto lock = std::unique_lock<std::recursive_mutex>(mutex);
781
- oldView = strongThis->maybeCreateLayoutAnimation(oldView, newChildShadowView, parentTag);
782
- window = strongThis->surfaceManager.getWindow(surfaceId);
783
- }
784
-
785
- const Snapshot currentValues(oldView, window);
786
- const Snapshot targetValues(newChildShadowView, window);
787
-
788
- auto &uiRuntime = strongThis->uiRuntime_;
789
- const jsi::Object yogaValues(uiRuntime);
790
- yogaValues.setProperty(uiRuntime, "currentOriginX", currentValues.x);
791
- yogaValues.setProperty(uiRuntime, "currentGlobalOriginX", currentValues.x);
792
- yogaValues.setProperty(uiRuntime, "currentOriginY", currentValues.y);
793
- yogaValues.setProperty(uiRuntime, "currentGlobalOriginY", currentValues.y);
794
- yogaValues.setProperty(uiRuntime, "currentWidth", currentValues.width);
795
- yogaValues.setProperty(uiRuntime, "currentHeight", currentValues.height);
796
- yogaValues.setProperty(uiRuntime, "targetOriginX", targetValues.x);
797
- yogaValues.setProperty(uiRuntime, "targetGlobalOriginX", targetValues.x);
798
- yogaValues.setProperty(uiRuntime, "targetOriginY", targetValues.y);
799
- yogaValues.setProperty(uiRuntime, "targetGlobalOriginY", targetValues.y);
800
- yogaValues.setProperty(uiRuntime, "targetWidth", targetValues.width);
801
- yogaValues.setProperty(uiRuntime, "targetHeight", targetValues.height);
802
- yogaValues.setProperty(uiRuntime, "windowWidth", targetValues.windowWidth);
803
- yogaValues.setProperty(uiRuntime, "windowHeight", targetValues.windowHeight);
804
- strongThis->layoutAnimationsManager_->startLayoutAnimation(
805
- uiRuntime, tag, LayoutAnimationType::LAYOUT, yogaValues);
806
- });
807
- }
808
-
809
- void LayoutAnimationsProxy_Experimental::startSharedTransition(
810
- const int tag,
811
- const ShadowView &before,
812
- const ShadowView &after,
813
- SurfaceId surfaceId) const {
814
- uiScheduler_->scheduleOnUI([weakThis = weak_from_this(), before, after, surfaceId, tag]() {
815
- auto strongThis = weakThis.lock();
816
- if (!strongThis) {
817
- return;
818
- }
819
-
820
- auto oldView = before;
821
- Rect window{};
822
- {
823
- auto &mutex = strongThis->mutex;
824
- auto lock = std::unique_lock<std::recursive_mutex>(mutex);
825
- oldView = strongThis->maybeCreateLayoutAnimation(oldView, after, surfaceId);
826
- window = strongThis->surfaceManager.getWindow(surfaceId);
827
- }
828
-
829
- auto &uiRuntime = strongThis->uiRuntime_;
830
- auto propsDiffer = PropsDiffer(uiRuntime, oldView, after);
831
-
832
- const auto &propsDiff = propsDiffer.computeDiff(uiRuntime);
833
-
834
- propsDiff.setProperty(uiRuntime, "windowWidth", window.width);
835
- propsDiff.setProperty(uiRuntime, "windowHeight", window.height);
836
-
837
- strongThis->layoutAnimationsManager_->startLayoutAnimation(
838
- uiRuntime, tag, LayoutAnimationType::SHARED_ELEMENT_TRANSITION, propsDiff);
839
- });
840
- }
841
-
842
- void LayoutAnimationsProxy_Experimental::startProgressTransition(
843
- const int tag,
844
- const ShadowView &before,
845
- const ShadowView &after,
846
- SurfaceId surfaceId) const {
847
- uiScheduler_->scheduleOnUI([weakThis = weak_from_this(), before, after, surfaceId]() {
848
- auto strongThis = weakThis.lock();
849
- if (!strongThis) {
850
- return;
851
- }
852
-
853
- auto oldView = before;
854
- Rect window{};
855
- {
856
- auto &mutex = strongThis->mutex;
857
- auto lock = std::unique_lock<std::recursive_mutex>(mutex);
858
- oldView = strongThis->maybeCreateLayoutAnimation(oldView, after, surfaceId);
859
- window = strongThis->surfaceManager.getWindow(surfaceId);
860
- }
861
- });
862
- }
863
-
864
- } // namespace reanimated
1
+ #include <glog/logging.h>
2
+ #include <react/renderer/animations/utils.h>
3
+ #include <react/renderer/core/ConcreteState.h>
4
+ #include <react/renderer/mounting/ShadowViewMutation.h>
5
+ #include <reanimated/LayoutAnimations/LayoutAnimationsProxy_Experimental.h>
6
+ #include <reanimated/LayoutAnimations/PropsDiffer.h>
7
+ #include <reanimated/NativeModules/ReanimatedModuleProxy.h>
8
+ #include <reanimated/Tools/ReanimatedSystraceSection.h>
9
+
10
+ #include <algorithm>
11
+ #include <memory>
12
+ #include <ranges>
13
+ #include <string>
14
+ #include <unordered_set>
15
+ #include <utility>
16
+ #include <vector>
17
+
18
+ namespace reanimated {
19
+ using enum LayoutAnimationType;
20
+ using enum ExitingState;
21
+
22
+ // MARK: MountingOverrideDelegate
23
+
24
+ std::optional<MountingTransaction> LayoutAnimationsProxy_Experimental::pullTransaction(
25
+ SurfaceId surfaceId,
26
+ MountingTransaction::Number transactionNumber,
27
+ const TransactionTelemetry &telemetry,
28
+ ShadowViewMutationList mutations) const {
29
+ ReanimatedSystraceSection d("pullTransaction");
30
+ auto lock = std::unique_lock<std::recursive_mutex>(mutex);
31
+ const PropsParserContext propsParserContext{surfaceId, *contextContainer_};
32
+ ShadowViewMutationList filteredMutations;
33
+ auto rootChildCount = static_cast<int>(lightNodes_[surfaceId]->children.size());
34
+ const std::vector<std::shared_ptr<MutationNode>> roots;
35
+ const bool isInTransition = transitionState_;
36
+
37
+ if (isInTransition) {
38
+ updateLightTree(propsParserContext, mutations, filteredMutations);
39
+ handleProgressTransition(filteredMutations, mutations, propsParserContext, surfaceId);
40
+ } else if (!synchronized_) {
41
+ auto actualTop = topScreen[surfaceId];
42
+ updateLightTree(propsParserContext, mutations, filteredMutations);
43
+ auto reactTop = findTopScreen(lightNodes_[surfaceId]);
44
+ if (reactTop == actualTop) {
45
+ synchronized_ = true;
46
+ }
47
+ } else if (!mutations.empty()) {
48
+ auto root = lightNodes_[surfaceId];
49
+ react_native_assert(root && "Root node not found");
50
+ auto beforeTopScreen = topScreen[surfaceId];
51
+ if (beforeTopScreen) {
52
+ ReanimatedSystraceSection s("find before elements");
53
+ findSharedElementsOnScreen(beforeTopScreen, BEFORE, propsParserContext);
54
+ }
55
+
56
+ updateLightTree(propsParserContext, mutations, filteredMutations);
57
+
58
+ auto afterTopScreen = findTopScreen(root);
59
+ topScreen[surfaceId] = afterTopScreen;
60
+ if (afterTopScreen) {
61
+ ReanimatedSystraceSection s("find after elements");
62
+ findSharedElementsOnScreen(afterTopScreen, AFTER, propsParserContext);
63
+ #ifdef __APPLE__
64
+ forceScreenSnapshot_(afterTopScreen->current.tag);
65
+ #endif
66
+ }
67
+ const bool hasScreenChanged = beforeTopScreen && afterTopScreen && beforeTopScreen != afterTopScreen;
68
+
69
+ if (hasScreenChanged) {
70
+ // We want to add mutations to hide the views that will start their transitions.
71
+ // To keep things simple, we put mutations related to source views before all muatations
72
+ // and mutations to hide target views after all mutations.
73
+ std::vector<ShadowViewMutation> mergedMutations;
74
+ hideTransitioningViews(BEFORE, mergedMutations, propsParserContext);
75
+ mergedMutations.insert(mergedMutations.end(), filteredMutations.begin(), filteredMutations.end());
76
+ hideTransitioningViews(AFTER, mergedMutations, propsParserContext);
77
+ std::swap(filteredMutations, mergedMutations);
78
+ }
79
+
80
+ handleSharedTransitionsStart(
81
+ afterTopScreen, beforeTopScreen, filteredMutations, mutations, propsParserContext, surfaceId);
82
+ }
83
+
84
+ for (auto &node : entering_) {
85
+ startEnteringAnimation(node);
86
+ }
87
+ for (auto &node : layout_) {
88
+ startLayoutAnimation(node);
89
+ }
90
+ entering_.clear();
91
+ layout_.clear();
92
+
93
+ handleRemovals(filteredMutations, exiting_);
94
+ exiting_.clear();
95
+
96
+ addOngoingAnimations(surfaceId, filteredMutations);
97
+
98
+ cleanupAnimations(filteredMutations, propsParserContext, surfaceId);
99
+
100
+ transitionMap_.clear();
101
+ transitions_.clear();
102
+
103
+ insertContainers(filteredMutations, rootChildCount, surfaceId);
104
+
105
+ return MountingTransaction{surfaceId, transactionNumber, std::move(filteredMutations), telemetry};
106
+ }
107
+
108
+ bool LayoutAnimationsProxy_Experimental::shouldOverridePullTransaction() const {
109
+ // we need to listen to every possible mutation to keep the light tree updated
110
+ return true;
111
+ }
112
+
113
+ // MARK: Light Tree
114
+
115
+ void LayoutAnimationsProxy_Experimental::updateLightTree(
116
+ const PropsParserContext &propsParserContext,
117
+ const ShadowViewMutationList &mutations,
118
+ ShadowViewMutationList &filteredMutations) const {
119
+ ReanimatedSystraceSection s("updateLightTree");
120
+ std::unordered_set<Tag> inserted, moved, deleted;
121
+ for (auto it = mutations.rbegin(); it != mutations.rend(); it++) {
122
+ const auto &mutation = *it;
123
+ switch (mutation.type) {
124
+ case ShadowViewMutation::Delete: {
125
+ deleted.insert(mutation.oldChildShadowView.tag);
126
+ break;
127
+ }
128
+ case ShadowViewMutation::Insert: {
129
+ inserted.insert(mutation.newChildShadowView.tag);
130
+ break;
131
+ }
132
+ case ShadowViewMutation::Remove: {
133
+ const auto tag = mutation.oldChildShadowView.tag;
134
+ if (inserted.contains(tag)) {
135
+ moved.insert(tag);
136
+ }
137
+ break;
138
+ }
139
+ default: {
140
+ // Skip other mutation types. We are only interested in moves and deletions here.
141
+ break;
142
+ }
143
+ }
144
+ }
145
+
146
+ for (const auto &mutation : mutations) {
147
+ maybeUpdateWindowDimensions(mutation);
148
+ switch (mutation.type) {
149
+ case ShadowViewMutation::Update: {
150
+ auto &node = lightNodes_[mutation.newChildShadowView.tag];
151
+ react_native_assert(node && "LightNode not found");
152
+ node->previous = mutation.oldChildShadowView;
153
+ #ifdef ANDROID
154
+ // TODO (future): We don't merge the root view as the currently stored version might not be accurate, because of the inconsequential initialization order of proxy and the surface
155
+ if (!isRoot(node) && node->current.props) {
156
+ // On android rawProps are used to store the diffed props so we need to merge them
157
+ // This should soon be replaced in RN with Props 2.0 (the diffing will be done at the end of the pipeline)
158
+ auto &currentRawProps = node->current.props->rawProps;
159
+ auto mergedRawProps = folly::dynamic::merge(currentRawProps, mutation.newChildShadowView.props->rawProps);
160
+ node->current = mutation.newChildShadowView;
161
+ node->current.props =
162
+ getComponentDescriptorForShadowView(node->current)
163
+ .cloneProps(propsParserContext, mutation.newChildShadowView.props, RawProps(mergedRawProps));
164
+ } else {
165
+ node->current = mutation.newChildShadowView;
166
+ }
167
+ #else
168
+ node->current = mutation.newChildShadowView;
169
+ #endif // ANDROID
170
+ auto tag = mutation.newChildShadowView.tag;
171
+ if (layoutAnimationsManager_->hasLayoutAnimation(tag, LAYOUT)) {
172
+ layout_.push_back(node);
173
+ } else {
174
+ filteredMutations.push_back(mutation);
175
+ }
176
+ break;
177
+ }
178
+ case ShadowViewMutation::Create: {
179
+ const auto &node = std::make_shared<LightNode>();
180
+ node->current = mutation.newChildShadowView;
181
+ react_native_assert(!lightNodes_.contains(mutation.newChildShadowView.tag) && "LightNode already exists");
182
+
183
+ lightNodes_[mutation.newChildShadowView.tag] = node;
184
+ filteredMutations.push_back(mutation);
185
+ break;
186
+ }
187
+ case ShadowViewMutation::Delete: {
188
+ lightNodes_.erase(mutation.oldChildShadowView.tag);
189
+ break;
190
+ }
191
+ case ShadowViewMutation::Insert: {
192
+ transferConfigFromNativeID(mutation.newChildShadowView.props->nativeId, mutation.newChildShadowView.tag);
193
+ auto &node = lightNodes_[mutation.newChildShadowView.tag];
194
+ auto &parent = lightNodes_[mutation.parentTag];
195
+ parent->children.insert(parent->children.begin() + mutation.index, node);
196
+ node->parent = parent;
197
+ const auto tag = mutation.newChildShadowView.tag;
198
+ if (moved.contains(tag) && layoutAnimationsManager_->hasLayoutAnimation(tag, LAYOUT)) {
199
+ filteredMutations.push_back(
200
+ ShadowViewMutation::InsertMutation(mutation.parentTag, node->previous, mutation.index));
201
+ } else if (layoutAnimationsManager_->hasLayoutAnimation(tag, ENTERING)) {
202
+ entering_.push_back(node);
203
+ filteredMutations.push_back(mutation);
204
+ } else {
205
+ filteredMutations.push_back(mutation);
206
+ }
207
+ break;
208
+ }
209
+ case ShadowViewMutation::Remove: {
210
+ const auto &node = lightNodes_[mutation.oldChildShadowView.tag];
211
+ const auto tag = node->current.tag;
212
+ const auto parentTag = mutation.parentTag;
213
+ const auto &parent = lightNodes_[parentTag];
214
+ react_native_assert(
215
+ parent->children[mutation.index]->current.tag == mutation.oldChildShadowView.tag &&
216
+ "Indicies are wrong in Remove mutation");
217
+
218
+ if (deleted.contains(tag) && !deleted.contains(parentTag)) {
219
+ exiting_.push_back(node);
220
+ filteredMutations.push_back(mutation);
221
+ parent->children.erase(parent->children.begin() + mutation.index);
222
+ } else if (!deleted.contains(tag)) {
223
+ filteredMutations.push_back(mutation);
224
+ parent->children.erase(parent->children.begin() + mutation.index);
225
+ }
226
+ break;
227
+ }
228
+ default: {
229
+ react_native_assert(false && "Unsupported mutation type");
230
+ break;
231
+ }
232
+ }
233
+ }
234
+ }
235
+
236
+ // MARK: Layout Animation Updates
237
+
238
+ std::optional<SurfaceId> LayoutAnimationsProxy_Experimental::progressLayoutAnimation(
239
+ int tag,
240
+ const jsi::Object &newStyle) {
241
+ ReanimatedSystraceSection s("progressLayoutAnimation");
242
+ const auto lock = std::unique_lock<std::recursive_mutex>(mutex);
243
+ const auto layoutAnimationIt = layoutAnimations_.find(tag);
244
+
245
+ if (layoutAnimationIt == layoutAnimations_.end()) {
246
+ return {};
247
+ }
248
+
249
+ auto &layoutAnimation = layoutAnimationIt->second;
250
+
251
+ maybeRestoreOpacity(layoutAnimation, newStyle);
252
+
253
+ auto rawProps = std::make_shared<RawProps>(uiRuntime_, jsi::Value(uiRuntime_, newStyle));
254
+
255
+ const PropsParserContext propsParserContext{layoutAnimation.finalView.surfaceId, *contextContainer_};
256
+ #ifdef RN_SERIALIZABLE_STATE
257
+ rawProps = std::make_shared<RawProps>(
258
+ folly::dynamic::merge(layoutAnimation.finalView.props->rawProps, (folly::dynamic)*rawProps));
259
+ #endif
260
+ auto newProps = getComponentDescriptorForShadowView(layoutAnimation.finalView)
261
+ .cloneProps(propsParserContext, layoutAnimation.finalView.props, std::move(*rawProps));
262
+ auto &updateMap = surfaceManager.getUpdateMap(layoutAnimation.finalView.surfaceId);
263
+ updateMap.insert_or_assign(tag, UpdateValues{newProps, Frame(uiRuntime_, newStyle)});
264
+
265
+ return layoutAnimation.finalView.surfaceId;
266
+ }
267
+
268
+ std::optional<SurfaceId> LayoutAnimationsProxy_Experimental::endLayoutAnimation(int tag, bool shouldRemove) {
269
+ auto lock = std::unique_lock<std::recursive_mutex>(mutex);
270
+ auto layoutAnimationIt = layoutAnimations_.find(tag);
271
+
272
+ if (layoutAnimationIt == layoutAnimations_.end()) {
273
+ return {};
274
+ }
275
+
276
+ auto &layoutAnimation = layoutAnimationIt->second;
277
+
278
+ // multiple layout animations can be triggered for a view
279
+ // one after the other, so we need to keep count of how many
280
+ // were actually triggered, so that we don't cleanup necessary
281
+ // structures too early
282
+ if (layoutAnimation.count > 1) {
283
+ layoutAnimation.count--;
284
+ return {};
285
+ }
286
+ finishedAnimationTags_.push_back(tag);
287
+ auto surfaceId = layoutAnimation.finalView.surfaceId;
288
+
289
+ if (sharedTransitionManager_->tagToName_.contains(tag)) {
290
+ auto sharedTag = sharedTransitionManager_->tagToName_[tag];
291
+ sharedTransitionManager_->containerTags_.erase(sharedTag);
292
+
293
+ sharedContainersToRemove_.push_back(tag);
294
+ tagsToRestore_.push_back(restoreMap_[tag][1]);
295
+ transformForNode_.clear();
296
+ }
297
+ if (!shouldRemove) {
298
+ return surfaceId;
299
+ }
300
+
301
+ auto node = lightNodes_[tag];
302
+ react_native_assert(node && "LightNode not found");
303
+
304
+ node->state = DEAD;
305
+ lightNodes_.erase(tag);
306
+ deadNodes.insert(node);
307
+
308
+ return surfaceId;
309
+ }
310
+
311
+ void LayoutAnimationsProxy_Experimental::handleRemovals(
312
+ ShadowViewMutationList &filteredMutations,
313
+ std::vector<std::shared_ptr<LightNode>> &roots) const {
314
+ ReanimatedSystraceSection s("handleRemovals");
315
+ // iterate from the end, so that children
316
+ // with higher indices appear first in the mutations list
317
+ for (auto it = roots.rbegin(); it != roots.rend(); it++) {
318
+ auto &node = *it;
319
+
320
+ const StartAnimationsRecursivelyConfig config = {
321
+ .shouldRemoveSubviewsWithoutAnimations = true,
322
+ .shouldAnimate = true,
323
+ .isScreenPop = false,
324
+ };
325
+
326
+ if (startAnimationsRecursively(node, filteredMutations, config)) {
327
+ auto parent = node->parent.lock();
328
+ react_native_assert(parent && "Parent node is nullptr");
329
+ // TODO (future): figure out a better way to handle this
330
+ // Currently we remove each view, and then if we want to animate it, reinsert it at the end.
331
+ // This is nice, but introduces extra mutations (which could have some side effects, like making a snapshot in RNScreens),
332
+ // and it changes the zIndex of animated views, which is different from what've had.
333
+ // The biggest convenience of this approach is that it is much easier to maintain indices of animated views, and handle reparentings.
334
+
335
+ auto current = node->current;
336
+ if (layoutAnimations_.contains(node->current.tag)) {
337
+ current = layoutAnimations_.at(node->current.tag).currentView;
338
+ }
339
+ filteredMutations.push_back(
340
+ ShadowViewMutation::InsertMutation(parent->current.tag, current, static_cast<int>(parent->children.size())));
341
+ parent->children.push_back(node);
342
+ if (node->state == UNDEFINED) {
343
+ node->state = WAITING;
344
+ }
345
+ } else {
346
+ maybeCancelAnimation(node->current.tag);
347
+ filteredMutations.push_back(ShadowViewMutation::DeleteMutation(node->current));
348
+ }
349
+ }
350
+
351
+ for (const auto &node : deadNodes) {
352
+ if (node->state != DELETED) {
353
+ auto parent = node->parent.lock();
354
+ react_native_assert(parent && "Parent node is nullptr");
355
+ auto index = parent->removeChild(node);
356
+ react_native_assert(index != -1 && "Dead node not found");
357
+
358
+ endAnimationsRecursively(node, index, filteredMutations);
359
+ maybeDropAncestors(parent, filteredMutations);
360
+ }
361
+ }
362
+ deadNodes.clear();
363
+ }
364
+
365
+ void LayoutAnimationsProxy_Experimental::addOngoingAnimations(SurfaceId surfaceId, ShadowViewMutationList &mutations)
366
+ const {
367
+ ReanimatedSystraceSection s1("addOngoingAnimations");
368
+ auto &updateMap = surfaceManager.getUpdateMap(surfaceId);
369
+ #ifdef ANDROID
370
+ std::vector<int> tagsToUpdate;
371
+ tagsToUpdate.reserve(updateMap.size());
372
+ for (auto &[tag, updateValues] : updateMap) {
373
+ tagsToUpdate.push_back(tag);
374
+ }
375
+
376
+ auto maybeCorrectedTags = preserveMountedTags_(tagsToUpdate);
377
+ if (!maybeCorrectedTags.has_value()) {
378
+ return;
379
+ }
380
+
381
+ auto correctedTags = maybeCorrectedTags->get();
382
+
383
+ // since the map is not updated, we can assume that the ordering of tags in
384
+ // correctedTags matches the iterator
385
+ int i = -1;
386
+ #endif
387
+ for (auto &[tag, updateValues] : updateMap) {
388
+ #ifdef ANDROID
389
+ i++;
390
+ if (correctedTags[i] == -1) {
391
+ // skip views that have not been mounted yet
392
+ // on Android we start entering animations from the JS thread
393
+ // so it might happen, that the first frame of the animation goes through
394
+ // before the view is first mounted
395
+ // https://github.com/software-mansion/react-native-reanimated/issues/7493
396
+ continue;
397
+ }
398
+ #endif
399
+
400
+ const auto layoutAnimationIt = layoutAnimations_.find(tag);
401
+
402
+ if (layoutAnimationIt == layoutAnimations_.end()) {
403
+ continue;
404
+ }
405
+
406
+ auto &layoutAnimation = layoutAnimationIt->second;
407
+ layoutAnimation.isViewAlreadyMounted = true;
408
+ auto newView = layoutAnimation.finalView;
409
+ if (updateValues.newProps) {
410
+ newView.props = updateValues.newProps;
411
+ }
412
+ updateLayoutMetrics(newView.layoutMetrics, updateValues.frame);
413
+
414
+ mutations.push_back(
415
+ ShadowViewMutation::UpdateMutation(layoutAnimation.currentView, newView, layoutAnimation.parentTag));
416
+ layoutAnimation.currentView = newView;
417
+ }
418
+ updateMap.clear();
419
+ }
420
+
421
+ void LayoutAnimationsProxy_Experimental::endAnimationsRecursively(
422
+ const std::shared_ptr<LightNode> &node,
423
+ int index,
424
+ ShadowViewMutationList &mutations) const {
425
+ maybeCancelAnimation(node->current.tag);
426
+ node->state = DELETED;
427
+ // iterate from the end, so that children
428
+ // with higher indices appear first in the mutations list
429
+
430
+ const int childrenSize = static_cast<int>(node->children.size());
431
+ for (int i = childrenSize - 1; i >= 0; i--) {
432
+ auto &subNode = node->children[i];
433
+ if (subNode->state != DELETED) {
434
+ endAnimationsRecursively(subNode, i, mutations);
435
+ }
436
+ }
437
+ node->children.clear();
438
+
439
+ const auto &parent = node->parent.lock();
440
+ react_native_assert(parent && "Parent node is nullptr");
441
+ mutations.push_back(ShadowViewMutation::RemoveMutation(parent->current.tag, node->current, index));
442
+ mutations.push_back(ShadowViewMutation::DeleteMutation(node->current));
443
+ }
444
+
445
+ void LayoutAnimationsProxy_Experimental::maybeDropAncestors(
446
+ const std::shared_ptr<LightNode> &node,
447
+ ShadowViewMutationList &cleanupMutations) const {
448
+ if (node->children.size() != 0 || node->state == ANIMATING || node->state == UNDEFINED) {
449
+ return;
450
+ }
451
+
452
+ auto parent = node->parent.lock();
453
+ react_native_assert(parent && "Parent node is nullptr");
454
+ auto index = parent->removeChild(node);
455
+ react_native_assert(index != -1 && "Child node not found");
456
+
457
+ node->state = DELETED;
458
+ maybeCancelAnimation(node->current.tag);
459
+ cleanupMutations.push_back(ShadowViewMutation::RemoveMutation(parent->current.tag, node->current, index));
460
+ cleanupMutations.push_back(ShadowViewMutation::DeleteMutation(node->current));
461
+ maybeDropAncestors(parent, cleanupMutations);
462
+ }
463
+
464
+ const ComponentDescriptor &LayoutAnimationsProxy_Experimental::getComponentDescriptorForShadowView(
465
+ const ShadowView &shadowView) const {
466
+ return componentDescriptorRegistry_->at(shadowView.componentHandle);
467
+ }
468
+
469
+ bool LayoutAnimationsProxy_Experimental::startAnimationsRecursively(
470
+ const std::shared_ptr<LightNode> &node,
471
+ ShadowViewMutationList &mutations,
472
+ StartAnimationsRecursivelyConfig config) const {
473
+ auto &[shouldRemoveSubviewsWithoutAnimations, shouldAnimate, isScreenPop] = config;
474
+ if (isRNSScreenOrStack(node)) {
475
+ isScreenPop = true;
476
+ }
477
+
478
+ shouldAnimate = !isScreenPop && layoutAnimationsManager_->shouldAnimateExiting(node->current.tag, shouldAnimate);
479
+
480
+ const bool hasExitAnimation =
481
+ shouldAnimate && layoutAnimationsManager_->hasLayoutAnimation(node->current.tag, LayoutAnimationType::EXITING);
482
+ bool hasAnimatedChildren = false;
483
+
484
+ shouldRemoveSubviewsWithoutAnimations = shouldRemoveSubviewsWithoutAnimations && !hasExitAnimation;
485
+ std::vector<std::shared_ptr<LightNode>> toBeRemoved;
486
+
487
+ // iterate from the end, so that children
488
+ // with higher indices appear first in the mutations list
489
+ auto index = static_cast<int>(node->children.size());
490
+ for (auto it = node->children.rbegin(); it != node->children.rend(); it++) {
491
+ index--;
492
+ auto &subNode = *it;
493
+ if (subNode->state != UNDEFINED) {
494
+ if (shouldAnimate && subNode->state != DEAD) {
495
+ hasAnimatedChildren = true;
496
+ } else {
497
+ endAnimationsRecursively(subNode, index, mutations);
498
+ toBeRemoved.push_back(subNode);
499
+ }
500
+ } else if (startAnimationsRecursively(subNode, mutations, config)) {
501
+ hasAnimatedChildren = true;
502
+ } else if (shouldRemoveSubviewsWithoutAnimations) {
503
+ maybeCancelAnimation(subNode->current.tag);
504
+ mutations.push_back(ShadowViewMutation::RemoveMutation(node->current.tag, subNode->current, index));
505
+ toBeRemoved.push_back(subNode);
506
+ subNode->state = DELETED;
507
+ mutations.push_back(ShadowViewMutation::DeleteMutation(subNode->current));
508
+ } else {
509
+ subNode->state = WAITING;
510
+ }
511
+ }
512
+
513
+ for (auto &subNode : toBeRemoved) {
514
+ node->removeChild(subNode);
515
+ }
516
+
517
+ const bool wantAnimateExit = hasExitAnimation || hasAnimatedChildren;
518
+
519
+ if (hasExitAnimation) {
520
+ node->state = ANIMATING;
521
+ startExitingAnimation(node);
522
+ lightNodes_[node->current.tag] = node;
523
+ } else {
524
+ // TODO (future): add proper cleanup
525
+ // layoutAnimationsManager_->clearLayoutAnimationConfig(node->tag);
526
+ }
527
+
528
+ return wantAnimateExit;
529
+ }
530
+
531
+ void LayoutAnimationsProxy_Experimental::updateOngoingAnimationTarget(const int tag, const ShadowViewMutation &mutation)
532
+ const {
533
+ layoutAnimations_[tag].finalView = mutation.newChildShadowView;
534
+ }
535
+
536
+ void LayoutAnimationsProxy_Experimental::maybeCancelAnimation(const int tag) const {
537
+ if (!layoutAnimations_.contains(tag)) {
538
+ return;
539
+ }
540
+ layoutAnimations_.erase(tag);
541
+ uiScheduler_->scheduleOnUI([weakThis = weak_from_this(), tag]() {
542
+ auto strongThis = weakThis.lock();
543
+ if (!strongThis) {
544
+ return;
545
+ }
546
+
547
+ auto &uiRuntime = strongThis->uiRuntime_;
548
+ strongThis->layoutAnimationsManager_->cancelLayoutAnimation(uiRuntime, tag);
549
+ });
550
+ }
551
+
552
+ void LayoutAnimationsProxy_Experimental::transferConfigFromNativeID(const std::string &nativeIdString, const int tag)
553
+ const {
554
+ if (nativeIdString.empty() || nativeIdString.length() > 9) {
555
+ return;
556
+ }
557
+ auto nativeId = 0;
558
+ for (int i = 0; i < nativeIdString.length(); i++) {
559
+ if (nativeIdString[i] < '0' || nativeIdString[i] > '9') {
560
+ return;
561
+ }
562
+ nativeId *= 10;
563
+ nativeId += nativeIdString[i] - '0';
564
+ }
565
+
566
+ layoutAnimationsManager_->transferConfigFromNativeID(nativeId, tag);
567
+ }
568
+
569
+ // When entering animations start, we temporarily set opacity to 0
570
+ // so that we can immediately insert the view at the right position
571
+ // and schedule the animation on the UI thread
572
+ ShadowView LayoutAnimationsProxy_Experimental::cloneViewWithoutOpacity(
573
+ const ShadowView &shadowView,
574
+ const PropsParserContext &propsParserContext) const {
575
+ auto newView = shadowView;
576
+ const folly::dynamic opacity = folly::dynamic::object("opacity", 0);
577
+ auto newProps =
578
+ getComponentDescriptorForShadowView(newView).cloneProps(propsParserContext, newView.props, RawProps(opacity));
579
+ newView.props = newProps;
580
+ return newView;
581
+ }
582
+
583
+ ShadowView LayoutAnimationsProxy_Experimental::cloneViewWithOpacity(
584
+ const ShadowView &shadowView,
585
+ const PropsParserContext &propsParserContext) const {
586
+ auto newView = shadowView;
587
+ const auto &props = static_cast<const ViewProps &>(*newView.props);
588
+ const folly::dynamic opacity = folly::dynamic::object("opacity", props.opacity);
589
+ auto newProps =
590
+ getComponentDescriptorForShadowView(newView).cloneProps(propsParserContext, newView.props, RawProps(opacity));
591
+ newView.props = newProps;
592
+ return newView;
593
+ }
594
+
595
+ void LayoutAnimationsProxy_Experimental::maybeRestoreOpacity(
596
+ reanimated::LayoutAnimation &layoutAnimation,
597
+ const jsi::Object &newStyle) const {
598
+ if (layoutAnimation.opacity && !newStyle.hasProperty(uiRuntime_, "opacity")) {
599
+ newStyle.setProperty(uiRuntime_, "opacity", jsi::Value(*layoutAnimation.opacity));
600
+ if (layoutAnimation.isViewAlreadyMounted) {
601
+ // We want to reset opacity only when we are sure that this update will be
602
+ // applied to the native view. Otherwise, we want to update opacity using
603
+ // the `restoreOpacityInCaseOfFlakyEnteringAnimation` method.
604
+ layoutAnimation.opacity.reset();
605
+ }
606
+ }
607
+ }
608
+
609
+ void LayoutAnimationsProxy_Experimental::maybeUpdateWindowDimensions(
610
+ const facebook::react::ShadowViewMutation &mutation) const {
611
+ if (mutation.type == ShadowViewMutation::Update &&
612
+ !std::strcmp(mutation.oldChildShadowView.componentName, RootComponentName)) {
613
+ surfaceManager.updateWindow(
614
+ mutation.newChildShadowView.tag,
615
+ mutation.newChildShadowView.layoutMetrics.frame.size.width,
616
+ mutation.newChildShadowView.layoutMetrics.frame.size.height);
617
+ }
618
+ }
619
+
620
+ void LayoutAnimationsProxy_Experimental::cleanupAnimations(
621
+ ShadowViewMutationList &filteredMutations,
622
+ const PropsParserContext &propsParserContext,
623
+ SurfaceId surfaceId) const {
624
+ ReanimatedSystraceSection s("cleanupAnimations");
625
+ cleanupSharedTransitions(filteredMutations, propsParserContext, surfaceId);
626
+
627
+ #ifdef ANDROID
628
+ restoreOpacityInCaseOfFlakyEnteringAnimation(surfaceId);
629
+ #endif // ANDROID
630
+ for (const auto tag : finishedAnimationTags_) {
631
+ auto &updateMap = surfaceManager.getUpdateMap(surfaceId);
632
+ layoutAnimations_.erase(tag);
633
+ updateMap.erase(tag);
634
+ }
635
+ finishedAnimationTags_.clear();
636
+ }
637
+
638
+ // MARK: Start Animation
639
+
640
+ ShadowView LayoutAnimationsProxy_Experimental::maybeCreateLayoutAnimation(
641
+ ShadowView &before,
642
+ const ShadowView &after,
643
+ const Tag parentTag) const {
644
+ auto count = 1;
645
+ const auto tag = after.tag;
646
+ auto layoutAnimationIt = layoutAnimations_.find(tag);
647
+ auto &oldView = before;
648
+
649
+ if (layoutAnimationIt != layoutAnimations_.end()) {
650
+ auto &layoutAnimation = layoutAnimationIt->second;
651
+ oldView = layoutAnimation.currentView;
652
+ count = layoutAnimation.count + 1;
653
+ }
654
+
655
+ auto finalView = after;
656
+ auto currentView = oldView;
657
+ auto startView = oldView;
658
+
659
+ layoutAnimations_[tag] = {
660
+ .finalView = finalView,
661
+ .currentView = currentView,
662
+ .startView = startView,
663
+ .parentTag = parentTag,
664
+ .count = count,
665
+ };
666
+
667
+ return oldView;
668
+ }
669
+
670
+ void LayoutAnimationsProxy_Experimental::startEnteringAnimation(const std::shared_ptr<LightNode> &node) const {
671
+ auto newChildShadowView = node->current;
672
+ const auto &finalView = newChildShadowView;
673
+ const auto &currentView = newChildShadowView;
674
+
675
+ const auto &props = newChildShadowView.props;
676
+ auto &viewProps = static_cast<const ViewProps &>(*props);
677
+ const auto opacity = viewProps.opacity;
678
+ const auto &parent = node->parent.lock();
679
+ react_native_assert(parent && "Parent node is nullptr");
680
+ const auto parentTag = parent->current.tag;
681
+
682
+ uiScheduler_->scheduleOnUI(
683
+ [weakThis = weak_from_this(), finalView, currentView, newChildShadowView, parentTag, opacity]() {
684
+ auto strongThis = weakThis.lock();
685
+ if (!strongThis) {
686
+ return;
687
+ }
688
+
689
+ Rect window;
690
+ const auto tag = newChildShadowView.tag;
691
+ {
692
+ auto lock = std::unique_lock<std::recursive_mutex>(strongThis->mutex);
693
+ strongThis->layoutAnimations_[tag] = {
694
+ .finalView = newChildShadowView,
695
+ .currentView = newChildShadowView,
696
+ .startView = newChildShadowView,
697
+ .parentTag = parentTag,
698
+ .opacity = opacity,
699
+ };
700
+ window = strongThis->surfaceManager.getWindow(newChildShadowView.surfaceId);
701
+ }
702
+
703
+ const Snapshot values(newChildShadowView, window);
704
+ auto &uiRuntime = strongThis->uiRuntime_;
705
+ const jsi::Object yogaValues(uiRuntime);
706
+ yogaValues.setProperty(uiRuntime, "targetOriginX", values.x);
707
+ yogaValues.setProperty(uiRuntime, "targetGlobalOriginX", values.x);
708
+ yogaValues.setProperty(uiRuntime, "targetOriginY", values.y);
709
+ yogaValues.setProperty(uiRuntime, "targetGlobalOriginY", values.y);
710
+ yogaValues.setProperty(uiRuntime, "targetWidth", values.width);
711
+ yogaValues.setProperty(uiRuntime, "targetHeight", values.height);
712
+ yogaValues.setProperty(uiRuntime, "windowWidth", values.windowWidth);
713
+ yogaValues.setProperty(uiRuntime, "windowHeight", values.windowHeight);
714
+ strongThis->layoutAnimationsManager_->startLayoutAnimation(
715
+ uiRuntime, tag, LayoutAnimationType::ENTERING, yogaValues);
716
+ });
717
+ }
718
+
719
+ void LayoutAnimationsProxy_Experimental::startExitingAnimation(const std::shared_ptr<LightNode> &node) const {
720
+ auto &oldChildShadowView = node->current;
721
+ const auto surfaceId = oldChildShadowView.surfaceId;
722
+ const auto tag = oldChildShadowView.tag;
723
+ const auto &parent = node->parent.lock();
724
+ react_native_assert(parent && "Parent node is nullptr");
725
+ const auto parentTag = parent->current.tag;
726
+
727
+ uiScheduler_->scheduleOnUI([weakThis = weak_from_this(), tag, parentTag, oldChildShadowView, surfaceId]() {
728
+ auto strongThis = weakThis.lock();
729
+ if (!strongThis) {
730
+ return;
731
+ }
732
+
733
+ auto oldView = oldChildShadowView;
734
+ Rect window{};
735
+ {
736
+ auto &mutex = strongThis->mutex;
737
+ auto lock = std::unique_lock<std::recursive_mutex>(mutex);
738
+ oldView = strongThis->maybeCreateLayoutAnimation(oldView, oldView, parentTag);
739
+ window = strongThis->surfaceManager.getWindow(surfaceId);
740
+ }
741
+
742
+ const Snapshot values(oldView, window);
743
+
744
+ auto &uiRuntime = strongThis->uiRuntime_;
745
+ const jsi::Object yogaValues(uiRuntime);
746
+ yogaValues.setProperty(uiRuntime, "currentOriginX", values.x);
747
+ yogaValues.setProperty(uiRuntime, "currentGlobalOriginX", values.x);
748
+ yogaValues.setProperty(uiRuntime, "currentOriginY", values.y);
749
+ yogaValues.setProperty(uiRuntime, "currentGlobalOriginY", values.y);
750
+ yogaValues.setProperty(uiRuntime, "currentWidth", values.width);
751
+ yogaValues.setProperty(uiRuntime, "currentHeight", values.height);
752
+ yogaValues.setProperty(uiRuntime, "windowWidth", values.windowWidth);
753
+ yogaValues.setProperty(uiRuntime, "windowHeight", values.windowHeight);
754
+ strongThis->layoutAnimationsManager_->startLayoutAnimation(
755
+ uiRuntime, tag, LayoutAnimationType::EXITING, yogaValues);
756
+ strongThis->layoutAnimationsManager_->clearLayoutAnimationConfig(tag);
757
+ });
758
+ }
759
+
760
+ void LayoutAnimationsProxy_Experimental::startLayoutAnimation(const std::shared_ptr<LightNode> &node) const {
761
+ auto oldChildShadowView = node->previous;
762
+ auto newChildShadowView = node->current;
763
+ auto surfaceId = oldChildShadowView.surfaceId;
764
+ const auto tag = oldChildShadowView.tag;
765
+ const auto &parent = node->parent.lock();
766
+ react_native_assert(parent && "Parent node is nullptr");
767
+ const auto parentTag = parent->current.tag;
768
+
769
+ uiScheduler_->scheduleOnUI(
770
+ [weakThis = weak_from_this(), surfaceId, oldChildShadowView, newChildShadowView, parentTag, tag]() {
771
+ auto strongThis = weakThis.lock();
772
+ if (!strongThis) {
773
+ return;
774
+ }
775
+
776
+ auto oldView = oldChildShadowView;
777
+ Rect window{};
778
+ {
779
+ auto &mutex = strongThis->mutex;
780
+ auto lock = std::unique_lock<std::recursive_mutex>(mutex);
781
+ oldView = strongThis->maybeCreateLayoutAnimation(oldView, newChildShadowView, parentTag);
782
+ window = strongThis->surfaceManager.getWindow(surfaceId);
783
+ }
784
+
785
+ const Snapshot currentValues(oldView, window);
786
+ const Snapshot targetValues(newChildShadowView, window);
787
+
788
+ auto &uiRuntime = strongThis->uiRuntime_;
789
+ const jsi::Object yogaValues(uiRuntime);
790
+ yogaValues.setProperty(uiRuntime, "currentOriginX", currentValues.x);
791
+ yogaValues.setProperty(uiRuntime, "currentGlobalOriginX", currentValues.x);
792
+ yogaValues.setProperty(uiRuntime, "currentOriginY", currentValues.y);
793
+ yogaValues.setProperty(uiRuntime, "currentGlobalOriginY", currentValues.y);
794
+ yogaValues.setProperty(uiRuntime, "currentWidth", currentValues.width);
795
+ yogaValues.setProperty(uiRuntime, "currentHeight", currentValues.height);
796
+ yogaValues.setProperty(uiRuntime, "targetOriginX", targetValues.x);
797
+ yogaValues.setProperty(uiRuntime, "targetGlobalOriginX", targetValues.x);
798
+ yogaValues.setProperty(uiRuntime, "targetOriginY", targetValues.y);
799
+ yogaValues.setProperty(uiRuntime, "targetGlobalOriginY", targetValues.y);
800
+ yogaValues.setProperty(uiRuntime, "targetWidth", targetValues.width);
801
+ yogaValues.setProperty(uiRuntime, "targetHeight", targetValues.height);
802
+ yogaValues.setProperty(uiRuntime, "windowWidth", targetValues.windowWidth);
803
+ yogaValues.setProperty(uiRuntime, "windowHeight", targetValues.windowHeight);
804
+ strongThis->layoutAnimationsManager_->startLayoutAnimation(
805
+ uiRuntime, tag, LayoutAnimationType::LAYOUT, yogaValues);
806
+ });
807
+ }
808
+
809
+ void LayoutAnimationsProxy_Experimental::startSharedTransition(
810
+ const int tag,
811
+ const ShadowView &before,
812
+ const ShadowView &after,
813
+ SurfaceId surfaceId) const {
814
+ uiScheduler_->scheduleOnUI([weakThis = weak_from_this(), before, after, surfaceId, tag]() {
815
+ auto strongThis = weakThis.lock();
816
+ if (!strongThis) {
817
+ return;
818
+ }
819
+
820
+ auto oldView = before;
821
+ Rect window{};
822
+ {
823
+ auto &mutex = strongThis->mutex;
824
+ auto lock = std::unique_lock<std::recursive_mutex>(mutex);
825
+ oldView = strongThis->maybeCreateLayoutAnimation(oldView, after, surfaceId);
826
+ window = strongThis->surfaceManager.getWindow(surfaceId);
827
+ }
828
+
829
+ auto &uiRuntime = strongThis->uiRuntime_;
830
+ auto propsDiffer = PropsDiffer(uiRuntime, oldView, after);
831
+
832
+ const auto &propsDiff = propsDiffer.computeDiff(uiRuntime);
833
+
834
+ propsDiff.setProperty(uiRuntime, "windowWidth", window.width);
835
+ propsDiff.setProperty(uiRuntime, "windowHeight", window.height);
836
+
837
+ strongThis->layoutAnimationsManager_->startLayoutAnimation(
838
+ uiRuntime, tag, LayoutAnimationType::SHARED_ELEMENT_TRANSITION, propsDiff);
839
+ });
840
+ }
841
+
842
+ void LayoutAnimationsProxy_Experimental::startProgressTransition(
843
+ const int tag,
844
+ const ShadowView &before,
845
+ const ShadowView &after,
846
+ SurfaceId surfaceId) const {
847
+ uiScheduler_->scheduleOnUI([weakThis = weak_from_this(), before, after, surfaceId]() {
848
+ auto strongThis = weakThis.lock();
849
+ if (!strongThis) {
850
+ return;
851
+ }
852
+
853
+ auto oldView = before;
854
+ Rect window{};
855
+ {
856
+ auto &mutex = strongThis->mutex;
857
+ auto lock = std::unique_lock<std::recursive_mutex>(mutex);
858
+ oldView = strongThis->maybeCreateLayoutAnimation(oldView, after, surfaceId);
859
+ window = strongThis->surfaceManager.getWindow(surfaceId);
860
+ }
861
+ });
862
+ }
863
+
864
+ } // namespace reanimated