@apexnative/navigation 1.0.0-alpha.5 → 1.0.0-alpha.7
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.
- package/ApexNavigation.podspec +2 -1
- package/CHANGELOG.md +32 -0
- package/README.md +1 -1
- package/android/CLAUDE.md +31 -20
- package/android/CORE.md +12 -8
- package/android/consumer-rules.pro +6 -0
- package/android/src/main/java/dev/apexnative/navigation/NavigationActivity.kt +36 -5
- package/android/src/main/java/dev/apexnative/navigation/options/BottomTabOptions.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/options/BottomTabsOptions.kt +13 -8
- package/android/src/main/java/dev/apexnative/navigation/options/ButtonOptions.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/options/LargeTitleOptions.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/options/LayoutAnimation.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/options/OptionKey.kt +18 -0
- package/android/src/main/java/dev/apexnative/navigation/options/OptionPaths.kt +91 -0
- package/android/src/main/java/dev/apexnative/navigation/options/SheetOptions.kt +7 -4
- package/android/src/main/java/dev/apexnative/navigation/options/TitleOptions.kt +2 -2
- package/android/src/main/java/dev/apexnative/navigation/options/TopBarAppearanceOptions.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/options/TopBarOptions.kt +16 -7
- package/android/src/main/java/dev/apexnative/navigation/react/ContentHeights.kt +95 -0
- package/android/src/main/java/dev/apexnative/navigation/react/ContentMounts.kt +66 -0
- package/android/src/main/java/dev/apexnative/navigation/react/NavigationTurboModule.kt +7 -3
- package/android/src/main/java/dev/apexnative/navigation/react/OptionsCommands.kt +41 -3
- package/android/src/main/java/dev/apexnative/navigation/react/ReactView.kt +16 -1
- package/android/src/main/java/dev/apexnative/navigation/react/ReloadCoordinator.kt +0 -2
- package/android/src/main/java/dev/apexnative/navigation/react/ScreenEnvironment.kt +177 -0
- package/android/src/main/java/dev/apexnative/navigation/react/ScreenRegions.kt +12 -49
- package/android/src/main/java/dev/apexnative/navigation/react/ScrollEvents.kt +49 -128
- package/android/src/main/java/dev/apexnative/navigation/safearea/SafeAreaView.kt +6 -6
- package/android/src/main/java/dev/apexnative/navigation/slots/SlotScreenView.kt +27 -7
- package/android/src/main/java/dev/apexnative/navigation/slots/SlotView.kt +12 -1
- package/android/src/main/java/dev/apexnative/navigation/utils/MaterialTheme.kt +5 -6
- package/android/src/main/java/dev/apexnative/navigation/utils/SystemAnimations.kt +36 -0
- package/android/src/main/java/dev/apexnative/navigation/utils/ViewExtensions.kt +0 -13
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/arrangement/ArrangementController.kt +9 -7
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsCollapseBehavior.kt +5 -3
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsController.kt +13 -10
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/CustomTabRowGeometry.kt +22 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/TabsRoom.kt +0 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ComponentViewController.kt +7 -8
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ScreenSafeArea.kt +29 -11
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/externalcomponent/ExternalComponentViewController.kt +2 -6
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalCoordinator.kt +20 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalSheet.kt +443 -58
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalViews.kt +33 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/SheetBack.kt +42 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/SheetStops.kt +60 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/Navigator.kt +4 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/ParentController.kt +3 -6
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuMotion.kt +8 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/BackPreview.kt +32 -4
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/PreparedFrame.kt +3 -3
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackCommands.kt +2 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackController.kt +50 -7
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackQueue.kt +15 -3
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackViews.kt +10 -4
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/fab/FabMotion.kt +142 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/fab/FabPresenter.kt +215 -43
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/search/StackSearchPresenter.kt +25 -26
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/BarRowTransition.kt +3 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/ButtonPlaces.kt +11 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/TopBarPresenter.kt +36 -38
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/viewcontroller/ScrollEventListener.kt +6 -9
- package/android/src/main/java/dev/apexnative/navigation/views/animations/AnimationLayer.kt +73 -0
- package/android/src/main/java/dev/apexnative/navigation/views/animations/ValueInterpolation.kt +14 -0
- package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/BottomTabsLayout.kt +61 -2
- package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/CustomTabRow.kt +72 -10
- package/android/src/main/java/dev/apexnative/navigation/views/element/ElementTransitions.kt +129 -179
- package/android/src/main/java/dev/apexnative/navigation/views/element/TargetsWait.kt +8 -1
- package/android/src/main/java/dev/apexnative/navigation/views/element/TransitionLayer.kt +37 -112
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ElementPictures.kt +67 -3
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/FlightGeometry.kt +346 -36
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ImageMorph.kt +199 -0
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/SharedAnimatorFactory.kt +55 -42
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/TextMorph.kt +176 -0
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ViewMorph.kt +108 -0
- package/android/src/main/java/dev/apexnative/navigation/views/stack/fab/FabCopy.kt +85 -0
- package/android/src/main/java/dev/apexnative/navigation/views/stack/fab/FabMenu.kt +13 -0
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/TitleBar.kt +5 -24
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/TopBar.kt +51 -34
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/BarButtonComponentCell.kt +6 -6
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/BarButtonView.kt +113 -0
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/BarMenu.kt +219 -0
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonBar.kt +121 -175
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonMenus.kt +34 -64
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonRow.kt +216 -0
- package/android/src/main/jni/ANNContentHeights.cpp +82 -0
- package/android/src/main/res/drawable/apex_navigation_ic_arrow_right.xml +14 -0
- package/android/src/main/res/layout/apex_navigation_menu_header.xml +19 -0
- package/android/src/main/res/layout/apex_navigation_menu_item.xml +68 -0
- package/android/src/main/res/values/styles.xml +1 -1
- package/android/src/main/res/values-night/styles.xml +1 -1
- package/cli/doctor/checks/app.js +16 -1
- package/cli/project.js +4 -0
- package/cli/setup/index.js +5 -0
- package/cli/setup/steps/metro.js +46 -0
- package/docs-md/architecture/native-screens.md +4 -0
- package/docs-md/architecture/theme-and-context.md +131 -12
- package/docs-md/architecture/transitions.md +46 -5
- package/docs-md/containers/modals.md +2 -0
- package/docs-md/containers/overlays.md +1 -1
- package/docs-md/containers/side-menu.md +1 -1
- package/docs-md/containers/tabs.md +2 -0
- package/docs-md/flows/bottom-sheets.md +4 -2
- package/docs-md/fundamentals/screens-and-props.md +9 -1
- package/docs-md/fundamentals/starting-the-app.md +1 -1
- package/docs-md/guides/cli.md +3 -1
- package/docs-md/help/glossary.md +2 -2
- package/docs-md/help/troubleshooting.md +22 -1
- package/docs-md/index.json +41 -1
- package/docs-md/migration/from-expo-router.md +1 -1
- package/docs-md/migration/from-react-native-navigation.md +1 -1
- package/docs-md/migration/from-react-navigation.md +2 -2
- package/docs-md/screen-ui/back-and-gestures.md +17 -1
- package/docs-md/screen-ui/bar-buttons.md +5 -5
- package/docs-md/screen-ui/search.md +1 -1
- package/docs-md/screen-ui/system-ui.md +16 -11
- package/docs-md/screen-ui/toolbar-and-fab.md +4 -2
- package/docs-md/screen-ui/top-bar.md +8 -4
- package/docs-md/start/installation.md +16 -1
- package/ios/Animations/ANNFrameDriver.h +55 -15
- package/ios/Animations/ANNFrameDriver.mm +216 -60
- package/ios/Animations/ANNTransitionAnimator.h +26 -5
- package/ios/Animations/ANNTransitionAnimator.mm +49 -3
- package/ios/Animations/ANNTransitionPlan.h +2 -2
- package/ios/Animations/ANNTransitionPlan.mm +10 -0
- package/ios/Animations/Elements/ANNElementFinder.h +2 -2
- package/ios/Animations/Elements/ANNElementFinder.mm +2 -2
- package/ios/Animations/Elements/ANNElementTransition.h +3 -3
- package/ios/Animations/Elements/ANNElementTransition.mm +2 -2
- package/ios/Animations/Elements/ANNSharedElementFlight.h +3 -3
- package/ios/Animations/Elements/ANNSharedElementFlight.mm +249 -45
- package/ios/Animations/Interpolators/ANNInterpolate.h +2 -30
- package/ios/Animations/Interpolators/ANNTransformParts.h +48 -0
- package/ios/Animations/Interpolators/ANNTransformParts.mm +507 -0
- package/ios/Animations/Interpolators/ANNViewTracks.h +9 -6
- package/ios/Animations/Interpolators/ANNViewTracks.mm +100 -30
- package/ios/CLAUDE.md +32 -22
- package/ios/CORE.md +25 -21
- package/ios/Contract/ANNCommandRunner.h +8 -7
- package/ios/Contract/ANNCommandRunner.mm +21 -27
- package/ios/Contract/ANNLayoutNode.h +3 -3
- package/ios/Contract/ANNLayoutReader.h +3 -3
- package/ios/Core/ANNAppDelegate.mm +0 -2
- package/ios/Core/ANNDeepLinkQueue.h +6 -5
- package/ios/Core/ANNDeepLinkQueue.mm +22 -10
- package/ios/Core/ANNJavaScriptCalls.h +11 -12
- package/ios/Core/ANNJavaScriptCalls.mm +7 -16
- package/ios/Core/ANNReloadCoordinator.mm +4 -8
- package/ios/Core/ANNSceneDelegate.mm +2 -2
- package/ios/Core/ApexNavigation+Internal.h +1 -1
- package/ios/Core/ApexNavigation.mm +6 -2
- package/ios/Layouts/Arrangement/ANNArrangementState.h +2 -17
- package/ios/Layouts/Arrangement/ANNArrangementState.mm +0 -38
- package/ios/Layouts/Arrangement/ANNArrangementViewController.mm +4 -4
- package/ios/Layouts/Root/ANNRootCoordinator.mm +45 -15
- package/ios/Layouts/Screen/ANNComponentViewController.h +2 -2
- package/ios/Layouts/Screen/ANNComponentViewController.mm +13 -23
- package/ios/Layouts/Screen/ANNPreviewInteraction.h +7 -4
- package/ios/Layouts/Screen/ANNPreviewInteraction.mm +72 -10
- package/ios/Layouts/Screen/ANNScreenEnvironment.h +63 -0
- package/ios/Layouts/Screen/ANNScreenEnvironment.mm +181 -0
- package/ios/Layouts/Screen/ANNScreenRegions.h +3 -18
- package/ios/Layouts/Screen/ANNScreenRegions.mm +0 -38
- package/ios/Layouts/Screen/ANNScreenSafeArea.h +4 -9
- package/ios/Layouts/Screen/ANNScreenSafeArea.mm +14 -16
- package/ios/Layouts/Stack/ANNPreviewPush.h +7 -6
- package/ios/Layouts/Stack/ANNPreviewPush.mm +57 -5
- package/ios/Layouts/Stack/ANNStackAnimatingDelegate.h +11 -2
- package/ios/Layouts/Stack/ANNStackAnimatingDelegate.mm +14 -7
- package/ios/Layouts/Stack/ANNStackController.h +8 -0
- package/ios/Layouts/Stack/ANNStackController.mm +153 -11
- package/ios/Layouts/Stack/ANNSwipePopInteraction.h +26 -0
- package/ios/Layouts/Stack/ANNSwipePopInteraction.mm +185 -0
- package/ios/Layouts/Stack/InteractivePopGestureDelegate.mm +28 -4
- package/ios/Layouts/Tabs/ANNBottomTabsAccessoryView.h +12 -1
- package/ios/Layouts/Tabs/ANNBottomTabsAccessoryView.mm +23 -0
- package/ios/Layouts/Tabs/ANNBottomTabsController.mm +2 -1
- package/ios/Layouts/Tabs/ANNBottomTabsCustomRow.mm +8 -3
- package/ios/Layouts/Tabs/ANNBottomTabsPresenter.h +4 -0
- package/ios/Layouts/Tabs/ANNBottomTabsPresenter.mm +123 -36
- package/ios/Layouts/Tabs/ANNTabsDesign.h +6 -5
- package/ios/Layouts/Tabs/ANNTabsDesign.mm +9 -1
- package/ios/Layouts/Tabs/UITabBar+utils.h +5 -5
- package/ios/Layouts/Tabs/UITabBar+utils.mm +32 -13
- package/ios/Options/ANNAnimationOptions.h +2 -1
- package/ios/Options/ANNAnimationOptions.mm +1 -1
- package/ios/Options/ANNBottomTabsOptions.h +2 -0
- package/ios/Options/ANNBottomTabsOptions.mm +1 -0
- package/ios/Options/ANNOptions.h +25 -0
- package/ios/Options/ANNOptions.mm +157 -1
- package/ios/Options/ANNOptionsReader.mm +108 -0
- package/ios/Options/ANNStackPopAnimationOptions.h +13 -0
- package/ios/Options/ANNStackPopAnimationOptions.mm +11 -0
- package/ios/Options/Params/ANNParam.h +15 -0
- package/ios/Options/Params/ANNParam.mm +61 -0
- package/ios/Options/Params/Color.h +3 -0
- package/ios/Options/Params/Color.mm +21 -0
- package/ios/Options/Params/ColorParser.h +4 -3
- package/ios/Options/Params/ColorParser.mm +22 -4
- package/ios/Options/Params/Image.h +4 -0
- package/ios/Options/Params/Image.mm +20 -0
- package/ios/React/ANNReactView.mm +6 -25
- package/ios/React/ANNSafeAreaViewComponentView.mm +26 -15
- package/ios/React/ANNSurfaceHostingView.h +14 -0
- package/ios/React/ANNSurfaceHostingView.mm +144 -1
- package/ios/React/Slots/ANNSlotScreenView.mm +8 -2
- package/ios/TopBar/ANNBackButtonPresenter.mm +6 -5
- package/ios/TopBar/ANNBarAppearance.h +2 -1
- package/ios/TopBar/ANNBarAppearance.mm +111 -30
- package/ios/TopBar/ANNBarBackgroundComponent.mm +16 -0
- package/ios/TopBar/ANNBarButtonComponentView.h +4 -4
- package/ios/TopBar/ANNBarButtonComponentView.mm +1 -1
- package/ios/TopBar/ANNBarButtons.h +5 -3
- package/ios/TopBar/ANNBarButtons.mm +186 -17
- package/ios/TopBar/ANNLargeTitlePresenter.mm +24 -4
- package/ios/TopBar/ANNMainList.h +3 -0
- package/ios/TopBar/ANNMainList.mm +4 -0
- package/ios/TopBar/ANNScrollEdgeEffects.h +22 -6
- package/ios/TopBar/ANNScrollEdgeEffects.mm +123 -16
- package/ios/TopBar/ANNSearchPresenter.mm +2 -2
- package/ios/TopBar/ANNSearchResultsViewController.mm +5 -5
- package/ios/TopBar/ANNTopBarPresenter.h +3 -2
- package/ios/TopBar/ANNTopBarPresenter.mm +95 -22
- package/ios/TurboModules/ANNTurboModule.mm +66 -16
- package/ios/cpp/react/renderer/components/ApexNavigationSpec/ANNSlotState.cpp +20 -0
- package/ios/cpp/react/renderer/components/ApexNavigationSpec/ANNSlotState.h +5 -14
- package/lib/module/ARCHITECTURE.md +17 -7
- package/lib/module/adapters/NativeANNTurboModule.js.map +1 -1
- package/lib/module/api/app/AppRegistry.js +14 -2
- package/lib/module/api/app/AppRegistry.js.map +1 -1
- package/lib/module/api/app/createNavigation.js +188 -66
- package/lib/module/api/app/createNavigation.js.map +1 -1
- package/lib/module/api/events/navigationEvents.js +6 -2
- package/lib/module/api/events/navigationEvents.js.map +1 -1
- package/lib/module/api/hooks/useSafeAreaInsets.js +4 -3
- package/lib/module/api/hooks/useSafeAreaInsets.js.map +1 -1
- package/lib/module/api/linking/linking.js +11 -0
- package/lib/module/api/linking/linking.js.map +1 -1
- package/lib/module/api/options/OptionsChain.js +2 -2
- package/lib/module/api/screens/defineScreen.js +45 -3
- package/lib/module/api/screens/defineScreen.js.map +1 -1
- package/lib/module/api/screens/nativeScreens.js +31 -6
- package/lib/module/api/screens/nativeScreens.js.map +1 -1
- package/lib/module/api/screens/registerScreens.js +172 -35
- package/lib/module/api/screens/registerScreens.js.map +1 -1
- package/lib/module/api/theme/theme.js +5 -0
- package/lib/module/api/theme/theme.js.map +1 -1
- package/lib/module/engine/commands.js +42 -2
- package/lib/module/engine/commands.js.map +1 -1
- package/lib/module/engine/layout.js +7 -2
- package/lib/module/engine/layout.js.map +1 -1
- package/lib/module/engine/nativeScreens.js +9 -0
- package/lib/module/engine/nativeScreens.js.map +1 -1
- package/lib/module/engine/options.js +5 -4
- package/lib/module/engine/options.js.map +1 -1
- package/lib/module/engine/optionsChange.js +102 -0
- package/lib/module/engine/optionsChange.js.map +1 -0
- package/lib/module/engine/refresh.js +85 -0
- package/lib/module/engine/refresh.js.map +1 -0
- package/lib/module/engine/rememberedOptions.js +60 -0
- package/lib/module/engine/rememberedOptions.js.map +1 -1
- package/lib/module/engine/screens.js +55 -4
- package/lib/module/engine/screens.js.map +1 -1
- package/lib/typescript/adapters/NativeANNTurboModule.d.ts +7 -0
- package/lib/typescript/adapters/NativeANNTurboModule.d.ts.map +1 -1
- package/lib/typescript/api/app/AppRegistry.d.ts.map +1 -1
- package/lib/typescript/api/app/createNavigation.d.ts +8 -3
- package/lib/typescript/api/app/createNavigation.d.ts.map +1 -1
- package/lib/typescript/api/events/navigationEvents.d.ts +2 -2
- package/lib/typescript/api/events/navigationEvents.d.ts.map +1 -1
- package/lib/typescript/api/hooks/useSafeAreaInsets.d.ts +4 -3
- package/lib/typescript/api/hooks/useSafeAreaInsets.d.ts.map +1 -1
- package/lib/typescript/api/index.d.ts +1 -1
- package/lib/typescript/api/index.d.ts.map +1 -1
- package/lib/typescript/api/linking/linking.d.ts +8 -0
- package/lib/typescript/api/linking/linking.d.ts.map +1 -1
- package/lib/typescript/api/options/OptionsChain.d.ts +2 -2
- package/lib/typescript/api/screens/defineScreen.d.ts +23 -4
- package/lib/typescript/api/screens/defineScreen.d.ts.map +1 -1
- package/lib/typescript/api/screens/nativeScreens.d.ts +8 -1
- package/lib/typescript/api/screens/nativeScreens.d.ts.map +1 -1
- package/lib/typescript/api/screens/registerScreens.d.ts.map +1 -1
- package/lib/typescript/api/theme/theme.d.ts +2 -0
- package/lib/typescript/api/theme/theme.d.ts.map +1 -1
- package/lib/typescript/engine/commands.d.ts +5 -0
- package/lib/typescript/engine/commands.d.ts.map +1 -1
- package/lib/typescript/engine/layout.d.ts.map +1 -1
- package/lib/typescript/engine/nativeScreens.d.ts +5 -0
- package/lib/typescript/engine/nativeScreens.d.ts.map +1 -1
- package/lib/typescript/engine/optionsChange.d.ts +28 -0
- package/lib/typescript/engine/optionsChange.d.ts.map +1 -0
- package/lib/typescript/engine/refresh.d.ts +35 -0
- package/lib/typescript/engine/refresh.d.ts.map +1 -0
- package/lib/typescript/engine/rememberedOptions.d.ts +13 -0
- package/lib/typescript/engine/rememberedOptions.d.ts.map +1 -1
- package/lib/typescript/engine/screens.d.ts +27 -6
- package/lib/typescript/engine/screens.d.ts.map +1 -1
- package/lib/typescript/interfaces/ComponentEvents.d.ts +2 -2
- package/lib/typescript/interfaces/options/animations.d.ts +44 -14
- package/lib/typescript/interfaces/options/animations.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/bottomTabs.d.ts +19 -6
- package/lib/typescript/interfaces/options/bottomTabs.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/buttons.d.ts +10 -10
- package/lib/typescript/interfaces/options/modals.d.ts +6 -7
- package/lib/typescript/interfaces/options/modals.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/stack.d.ts +8 -3
- package/lib/typescript/interfaces/options/stack.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/system.d.ts +8 -5
- package/lib/typescript/interfaces/options/system.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/toolbar.d.ts +2 -2
- package/lib/typescript/interfaces/options/topBar.d.ts +46 -29
- package/lib/typescript/interfaces/options/topBar.d.ts.map +1 -1
- package/metro/acceptPlugin.js +57 -0
- package/metro/babelTransformer.js +45 -0
- package/metro/index.js +36 -0
- package/package.json +3 -1
- package/src/ARCHITECTURE.md +17 -7
- package/src/adapters/NativeANNTurboModule.ts +7 -0
- package/src/api/app/AppRegistry.ts +16 -2
- package/src/api/app/createNavigation.ts +201 -69
- package/src/api/events/navigationEvents.ts +9 -3
- package/src/api/hooks/useSafeAreaInsets.ts +4 -3
- package/src/api/index.ts +1 -0
- package/src/api/linking/linking.ts +22 -1
- package/src/api/options/OptionsChain.ts +2 -2
- package/src/api/screens/defineScreen.ts +49 -5
- package/src/api/screens/nativeScreens.ts +40 -4
- package/src/api/screens/registerScreens.tsx +170 -42
- package/src/api/theme/theme.ts +5 -0
- package/src/engine/commands.ts +51 -6
- package/src/engine/layout.ts +11 -2
- package/src/engine/nativeScreens.ts +10 -1
- package/src/engine/options.ts +6 -8
- package/src/engine/optionsChange.ts +107 -0
- package/src/engine/refresh.ts +97 -0
- package/src/engine/rememberedOptions.ts +70 -0
- package/src/engine/screens.tsx +53 -8
- package/src/interfaces/ComponentEvents.ts +2 -2
- package/src/interfaces/options/animations.ts +44 -14
- package/src/interfaces/options/bottomTabs.ts +19 -6
- package/src/interfaces/options/buttons.ts +10 -10
- package/src/interfaces/options/modals.ts +6 -7
- package/src/interfaces/options/stack.ts +8 -3
- package/src/interfaces/options/system.ts +8 -5
- package/src/interfaces/options/toolbar.ts +2 -2
- package/src/interfaces/options/topBar.ts +46 -29
- package/android/src/main/java/dev/apexnative/navigation/react/ArrangementStates.kt +0 -42
- package/android/src/main/java/dev/apexnative/navigation/react/ScreenInsets.kt +0 -70
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/CustomTabRowPlacer.kt +0 -223
- package/android/src/main/java/dev/apexnative/navigation/views/element/ElementStub.kt +0 -31
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ImageMatrixAnimator.kt +0 -136
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/PlainViewAnimator.kt +0 -86
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/PropertyAnimatorCreator.kt +0 -33
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ReactImageAnimator.kt +0 -64
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/TextChangeAnimator.kt +0 -177
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ViewChangeAnimator.kt +0 -137
- package/ios/Layouts/Screen/ANNScreenInsets.h +0 -30
- package/ios/Layouts/Screen/ANNScreenInsets.mm +0 -70
|
@@ -2,149 +2,78 @@ package dev.apexnative.navigation.views.element
|
|
|
2
2
|
|
|
3
3
|
import android.animation.Animator
|
|
4
4
|
import android.animation.AnimatorListenerAdapter
|
|
5
|
-
import android.graphics.Rect
|
|
6
5
|
import android.os.Build
|
|
7
6
|
import android.util.Log
|
|
8
7
|
import android.view.View
|
|
9
8
|
import android.view.ViewGroup
|
|
10
|
-
import com.facebook.react.views.view.ReactViewGroup
|
|
11
9
|
import dev.apexnative.navigation.options.ElementTransitionOptions
|
|
12
10
|
import dev.apexnative.navigation.options.LayoutAnimation
|
|
13
11
|
import dev.apexnative.navigation.options.SharedElementTransitionOptions
|
|
14
12
|
import dev.apexnative.navigation.react.events.AppearanceDispatcher
|
|
15
13
|
import dev.apexnative.navigation.utils.DevelopmentLog
|
|
16
14
|
import dev.apexnative.navigation.utils.NavigationLog
|
|
15
|
+
import dev.apexnative.navigation.utils.SystemAnimations
|
|
17
16
|
import dev.apexnative.navigation.viewcontrollers.viewcontroller.ViewController
|
|
17
|
+
import dev.apexnative.navigation.views.animations.AnimationLayer
|
|
18
18
|
import dev.apexnative.navigation.views.animations.SideAnimator
|
|
19
19
|
import dev.apexnative.navigation.views.element.animators.SharedAnimatorFactory
|
|
20
|
+
import java.util.Collections
|
|
21
|
+
import java.util.WeakHashMap
|
|
20
22
|
|
|
21
23
|
/**
|
|
22
|
-
* The elements of one transition: the element transitions and the
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
24
|
+
* The elements of one transition: the element transitions and the shared pairs found by their `nativeID` (depth first,
|
|
25
|
+
* the first match) in the whole view of the screen each side shows — an element in the screen that goes first, then in
|
|
26
|
+
* the one that comes; a pair's `fromId` in the screen that goes, its `toId` in the one that comes; each screen is
|
|
27
|
+
* walked once for all of them ([TransitionViews]). What isn't found, what another transition plays now and an image
|
|
28
|
+
* that isn't loaded is skipped; so is an element whose start fails ([elementStep]): it gets its values back at once and
|
|
29
|
+
* the rest plays. No view leaves its parent, as on iOS. An element plays where it is, in its screen: its properties
|
|
30
|
+
* animate about its center and it moves with its screen. A pair flies as a copy drawn in a [TransitionLayer] over the
|
|
31
|
+
* screens, the copies in the order their targets are drawn; its `to` is hidden from the start, its `from` from the
|
|
32
|
+
* start of its flight. [finish] gives every element the values of its properties read before, shows the pairs' views
|
|
33
|
+
* again and takes the layer away. Main thread only.
|
|
32
34
|
*/
|
|
33
|
-
internal class ElementTransition private constructor(
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
val pivotSet: Boolean,
|
|
42
|
-
// Where its parent's origin is in the layer: what `x` and `y` are counted from.
|
|
43
|
-
val originX: Int,
|
|
44
|
-
val originY: Int,
|
|
45
|
-
)
|
|
35
|
+
internal class ElementTransition private constructor(
|
|
36
|
+
private val layer: TransitionLayer?,
|
|
37
|
+
// The views of the screens, as far as the parents that cut a pair's views count.
|
|
38
|
+
private val fromRoot: View?,
|
|
39
|
+
private val toRoot: View?,
|
|
40
|
+
) {
|
|
41
|
+
// An element playing where it is: what it was.
|
|
42
|
+
private class InPlace(val view: View, val values: FloatArray, val pivotSet: Boolean)
|
|
46
43
|
|
|
47
|
-
private val
|
|
48
|
-
private val
|
|
44
|
+
private val inPlace = ArrayList<InPlace>()
|
|
45
|
+
private val taken = ArrayList<View>()
|
|
46
|
+
// The views of the pairs hidden while their copies fly, with the alpha each had.
|
|
47
|
+
private val hidden = LinkedHashMap<View, Float>()
|
|
49
48
|
private var finished = false
|
|
50
49
|
|
|
51
50
|
/** The animators of the elements and of the shared elements, each with its own time. */
|
|
52
51
|
val animators = ArrayList<Animator>()
|
|
53
52
|
|
|
54
|
-
/**
|
|
53
|
+
/**
|
|
54
|
+
* Every element's values back, the pairs' views seen, the layer gone; at the end of the transition and at any stop.
|
|
55
|
+
* Once.
|
|
56
|
+
*/
|
|
55
57
|
fun finish() {
|
|
56
58
|
if (finished) return
|
|
57
59
|
finished = true
|
|
58
|
-
for ((view, alpha) in hidden) view
|
|
60
|
+
for ((view, alpha) in hidden) show(view, alpha)
|
|
59
61
|
hidden.clear()
|
|
60
|
-
// Each
|
|
61
|
-
for (item in
|
|
62
|
+
// Each element on its own: one that can't get its values back doesn't keep the others from theirs.
|
|
63
|
+
for (item in inPlace.asReversed()) {
|
|
62
64
|
try {
|
|
63
|
-
|
|
65
|
+
restore(item.view, item.values, item.pivotSet)
|
|
64
66
|
} catch (e: RuntimeException) {
|
|
65
|
-
Log.w(NavigationLog.TAG, "[ApexNavigation] An element of a transition couldn't
|
|
67
|
+
Log.w(NavigationLog.TAG, "[ApexNavigation] An element of a transition couldn't get its values back", e)
|
|
66
68
|
}
|
|
67
69
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
+
inPlace.clear()
|
|
71
|
+
playing -= taken.toSet()
|
|
72
|
+
taken.clear()
|
|
73
|
+
layer?.detach()
|
|
70
74
|
}
|
|
71
75
|
|
|
72
|
-
private fun
|
|
73
|
-
val parent = view.parent as? ViewGroup ?: return null
|
|
74
|
-
// A parent that clips its subviews keeps its own list of children, which a stub swapped in would leave
|
|
75
|
-
// behind: its element stays where it is.
|
|
76
|
-
if ((parent as? ReactViewGroup)?.removeClippedSubviews == true) return null
|
|
77
|
-
val index = parent.indexOfChild(view)
|
|
78
|
-
if (index < 0) return null
|
|
79
|
-
val onScreen = IntArray(2)
|
|
80
|
-
parent.getLocationOnScreen(onScreen)
|
|
81
|
-
val origin = layer.originOnScreen
|
|
82
|
-
val originX = onScreen[0] - parent.scrollX - origin.x
|
|
83
|
-
val originY = onScreen[1] - parent.scrollY - origin.y
|
|
84
|
-
val frame = Rect(view.left, view.top, view.right, view.bottom)
|
|
85
|
-
val params = view.layoutParams ?: ViewGroup.LayoutParams(view.width, view.height)
|
|
86
|
-
val pivotSet = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && view.isPivotSet
|
|
87
|
-
val values = floatArrayOf(
|
|
88
|
-
view.alpha, view.translationX, view.translationY, view.scaleX, view.scaleY, view.rotation,
|
|
89
|
-
view.rotationX, view.rotationY, view.pivotX, view.pivotY,
|
|
90
|
-
)
|
|
91
|
-
val stub = ElementStub(view.context, view)
|
|
92
|
-
try {
|
|
93
|
-
parent.removeViewAt(index)
|
|
94
|
-
parent.addView(stub, index, params)
|
|
95
|
-
stub.layout(frame.left, frame.top, frame.right, frame.bottom)
|
|
96
|
-
val left = originX + frame.left
|
|
97
|
-
val top = originY + frame.top
|
|
98
|
-
layer.put(view, left, top, frame.width(), frame.height())
|
|
99
|
-
} catch (e: RuntimeException) {
|
|
100
|
-
putBack(view, stub, parent, index, params, frame)
|
|
101
|
-
throw e
|
|
102
|
-
}
|
|
103
|
-
// Scale and rotations turn about the center.
|
|
104
|
-
view.pivotX = frame.width() / 2f
|
|
105
|
-
view.pivotY = frame.height() / 2f
|
|
106
|
-
return Moved(view, stub, params, frame, values, pivotSet, originX, originY).also { moved += it }
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// A move that failed half way undone: the view back at its index in its parent, the stub gone.
|
|
110
|
-
private fun putBack(
|
|
111
|
-
view: View,
|
|
112
|
-
stub: ElementStub,
|
|
113
|
-
parent: ViewGroup,
|
|
114
|
-
index: Int,
|
|
115
|
-
params: ViewGroup.LayoutParams,
|
|
116
|
-
frame: Rect,
|
|
117
|
-
) {
|
|
118
|
-
if (view.parent === layer) layer.removeView(view)
|
|
119
|
-
val stubIndex = parent.indexOfChild(stub)
|
|
120
|
-
if (stubIndex >= 0) parent.removeViewAt(stubIndex)
|
|
121
|
-
if (view.parent == null) {
|
|
122
|
-
parent.addView(view, index.coerceAtMost(parent.childCount), params)
|
|
123
|
-
view.layout(frame.left, frame.top, frame.right, frame.bottom)
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
private fun giveBack(item: Moved) {
|
|
128
|
-
val view = item.view
|
|
129
|
-
// A commit of Fabric meanwhile laid it out in its parent's coordinates: the newest such frame holds.
|
|
130
|
-
val reactFrame = if (view.parent === layer) layer.frameFromReact(view) else null
|
|
131
|
-
if (view.parent === layer) layer.removeView(view)
|
|
132
|
-
restore(view, item)
|
|
133
|
-
val parent = item.stub.parent as? ViewGroup ?: return
|
|
134
|
-
val index = parent.indexOfChild(item.stub)
|
|
135
|
-
if (index < 0) return
|
|
136
|
-
parent.removeViewAt(index)
|
|
137
|
-
parent.addView(view, index, item.params)
|
|
138
|
-
val frame = reactFrame ?: item.frame
|
|
139
|
-
view.measure(
|
|
140
|
-
View.MeasureSpec.makeMeasureSpec(frame.width(), View.MeasureSpec.EXACTLY),
|
|
141
|
-
View.MeasureSpec.makeMeasureSpec(frame.height(), View.MeasureSpec.EXACTLY),
|
|
142
|
-
)
|
|
143
|
-
view.layout(frame.left, frame.top, frame.right, frame.bottom)
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
private fun restore(view: View, item: Moved) {
|
|
147
|
-
val values = item.values
|
|
76
|
+
private fun restore(view: View, values: FloatArray, pivotSet: Boolean) {
|
|
148
77
|
view.alpha = values[ALPHA]
|
|
149
78
|
view.translationX = values[TRANSLATION_X]
|
|
150
79
|
view.translationY = values[TRANSLATION_Y]
|
|
@@ -153,7 +82,7 @@ internal class ElementTransition private constructor(private val layer: Transiti
|
|
|
153
82
|
view.rotation = values[ROTATION]
|
|
154
83
|
view.rotationX = values[ROTATION_X]
|
|
155
84
|
view.rotationY = values[ROTATION_Y]
|
|
156
|
-
if (!
|
|
85
|
+
if (!pivotSet && Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
|
157
86
|
view.resetPivot()
|
|
158
87
|
} else {
|
|
159
88
|
view.pivotX = values[PIVOT_X]
|
|
@@ -161,47 +90,74 @@ internal class ElementTransition private constructor(private val layer: Transiti
|
|
|
161
90
|
}
|
|
162
91
|
}
|
|
163
92
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
93
|
+
// An element with views in it fades through a hardware layer only where its alpha would draw it into an offscreen
|
|
94
|
+
// buffer at every frame (AnimationLayer: its rendering overlaps). React's views overlap only with
|
|
95
|
+
// `needsOffscreenAlphaCompositing`, so most elements fade without one and nothing they draw outside their bounds (a
|
|
96
|
+
// box shadow) is clipped. A view without children fades its own drawing at no extra cost. Scale and rotations turn
|
|
97
|
+
// about the element's center; `x` and `y` are its place in its own parent.
|
|
98
|
+
private fun addElement(options: ElementTransitionOptions, view: View) {
|
|
99
|
+
inPlace += InPlace(view, valuesOf(view), pivotSetOf(view))
|
|
100
|
+
view.pivotX = view.width / 2f
|
|
101
|
+
view.pivotY = view.height / 2f
|
|
102
|
+
val animator = SideAnimator.build(view, options, SideAnimator.Base()) ?: return
|
|
103
|
+
if (view is ViewGroup) AnimationLayer.during(view, animator)
|
|
104
|
+
animators += animator
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// An element whose start failed gets its values back now.
|
|
108
|
+
private fun giveValuesBack(view: View) {
|
|
109
|
+
val item = inPlace.lastOrNull { it.view === view } ?: return
|
|
110
|
+
inPlace -= item
|
|
111
|
+
try {
|
|
112
|
+
restore(view, item.values, item.pivotSet)
|
|
113
|
+
} catch (e: RuntimeException) {
|
|
114
|
+
Log.w(NavigationLog.TAG, "[ApexNavigation] An element of a transition couldn't get its values back", e)
|
|
115
|
+
}
|
|
167
116
|
}
|
|
168
117
|
|
|
169
|
-
// The pair's flight: `to` hidden
|
|
118
|
+
// The pair's flight: `to` hidden from now, `from` from its start, both seen again when it stops or its copy can't
|
|
119
|
+
// be drawn. Nothing changes when it doesn't fly.
|
|
170
120
|
private fun addPair(
|
|
171
121
|
options: SharedElementTransitionOptions,
|
|
172
122
|
from: View,
|
|
173
|
-
|
|
174
|
-
|
|
123
|
+
to: View,
|
|
124
|
+
name: String,
|
|
175
125
|
fallbackDuration: Long,
|
|
176
|
-
)
|
|
177
|
-
val
|
|
126
|
+
) {
|
|
127
|
+
val layer = layer ?: return
|
|
178
128
|
val flight = SharedAnimatorFactory.create(
|
|
179
|
-
from, to,
|
|
180
|
-
) ?: return
|
|
181
|
-
val alpha = item.values[ALPHA]
|
|
129
|
+
from, to, fromRoot, toRoot, layer, options, fallbackDuration, DevelopmentLog::warn,
|
|
130
|
+
) ?: return
|
|
182
131
|
val fromAlpha = from.alpha
|
|
183
|
-
|
|
184
|
-
|
|
132
|
+
val seenAgain = {
|
|
133
|
+
flight.picture.shown = false
|
|
134
|
+
hidden.remove(from)?.let { show(from, it) }
|
|
135
|
+
hidden.remove(to)?.let { show(to, it) }
|
|
136
|
+
layer.invalidate()
|
|
137
|
+
}
|
|
138
|
+
flight.picture.onFailed = { e ->
|
|
139
|
+
elementSkipped(name, e.toString())
|
|
140
|
+
seenAgain()
|
|
141
|
+
}
|
|
185
142
|
flight.animator.addListener(object : AnimatorListenerAdapter() {
|
|
186
143
|
private var stopped = false
|
|
187
144
|
|
|
188
145
|
override fun onAnimationStart(animation: Animator) {
|
|
189
|
-
if (stopped) return
|
|
146
|
+
if (stopped || finished) return
|
|
147
|
+
hidden[from] = fromAlpha
|
|
190
148
|
from.alpha = 0f
|
|
191
|
-
if (!flight.drawsPictures) to.alpha = alpha
|
|
192
149
|
}
|
|
193
150
|
|
|
194
|
-
// A flight whose start or frame failed stops (`MoveAnimator`), maybe inside its own start
|
|
195
|
-
// again in its screen, and a `to` that moves itself in its place, as at any stop (a flight of pictures
|
|
196
|
-
// shows its `to` at its end).
|
|
151
|
+
// A flight whose start or frame failed stops (`MoveAnimator`), maybe inside its own start.
|
|
197
152
|
override fun onAnimationCancel(animation: Animator) {
|
|
198
153
|
stopped = true
|
|
199
|
-
|
|
200
|
-
if (!flight.drawsPictures) to.alpha = alpha
|
|
154
|
+
seenAgain()
|
|
201
155
|
}
|
|
202
156
|
})
|
|
157
|
+
layer.add(flight.picture)
|
|
158
|
+
hidden[to] = to.alpha
|
|
159
|
+
to.alpha = 0f
|
|
203
160
|
animators += flight.animator
|
|
204
|
-
return true
|
|
205
161
|
}
|
|
206
162
|
|
|
207
163
|
companion object {
|
|
@@ -216,10 +172,26 @@ internal class ElementTransition private constructor(private val layer: Transiti
|
|
|
216
172
|
private const val PIVOT_X = 8
|
|
217
173
|
private const val PIVOT_Y = 9
|
|
218
174
|
|
|
175
|
+
// The views the transitions that run now play: another transition leaves them alone.
|
|
176
|
+
private val playing: MutableSet<View> = Collections.newSetFromMap(WeakHashMap())
|
|
177
|
+
|
|
178
|
+
private fun valuesOf(view: View) = floatArrayOf(
|
|
179
|
+
view.alpha, view.translationX, view.translationY, view.scaleX, view.scaleY, view.rotation,
|
|
180
|
+
view.rotationX, view.rotationY, view.pivotX, view.pivotY,
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
private fun pivotSetOf(view: View) = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && view.isPivotSet
|
|
184
|
+
|
|
185
|
+
// A view hidden for a flight shows again with its alpha, unless React gave it another one meanwhile. React
|
|
186
|
+
// writes the same alpha: an opacity it commits during the flight shows the view beside its copy until the end.
|
|
187
|
+
private fun show(view: View, alpha: Float) {
|
|
188
|
+
if (view.alpha == 0f) view.alpha = alpha
|
|
189
|
+
}
|
|
190
|
+
|
|
219
191
|
/**
|
|
220
|
-
* The elements of [animation] from [from] to [to]
|
|
221
|
-
* top without one)
|
|
222
|
-
* [fallbackDuration], the screen's fade.
|
|
192
|
+
* The elements of [animation] from [from] to [to]; the copies of the pairs in a layer that joins [host] at
|
|
193
|
+
* [layerIndex] (its top without one). None when none of them is found or the system's animations are off. A
|
|
194
|
+
* shared element without a duration takes [fallbackDuration], the screen's fade.
|
|
223
195
|
*/
|
|
224
196
|
fun start(
|
|
225
197
|
animation: LayoutAnimation,
|
|
@@ -229,6 +201,7 @@ internal class ElementTransition private constructor(private val layer: Transiti
|
|
|
229
201
|
layerIndex: Int?,
|
|
230
202
|
fallbackDuration: Long,
|
|
231
203
|
): ElementTransition? {
|
|
204
|
+
if (SystemAnimations.areOff(host.context)) return null
|
|
232
205
|
val fromView = from?.let { AppearanceDispatcher.visibleNode(it).peekView() }
|
|
233
206
|
val toView = AppearanceDispatcher.visibleNode(to).peekView()
|
|
234
207
|
val transitions = animation.elementTransitions.transitions
|
|
@@ -238,27 +211,28 @@ internal class ElementTransition private constructor(private val layer: Transiti
|
|
|
238
211
|
val elements = ArrayList<Pair<ElementTransitionOptions, View>>()
|
|
239
212
|
for (element in transitions) {
|
|
240
213
|
if (element.id.isEmpty()) continue
|
|
241
|
-
val view =
|
|
242
|
-
if (
|
|
214
|
+
val view = views.leaving(element.id) ?: views.arriving(element.id) ?: continue
|
|
215
|
+
if (view in playing || !taken.add(view)) continue
|
|
243
216
|
elements += element to view
|
|
244
217
|
}
|
|
245
218
|
val pairs = ArrayList<Triple<SharedElementTransitionOptions, View, View>>()
|
|
246
219
|
for (pair in shared) {
|
|
247
220
|
val fromId = pair.fromId.get(null) ?: continue
|
|
248
221
|
val toId = pair.toId.get(null) ?: continue
|
|
249
|
-
val source =
|
|
250
|
-
val target =
|
|
251
|
-
if (source === target ||
|
|
222
|
+
val source = views.leaving(fromId) ?: continue
|
|
223
|
+
val target = views.arriving(toId) ?: continue
|
|
224
|
+
if (source === target || source in playing || target in playing) continue
|
|
252
225
|
if (target in taken || source in taken) continue
|
|
253
226
|
if (!loaded(source, fromId) || !loaded(target, toId)) continue
|
|
227
|
+
taken += source
|
|
254
228
|
taken += target
|
|
255
229
|
pairs += Triple(pair, source, target)
|
|
256
230
|
}
|
|
257
231
|
if (elements.isEmpty() && pairs.isEmpty()) return null
|
|
258
|
-
val layer = TransitionLayer(host.context)
|
|
259
|
-
val transition = ElementTransition(layer)
|
|
232
|
+
val layer = if (pairs.isEmpty()) null else TransitionLayer(host.context)
|
|
233
|
+
val transition = ElementTransition(layer, fromView, toView)
|
|
260
234
|
try {
|
|
261
|
-
layer
|
|
235
|
+
layer?.attachTo(host, layerIndex ?: host.childCount)
|
|
262
236
|
transition.fill(host, elements, pairs, fallbackDuration)
|
|
263
237
|
} catch (e: RuntimeException) {
|
|
264
238
|
transition.finish()
|
|
@@ -268,8 +242,8 @@ internal class ElementTransition private constructor(private val layer: Transiti
|
|
|
268
242
|
}
|
|
269
243
|
|
|
270
244
|
/**
|
|
271
|
-
* [start], and when that fails, a line in the log and none: the screens play without their elements; every
|
|
272
|
-
*
|
|
245
|
+
* [start], and when that fails, a line in the log and none: the screens play without their elements; every
|
|
246
|
+
* element has its values back already.
|
|
273
247
|
*/
|
|
274
248
|
fun startOrLog(
|
|
275
249
|
animation: LayoutAnimation,
|
|
@@ -285,8 +259,6 @@ internal class ElementTransition private constructor(private val layer: Transiti
|
|
|
285
259
|
null
|
|
286
260
|
}
|
|
287
261
|
|
|
288
|
-
private fun found(view: View?): View? = view?.takeUnless { it is ElementStub }
|
|
289
|
-
|
|
290
262
|
// An image not loaded drops out of the transition; its wait logged it already, else it is logged now.
|
|
291
263
|
private fun loaded(view: View, id: String): Boolean {
|
|
292
264
|
if (ImageLoads.isLoaded(view)) return true
|
|
@@ -295,45 +267,23 @@ internal class ElementTransition private constructor(private val layer: Transiti
|
|
|
295
267
|
}
|
|
296
268
|
}
|
|
297
269
|
|
|
298
|
-
// The
|
|
299
|
-
//
|
|
270
|
+
// The elements' animators where they are, then the pairs' flights, their copies in the order their targets are
|
|
271
|
+
// drawn. Each element's steps run on their own ([elementStep]): one that fails is left as it was, the others play.
|
|
300
272
|
private fun fill(
|
|
301
273
|
host: ViewGroup,
|
|
302
274
|
elements: List<Pair<ElementTransitionOptions, View>>,
|
|
303
275
|
pairs: List<Triple<SharedElementTransitionOptions, View, View>>,
|
|
304
276
|
fallbackDuration: Long,
|
|
305
277
|
) {
|
|
306
|
-
|
|
307
|
-
for ((
|
|
308
|
-
|
|
309
|
-
val views = elements.map { it.second } + pairs.map { it.third }
|
|
310
|
-
val parents = views.associateWith { it.parent as? View }
|
|
311
|
-
val placed = HashMap<View, Moved>()
|
|
312
|
-
for (view in DrawOrder.sorted(views, host) { it }) {
|
|
313
|
-
var item: Moved? = null
|
|
314
|
-
if (elementStep(names.getValue(view)) { item = moveIntoLayer(view) }) item?.let { placed[view] = it }
|
|
315
|
-
}
|
|
278
|
+
for ((_, view) in elements) taken += view
|
|
279
|
+
for ((_, source, target) in pairs) taken += listOf(source, target)
|
|
280
|
+
playing += taken
|
|
316
281
|
for ((options, view) in elements) {
|
|
317
|
-
|
|
318
|
-
if (!elementStep(names.getValue(view)) { addElement(options, item) }) goBack(item)
|
|
319
|
-
}
|
|
320
|
-
for ((options, source, target) in pairs) {
|
|
321
|
-
val item = placed[target] ?: continue
|
|
322
|
-
var flies = false
|
|
323
|
-
elementStep(names.getValue(target)) {
|
|
324
|
-
flies = addPair(options, source, item, parents[target], fallbackDuration)
|
|
325
|
-
}
|
|
326
|
-
if (!flies) goBack(item)
|
|
282
|
+
if (!elementStep(elementName(options.id)) { addElement(options, view) }) giveValuesBack(view)
|
|
327
283
|
}
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
private fun goBack(item: Moved) {
|
|
332
|
-
moved -= item
|
|
333
|
-
try {
|
|
334
|
-
giveBack(item)
|
|
335
|
-
} catch (e: RuntimeException) {
|
|
336
|
-
Log.w(NavigationLog.TAG, "[ApexNavigation] An element of a transition couldn't go back", e)
|
|
284
|
+
for ((options, source, target) in DrawOrder.sorted(pairs, host) { it.third }) {
|
|
285
|
+
val name = pairName(options.fromId.get(""), options.toId.get(""))
|
|
286
|
+
elementStep(name) { addPair(options, source, target, name, fallbackDuration) }
|
|
337
287
|
}
|
|
338
288
|
}
|
|
339
289
|
}
|
|
@@ -7,6 +7,7 @@ import dev.apexnative.navigation.options.LayoutAnimation
|
|
|
7
7
|
import dev.apexnative.navigation.react.events.AppearanceDispatcher
|
|
8
8
|
import dev.apexnative.navigation.utils.DevelopmentLog
|
|
9
9
|
import dev.apexnative.navigation.utils.NavigationLog
|
|
10
|
+
import dev.apexnative.navigation.utils.SystemAnimations
|
|
10
11
|
import dev.apexnative.navigation.viewcontrollers.viewcontroller.ViewController
|
|
11
12
|
import kotlinx.coroutines.CancellationException
|
|
12
13
|
import kotlinx.coroutines.CoroutineScope
|
|
@@ -17,7 +18,8 @@ import kotlinx.coroutines.launch
|
|
|
17
18
|
/**
|
|
18
19
|
* The wait of a forward transition with elements for its targets: the module's frames (`awaitTransitionTargets`, 0.5 s
|
|
19
20
|
* at most, then one frame more), then the images of the shared elements found ([ImageWait], 1 s at most each). It ends
|
|
20
|
-
* early when the screen that goes is destroyed
|
|
21
|
+
* early when the screen that goes is destroyed, and doesn't wait with the system's animations off. A failure in it is
|
|
22
|
+
* logged and the transition starts. Main thread only.
|
|
21
23
|
*/
|
|
22
24
|
internal object TargetsWait {
|
|
23
25
|
// The waits run on the main thread's frames; each is cancelled on its own.
|
|
@@ -31,6 +33,11 @@ internal object TargetsWait {
|
|
|
31
33
|
waiting: () -> Boolean,
|
|
32
34
|
done: () -> Unit,
|
|
33
35
|
): () -> Unit {
|
|
36
|
+
// With the system's animations off no element moves ([ElementTransition.start]): nothing to wait for.
|
|
37
|
+
if (SystemAnimations.areOff(to.peekView()?.context)) {
|
|
38
|
+
guarded { done() }
|
|
39
|
+
return NOTHING
|
|
40
|
+
}
|
|
34
41
|
var stopped = false
|
|
35
42
|
var stopImages: () -> Unit = NOTHING
|
|
36
43
|
val still = { !stopped && waiting() && from?.isDestroyed != true }
|