From 65238b0a1eef9a0f65d526e6624aa0a8d7cab07b Mon Sep 17 00:00:00 2001 From: Tomek Zawadzki Date: Wed, 29 Mar 2023 22:00:10 +0200 Subject: [PATCH] Unify example apps (#4288) ## Summary Note: This is a huge PR, please review the commits one-by-one. ### Changes - Create app package that holds the common code for all example apps + add CI checks - Move all examples from Example, FabricExample and WebExample to app directory - Use `App.tsx` from app directory in Example, FabricExample and WebExample apps - Use `export default function` wherever possible - Use `NativeStackNavigationProp` type instead of `StackNavigationProp` in SET examples and remove dependency - Remove test, test-suite and e2e directories and Detox configuration - Regenerate Example app using `npx react-native@next ReanimatedExample --version 0.71.3 --skip-install` - Use autolinking instead of manual linking in Example app (Android & iOS) like in FabricExample - Use original TypeScript and ESLint configuration in Example and FabricExample apps - Move `react-native-reanimated-tests.tsx` from FabricExample to `__typetests__` (as in react-native repo) ### TODO - [ ] Check apps in release mode ### Next steps - [ ] Make example list hierarchical - [ ] WebExample takes too long to bundle - [ ] Don't return to home screen after fast refresh on web ## Test plan Check if Example, FabricExample and WebExample work properly. --- .../workflows/static-example-apps-checks.yml | 2 +- .github/workflows/validate-app.yml | 37 + Example/.detoxrc.json | 42 - Example/.eslintrc.js | 2 +- Example/.gitignore | 4 - Example/.prettierrc.js | 7 + Example/App.tsx | 3 + Example/android/app/.gitignore | 3 - Example/android/app/build.gradle | 10 - .../reanimated/example/DetoxTest.java | 35 - .../reanimated/example/MainApplication.java | 2 - Example/android/gradle.properties | 2 + Example/android/settings.gradle | 4 - Example/app.json | 11 +- Example/babel.config.js | 46 +- Example/e2e/config.json | 9 - Example/e2e/environment.js | 23 - Example/e2e/testExitingAnimation.e2e.js | 24 - Example/index-template.js | 11 - Example/index.js | 16 +- Example/ios/Podfile | 2 - Example/ios/Podfile.lock | 35 +- .../AppIcon.appiconset/Contents.json | 101 +- .../ReanimatedExampleTests.m | 66 + .../ios/ReanimatedExampleTests/SampleTest.mm | 16 - Example/metro.config.js | 43 +- Example/package.json | 68 +- ...tch => metro-inspector-proxy+0.73.9.patch} | 0 .../patches/react-native-box2d+0.2.5.patch | 85 + Example/scripts/generateIndex.js | 48 - Example/src/AnimatedKeyboardExample.tsx | 89 - Example/src/App.tsx | 412 -- Example/src/CustomHandler/index.tsx | 1 - Example/src/LayoutReanimation/index.ts | 16 - Example/src/LightboxExample.tsx | 335 -- Example/src/LiquidSwipe/index.tsx | 1 - Example/src/ScrollViewOffsetExample.tsx | 57 - Example/src/WebApp.tsx | 186 - Example/test-suite/.gitignore | 2 - Example/test-suite/App.js | 10 - Example/test-suite/AppNavigator.js | 48 - Example/test-suite/TestModules.js | 16 - Example/test-suite/assets/LLizard.mp3 | Bin 333435 -> 0 bytes Example/test-suite/assets/asset-db.db | Bin 8192 -> 0 bytes Example/test-suite/assets/black-128x256.png | Bin 6470 -> 0 bytes Example/test-suite/assets/comic.ttf | Bin 63648 -> 0 bytes Example/test-suite/assets/datamatrix_expo.png | Bin 222 -> 0 bytes Example/test-suite/assets/example_image_1.jpg | Bin 63634 -> 0 bytes Example/test-suite/assets/icons/app.png | Bin 7168 -> 0 bytes Example/test-suite/assets/icons/loading.png | Bin 7168 -> 0 bytes Example/test-suite/assets/multiple_codes.png | Bin 1634 -> 0 bytes .../assets/qrcode_photo_wikipedia.jpg | Bin 46567 -> 0 bytes .../test-suite/assets/unsupported_bunny.webm | Bin 146342 -> 0 bytes Example/test-suite/components/DoneText.js | 41 - .../components/PlatformTouchable.android.js | 6 - .../components/PlatformTouchable.js | 6 - Example/test-suite/components/Portal.js | 24 - Example/test-suite/components/RunnerError.js | 24 - Example/test-suite/components/SpecResult.js | 54 - Example/test-suite/components/SuiteResult.js | 69 - Example/test-suite/components/Suites.js | 54 - Example/test-suite/constants/Colors.js | 11 - Example/test-suite/constants/StatusEmojis.js | 8 - Example/test-suite/constants/Statuses.js | 7 - Example/test-suite/screens/SelectScreen.js | 209 -- Example/test-suite/screens/TestScreen.js | 297 -- Example/test-suite/tests/AnimatedRef.js | 64 - Example/test-suite/tests/AttachComponent.js | 75 - Example/test-suite/tests/Basic.js | 18 - Example/test-suite/tests/Camera.js | 369 -- Example/test-suite/tests/Cellular.js | 64 - Example/test-suite/tests/Colors.js | 55 - Example/test-suite/tests/FileSystem.js | 494 --- Example/test-suite/tests/Pitagoras.js | 11 - Example/test-suite/tests/helpers.js | 116 - Example/test-suite/utils/Environment.js | 16 - Example/test/AdaptersTest.js | 100 - Example/test/AnimatedReactionTest.js | 101 - Example/test/Animations.js | 135 - Example/test/CustomLayout2.tsx | 90 - Example/test/CustomLayout3.tsx | 85 - Example/test/FastRefreshTest.js | 232 -- Example/test/LayoutAnimationsRemovalTest.tsx | 60 - Example/test/MeasureTest.js | 89 - Example/test/ModalInNavigation.tsx | 60 - Example/test/ModalInNavigationNativeStack.tsx | 53 - Example/test/SimpleTest.js | 276 -- Example/test/TestApp.js | 145 - Example/test/TestRemovalOrder.js | 68 - Example/test/TransformsTest.js | 178 - Example/test/UpdatePropsTest.js | 95 - Example/test/WithNavigation.tsx | 85 - Example/test/WithNavigationNested.tsx | 112 - Example/test/scrollToTest.js | 58 - Example/tsconfig.json | 9 +- Example/yarn.lock | 3316 ++--------------- FabricExample/.prettierrc.js | 7 + FabricExample/.prettierrc.json | 9 - FabricExample/App.tsx | 285 +- FabricExample/ios/Podfile.lock | 18 + FabricExample/metro.config.js | 5 +- FabricExample/package.json | 11 +- FabricExample/src/FrameCallbackExample.tsx | 121 - FabricExample/src/useJSThreadKiller.ts | 13 - FabricExample/tsconfig.json | 7 +- FabricExample/yarn.lock | 24 +- TVOSExample/App.js | 43 - TVOSExample/App.tsx | 3 + TVOSExample/babel.config.js | 45 +- TVOSExample/ios/Podfile | 3 - TVOSExample/ios/Podfile.lock | 404 +- TVOSExample/metro.config.js | 43 +- TVOSExample/package.json | 5 +- TVOSExample/yarn.lock | 58 +- WebExample/App.tsx | 86 +- WebExample/package.json | 3 +- WebExample/yarn.lock | 13 +- .../react-native-reanimated-tests.tsx | 2 +- app/.eslintrc.js | 8 + app/babel.config.js | 4 + app/index.ts | 3 + app/package.json | 39 + app/src/App.tsx | 150 + app/src/examples/AboutExample.tsx | 78 + .../src/examples}/AnimatedKeyboardExample.tsx | 15 +- .../src/examples}/AnimatedSensorExample.tsx | 0 .../examples}/AnimatedStyleUpdateExample.tsx | 4 +- .../src/examples}/AnimatedTabBarExample.tsx | 4 +- .../examples}/AnimatedTextInputExample.tsx | 0 .../examples}/AnimatedTextWidthExample.tsx | 0 .../src/examples}/ArticleProgressExample.tsx | 0 .../src/examples}/BilliardExample.tsx | 0 app/src/examples/BilliardExample.web.tsx | 19 + .../src => app/src/examples}/BokehExample.tsx | 6 +- .../src/examples}/BouncingBoxExample.tsx | 0 .../src/examples}/BubblesExample.tsx | 6 +- .../src/examples}/ChatHeadsExample.tsx | 4 +- .../src/examples}/ChessboardExample.tsx | 0 .../src => app/src/examples}/ColorExample.tsx | 0 .../examples}/ColorInterpolationExample.tsx | 2 +- .../src => app/src/examples}/CubesExample.tsx | 0 .../examples}/CustomHandler/AnimatedText.tsx | 0 .../examples}/CustomHandler/PagerExample.tsx | 2 +- .../CustomHandler/PagerExample.web.tsx | 19 + .../examples}/CustomHandler/Pagination.tsx | 0 .../CustomHandler/useAnimatedPagerHandler.ts | 0 .../src/examples}/DragAndSnapExample.tsx | 4 +- .../src/examples}/EmojiWaterfallExample.tsx | 4 +- .../src => app/src/examples}/EmptyExample.tsx | 0 .../src/examples}/ExtrapolationExample.tsx | 4 +- .../src/examples}/FrameCallbackExample.tsx | 0 .../src/examples}/GestureHandlerExample.tsx | 21 +- .../src/examples/IPodExample.tsx | 4 +- .../src/examples}/InvertedFlatListExample.tsx | 4 +- .../LayoutAnimations}/AnimatedList.tsx | 0 .../BasicLayoutAnimation.tsx | 2 +- .../BasicNestedAnimation.tsx | 2 +- .../BasicNestedLayoutAnimation.tsx | 2 +- .../examples/LayoutAnimations}/Bulbasaur.png | Bin .../examples/LayoutAnimations}/Butterfree.png | Bin .../examples/LayoutAnimations}/Carousel.tsx | 12 +- .../examples/LayoutAnimations}/Charizard.png | Bin .../examples/LayoutAnimations}/Combined.tsx | 4 +- .../LayoutAnimations}/CustomLayout.tsx | 10 +- .../LayoutAnimations}/DefaultAnimations.tsx | 128 +- .../DeleteAncestorOfExiting.tsx | 2 +- .../LayoutAnimations}/KeyframeAnimation.tsx | 6 +- .../src/examples/LayoutAnimations}/Modal.tsx | 12 +- .../LayoutAnimations}/ModalNewAPI.tsx | 14 +- .../LayoutAnimations}/MountingUnmounting.tsx | 16 +- .../LayoutAnimations}/NativeModals.tsx | 11 +- .../src/examples/LayoutAnimations}/Nested.tsx | 4 +- .../NestedNativeStacksWithLayout.tsx | 3 +- .../LayoutAnimations}/OlympicAnimation.tsx | 6 +- .../ReactionsCounterExample.tsx | 2 +- .../SpringLayoutAnimation.tsx | 6 +- .../LayoutAnimations}/SwipeableList.tsx | 6 +- .../WaterfallGridExample.tsx | 13 +- .../src/examples}/LightBoxExample.tsx | 7 +- .../src/examples}/LiquidSwipe/Button.tsx | 8 +- .../src/examples}/LiquidSwipe/Content.tsx | 6 +- .../src/examples}/LiquidSwipe/LiquidSwipe.tsx | 4 +- .../examples/LiquidSwipe/LiquidSwipe.web.tsx | 19 + .../src/examples}/LiquidSwipe/Weave.tsx | 5 +- .../examples}/LiquidSwipe/WeaveHelpers.tsx | 0 .../LiquidSwipe/assets/firstPageImage.png | Bin .../LiquidSwipe/assets/firstPageImage@2x.png | Bin .../LiquidSwipe/assets/firstPageImage@3x.png | Bin .../LiquidSwipe/assets/secondPageImage.png | Bin .../LiquidSwipe/assets/secondPageImage@2x.png | Bin .../LiquidSwipe/assets/secondPageImage@3x.png | Bin .../src/examples}/MeasureExample.tsx | 2 +- ...NewestShadowNodesRegistryRemoveExample.tsx | 0 .../src/examples/OldAnimatedSensorExample.tsx | 2 +- .../src/examples/OldMeasureExample.tsx | 4 +- .../src/examples}/OverlappingBoxesExample.tsx | 0 .../src/examples/PinExample.tsx | 4 +- .../src => app/src/examples}/RefExample.tsx | 2 +- .../src/examples}/ScreenStackExample.tsx | 0 ...tackHeaderConfigBackgroundColorExample.tsx | 19 +- .../src/examples}/ScrollEventExample.tsx | 4 +- .../src/examples}/ScrollToExample.tsx | 0 .../src/examples}/ScrollViewExample.tsx | 0 .../src/examples}/ScrollViewOffsetExample.tsx | 0 .../src/examples}/ScrollableViewExample.tsx | 4 +- .../SharedElementTransitions}/Card.tsx | 10 +- .../CustomTransition.tsx | 10 +- .../SharedElementTransitions}/FlatList.tsx | 8 +- .../SharedElementTransitions}/Gallery.tsx | 0 .../SharedElementTransitions}/ImageStack.tsx | 16 +- .../LayoutAnimation.tsx | 10 +- .../SharedElementTransitions}/ManyScreens.tsx | 12 +- .../SharedElementTransitions}/ManyTags.tsx | 10 +- .../SharedElementTransitions}/Modals.tsx | 10 +- .../NestedStacks.tsx | 12 +- .../RestoreState.tsx | 12 +- .../assets/countryside.jpg | Bin .../SharedElementTransitions}/assets/dawn.jpg | Bin .../assets/florence.jpg | Bin .../assets/image.jpg | Bin .../src/examples/SharedStyleExample.tsx | 2 +- .../src => app/src/examples}/SvgExample.tsx | 0 .../src/examples}/SwipeableListExample.tsx | 4 +- .../src/examples}/TransformExample.tsx | 0 .../src => app/src/examples}/WidthExample.tsx | 0 .../examples/WithoutBabelPluginExample.tsx | 71 +- .../src/examples}/WobbleExample.tsx | 6 +- .../src/examples}/WorkletExample.tsx | 5 - app/src/examples/index.ts | 470 +++ .../webSpecificTypes.ts => app/src/types.ts | 6 +- app/tsconfig.json | 11 + app/yarn.lock | 1482 ++++++++ package.json | 13 +- tsconfig.json | 7 +- yarn.lock | 2 +- 235 files changed, 3740 insertions(+), 9781 deletions(-) create mode 100644 .github/workflows/validate-app.yml delete mode 100644 Example/.detoxrc.json create mode 100644 Example/.prettierrc.js create mode 100644 Example/App.tsx delete mode 100644 Example/android/app/.gitignore delete mode 100644 Example/android/app/src/androidTest/java/com/swmansion/reanimated/example/DetoxTest.java delete mode 100644 Example/e2e/config.json delete mode 100644 Example/e2e/environment.js delete mode 100644 Example/e2e/testExitingAnimation.e2e.js delete mode 100644 Example/index-template.js create mode 100644 Example/ios/ReanimatedExampleTests/ReanimatedExampleTests.m delete mode 100644 Example/ios/ReanimatedExampleTests/SampleTest.mm rename Example/patches/{metro-inspector-proxy+0.73.8.patch => metro-inspector-proxy+0.73.9.patch} (100%) create mode 100644 Example/patches/react-native-box2d+0.2.5.patch delete mode 100644 Example/scripts/generateIndex.js delete mode 100644 Example/src/AnimatedKeyboardExample.tsx delete mode 100644 Example/src/App.tsx delete mode 100644 Example/src/CustomHandler/index.tsx delete mode 100644 Example/src/LayoutReanimation/index.ts delete mode 100644 Example/src/LightboxExample.tsx delete mode 100644 Example/src/LiquidSwipe/index.tsx delete mode 100644 Example/src/ScrollViewOffsetExample.tsx delete mode 100644 Example/src/WebApp.tsx delete mode 100644 Example/test-suite/.gitignore delete mode 100644 Example/test-suite/App.js delete mode 100644 Example/test-suite/AppNavigator.js delete mode 100644 Example/test-suite/TestModules.js delete mode 100644 Example/test-suite/assets/LLizard.mp3 delete mode 100644 Example/test-suite/assets/asset-db.db delete mode 100644 Example/test-suite/assets/black-128x256.png delete mode 100644 Example/test-suite/assets/comic.ttf delete mode 100644 Example/test-suite/assets/datamatrix_expo.png delete mode 100644 Example/test-suite/assets/example_image_1.jpg delete mode 100644 Example/test-suite/assets/icons/app.png delete mode 100644 Example/test-suite/assets/icons/loading.png delete mode 100644 Example/test-suite/assets/multiple_codes.png delete mode 100644 Example/test-suite/assets/qrcode_photo_wikipedia.jpg delete mode 100644 Example/test-suite/assets/unsupported_bunny.webm delete mode 100644 Example/test-suite/components/DoneText.js delete mode 100644 Example/test-suite/components/PlatformTouchable.android.js delete mode 100644 Example/test-suite/components/PlatformTouchable.js delete mode 100644 Example/test-suite/components/Portal.js delete mode 100644 Example/test-suite/components/RunnerError.js delete mode 100644 Example/test-suite/components/SpecResult.js delete mode 100644 Example/test-suite/components/SuiteResult.js delete mode 100644 Example/test-suite/components/Suites.js delete mode 100644 Example/test-suite/constants/Colors.js delete mode 100644 Example/test-suite/constants/StatusEmojis.js delete mode 100644 Example/test-suite/constants/Statuses.js delete mode 100644 Example/test-suite/screens/SelectScreen.js delete mode 100644 Example/test-suite/screens/TestScreen.js delete mode 100644 Example/test-suite/tests/AnimatedRef.js delete mode 100644 Example/test-suite/tests/AttachComponent.js delete mode 100644 Example/test-suite/tests/Basic.js delete mode 100644 Example/test-suite/tests/Camera.js delete mode 100644 Example/test-suite/tests/Cellular.js delete mode 100644 Example/test-suite/tests/Colors.js delete mode 100644 Example/test-suite/tests/FileSystem.js delete mode 100644 Example/test-suite/tests/Pitagoras.js delete mode 100644 Example/test-suite/tests/helpers.js delete mode 100644 Example/test-suite/utils/Environment.js delete mode 100644 Example/test/AdaptersTest.js delete mode 100644 Example/test/AnimatedReactionTest.js delete mode 100644 Example/test/Animations.js delete mode 100644 Example/test/CustomLayout2.tsx delete mode 100644 Example/test/CustomLayout3.tsx delete mode 100644 Example/test/FastRefreshTest.js delete mode 100644 Example/test/LayoutAnimationsRemovalTest.tsx delete mode 100644 Example/test/MeasureTest.js delete mode 100644 Example/test/ModalInNavigation.tsx delete mode 100644 Example/test/ModalInNavigationNativeStack.tsx delete mode 100644 Example/test/SimpleTest.js delete mode 100644 Example/test/TestApp.js delete mode 100644 Example/test/TestRemovalOrder.js delete mode 100644 Example/test/TransformsTest.js delete mode 100644 Example/test/UpdatePropsTest.js delete mode 100644 Example/test/WithNavigation.tsx delete mode 100644 Example/test/WithNavigationNested.tsx delete mode 100644 Example/test/scrollToTest.js create mode 100644 FabricExample/.prettierrc.js delete mode 100644 FabricExample/.prettierrc.json delete mode 100644 FabricExample/src/FrameCallbackExample.tsx delete mode 100644 FabricExample/src/useJSThreadKiller.ts delete mode 100644 TVOSExample/App.js create mode 100644 TVOSExample/App.tsx rename {FabricExample => __typetests__}/react-native-reanimated-tests.tsx (99%) create mode 100644 app/.eslintrc.js create mode 100644 app/babel.config.js create mode 100644 app/index.ts create mode 100644 app/package.json create mode 100644 app/src/App.tsx create mode 100644 app/src/examples/AboutExample.tsx rename {FabricExample/src => app/src/examples}/AnimatedKeyboardExample.tsx (95%) rename {FabricExample/src => app/src/examples}/AnimatedSensorExample.tsx (100%) rename {Example/src => app/src/examples}/AnimatedStyleUpdateExample.tsx (88%) rename {Example/src => app/src/examples}/AnimatedTabBarExample.tsx (98%) rename {FabricExample/src => app/src/examples}/AnimatedTextInputExample.tsx (100%) rename {FabricExample/src => app/src/examples}/AnimatedTextWidthExample.tsx (100%) rename {FabricExample/src => app/src/examples}/ArticleProgressExample.tsx (100%) rename {FabricExample/src => app/src/examples}/BilliardExample.tsx (100%) create mode 100644 app/src/examples/BilliardExample.web.tsx rename {FabricExample/src => app/src/examples}/BokehExample.tsx (100%) rename {FabricExample/src => app/src/examples}/BouncingBoxExample.tsx (100%) rename {FabricExample/src => app/src/examples}/BubblesExample.tsx (100%) rename {Example/src => app/src/examples}/ChatHeadsExample.tsx (98%) rename {FabricExample/src => app/src/examples}/ChessboardExample.tsx (100%) rename {FabricExample/src => app/src/examples}/ColorExample.tsx (100%) rename {Example/src => app/src/examples}/ColorInterpolationExample.tsx (98%) rename {Example/src => app/src/examples}/CubesExample.tsx (100%) rename {Example/src => app/src/examples}/CustomHandler/AnimatedText.tsx (100%) rename {Example/src => app/src/examples}/CustomHandler/PagerExample.tsx (97%) create mode 100644 app/src/examples/CustomHandler/PagerExample.web.tsx rename {Example/src => app/src/examples}/CustomHandler/Pagination.tsx (100%) rename {Example/src => app/src/examples}/CustomHandler/useAnimatedPagerHandler.ts (100%) rename {Example/src => app/src/examples}/DragAndSnapExample.tsx (96%) rename {Example/src => app/src/examples}/EmojiWaterfallExample.tsx (96%) rename {FabricExample/src => app/src/examples}/EmptyExample.tsx (100%) rename {Example/src => app/src/examples}/ExtrapolationExample.tsx (96%) rename {Example/src => app/src/examples}/FrameCallbackExample.tsx (100%) rename {FabricExample/src => app/src/examples}/GestureHandlerExample.tsx (99%) rename Example/src/AnimatedScrollExample.tsx => app/src/examples/IPodExample.tsx (98%) rename {Example/src => app/src/examples}/InvertedFlatListExample.tsx (97%) rename {Example/src/LayoutReanimation => app/src/examples/LayoutAnimations}/AnimatedList.tsx (100%) rename {Example/src/LayoutReanimation => app/src/examples/LayoutAnimations}/BasicLayoutAnimation.tsx (95%) rename {Example/src/LayoutReanimation => app/src/examples/LayoutAnimations}/BasicNestedAnimation.tsx (96%) rename {Example/src/LayoutReanimation => app/src/examples/LayoutAnimations}/BasicNestedLayoutAnimation.tsx (95%) rename {Example/src/LayoutReanimation => app/src/examples/LayoutAnimations}/Bulbasaur.png (100%) rename {Example/src/LayoutReanimation => app/src/examples/LayoutAnimations}/Butterfree.png (100%) rename {Example/src/LayoutReanimation => app/src/examples/LayoutAnimations}/Carousel.tsx (97%) rename {Example/src/LayoutReanimation => app/src/examples/LayoutAnimations}/Charizard.png (100%) rename {Example/src/LayoutReanimation => app/src/examples/LayoutAnimations}/Combined.tsx (96%) rename {Example/src/LayoutReanimation => app/src/examples/LayoutAnimations}/CustomLayout.tsx (93%) rename {Example/src/LayoutReanimation => app/src/examples/LayoutAnimations}/DefaultAnimations.tsx (99%) rename {Example/src/LayoutReanimation => app/src/examples/LayoutAnimations}/DeleteAncestorOfExiting.tsx (95%) rename {Example/src/LayoutReanimation => app/src/examples/LayoutAnimations}/KeyframeAnimation.tsx (93%) rename {Example/src/LayoutReanimation => app/src/examples/LayoutAnimations}/Modal.tsx (95%) rename {Example/src/LayoutReanimation => app/src/examples/LayoutAnimations}/ModalNewAPI.tsx (92%) rename {Example/src/LayoutReanimation => app/src/examples/LayoutAnimations}/MountingUnmounting.tsx (93%) rename {Example/src/LayoutReanimation => app/src/examples/LayoutAnimations}/NativeModals.tsx (96%) rename {Example/src/LayoutReanimation => app/src/examples/LayoutAnimations}/Nested.tsx (97%) rename {Example/src/LayoutReanimation => app/src/examples/LayoutAnimations}/NestedNativeStacksWithLayout.tsx (93%) rename {Example/src/LayoutReanimation => app/src/examples/LayoutAnimations}/OlympicAnimation.tsx (98%) rename {Example/src => app/src/examples/LayoutAnimations}/ReactionsCounterExample.tsx (98%) rename {Example/src/LayoutReanimation => app/src/examples/LayoutAnimations}/SpringLayoutAnimation.tsx (90%) rename {Example/src/LayoutReanimation => app/src/examples/LayoutAnimations}/SwipeableList.tsx (86%) rename {Example/src/LayoutReanimation => app/src/examples/LayoutAnimations}/WaterfallGridExample.tsx (96%) rename {Example/src/WebSpecific => app/src/examples}/LightBoxExample.tsx (98%) rename {Example/src => app/src/examples}/LiquidSwipe/Button.tsx (92%) rename {Example/src => app/src/examples}/LiquidSwipe/Content.tsx (95%) rename {Example/src => app/src/examples}/LiquidSwipe/LiquidSwipe.tsx (97%) create mode 100644 app/src/examples/LiquidSwipe/LiquidSwipe.web.tsx rename {Example/src => app/src/examples}/LiquidSwipe/Weave.tsx (97%) rename {Example/src => app/src/examples}/LiquidSwipe/WeaveHelpers.tsx (100%) rename {Example/src => app/src/examples}/LiquidSwipe/assets/firstPageImage.png (100%) rename {Example/src => app/src/examples}/LiquidSwipe/assets/firstPageImage@2x.png (100%) rename {Example/src => app/src/examples}/LiquidSwipe/assets/firstPageImage@3x.png (100%) rename {Example/src => app/src/examples}/LiquidSwipe/assets/secondPageImage.png (100%) rename {Example/src => app/src/examples}/LiquidSwipe/assets/secondPageImage@2x.png (100%) rename {Example/src => app/src/examples}/LiquidSwipe/assets/secondPageImage@3x.png (100%) rename {FabricExample/src => app/src/examples}/MeasureExample.tsx (95%) rename {FabricExample/src => app/src/examples}/NewestShadowNodesRegistryRemoveExample.tsx (100%) rename Example/src/AnimatedSensorExample.tsx => app/src/examples/OldAnimatedSensorExample.tsx (95%) rename Example/src/MeasureExample.tsx => app/src/examples/OldMeasureExample.tsx (98%) rename {FabricExample/src => app/src/examples}/OverlappingBoxesExample.tsx (100%) rename Example/src/ScrollToExample.tsx => app/src/examples/PinExample.tsx (98%) rename {FabricExample/src => app/src/examples}/RefExample.tsx (96%) rename {FabricExample/src => app/src/examples}/ScreenStackExample.tsx (100%) rename {FabricExample/src => app/src/examples}/ScreenStackHeaderConfigBackgroundColorExample.tsx (97%) rename {Example/src => app/src/examples}/ScrollEventExample.tsx (96%) rename {FabricExample/src => app/src/examples}/ScrollToExample.tsx (100%) rename {FabricExample/src => app/src/examples}/ScrollViewExample.tsx (100%) rename {FabricExample/src => app/src/examples}/ScrollViewOffsetExample.tsx (100%) rename {Example/src => app/src/examples}/ScrollableViewExample.tsx (98%) rename {Example/src/SharedElementTransition => app/src/examples/SharedElementTransitions}/Card.tsx (90%) rename {Example/src/SharedElementTransition => app/src/examples/SharedElementTransitions}/CustomTransition.tsx (86%) rename {Example/src/SharedElementTransition => app/src/examples/SharedElementTransitions}/FlatList.tsx (93%) rename {Example/src/SharedElementTransition => app/src/examples/SharedElementTransitions}/Gallery.tsx (100%) rename {Example/src/SharedElementTransition => app/src/examples/SharedElementTransitions}/ImageStack.tsx (92%) rename {Example/src/SharedElementTransition => app/src/examples/SharedElementTransitions}/LayoutAnimation.tsx (90%) rename {Example/src/SharedElementTransition => app/src/examples/SharedElementTransitions}/ManyScreens.tsx (83%) rename {Example/src/SharedElementTransition => app/src/examples/SharedElementTransitions}/ManyTags.tsx (91%) rename {Example/src/SharedElementTransition => app/src/examples/SharedElementTransitions}/Modals.tsx (93%) rename {Example/src/SharedElementTransition => app/src/examples/SharedElementTransitions}/NestedStacks.tsx (86%) rename {Example/src/SharedElementTransition => app/src/examples/SharedElementTransitions}/RestoreState.tsx (86%) rename {Example/src/SharedElementTransition => app/src/examples/SharedElementTransitions}/assets/countryside.jpg (100%) rename {Example/src/SharedElementTransition => app/src/examples/SharedElementTransitions}/assets/dawn.jpg (100%) rename {Example/src/SharedElementTransition => app/src/examples/SharedElementTransitions}/assets/florence.jpg (100%) rename {Example/src/SharedElementTransition => app/src/examples/SharedElementTransitions}/assets/image.jpg (100%) rename Example/src/AnimatedSharedStyleExample.tsx => app/src/examples/SharedStyleExample.tsx (97%) rename {FabricExample/src => app/src/examples}/SvgExample.tsx (100%) rename {Example/src => app/src/examples}/SwipeableListExample.tsx (98%) rename {FabricExample/src => app/src/examples}/TransformExample.tsx (100%) rename {FabricExample/src => app/src/examples}/WidthExample.tsx (100%) rename WebExample/WithoutBabel.tsx => app/src/examples/WithoutBabelPluginExample.tsx (54%) rename {Example/src => app/src/examples}/WobbleExample.tsx (92%) rename {FabricExample/src => app/src/examples}/WorkletExample.tsx (98%) create mode 100644 app/src/examples/index.ts rename Example/src/webSpecificTypes.ts => app/src/types.ts (88%) create mode 100644 app/tsconfig.json create mode 100644 app/yarn.lock diff --git a/.github/workflows/static-example-apps-checks.yml b/.github/workflows/static-example-apps-checks.yml index 463239aec7e..b43496ea893 100644 --- a/.github/workflows/static-example-apps-checks.yml +++ b/.github/workflows/static-example-apps-checks.yml @@ -39,4 +39,4 @@ jobs: run: yarn tsc --noEmit - name: Lint working-directory: ${{ matrix.working-directory }} - run: yarn lint:js + run: yarn lint diff --git a/.github/workflows/validate-app.yml b/.github/workflows/validate-app.yml new file mode 100644 index 00000000000..31de7e0728f --- /dev/null +++ b/.github/workflows/validate-app.yml @@ -0,0 +1,37 @@ +name: Validate app +on: + pull_request: + paths: + - '.github/workflows/validate-app.yml' + - 'app/**' + push: + branches: + - main +jobs: + check: + runs-on: ubuntu-latest + concurrency: + group: app-${{ github.ref }} + cancel-in-progress: true + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Use Node.js 16 + uses: actions/setup-node@v3 + with: + node-version: 16 + cache: 'yarn' + - name: Install node dependencies + run: yarn + - name: Install app dependencies + working-directory: app + run: yarn + - name: Check types + working-directory: app + run: yarn type:check + - name: Lint with ESLint + working-directory: app + run: yarn lint:eslint + - name: Lint with Prettier + working-directory: app + run: yarn lint:prettier diff --git a/Example/.detoxrc.json b/Example/.detoxrc.json deleted file mode 100644 index 30b771d4f00..00000000000 --- a/Example/.detoxrc.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "testRunner": "jest", - "runnerConfig": "e2e/config.json", - "skipLegacyWorkersInjection": true, - "apps": { - "ios": { - "type": "ios.app", - "binaryPath": "./ios/build/Build/Products/Release-iphonesimulator/ReanimatedExample.app", - "build": "xcodebuild -workspace ios/ReanimatedExample.xcworkspace -scheme ReanimatedExample -configuration Release -sdk iphonesimulator -derivedDataPath ios/build" - }, - "android": { - "type": "android.apk", - "testBinaryPath": "./android/app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk", - "binaryPath": "./android/app/build/outputs/apk/debug/app-debug.apk", - "build": "react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res && cd android && ./gradlew :app:assembleDebug :app:assembleAndroidTest && cd .." - } - }, - "devices": { - "simulator": { - "type": "ios.simulator", - "device": { - "type": "iPhone 11" - } - }, - "emulator": { - "type": "android.emulator", - "device": { - "avdName": "Pixel_3a_API_30_x86" - } - } - }, - "configurations": { - "ios": { - "device": "simulator", - "app": "ios" - }, - "android": { - "device": "emulator", - "app": "android" - } - } -} \ No newline at end of file diff --git a/Example/.eslintrc.js b/Example/.eslintrc.js index 187894b6af2..40c6dcd05f3 100644 --- a/Example/.eslintrc.js +++ b/Example/.eslintrc.js @@ -1,4 +1,4 @@ module.exports = { root: true, - extends: '@react-native', + extends: '@react-native-community', }; diff --git a/Example/.gitignore b/Example/.gitignore index a1ff01759d7..16f8c30773d 100644 --- a/Example/.gitignore +++ b/Example/.gitignore @@ -61,7 +61,3 @@ yarn-error.log # Temporary files created by Metro to check the health of the file watcher .metro-health-check* - -# Expo -/.expo -/web-build diff --git a/Example/.prettierrc.js b/Example/.prettierrc.js new file mode 100644 index 00000000000..2b540746a75 --- /dev/null +++ b/Example/.prettierrc.js @@ -0,0 +1,7 @@ +module.exports = { + arrowParens: 'avoid', + bracketSameLine: true, + bracketSpacing: false, + singleQuote: true, + trailingComma: 'all', +}; diff --git a/Example/App.tsx b/Example/App.tsx new file mode 100644 index 00000000000..6d539778589 --- /dev/null +++ b/Example/App.tsx @@ -0,0 +1,3 @@ +import App from '../app'; + +export default App; diff --git a/Example/android/app/.gitignore b/Example/android/app/.gitignore deleted file mode 100644 index ee3ce889c41..00000000000 --- a/Example/android/app/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -*pass -*drawable-** -*assets diff --git a/Example/android/app/build.gradle b/Example/android/app/build.gradle index a9542ca22f0..c7b2e6eac6b 100644 --- a/Example/android/app/build.gradle +++ b/Example/android/app/build.gradle @@ -102,9 +102,6 @@ android { targetSdkVersion rootProject.ext.targetSdkVersion versionCode 1 versionName "1.0" - - testBuildType System.getProperty('testBuildType', 'debug') - testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' } splits { @@ -154,13 +151,6 @@ android { } dependencies { - implementation(project(':react-native-reanimated')) { - exclude group:'com.facebook.fbjni' // resolves "Duplicate class com.facebook.jni.CppException" - // TODO: use `implementation "com.facebook.fbjni:fbjni-java-only:" + FBJNI_VERSION` in build.gradle - } - - androidTestImplementation('com.wix:detox:+') - // The version of react-native is set by the React Native Gradle Plugin implementation("com.facebook.react:react-android") diff --git a/Example/android/app/src/androidTest/java/com/swmansion/reanimated/example/DetoxTest.java b/Example/android/app/src/androidTest/java/com/swmansion/reanimated/example/DetoxTest.java deleted file mode 100644 index 3d459cfcc39..00000000000 --- a/Example/android/app/src/androidTest/java/com/swmansion/reanimated/example/DetoxTest.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.swmansion.reanimated.example; - -import com.wix.detox.Detox; -import com.wix.detox.config.DetoxConfig; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.filters.LargeTest; -import androidx.test.rule.ActivityTestRule; - -@RunWith(AndroidJUnit4.class) -@LargeTest -public class DetoxTest { - // Replace 'MainActivity' with the value of android:name entry in - // in AndroidManifest.xml - @Rule - public ActivityTestRule mActivityRule = new ActivityTestRule<>(MainActivity.class, false, false); - - @Test - public void runDetoxTests() { - // This is optional - in case you've decided to integrate TestButler - // See https://github.com/wix/Detox/blob/master/docs/Introduction.Android.md#8-test-butler-support-optional - // TestButlerProbe.assertReadyIfInstalled(); - - DetoxConfig detoxConfig = new DetoxConfig(); - detoxConfig.idlePolicyConfig.masterTimeoutSec = 90; - detoxConfig.idlePolicyConfig.idleResourceTimeoutSec = 60; - detoxConfig.rnContextLoadTimeoutSec = (com.swmansion.reanimated.example.BuildConfig.DEBUG ? 180 : 60); - - Detox.runTests(mActivityRule, detoxConfig); - } -} diff --git a/Example/android/app/src/main/java/com/swmansion/reanimated/example/MainApplication.java b/Example/android/app/src/main/java/com/swmansion/reanimated/example/MainApplication.java index 809cf2b3088..e7d69ef4114 100644 --- a/Example/android/app/src/main/java/com/swmansion/reanimated/example/MainApplication.java +++ b/Example/android/app/src/main/java/com/swmansion/reanimated/example/MainApplication.java @@ -8,7 +8,6 @@ import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint; import com.facebook.react.defaults.DefaultReactNativeHost; import com.facebook.soloader.SoLoader; -import com.swmansion.reanimated.ReanimatedPackage; import java.util.List; public class MainApplication extends Application implements ReactApplication { @@ -26,7 +25,6 @@ protected List getPackages() { List packages = new PackageList(this).getPackages(); // Packages that cannot be autolinked yet can be added manually here, for example: // packages.add(new MyReactNativePackage()); - packages.add(new ReanimatedPackage()); return packages; } diff --git a/Example/android/gradle.properties b/Example/android/gradle.properties index e4af465e8a1..710d92d964f 100644 --- a/Example/android/gradle.properties +++ b/Example/android/gradle.properties @@ -42,3 +42,5 @@ newArchEnabled=false # Use this property to enable or disable the Hermes JS engine. # If set to false, you will be using JSC instead. hermesEnabled=true + +disableMultipleInstancesCheck=true diff --git a/Example/android/settings.gradle b/Example/android/settings.gradle index 91d3586f802..268c9d2ae95 100644 --- a/Example/android/settings.gradle +++ b/Example/android/settings.gradle @@ -1,8 +1,4 @@ rootProject.name = 'ReanimatedExample' apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) - -include ':react-native-reanimated' -project(':react-native-reanimated').projectDir = new File(rootProject.projectDir, '../../android') - include ':app' includeBuild('../node_modules/react-native-gradle-plugin') diff --git a/Example/app.json b/Example/app.json index 47e95fa9c6e..84ea9e6d085 100644 --- a/Example/app.json +++ b/Example/app.json @@ -1,11 +1,4 @@ { "name": "ReanimatedExample", - "displayName": "ReanimatedExample", - "expo": { - "name": "ReanimatedExample", - "privacy": "unlisted", - "sdkVersion": "34.0.0", - "version": "1.0.0", - "platforms": ["ios", "android", "web"] - } -} + "displayName": "ReanimatedExample" +} \ No newline at end of file diff --git a/Example/babel.config.js b/Example/babel.config.js index 0bb2a38e4cc..cdeeffd80e3 100644 --- a/Example/babel.config.js +++ b/Example/babel.config.js @@ -1,44 +1,4 @@ -module.exports = (api) => { - const isWeb = api.caller(isTargetWeb); - - return { - presets: [ - '@babel/preset-typescript', - 'module:metro-react-native-babel-preset', - ], - plugins: [ - '@babel/plugin-proposal-export-namespace-from', - '@babel/plugin-proposal-optional-chaining', - '@babel/plugin-transform-modules-commonjs', - '../plugin', - isWeb - ? [ - 'module-resolver', - { - alias: { - 'react-native-reanimated': './Animated/', - }, - }, - ] - : [ - 'module-resolver', - { - alias: { - 'react-native-reanimated': '../src/index', - react: './node_modules/react', - 'react-native': './node_modules/react-native', - '@babel': './node_modules/@babel', - 'hoist-non-react-statics': - './node_modules/hoist-non-react-statics', - invariant: './node_modules/invariant', - 'prop-types': './node_modules/prop-types', - }, - }, - ], - ].filter(Boolean), - }; +module.exports = { + presets: ['module:metro-react-native-babel-preset'], + plugins: ['../plugin'], }; - -function isTargetWeb(caller) { - return caller && caller.name === 'babel-loader'; -} diff --git a/Example/e2e/config.json b/Example/e2e/config.json deleted file mode 100644 index 1f9b30c47b2..00000000000 --- a/Example/e2e/config.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "maxWorkers": 1, - "testEnvironment": "./environment", - "testRunner": "jest-circus/runner", - "testTimeout": 120000, - "testRegex": "\\.e2e\\.js$", - "reporters": ["detox/runners/jest/streamlineReporter"], - "verbose": true -} diff --git a/Example/e2e/environment.js b/Example/e2e/environment.js deleted file mode 100644 index 7f4fc942fc4..00000000000 --- a/Example/e2e/environment.js +++ /dev/null @@ -1,23 +0,0 @@ -const { - DetoxCircusEnvironment, - SpecReporter, - WorkerAssignReporter, -} = require('detox/runners/jest-circus'); - -class CustomDetoxEnvironment extends DetoxCircusEnvironment { - constructor(config, context) { - super(config, context); - - // Can be safely removed, if you are content with the default value (=300000ms) - this.initTimeout = 300000; - - // This takes care of generating status logs on a per-spec basis. By default, Jest only reports at file-level. - // This is strictly optional. - this.registerListeners({ - SpecReporter, - WorkerAssignReporter, - }); - } -} - -module.exports = CustomDetoxEnvironment; diff --git a/Example/e2e/testExitingAnimation.e2e.js b/Example/e2e/testExitingAnimation.e2e.js deleted file mode 100644 index c7ba18e611c..00000000000 --- a/Example/e2e/testExitingAnimation.e2e.js +++ /dev/null @@ -1,24 +0,0 @@ -import { device, element, waitFor, by } from 'detox'; - -describe('Layout Animations', () => { - beforeAll(async () => { - await device.launchApp(); - }); - - beforeEach(async () => { - await device.reloadReactNative(); - }); - - it('should remove components', async () => { - await element(by.text('test exiting animations')).tap(); - await element(by.id('buttonB')).tap(); - await expect(element(by.id('componentB'))).not.toBeVisible(); - await element(by.id('buttonC')).tap(); - await expect(element(by.id('componentC'))).not.toBeVisible(); - await element(by.id('buttonA')).tap(); - await expect(element(by.id('componentA'))).toBeVisible(); - await waitFor(element(by.id('componentA'))) - .not.toBeVisible() - .withTimeout(10000); - }); -}); diff --git a/Example/index-template.js b/Example/index-template.js deleted file mode 100644 index 079f9d0bf24..00000000000 --- a/Example/index-template.js +++ /dev/null @@ -1,11 +0,0 @@ -import { AppRegistry, Platform } from 'react-native'; -import { name as appName } from './app.json'; -import ${component} from '${path}'; - -AppRegistry.registerComponent(appName, () => ${component}); - -// TODO(Bacon): When `expo` has removed Updates, replace this with using the `expo` entry for better error handling -if (Platform.OS === 'web') { - const rootTag = document.getElementById('root'); - AppRegistry.runApplication(appName, { rootTag }); -} diff --git a/Example/index.js b/Example/index.js index dcc51414f0b..a850d031de7 100644 --- a/Example/index.js +++ b/Example/index.js @@ -1,11 +1,9 @@ -import { AppRegistry, Platform } from 'react-native'; -import { name as appName } from './app.json'; -import App from './src/App'; +/** + * @format + */ -AppRegistry.registerComponent(appName, () => App); +import {AppRegistry} from 'react-native'; +import App from './App'; +import {name as appName} from './app.json'; -// TODO(Bacon): When `expo` has removed Updates, replace this with using the `expo` entry for better error handling -if (Platform.OS === 'web') { - const rootTag = document.getElementById('root'); - AppRegistry.runApplication(appName, { rootTag }); -} +AppRegistry.registerComponent(appName, () => App); diff --git a/Example/ios/Podfile b/Example/ios/Podfile index 69bc88c6024..05e3b222655 100644 --- a/Example/ios/Podfile +++ b/Example/ios/Podfile @@ -45,8 +45,6 @@ target 'ReanimatedExample' do :app_path => "#{Pod::Config.instance.installation_root}/.." ) - pod 'RNReanimated', :path => '../../' - target 'ReanimatedExampleTests' do inherit! :complete # Pods for testing diff --git a/Example/ios/Podfile.lock b/Example/ios/Podfile.lock index 90401fcc99e..301a1057e0d 100644 --- a/Example/ios/Podfile.lock +++ b/Example/ios/Podfile.lock @@ -329,7 +329,12 @@ PODS: - React-jsinspector (0.71.3) - React-logger (0.71.3): - glog - - react-native-pager-view (5.4.25): + - react-native-box2d (0.2.5): + - React-Core + - react-native-box2d/Box2dHeaders (= 0.2.5) + - react-native-box2d/Box2dHeaders (0.2.5): + - React-Core + - react-native-pager-view (5.4.24): - React-Core - react-native-safe-area-context (4.5.0): - RCT-Folly @@ -337,8 +342,6 @@ PODS: - RCTTypeSafety - React-Core - ReactCommon/turbomodule/core - - react-native-slider (4.4.2): - - React-Core - React-perflogger (0.71.3) - React-RCTActionSheet (0.71.3): - React-Core/RCTActionSheetHeaders (= 0.71.3) @@ -425,7 +428,7 @@ PODS: - React-perflogger (= 0.71.3) - RNCMaskedView (0.2.8): - React-Core - - RNCPicker (1.8.1): + - RNCPicker (2.4.9): - React-Core - RNGestureHandler (2.9.0): - React-Core @@ -512,9 +515,9 @@ DEPENDENCIES: - React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`) - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`) - React-logger (from `../node_modules/react-native/ReactCommon/logger`) + - react-native-box2d (from `../node_modules/react-native-box2d`) - react-native-pager-view (from `../node_modules/react-native-pager-view`) - react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`) - - "react-native-slider (from `../node_modules/@react-native-community/slider`)" - React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`) - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`) - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`) @@ -529,9 +532,9 @@ DEPENDENCIES: - React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`) - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) - "RNCMaskedView (from `../node_modules/@react-native-masked-view/masked-view`)" - - "RNCPicker (from `../node_modules/@react-native-community/picker`)" + - "RNCPicker (from `../node_modules/@react-native-picker/picker`)" - RNGestureHandler (from `../node_modules/react-native-gesture-handler`) - - RNReanimated (from `../../`) + - RNReanimated (from `../node_modules/react-native-reanimated`) - RNScreens (from `../node_modules/react-native-screens`) - RNSVG (from `../node_modules/react-native-svg`) - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) @@ -595,12 +598,12 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon/jsinspector" React-logger: :path: "../node_modules/react-native/ReactCommon/logger" + react-native-box2d: + :path: "../node_modules/react-native-box2d" react-native-pager-view: :path: "../node_modules/react-native-pager-view" react-native-safe-area-context: :path: "../node_modules/react-native-safe-area-context" - react-native-slider: - :path: "../node_modules/@react-native-community/slider" React-perflogger: :path: "../node_modules/react-native/ReactCommon/reactperflogger" React-RCTActionSheet: @@ -630,11 +633,11 @@ EXTERNAL SOURCES: RNCMaskedView: :path: "../node_modules/@react-native-masked-view/masked-view" RNCPicker: - :path: "../node_modules/@react-native-community/picker" + :path: "../node_modules/@react-native-picker/picker" RNGestureHandler: :path: "../node_modules/react-native-gesture-handler" RNReanimated: - :path: "../../" + :path: "../node_modules/react-native-reanimated" RNScreens: :path: "../node_modules/react-native-screens" RNSVG: @@ -676,9 +679,9 @@ SPEC CHECKSUMS: React-jsiexecutor: 515b703d23ffadeac7687bc2d12fb08b90f0aaa1 React-jsinspector: 9f7c9137605e72ca0343db4cea88006cb94856dd React-logger: 957e5dc96d9dbffc6e0f15e0ee4d2b42829ff207 - react-native-pager-view: da490aa1f902c9a5aeecf0909cc975ad0e92e53e + react-native-box2d: a5126c70227755b79a1b5b8d867e3932041631b3 + react-native-pager-view: 95d0418c3c74279840abec6926653d32447bafb6 react-native-safe-area-context: 39c2d8be3328df5d437ac1700f4f3a4f75716acc - react-native-slider: 33b8d190b59d4f67a541061bb91775d53d617d9d React-perflogger: af8a3d31546077f42d729b949925cc4549f14def React-RCTActionSheet: 57cc5adfefbaaf0aae2cf7e10bccd746f2903673 React-RCTAnimation: 11c61e94da700c4dc915cf134513764d87fc5e2b @@ -693,7 +696,7 @@ SPEC CHECKSUMS: React-runtimeexecutor: 7bf0dafc7b727d93c8cb94eb00a9d3753c446c3e ReactCommon: 6f65ea5b7d84deb9e386f670dd11ce499ded7b40 RNCMaskedView: bc0170f389056201c82a55e242e5d90070e18e5a - RNCPicker: 914b557e20b3b8317b084aca9ff4b4edb95f61e4 + RNCPicker: 567de6dc0c6735cf249700d940c80b90b090e4db RNGestureHandler: 071d7a9ad81e8b83fe7663b303d132406a7d8f39 RNReanimated: f0dd6b881808e635ef0673f89642937d6c141314 RNScreens: 218801c16a2782546d30bd2026bb625c0302d70f @@ -702,6 +705,6 @@ SPEC CHECKSUMS: Yoga: 5ed1699acbba8863755998a4245daa200ff3817b YogaKit: f782866e155069a2cca2517aafea43200b01fd5a -PODFILE CHECKSUM: 31e0b0ac6e862d137680370ed6beac6cb1a3d455 +PODFILE CHECKSUM: abdcd7d1dc94572a01198620e1a07af30f40d751 -COCOAPODS: 1.11.3 +COCOAPODS: 1.12.0 diff --git a/Example/ios/ReanimatedExample/Images.xcassets/AppIcon.appiconset/Contents.json b/Example/ios/ReanimatedExample/Images.xcassets/AppIcon.appiconset/Contents.json index 73d3b7f6d10..e342e1a0428 100644 --- a/Example/ios/ReanimatedExample/Images.xcassets/AppIcon.appiconset/Contents.json +++ b/Example/ios/ReanimatedExample/Images.xcassets/AppIcon.appiconset/Contents.json @@ -1 +1,100 @@ -{"images":[{"size":"60x60","expected-size":"180","filename":"180.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"40x40","expected-size":"80","filename":"80.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"40x40","expected-size":"120","filename":"120.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"60x60","expected-size":"120","filename":"120.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"57x57","expected-size":"57","filename":"57.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"1x"},{"size":"29x29","expected-size":"58","filename":"58.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"29x29","expected-size":"29","filename":"29.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"1x"},{"size":"29x29","expected-size":"87","filename":"87.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"57x57","expected-size":"114","filename":"114.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"20x20","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"20x20","expected-size":"60","filename":"60.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"1024x1024","filename":"1024.png","expected-size":"1024","idiom":"ios-marketing","folder":"Assets.xcassets/AppIcon.appiconset/","scale":"1x"}]} \ No newline at end of file +{ + "images": [ + { + "size": "60x60", + "expected-size": "180", + "filename": "180.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "iphone", + "scale": "3x" + }, + { + "size": "40x40", + "expected-size": "80", + "filename": "80.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "iphone", + "scale": "2x" + }, + { + "size": "40x40", + "expected-size": "120", + "filename": "120.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "iphone", + "scale": "3x" + }, + { + "size": "60x60", + "expected-size": "120", + "filename": "120.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "iphone", + "scale": "2x" + }, + { + "size": "57x57", + "expected-size": "57", + "filename": "57.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "iphone", + "scale": "1x" + }, + { + "size": "29x29", + "expected-size": "58", + "filename": "58.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "iphone", + "scale": "2x" + }, + { + "size": "29x29", + "expected-size": "29", + "filename": "29.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "iphone", + "scale": "1x" + }, + { + "size": "29x29", + "expected-size": "87", + "filename": "87.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "iphone", + "scale": "3x" + }, + { + "size": "57x57", + "expected-size": "114", + "filename": "114.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "iphone", + "scale": "2x" + }, + { + "size": "20x20", + "expected-size": "40", + "filename": "40.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "iphone", + "scale": "2x" + }, + { + "size": "20x20", + "expected-size": "60", + "filename": "60.png", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "idiom": "iphone", + "scale": "3x" + }, + { + "size": "1024x1024", + "filename": "1024.png", + "expected-size": "1024", + "idiom": "ios-marketing", + "folder": "Assets.xcassets/AppIcon.appiconset/", + "scale": "1x" + } + ] +} diff --git a/Example/ios/ReanimatedExampleTests/ReanimatedExampleTests.m b/Example/ios/ReanimatedExampleTests/ReanimatedExampleTests.m new file mode 100644 index 00000000000..7aa4f2a5333 --- /dev/null +++ b/Example/ios/ReanimatedExampleTests/ReanimatedExampleTests.m @@ -0,0 +1,66 @@ +#import +#import + +#import +#import + +#define TIMEOUT_SECONDS 600 +#define TEXT_TO_LOOK_FOR @"Welcome to React" + +@interface ReanimatedExampleTests : XCTestCase + +@end + +@implementation ReanimatedExampleTests + +- (BOOL)findSubviewInView:(UIView *)view matching:(BOOL (^)(UIView *view))test +{ + if (test(view)) { + return YES; + } + for (UIView *subview in [view subviews]) { + if ([self findSubviewInView:subview matching:test]) { + return YES; + } + } + return NO; +} + +- (void)testRendersWelcomeScreen +{ + UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController]; + NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; + BOOL foundElement = NO; + + __block NSString *redboxError = nil; +#ifdef DEBUG + RCTSetLogFunction( + ^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) { + if (level >= RCTLogLevelError) { + redboxError = message; + } + }); +#endif + + while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { + [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; + [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; + + foundElement = [self findSubviewInView:vc.view + matching:^BOOL(UIView *view) { + if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) { + return YES; + } + return NO; + }]; + } + +#ifdef DEBUG + RCTSetLogFunction(RCTDefaultLogFunction); +#endif + + XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); + XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); +} + +@end diff --git a/Example/ios/ReanimatedExampleTests/SampleTest.mm b/Example/ios/ReanimatedExampleTests/SampleTest.mm deleted file mode 100644 index d47257867f4..00000000000 --- a/Example/ios/ReanimatedExampleTests/SampleTest.mm +++ /dev/null @@ -1,16 +0,0 @@ -#import - -@interface SampleTest : XCTestCase -@end - -@implementation SampleTest - -- (void)testExample { -// SharedDouble sd(0, 5.7, nullptr, nullptr, nullptr); -// XCTAssert(0 == sd.id, @"id passed"); -// XCTAssert(5.7 == sd.value, @"value passed"); -// sd.setNewValue(std::shared_ptr(new SharedDouble(1, 55.2, nullptr, nullptr, nullptr))); -// XCTAssert(55.2 == sd.value, @"value cahnged"); -} - -@end diff --git a/Example/metro.config.js b/Example/metro.config.js index e461d9858c9..6b535f5e332 100644 --- a/Example/metro.config.js +++ b/Example/metro.config.js @@ -1,32 +1,31 @@ -const blacklist = require('metro-config/src/defaults/exclusionList'); const path = require('path'); +const exclusionList = require('metro-config/src/defaults/exclusionList'); +const escape = require('escape-string-regexp'); +const pack = require('../package.json'); -const glob = require('glob-to-regexp'); +const root = path.resolve(__dirname, '..'); -function getBlacklist() { - const nodeModuleDirs = [ - glob(`${path.resolve(__dirname, '..')}/node_modules/*`), - glob(`${path.resolve(__dirname, '..')}/docs/*`), - glob(`${path.resolve(__dirname, '..')}/e2e/*`), - glob( - `${path.resolve( - __dirname - )}/node_modules/*/node_modules/hoist-non-react-statics/*` - ), - glob( - `${path.resolve( - __dirname - )}/node_modules/react-native/node_modules/@babel/*` - ), - ]; - return blacklist(nodeModuleDirs); -} +const modules = Object.keys(pack.peerDependencies); module.exports = { + projectRoot: __dirname, + watchFolders: [root], + + // We need to make sure that only one version is loaded for peerDependencies + // So we exclude them at the root, and alias them to the versions in example's node_modules resolver: { - blacklistRE: getBlacklist(), + blacklistRE: exclusionList( + modules.map( + m => new RegExp(`^${escape(path.join(root, 'node_modules', m))}\\/.*$`), + ), + ), + + extraNodeModules: modules.reduce((acc, name) => { + acc[name] = path.join(__dirname, 'node_modules', name); + return acc; + }, {}), }, - watchFolders: [path.resolve(__dirname, '..')], + transformer: { getTransformOptions: async () => ({ transform: { diff --git a/Example/package.json b/Example/package.json index e9e5f4aaa5a..60fc1a42fcc 100644 --- a/Example/package.json +++ b/Example/package.json @@ -3,86 +3,48 @@ "version": "0.0.1", "private": true, "scripts": { - "start": "node ./scripts/generateIndex.js && react-native start", - "start-web": "node ./scripts/generateIndex.js --web && yarn web", - "start-test": "node ./scripts/generateIndex.js --test && react-native start", - "start-test-suite": "node ./scripts/generateIndex.js --test-suite && react-native start", - "generate": "node ./scripts/generateIndex.js", - "generate-web": "node ./scripts/generateIndex.js --web", - "generate-test": "node ./scripts/generateIndex.js --test", - "generate-test-suite": "node ./scripts/generateIndex.js --test-suite", + "android": "react-native run-android", + "ios": "react-native run-ios", + "lint": "eslint .", + "start": "react-native start", "test": "jest", - "link-web": "npm link react-native-reanimated", - "web": "expo start --web || expo start --web --web-only", - "lint:js": "eslint --ext '.js,.ts,.tsx' src/ && yarn prettier --check src/", - "ts-check": "yarn tsc --noEmit", - "e2e:android": "node ./scripts/generateIndex.js --test && yarn detox build --configuration android && yarn detox test --configuration android", - "e2e:ios": "node ./scripts/generateIndex.js --test && yarn detox build --configuration ios && yarn detox test --configuration ios", - "e2e:tests": "yarn e2e:android && yarn e2e:ios", - "pod-install": "cd ios && pod install && cd ..", "postinstall": "patch-package" }, "dependencies": { - "@babel/plugin-proposal-export-namespace-from": "^7.18.9", - "@fortawesome/fontawesome-svg-core": "6.3.0", - "@fortawesome/free-solid-svg-icons": "6.3.0", - "@fortawesome/react-native-fontawesome": "0.3.0", - "@react-native-community/picker": "^1.8.1", - "@react-native-community/slider": "^4.4.0", + "@babel/plugin-proposal-export-namespace-from": "^7.17.12", "@react-native-masked-view/masked-view": "^0.2.8", - "@react-navigation/elements": "^1.3.13", - "@react-navigation/native": "^6.1.0", - "@react-navigation/native-stack": "^6.9.8", - "@react-navigation/stack": "^6.3.0", - "@react-navigation/web": "^1.0.0-alpha.9", - "async-retry": "^1.3.1", - "d3-shape": "^1.3.7", - "expo-asset": "^8.2.0", + "@react-native-picker/picker": "^2.4.9", + "@react-navigation/native": "^6.0.13", + "@react-navigation/native-stack": "^6.9.0", "react": "18.2.0", - "react-dom": "^16.13.1", "react-native": "0.71.3", + "react-native-box2d": "^0.2.5", "react-native-gesture-handler": "^2.9.0", - "react-native-pager-view": "^5.4.1", + "react-native-pager-view": "5.4.24", + "react-native-reanimated": "link:../", "react-native-safe-area-context": "^4.5.0", - "react-native-screens": "^3.19.0", - "react-native-status-bar-height": "^2.4.0", - "react-native-svg": "^13.7.0", - "react-native-web": "^0.14.7" + "react-native-screens": "^3.20.0", + "react-native-svg": "^13.8.0" }, "devDependencies": { "@babel/core": "^7.20.0", - "@babel/plugin-proposal-optional-chaining": "^7.12.13", "@babel/preset-env": "^7.20.0", "@babel/runtime": "^7.20.0", "@react-native-community/eslint-config": "^3.2.0", - "@react-native/eslint-config": "^0.72.1", "@tsconfig/react-native": "^2.0.2", - "@types/d3-shape": "^2.0.0", "@types/jest": "^29.2.1", "@types/react": "^18.0.24", "@types/react-test-renderer": "^18.0.0", "babel-jest": "^29.2.1", - "babel-plugin-module-resolver": "^3.2.0", - "detox": "^18.20.3", "eslint": "^8.19.0", - "expo": "^41.0.1", - "getenv": "^1.0.0", - "glob-to-regexp": "^0.4.0", - "immutable": "^4.0.0-rc.12", - "jasmine-core": "^3.5.0", "jest": "^29.2.1", - "jest-circus": "^27.1.0", "metro-react-native-babel-preset": "0.73.7", "patch-package": "^6.4.7", - "postinstall-postinstall": "^2.1.0", - "prettier": "^2.6.1", + "prettier": "^2.4.1", "react-test-renderer": "18.2.0", - "typescript": "^4.9.4" + "typescript": "4.8.4" }, "jest": { "preset": "react-native" - }, - "resolutions": { - "@babel/runtime": "7.12.13" } } diff --git a/Example/patches/metro-inspector-proxy+0.73.8.patch b/Example/patches/metro-inspector-proxy+0.73.9.patch similarity index 100% rename from Example/patches/metro-inspector-proxy+0.73.8.patch rename to Example/patches/metro-inspector-proxy+0.73.9.patch diff --git a/Example/patches/react-native-box2d+0.2.5.patch b/Example/patches/react-native-box2d+0.2.5.patch new file mode 100644 index 00000000000..10e0da3db5e --- /dev/null +++ b/Example/patches/react-native-box2d+0.2.5.patch @@ -0,0 +1,85 @@ +diff --git a/node_modules/react-native-box2d/android/CMakeLists.txt b/node_modules/react-native-box2d/android/CMakeLists.txt +index c346c4e..6bde55f 100644 +--- a/node_modules/react-native-box2d/android/CMakeLists.txt ++++ b/node_modules/react-native-box2d/android/CMakeLists.txt +@@ -3,6 +3,8 @@ cmake_minimum_required(VERSION 3.9.0) + set(PACKAGE_NAME "react-native-box2d") + set(BUILD_DIR ${CMAKE_SOURCE_DIR}/build) + ++find_package(ReactAndroid REQUIRED CONFIG) ++ + include_directories( + ../cpp + "${NODE_MODULES_DIR}/react-native/React" +@@ -38,25 +40,6 @@ find_library( + log-lib + log + ) +-find_library( +- REACT_NATIVE_JNI_LIB +- reactnativejni +- PATHS ${LIBRN_DIR} +- NO_CMAKE_FIND_ROOT_PATH +-) +- +-if(${REACT_NATIVE_VERSION} LESS 66) +- # JSI lib didn't exist on RN 0.65 and before. Simply omit it. +- set(JSI_LIB "") +-else() +- # RN 0.66 distributes libjsi.so, can be used instead of compiling jsi.cpp manually. +- find_library( +- JSI_LIB +- jsi +- PATHS ${LIBRN_DIR} +- NO_CMAKE_FIND_ROOT_PATH +- ) +-endif() + + # ### region: add box2d + target_include_directories( +@@ -78,8 +61,8 @@ set_property(TARGET box2d PROPERTY IMPORTED_LOCATION "${LIBS_PATH}/libbox2d.a") + target_link_libraries( + reactnativebox2d + ${log-lib} +- ${JSI_LIB} +- ${REACT_NATIVE_JNI_LIB} ++ ReactAndroid::jsi ++ ReactAndroid::reactnativejni + android + ${BOX2D_LIB} + ) +diff --git a/node_modules/react-native-box2d/android/build.gradle b/node_modules/react-native-box2d/android/build.gradle +index 41726f4..0580d5d 100644 +--- a/node_modules/react-native-box2d/android/build.gradle ++++ b/node_modules/react-native-box2d/android/build.gradle +@@ -51,7 +51,7 @@ def reactNativeArchitectures() { + return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"] + } + +-def sourceBuild = false ++def sourceBuild = true + def defaultDir = null + def androidSourcesDir = null + def androidSourcesName = 'React Native sources' +@@ -87,7 +87,9 @@ android { + compileSdkVersion getExtOrIntegerDefault('compileSdkVersion') + buildToolsVersion getExtOrDefault('buildToolsVersion') + ndkVersion getExtOrDefault('ndkVersion') +- ++ buildFeatures { ++ prefab true ++ } + defaultConfig { + minSdkVersion 21 + targetSdkVersion getExtOrIntegerDefault('targetSdkVersion') +@@ -342,8 +344,8 @@ def nativeBuildDependsOn(dependsOnTask, variant) { + + afterEvaluate { + if (sourceBuild) { +- nativeBuildDependsOn(":ReactAndroid:packageReactNdkDebugLibsForBuck", "Debug") +- nativeBuildDependsOn(":ReactAndroid:packageReactNdkReleaseLibsForBuck", "Rel") ++ // nativeBuildDependsOn(":ReactAndroid:packageReactNdkDebugLibsForBuck", "Debug") ++ // nativeBuildDependsOn(":ReactAndroid:packageReactNdkReleaseLibsForBuck", "Rel") + } else { + nativeBuildDependsOn(extractAARHeaders, null) + nativeBuildDependsOn(extractJNIFiles, null) diff --git a/Example/scripts/generateIndex.js b/Example/scripts/generateIndex.js deleted file mode 100644 index e5677b8e1a1..00000000000 --- a/Example/scripts/generateIndex.js +++ /dev/null @@ -1,48 +0,0 @@ -const fs = require('fs'); -const path = require('path'); - -const cwd = process.cwd(); - -// check if in Example directory -const cwdSplit = cwd.split(path.sep); -if (cwdSplit[cwdSplit.length - 1] !== 'Example') { - console.log('invalid path, please enter the Example directory'); - process.exit(1); -} - -const inputPath = cwd + path.sep + 'index-template.js'; -const outputPath = cwd + path.sep + 'index.js'; -// read command line arguments -const args = []; -process.argv.forEach((value, index) => { - if (index <= 1) return; - args.push(value); -}); - -console.log(`reading file ${inputPath}`); -let content = fs.readFileSync(inputPath).toString(); - -// replace -const replaces = { - component: ['App', 'WebApp', 'TestApp', 'TestSuite'], - path: ['./src/App', './src/WebApp', './test/TestApp', './test-suite/App'], -}; - -let replaceIndex = 0; -if (args.indexOf('--web') !== -1) replaceIndex = 1; -else if (args.indexOf('--test') !== -1) replaceIndex = 2; -else if (args.indexOf('--test-suite') !== -1) replaceIndex = 3; - -Object.keys(replaces).forEach((key) => { - content = content.split('${' + key + '}').join(replaces[key][replaceIndex]); -}); - -console.log(`writing to ${outputPath}`); -fs.writeFileSync(outputPath, content, function(err) { - if (err) { - console.log(err); - process.exit(1); - } -}); - -process.exit(0); diff --git a/Example/src/AnimatedKeyboardExample.tsx b/Example/src/AnimatedKeyboardExample.tsx deleted file mode 100644 index 08233e55169..00000000000 --- a/Example/src/AnimatedKeyboardExample.tsx +++ /dev/null @@ -1,89 +0,0 @@ -import Animated, { - useAnimatedStyle, - useAnimatedKeyboard, - KeyboardState, -} from 'react-native-reanimated'; -import { - View, - Button, - TextInput, - StyleSheet, - Keyboard, - ScrollView, -} from 'react-native'; -import React from 'react'; - -const BOX_SIZE = 50; - -function NestedView(): React.ReactElement { - useAnimatedKeyboard(); - return ; -} - -function AnimatedStyleUpdateExample(): React.ReactElement { - const keyboard = useAnimatedKeyboard(); - const OPENING = KeyboardState.OPENING; - const style = useAnimatedStyle(() => { - const color = keyboard.state.value === OPENING ? 'red' : 'blue'; - - return { - backgroundColor: color, - }; - }); - const translateStyle = useAnimatedStyle(() => { - return { - transform: [{ translateY: -keyboard.height.value }], - }; - }); - const [shouldShowNestedView, setShouldShowNestedView] = React.useState(false); - - return ( - - -