From 0fa7649355936a57e6635fa0d2196bb8e0515979 Mon Sep 17 00:00:00 2001 From: Krzysztof Magiera Date: Fri, 22 Apr 2022 14:36:06 +0200 Subject: [PATCH 01/45] Stashing work --- .../LayoutAnimationsProxy.cpp | 38 +++ .../NativeModules/NativeReanimatedModule.cpp | 9 + .../NativeReanimatedModuleSpec.cpp | 12 + .../LayoutAnimations/LayoutAnimationsProxy.h | 10 +- .../NativeModules/NativeReanimatedModule.h | 10 +- .../NativeReanimatedModuleSpec.h | 7 + Example/ios/Podfile.lock | 6 +- Example/src/App.tsx | 304 ++---------------- ios/LayoutReanimation/REAAnimationsManager.h | 12 +- ios/LayoutReanimation/REAAnimationsManager.m | 98 ++++-- ios/LayoutReanimation/REAUIManager.mm | 29 +- ios/native/NativeProxy.mm | 76 +++-- src/createAnimatedComponent.tsx | 79 +++-- .../NativeReanimated/NativeReanimated.ts | 5 + src/reanimated2/core.ts | 8 + .../LayoutAnimationRepository.ts | 62 ++-- 16 files changed, 321 insertions(+), 444 deletions(-) diff --git a/Common/cpp/LayoutAnimations/LayoutAnimationsProxy.cpp b/Common/cpp/LayoutAnimations/LayoutAnimationsProxy.cpp index 96bd26c17fd..841dbdc9a8e 100644 --- a/Common/cpp/LayoutAnimations/LayoutAnimationsProxy.cpp +++ b/Common/cpp/LayoutAnimations/LayoutAnimationsProxy.cpp @@ -40,4 +40,42 @@ void LayoutAnimationsProxy::notifyAboutCancellation(int tag) { this->notifyAboutEnd(tag, false); } +void LayoutAnimationsProxy::configureAnimation(int tag, const std::string &type, std::shared_ptr config) { + if (type == "entering") { + enteringAnimations[tag] = config; + } else if (type == "exiting") { + exitingAnimations[tag] = config; + } else if (type == "layout") { + layoutAnimations[tag] = config; + } +} + +bool LayoutAnimationsProxy::hasLayoutAnimation(int tag, const std::string &type) { + if (type == "entering") { + return enteringAnimations.find(tag) != enteringAnimations.end(); + } else if (type == "exiting") { + return exitingAnimations.find(tag) != exitingAnimations.end(); + } else if (type == "layout") { + return layoutAnimations.find(tag) != layoutAnimations.end(); + } + return false; +} + +void LayoutAnimationsProxy::startLayoutAnimation(jsi::Runtime &rt, int tag, const std::string &type, const jsi::Object &values) { + std::shared_ptr config; + if (type == "entering") { + config = enteringAnimations[tag]; + } else if (type == "exiting") { + config = exitingAnimations[tag]; + } else if (type == "layout") { + config = layoutAnimations[tag]; + } + jsi::Value layoutAnimationRepositoryAsValue = rt.global().getPropertyAsObject(rt, "global").getProperty(rt, "LayoutAnimationRepository"); + if (!layoutAnimationRepositoryAsValue.isUndefined()) { + jsi::Function startAnimationForTag = + layoutAnimationRepositoryAsValue.getObject(rt).getPropertyAsFunction(rt, "startAnimationForTag"); + startAnimationForTag.call(rt, jsi::Value(tag), jsi::String::createFromAscii(rt, type), values, config->toJSValue(rt)); + } +} + } // namespace reanimated diff --git a/Common/cpp/NativeModules/NativeReanimatedModule.cpp b/Common/cpp/NativeModules/NativeReanimatedModule.cpp index 50584dd7611..55f07fe9c74 100644 --- a/Common/cpp/NativeModules/NativeReanimatedModule.cpp +++ b/Common/cpp/NativeModules/NativeReanimatedModule.cpp @@ -257,6 +257,15 @@ jsi::Value NativeReanimatedModule::configureProps( return jsi::Value::undefined(); } +jsi::Value NativeReanimatedModule::configureLayoutAnimation( + jsi::Runtime &rt, + const jsi::Value &viewTag, + const jsi::Value &type, + const jsi::Value &config) { + layoutAnimationsProxy->configureAnimation(viewTag.asNumber(), type.asString(rt).utf8(rt), ShareableValue::adapt(rt, config, this)); + return jsi::Value::undefined(); +} + void NativeReanimatedModule::onEvent( std::string eventName, std::string eventAsString) { diff --git a/Common/cpp/NativeModules/NativeReanimatedModuleSpec.cpp b/Common/cpp/NativeModules/NativeReanimatedModuleSpec.cpp index 14819e06ff1..5969a3cb27c 100644 --- a/Common/cpp/NativeModules/NativeReanimatedModuleSpec.cpp +++ b/Common/cpp/NativeModules/NativeReanimatedModuleSpec.cpp @@ -138,6 +138,16 @@ static jsi::Value SPEC_PREFIX(configureProps)( return jsi::Value::undefined(); } +static jsi::Value SPEC_PREFIX(configureLayoutAnimation)( + jsi::Runtime &rt, + TurboModule &turboModule, + const jsi::Value *args, + size_t count) { + static_cast(&turboModule) + ->configureLayoutAnimation(rt, std::move(args[0]), std::move(args[1]), std::move(args[2])); + return jsi::Value::undefined(); +} + NativeReanimatedModuleSpec::NativeReanimatedModuleSpec( std::shared_ptr jsInvoker) : TurboModule("NativeReanimated", jsInvoker) { @@ -163,5 +173,7 @@ NativeReanimatedModuleSpec::NativeReanimatedModuleSpec( methodMap_["unregisterSensor"] = MethodMetadata{1, SPEC_PREFIX(unregisterSensor)}; methodMap_["configureProps"] = MethodMetadata{2, SPEC_PREFIX(configureProps)}; + + methodMap_["configureLayoutAnimation"] = MethodMetadata{3, SPEC_PREFIX(configureLayoutAnimation)}; } } // namespace reanimated diff --git a/Common/cpp/headers/LayoutAnimations/LayoutAnimationsProxy.h b/Common/cpp/headers/LayoutAnimations/LayoutAnimationsProxy.h index 5462669769f..4c5cb2799a5 100644 --- a/Common/cpp/headers/LayoutAnimations/LayoutAnimationsProxy.h +++ b/Common/cpp/headers/LayoutAnimations/LayoutAnimationsProxy.h @@ -11,6 +11,7 @@ namespace reanimated { using namespace facebook; class MutableValue; +class ShareableValue; class LayoutAnimationsProxy { public: @@ -18,15 +19,20 @@ class LayoutAnimationsProxy { std::function _notifyAboutProgress, std::function _notifyAboutEnd); - void - startObserving(int tag, std::shared_ptr sv, jsi::Runtime &rt); + void startObserving(int tag, std::shared_ptr sv, jsi::Runtime &rt); void stopObserving(int tag, bool finished); void notifyAboutCancellation(int tag); + void configureAnimation(int tag, const std::string& type, std::shared_ptr config); + bool hasLayoutAnimation(int tag, const std::string& type); + void startLayoutAnimation(jsi::Runtime &rt, int tag, const std::string& type, const jsi::Object &values); private: std::function notifyAboutProgress; std::function notifyAboutEnd; std::map> observedValues; + std::map> enteringAnimations; + std::map> exitingAnimations; + std::map> layoutAnimations; }; } // namespace reanimated diff --git a/Common/cpp/headers/NativeModules/NativeReanimatedModule.h b/Common/cpp/headers/NativeModules/NativeReanimatedModule.h index fdcea13424d..ce5528c8b34 100644 --- a/Common/cpp/headers/NativeModules/NativeReanimatedModule.h +++ b/Common/cpp/headers/NativeModules/NativeReanimatedModule.h @@ -90,6 +90,14 @@ class NativeReanimatedModule : public NativeReanimatedModuleSpec, const jsi::Value &sensorDataContainer) override; void unregisterSensor(jsi::Runtime &rt, const jsi::Value &sensorId) override; + jsi::Value configureLayoutAnimation( + jsi::Runtime &rt, + const jsi::Value &viewTag, + const jsi::Value &type, + const jsi::Value &config) override; + + std::shared_ptr layoutAnimationsProxy; + private: std::shared_ptr mapperRegistry; std::shared_ptr eventHandlerRegistry; @@ -100,7 +108,7 @@ class NativeReanimatedModule : public NativeReanimatedModuleSpec, std::function propObtainer; std::function onRenderCallback; - std::shared_ptr layoutAnimationsProxy; + AnimatedSensorModule animatedSensorModule; ConfigurePropsFunction configurePropsPlatformFunction; }; diff --git a/Common/cpp/headers/NativeModules/NativeReanimatedModuleSpec.h b/Common/cpp/headers/NativeModules/NativeReanimatedModuleSpec.h index eae4509f0eb..b048caab85c 100644 --- a/Common/cpp/headers/NativeModules/NativeReanimatedModuleSpec.h +++ b/Common/cpp/headers/NativeModules/NativeReanimatedModuleSpec.h @@ -77,6 +77,13 @@ class JSI_EXPORT NativeReanimatedModuleSpec : public TurboModule { jsi::Runtime &rt, const jsi::Value &uiProps, const jsi::Value &nativeProps) = 0; + + // layout animations + virtual jsi::Value configureLayoutAnimation( + jsi::Runtime &rt, + const jsi::Value &viewTag, + const jsi::Value &type, + const jsi::Value &config) = 0; }; } // namespace reanimated diff --git a/Example/ios/Podfile.lock b/Example/ios/Podfile.lock index f5fcfdcc057..4d60bba731e 100644 --- a/Example/ios/Podfile.lock +++ b/Example/ios/Podfile.lock @@ -477,8 +477,8 @@ SPEC CHECKSUMS: FBLazyVector: d2fd875e2b24bbc350722df0df9d383cb891b9f2 FBReactNativeSpec: 7493e074a31512df3253160059295264a84b8149 fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 - glog: 476ee3e89abb49e07f822b48323c51c57124b572 - RCT-Folly: 4d8508a426467c48885f1151029bc15fa5d7b3b8 + glog: 5337263514dd6f09803962437687240c5dc39aa4 + RCT-Folly: a21c126816d8025b547704b777a2ba552f3d9fa9 RCTRequired: bab4a7c3d7eb9553b13773ee190f279712efd1fc RCTTypeSafety: efbeb6e450ff6cef8e19c2cb5314c6d8bfeeef77 React: 28e4d45839b7d0fd9512af899e0379a17a5172ec @@ -509,7 +509,7 @@ SPEC CHECKSUMS: RNCMaskedView: 5a8ec07677aa885546a0d98da336457e2bea557f RNCPicker: 914b557e20b3b8317b084aca9ff4b4edb95f61e4 RNGestureHandler: 5e58135436aacc1c5d29b75547d3d2b9430d052c - RNReanimated: e42de406edd11350af29016cf6802ef16ee364d0 + RNReanimated: a05a0a5ba7c20a0be99fa15d18d0fbf21b025a57 RNScreens: eb0dfb2d6b21d2d7f980ad46b14eb306d2f1062e RNSVG: ce9d996113475209013317e48b05c21ee988d42e Yoga: 6671cf077f614314c22fd09ddf87d7abeee64e96 diff --git a/Example/src/App.tsx b/Example/src/App.tsx index 7b31a56fec1..2e81c4ce4c0 100644 --- a/Example/src/App.tsx +++ b/Example/src/App.tsx @@ -1,289 +1,33 @@ -import React from 'react'; -import { - FlatList, - StyleSheet, - Text, - View, - LogBox, - Platform, - UIManager, - ScrollView, -} from 'react-native'; -import { RectButton } from 'react-native-gesture-handler'; -import { - createStackNavigator, - StackNavigationProp, -} from '@react-navigation/stack'; -import { NavigationContainer } from '@react-navigation/native'; -import { - Carousel, - CustomLayoutAnimationScreen, - DefaultAnimations, - Modal, - ModalNewAPI, - MountingUnmounting, - SpringLayoutAnimation, - SwipeableList, - NativeModals, -} from './LayoutReanimation'; +import React, { useState } from 'react'; +import { StyleSheet, View, Button } from 'react-native'; +import Animated, { FadeIn, FadeOut } from 'react-native-reanimated'; -import AnimatedStyleUpdateExample from './AnimatedStyleUpdateExample'; -import AnimatedTabBarExample from './AnimatedTabBarExample'; -import ChatHeadsExample from './ChatHeadsExample'; -import { PagerExample } from './CustomHandler'; -import DragAndSnapExample from './DragAndSnapExample'; -import ExtrapolationExample from './ExtrapolationExample'; -import { KeyframeAnimation } from './LayoutReanimation/KeyframeAnimation'; -import LightboxExample from './LightboxExample'; -import LiquidSwipe from './LiquidSwipe'; -import MeasureExample from './MeasureExample'; -import { OlympicAnimation } from './LayoutReanimation/OlympicAnimation'; -import { ReactionsCounterExample } from './ReactionsCounterExample'; -// @ts-ignore JS file -import Reanimated1 from '../reanimated1/App'; -import ScrollEventExample from './ScrollEventExample'; -import ScrollExample from './AnimatedScrollExample'; -import ScrollToExample from './ScrollToExample'; -import ScrollableViewExample from './ScrollableViewExample'; -import SwipeableListExample from './SwipeableListExample'; -import WobbleExample from './WobbleExample'; -import AnimatedListExample from './LayoutReanimation/AnimatedList'; -import { WaterfallGridExample } from './LayoutReanimation/WaterfallGridExample'; -import AnimatedSensorExample from './AnimatedSensorExample'; -import AnimatedSharedStyleExample from './AnimatedSharedStyleExample'; - -LogBox.ignoreLogs(['Calling `getNode()`']); - -if (Platform.OS === 'android') { - if (UIManager.setLayoutAnimationEnabledExperimental) { - UIManager.setLayoutAnimationEnabledExperimental(true); - } -} - -type Screens = Record; - -const SCREENS: Screens = { - DefaultAnimations: { - screen: DefaultAnimations, - title: '🆕 Default layout animations', - }, - AnimatedSensor: { - screen: AnimatedSensorExample, - title: '🆕 Use Animated Sensor', - }, - DefaultTransistions: { - screen: WaterfallGridExample, - title: '🆕 Default layout transitions', - }, - KeyframeAnimation: { - screen: KeyframeAnimation, - title: '🆕 Keyframe animation', - }, - ParticipantList: { - screen: AnimatedListExample, - title: '🆕 Participant List', - }, - OlympicAnimation: { - screen: OlympicAnimation, - title: '🆕 Olympic animation', - }, - CustomLayoutAnimation: { - screen: CustomLayoutAnimationScreen, - title: '🆕 Custom layout animation', - }, - ModalNewAPI: { - title: '🆕 ModalNewAPI', - screen: ModalNewAPI, - }, - SpringLayoutAnimation: { - title: '🆕 Spring Layout Animation', - screen: SpringLayoutAnimation, - }, - MountingUnmounting: { - title: '🆕 Mounting Unmounting', - screen: MountingUnmounting, - }, - ReactionsCounterExample: { - screen: ReactionsCounterExample, - title: '🆕 Reactions counter', - }, - SwipeableList: { - title: '🆕 Swipeable list', - screen: SwipeableList, - }, - Modal: { - title: '🆕 Modal', - screen: Modal, - }, - NativeModals: { - title: '🆕 Native modals (RN and Screens)', - screen: NativeModals, - }, - Carousel: { - title: 'Carousel', - screen: Carousel, - }, - PagerExample: { - screen: PagerExample, - title: 'Custom Handler Example - Pager', - }, - AnimatedStyleUpdate: { - screen: AnimatedStyleUpdateExample, - title: 'Animated Style Update', - }, - AnimatedSharedStyle: { - screen: AnimatedSharedStyleExample, - title: 'Animated Shared Style', - }, - WobbleExample: { - screen: WobbleExample, - title: 'Animation Modifiers (Wobble Effect)', - }, - DragAndSnapExample: { - screen: DragAndSnapExample, - title: 'Drag and Snap', - }, - MeasureExample: { - screen: MeasureExample, - title: 'Synchronous Measure', - }, - ScrollEventExample: { - screen: ScrollEventExample, - title: 'Scroll Events', - }, - ChatHeadsExample: { - screen: ChatHeadsExample, - title: 'Chat Heads', - }, - ScrollableToExample: { - screen: ScrollToExample, - title: 'scrollTo', - }, - SwipeableListExample: { - screen: SwipeableListExample, - title: '(advanced) Swipeable List', - }, - LightboxExample: { - screen: LightboxExample, - title: '(advanced) Lightbox', - }, - ScrollableViewExample: { - screen: ScrollableViewExample, - title: '(advanced) ScrollView imitation', - }, - AnimatedTabBarExample: { - screen: AnimatedTabBarExample, - title: '(advanced) Tab Bar Example', - }, - LiquidSwipe: { - screen: LiquidSwipe, - title: 'Liquid Swipe Example', - }, - ExtrapolationExample: { - screen: ExtrapolationExample, - title: 'Extrapolation Example', - }, - ScrollExample: { - screen: ScrollExample, - title: 'Scroll Example', - }, -}; - -type RootStackParams = { Home: undefined } & { [key: string]: undefined }; -type MainScreenProps = { - navigation: StackNavigationProp; - setUseRea2: (useRea2: boolean) => void; -}; - -function MainScreen({ navigation, setUseRea2 }: MainScreenProps) { - const data = Object.keys(SCREENS).map((key) => ({ key })); +export default function App() { + const [show, setShow] = useState(false); + const [show2, setShow2] = useState(false); return ( - ( - navigation.navigate(key)} + +