@apexnative/navigation 1.0.0-alpha.2 → 1.0.0-alpha.4
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/CHANGELOG.md +31 -0
- package/android/CLAUDE.md +38 -9
- package/android/CORE.md +11 -4
- package/android/RECIPES.md +9 -3
- package/android/src/main/java/dev/apexnative/navigation/NavigationActivity.kt +29 -1
- package/android/src/main/java/dev/apexnative/navigation/NavigationApplication.kt +34 -13
- package/android/src/main/java/dev/apexnative/navigation/layout/LayoutChecks.kt +5 -1
- package/android/src/main/java/dev/apexnative/navigation/layout/LayoutNode.kt +6 -2
- package/android/src/main/java/dev/apexnative/navigation/nativescreen/NativeScreenContext.kt +2 -2
- package/android/src/main/java/dev/apexnative/navigation/options/ButtonMenuOptions.kt +2 -2
- package/android/src/main/java/dev/apexnative/navigation/options/ButtonOptions.kt +2 -2
- package/android/src/main/java/dev/apexnative/navigation/options/OptionsCache.kt +8 -4
- package/android/src/main/java/dev/apexnative/navigation/options/StatusBarOptions.kt +7 -3
- package/android/src/main/java/dev/apexnative/navigation/options/UserChoices.kt +159 -0
- package/android/src/main/java/dev/apexnative/navigation/react/CommandAnswer.kt +2 -24
- package/android/src/main/java/dev/apexnative/navigation/react/CommandContract.kt +59 -0
- package/android/src/main/java/dev/apexnative/navigation/react/Hinge.kt +27 -19
- package/android/src/main/java/dev/apexnative/navigation/react/NavigationTurboModule.kt +5 -4
- package/android/src/main/java/dev/apexnative/navigation/react/PendingCalls.kt +48 -0
- package/android/src/main/java/dev/apexnative/navigation/react/events/AppearanceDispatcher.kt +17 -7
- package/android/src/main/java/dev/apexnative/navigation/slots/SlotContainers.kt +10 -7
- package/android/src/main/java/dev/apexnative/navigation/slots/SlotView.kt +4 -3
- package/android/src/main/java/dev/apexnative/navigation/slots/SlotViews.kt +40 -0
- package/android/src/main/java/dev/apexnative/navigation/utils/ImageKey.kt +66 -0
- package/android/src/main/java/dev/apexnative/navigation/utils/ImageLoader.kt +7 -89
- package/android/src/main/java/dev/apexnative/navigation/utils/ImageRequests.kt +76 -0
- package/android/src/main/java/dev/apexnative/navigation/utils/OptionImages.kt +262 -0
- package/android/src/main/java/dev/apexnative/navigation/utils/ViewController.kt +3 -1
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/arrangement/SecondaryScreenPresenter.kt +13 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/AppliedTabCalls.kt +49 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsController.kt +92 -19
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsPresenter.kt +25 -24
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ComponentPresenter.kt +28 -7
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ContentReadiness.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/RenderWait.kt +27 -7
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ScreenFrame.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalAnimations.kt +22 -24
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalCoordinator.kt +79 -13
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalRecord.kt +21 -6
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalSheet.kt +29 -12
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalViews.kt +22 -18
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/BackCallbackState.kt +4 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/Navigator.kt +45 -6
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/RootCoordinator.kt +35 -9
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/overlay/OverlayCoordinator.kt +10 -8
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/Capabilities.kt +11 -4
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/ContainerBackground.kt +3 -3
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/ParentController.kt +3 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuController.kt +5 -1
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/splitview/SplitPanes.kt +23 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/splitview/SplitViewController.kt +72 -16
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/BackPreview.kt +287 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackCommands.kt +28 -18
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackController.kt +164 -13
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackDisplay.kt +26 -1
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackQueue.kt +136 -40
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackTransitions.kt +26 -8
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackViews.kt +107 -4
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/fab/FabPresenter.kt +7 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/search/StackSearchPresenter.kt +3 -3
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/MenuChecks.kt +13 -56
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/TopBarPresenter.kt +131 -9
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/viewcontroller/ViewController.kt +75 -21
- package/android/src/main/java/dev/apexnative/navigation/views/animations/Curves.kt +29 -11
- package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/BottomTabs.kt +4 -2
- package/android/src/main/java/dev/apexnative/navigation/views/stack/ScreenEdge.kt +15 -0
- package/android/src/main/java/dev/apexnative/navigation/views/stack/StackLayout.kt +137 -1
- package/android/src/main/java/dev/apexnative/navigation/views/stack/fab/Fab.kt +14 -10
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/TitleBar.kt +8 -1
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/TopBar.kt +26 -4
- package/cli/doctor/checks/app.js +61 -13
- package/cli/migrate/native.js +18 -0
- package/cli/setup/source.js +2 -1
- package/cli/setup/steps/mainApplication.js +134 -19
- package/docs-md/architecture/transitions.md +12 -7
- package/docs-md/containers/modals.md +4 -2
- package/docs-md/containers/overlays.md +3 -1
- package/docs-md/containers/side-menu.md +4 -2
- package/docs-md/containers/tabs.md +2 -0
- package/docs-md/flows/forms-in-a-modal.md +1 -1
- package/docs-md/help/glossary.md +2 -2
- package/docs-md/help/troubleshooting.md +20 -3
- package/docs-md/index.json +12 -0
- package/docs-md/migration/from-react-native-navigation.md +8 -2
- package/docs-md/screen-ui/back-and-gestures.md +8 -2
- package/docs-md/screen-ui/system-ui.md +1 -1
- package/docs-md/start/installation.md +3 -1
- package/ios/CLAUDE.md +17 -5
- package/ios/CORE.md +13 -8
- package/ios/Contract/ANNCommandAnswer.mm +5 -20
- package/ios/Contract/ANNCommandContract.h +15 -0
- package/ios/Contract/ANNCommandContract.mm +78 -0
- package/ios/Core/ANNAppearanceDispatcher.mm +1 -1
- package/ios/Core/ANNErrorHandler.h +1 -1
- package/ios/Core/ANNErrorHandler.mm +3 -1
- package/ios/Core/ANNEventEmitter.h +1 -1
- package/ios/Core/ANNEventEmitter.mm +2 -2
- package/ios/Core/ANNJavaScriptCalls.h +34 -0
- package/ios/Core/ANNJavaScriptCalls.mm +61 -0
- package/ios/Core/ANNNavigationState.h +7 -3
- package/ios/Core/ANNNavigationState.mm +10 -5
- package/ios/Core/ANNNodeHelper.h +32 -12
- package/ios/Core/ANNNodeHelper.mm +100 -3
- package/ios/Core/ANNRenderWait.h +15 -1
- package/ios/Core/ANNRenderWait.mm +119 -17
- package/ios/Core/UIViewController+LayoutProtocol.h +9 -2
- package/ios/Core/UIViewController+LayoutProtocol.mm +8 -0
- package/ios/Layouts/Modal/ANNModalCoordinator.h +1 -1
- package/ios/Layouts/Modal/ANNModalCoordinator.mm +55 -14
- package/ios/Layouts/Screen/ANNComponentViewController.h +8 -0
- package/ios/Layouts/Screen/ANNComponentViewController.mm +32 -5
- package/ios/Layouts/Screen/ANNScreenPlace.h +41 -0
- package/ios/Layouts/Screen/ANNScreenPlace.mm +175 -0
- package/ios/Layouts/SplitView/ANNSplitViewCommands.h +3 -2
- package/ios/Layouts/SplitView/ANNSplitViewCommands.mm +105 -39
- package/ios/Layouts/SplitView/ANNSplitViewController.mm +4 -2
- package/ios/Layouts/Stack/ANNStackCommands.mm +1 -0
- package/ios/Layouts/Stack/ANNStackController.mm +26 -3
- package/ios/Layouts/Stack/ANNStackQueue.h +3 -1
- package/ios/Layouts/Stack/ANNStackQueue.mm +56 -43
- package/ios/Layouts/Stack/UINavigationController+ANNCommands.h +4 -2
- package/ios/Layouts/Stack/UINavigationController+ANNCommands.mm +2 -3
- package/ios/Layouts/Tabs/ANNBottomTabItemBuilder.h +4 -0
- package/ios/Layouts/Tabs/ANNBottomTabItemBuilder.mm +11 -0
- package/ios/Layouts/Tabs/ANNBottomTabsController.mm +13 -5
- package/ios/Layouts/Tabs/ANNBottomTabsPresenter.h +2 -2
- package/ios/Layouts/Tabs/ANNBottomTabsPresenter.mm +109 -7
- package/ios/Options/ANNOptionsCache.h +7 -6
- package/ios/Options/ANNSearchBarOptions.h +4 -3
- package/ios/Options/ANNUserChoice.h +57 -0
- package/ios/Options/ANNUserChoice.mm +44 -0
- package/ios/Options/Params/ANNImageSource.h +61 -0
- package/ios/Options/Params/ANNImageSource.mm +101 -0
- package/ios/Options/Params/ANNOptionImages.h +37 -0
- package/ios/Options/Params/ANNOptionImages.mm +284 -0
- package/ios/Options/Params/Image.h +11 -2
- package/ios/Options/Params/Image.mm +15 -2
- package/ios/Options/Params/ImageParser.h +5 -5
- package/ios/Options/Params/ImageParser.mm +28 -46
- package/ios/Public/ApexNavigation/ApexNavigation.h +1 -1
- package/ios/RECIPES.md +11 -5
- package/ios/React/Slots/ANNSlotComponentView.mm +24 -17
- package/ios/React/Slots/ANNSlotContainers.h +14 -6
- package/ios/React/Slots/ANNSlotContainers.mm +75 -2
- package/ios/TopBar/ANNBarButtons.h +9 -5
- package/ios/TopBar/ANNBarButtons.mm +211 -63
- package/ios/TopBar/ANNIconButtonImage.h +1 -0
- package/ios/TopBar/ANNIconButtonImage.mm +34 -1
- package/ios/TopBar/ANNLargeTitlePresenter.h +13 -0
- package/ios/TopBar/ANNLargeTitlePresenter.mm +26 -3
- package/ios/TopBar/ANNSearchPresenter.mm +170 -19
- package/ios/TopBar/ANNTopBarPresenter.h +5 -0
- package/ios/TopBar/ANNTopBarPresenter.mm +60 -11
- package/ios/TurboModules/ANNTurboModule.mm +39 -21
- package/lib/module/ARCHITECTURE.md +18 -18
- package/lib/module/adapters/NativeANNTurboModule.js.map +1 -1
- package/lib/module/api/hooks/useNavigation.js +8 -3
- package/lib/module/api/hooks/useNavigation.js.map +1 -1
- package/lib/module/api/navigation.js.map +1 -1
- package/lib/module/engine/commands.js +9 -7
- package/lib/module/engine/commands.js.map +1 -1
- package/lib/module/engine/layout.js +13 -9
- package/lib/module/engine/layout.js.map +1 -1
- package/lib/module/engine/options.js +44 -11
- package/lib/module/engine/options.js.map +1 -1
- package/lib/module/engine/places.js +44 -7
- package/lib/module/engine/places.js.map +1 -1
- package/lib/module/engine/props.js +30 -1
- package/lib/module/engine/props.js.map +1 -1
- package/lib/module/engine/rememberedOptions.js +1 -1
- package/lib/module/engine/rememberedOptions.js.map +1 -1
- package/lib/module/engine/screens.js +22 -12
- package/lib/module/engine/screens.js.map +1 -1
- package/lib/module/interfaces/contract/commands.json +101 -0
- package/lib/typescript/adapters/NativeANNTurboModule.d.ts +5 -2
- package/lib/typescript/adapters/NativeANNTurboModule.d.ts.map +1 -1
- package/lib/typescript/api/events/navigationEvents.d.ts +1 -1
- package/lib/typescript/api/events/navigationEvents.d.ts.map +1 -1
- package/lib/typescript/api/hooks/useNavigation.d.ts +1 -1
- package/lib/typescript/api/hooks/useNavigation.d.ts.map +1 -1
- package/lib/typescript/api/navigation.d.ts +4 -1
- package/lib/typescript/api/navigation.d.ts.map +1 -1
- package/lib/typescript/engine/commands.d.ts.map +1 -1
- package/lib/typescript/engine/options.d.ts +5 -2
- package/lib/typescript/engine/options.d.ts.map +1 -1
- package/lib/typescript/engine/places.d.ts +5 -2
- package/lib/typescript/engine/places.d.ts.map +1 -1
- package/lib/typescript/engine/props.d.ts +8 -1
- package/lib/typescript/engine/props.d.ts.map +1 -1
- package/lib/typescript/engine/rememberedOptions.d.ts.map +1 -1
- package/lib/typescript/engine/screens.d.ts.map +1 -1
- package/lib/typescript/interfaces/ComponentEvents.d.ts +2 -2
- package/lib/typescript/interfaces/ComponentEvents.d.ts.map +1 -1
- package/lib/typescript/interfaces/Events.d.ts +19 -10
- package/lib/typescript/interfaces/Events.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/animations.d.ts +15 -7
- package/lib/typescript/interfaces/options/animations.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/buttons.d.ts +13 -5
- package/lib/typescript/interfaces/options/buttons.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/modals.d.ts +18 -13
- package/lib/typescript/interfaces/options/modals.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/system.d.ts +6 -3
- package/lib/typescript/interfaces/options/system.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/topBar.d.ts +22 -9
- package/lib/typescript/interfaces/options/topBar.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/ARCHITECTURE.md +18 -18
- package/src/adapters/NativeANNTurboModule.ts +5 -2
- package/src/api/events/navigationEvents.ts +1 -1
- package/src/api/hooks/useNavigation.ts +9 -4
- package/src/api/navigation.ts +4 -1
- package/src/engine/commands.ts +19 -7
- package/src/engine/layout.ts +16 -9
- package/src/engine/options.ts +39 -11
- package/src/engine/places.ts +56 -7
- package/src/engine/props.ts +30 -1
- package/src/engine/rememberedOptions.ts +4 -1
- package/src/engine/screens.tsx +23 -13
- package/src/interfaces/ComponentEvents.ts +2 -2
- package/src/interfaces/Events.ts +19 -10
- package/src/interfaces/contract/commands.json +101 -0
- package/src/interfaces/options/animations.ts +15 -7
- package/src/interfaces/options/buttons.ts +13 -5
- package/src/interfaces/options/modals.ts +18 -13
- package/src/interfaces/options/system.ts +6 -3
- package/src/interfaces/options/topBar.ts +22 -9
package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackController.kt
CHANGED
|
@@ -2,6 +2,7 @@ package dev.apexnative.navigation.viewcontrollers.stack
|
|
|
2
2
|
|
|
3
3
|
import android.app.Activity
|
|
4
4
|
import android.util.Log
|
|
5
|
+
import android.view.View
|
|
5
6
|
import dev.apexnative.navigation.NavigationActivity
|
|
6
7
|
import dev.apexnative.navigation.options.AnimationsOptions
|
|
7
8
|
import dev.apexnative.navigation.options.BottomTabsEnterExitAnimationOptions
|
|
@@ -11,6 +12,7 @@ import dev.apexnative.navigation.options.Options
|
|
|
11
12
|
import dev.apexnative.navigation.options.TopBarOptions
|
|
12
13
|
import dev.apexnative.navigation.react.CommandListener
|
|
13
14
|
import dev.apexnative.navigation.react.ErrorTexts
|
|
15
|
+
import dev.apexnative.navigation.react.PendingCalls
|
|
14
16
|
import dev.apexnative.navigation.react.events.AppearanceDispatcher
|
|
15
17
|
import dev.apexnative.navigation.utils.NavigationLog
|
|
16
18
|
import dev.apexnative.navigation.utils.UiThread
|
|
@@ -20,8 +22,8 @@ import dev.apexnative.navigation.viewcontrollers.child.ChildControllersRegistry
|
|
|
20
22
|
import dev.apexnative.navigation.viewcontrollers.component.ComponentViewController
|
|
21
23
|
import dev.apexnative.navigation.viewcontrollers.component.ContentReadiness
|
|
22
24
|
import dev.apexnative.navigation.viewcontrollers.component.Readiness
|
|
25
|
+
import dev.apexnative.navigation.viewcontrollers.component.RenderWait
|
|
23
26
|
import dev.apexnative.navigation.viewcontrollers.component.RestPlace
|
|
24
|
-
import dev.apexnative.navigation.viewcontrollers.component.ScreenContentFactory
|
|
25
27
|
import dev.apexnative.navigation.viewcontrollers.navigator.BackCallbackState
|
|
26
28
|
import dev.apexnative.navigation.viewcontrollers.navigator.Navigator
|
|
27
29
|
import dev.apexnative.navigation.viewcontrollers.parent.ContainerBackground
|
|
@@ -35,6 +37,7 @@ import dev.apexnative.navigation.viewcontrollers.stack.topbar.TopBarPresenter
|
|
|
35
37
|
import dev.apexnative.navigation.viewcontrollers.stack.topbar.TopBarRoom
|
|
36
38
|
import dev.apexnative.navigation.viewcontrollers.viewcontroller.Presenter
|
|
37
39
|
import dev.apexnative.navigation.viewcontrollers.viewcontroller.ViewController
|
|
40
|
+
import dev.apexnative.navigation.views.animations.AnimationRules
|
|
38
41
|
import dev.apexnative.navigation.views.component.ComponentLayout
|
|
39
42
|
import dev.apexnative.navigation.views.stack.StackLayout
|
|
40
43
|
import dev.apexnative.navigation.views.stack.topbar.LargeTitleView
|
|
@@ -79,26 +82,34 @@ class StackController(
|
|
|
79
82
|
|
|
80
83
|
/** The one queue of the stack. */
|
|
81
84
|
// The readiness of the screens reaches the queue's waits on the next turn of the main loop: a signal that comes
|
|
82
|
-
// inside a layout pass or a view's attach moves no view of the container there.
|
|
85
|
+
// inside a layout pass or a view's attach moves no view of the container there. A pushed screen's mount reaches
|
|
86
|
+
// its push behind the calls JavaScript made before it (`PendingCalls`), on a later turn too.
|
|
83
87
|
internal var queue = StackQueue(
|
|
84
88
|
display = StackViews(this),
|
|
85
89
|
readiness = ContentReadiness,
|
|
86
90
|
scheduler = { delay, task -> AppearanceDispatcher.scheduler.schedule(delay, task) },
|
|
87
91
|
host = QueueHost(),
|
|
88
92
|
deliver = { signal -> UiThread.post { signal() } },
|
|
93
|
+
afterCalls = PendingCalls::after,
|
|
89
94
|
)
|
|
90
95
|
private set
|
|
91
96
|
|
|
92
97
|
/**
|
|
93
98
|
* The unit tests run the stack over their own display, readiness and host (views are stubs there), before any
|
|
94
|
-
* screen joins it; the readiness signals come at once there.
|
|
99
|
+
* screen joins it; the readiness signals come at once there, and a push's behind the calls as [afterCalls] says.
|
|
95
100
|
*/
|
|
96
|
-
internal fun useQueueParts(
|
|
101
|
+
internal fun useQueueParts(
|
|
102
|
+
display: StackDisplay,
|
|
103
|
+
readiness: Readiness,
|
|
104
|
+
host: StackQueue.Host?,
|
|
105
|
+
afterCalls: (() -> Unit) -> Unit = { it() },
|
|
106
|
+
) {
|
|
97
107
|
queue = StackQueue(
|
|
98
108
|
display = display,
|
|
99
109
|
readiness = readiness,
|
|
100
110
|
scheduler = { delay, task -> AppearanceDispatcher.scheduler.schedule(delay, task) },
|
|
101
111
|
host = host ?: QueueHost(),
|
|
112
|
+
afterCalls = afterCalls,
|
|
102
113
|
)
|
|
103
114
|
}
|
|
104
115
|
|
|
@@ -257,6 +268,136 @@ class StackController(
|
|
|
257
268
|
*/
|
|
258
269
|
override fun canHandleBack(): Boolean = topBar.isSearchOpen() || queue.entries.size >= 2
|
|
259
270
|
|
|
271
|
+
/**
|
|
272
|
+
* The default pop of the top is what back does now and it can be previewed: two entries or more, nothing running
|
|
273
|
+
* or waiting, no open search, the top doesn't hold back and pops with the default transition, the screen under it
|
|
274
|
+
* has its view, and the stack shows.
|
|
275
|
+
*/
|
|
276
|
+
override fun stackPoppedByBack(): StackController? {
|
|
277
|
+
if (topBar.isSearchOpen() || !queue.isAtRest) return null
|
|
278
|
+
val entries = queue.entries
|
|
279
|
+
val top = queue.currentChild ?: return null
|
|
280
|
+
val target = entries.getOrNull(entries.size - 2) ?: return null
|
|
281
|
+
if (top !== entries.last() || target !in queue.shown || target.peekView() == null) return null
|
|
282
|
+
if (!queue.isRendered(target) || backGesture != null) return null
|
|
283
|
+
val options = resolvedOf(top)
|
|
284
|
+
val pop = options.animations.pop
|
|
285
|
+
if (options.hardwareBackButton.popStackOnPress.isFalse || pop.enabled.isFalse || AnimationRules.stackIsOwn(pop)) {
|
|
286
|
+
return null
|
|
287
|
+
}
|
|
288
|
+
val display = queue.display
|
|
289
|
+
return this.takeIf { display.isOnScreen && display.canAnimate }
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Starts the preview of the pop a back gesture would make ([stackPoppedByBack] said yes): the top shrinks toward
|
|
294
|
+
* the gesture's side ([fromLeft]) and follows the finger from [touchY]; the screen under it shows with its bar.
|
|
295
|
+
* None when it can't be shown.
|
|
296
|
+
*/
|
|
297
|
+
internal fun startBackGesture(fromLeft: Boolean, touchY: Float): BackGesture? {
|
|
298
|
+
val views = queue.display as? StackViews ?: return null
|
|
299
|
+
val top = queue.currentChild ?: return null
|
|
300
|
+
val target = queue.entries.getOrNull(queue.entries.size - 2) ?: return null
|
|
301
|
+
val gesture = BackGesture(views, top, target)
|
|
302
|
+
val preview = views.startBackPreview(top, target, fromLeft, touchY, gesture::reveal) ?: return null
|
|
303
|
+
gesture.preview = preview
|
|
304
|
+
backGesture = gesture
|
|
305
|
+
return gesture
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// The back gesture over this stack whose preview hasn't ended yet; none.
|
|
309
|
+
private var backGesture: BackGesture? = null
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* A back gesture over the top of this stack ([startBackGesture]): its progress, its cancel, and its release, which
|
|
313
|
+
* pops the top through the queue with the preview's end. A command accepted meanwhile, or the stack's destroy,
|
|
314
|
+
* ends the preview at once ([abort]).
|
|
315
|
+
*/
|
|
316
|
+
internal inner class BackGesture(
|
|
317
|
+
private val views: StackViews,
|
|
318
|
+
private val top: ViewController<*>,
|
|
319
|
+
private val target: ViewController<*>,
|
|
320
|
+
) {
|
|
321
|
+
lateinit var preview: BackPreview
|
|
322
|
+
// How the screen under the top was before the preview showed it: in the container and seen, its alpha and
|
|
323
|
+
// accessibility.
|
|
324
|
+
private var targetWasPlaced = false
|
|
325
|
+
private var targetAlpha = 1f
|
|
326
|
+
private var targetAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_AUTO
|
|
327
|
+
private var revealed = false
|
|
328
|
+
private var aborted = false
|
|
329
|
+
|
|
330
|
+
/** The gesture moved: [progress] 0 … 1, the finger at [touchY]. */
|
|
331
|
+
fun progress(progress: Float, touchY: Float) {
|
|
332
|
+
if (!aborted) preview.progress(progress, touchY)
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/** Cancelled: the preview springs back, then the screen under the top and the bar are as they were. */
|
|
336
|
+
fun cancel() {
|
|
337
|
+
if (!aborted) preview.cancel(::restore)
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* Released: the top pops, the preview playing its end; the default pop when its picture isn't there yet. False
|
|
342
|
+
* when the stack changed since the gesture started (a command ran, the stack went): back goes the usual way.
|
|
343
|
+
*/
|
|
344
|
+
fun commit(): Boolean {
|
|
345
|
+
if (aborted || isDestroyed) return false
|
|
346
|
+
if (!preview.isReady) {
|
|
347
|
+
abort()
|
|
348
|
+
queue.cut(target, null, id, "go back in the stack '$id'", null)
|
|
349
|
+
return true
|
|
350
|
+
}
|
|
351
|
+
if (backGesture === this) backGesture = null
|
|
352
|
+
queue.cut(target, null, id, "go back in the stack '$id'", null, gesture = true)
|
|
353
|
+
return true
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/** The stack changed or goes: the preview ends at once and the stack is as it was. */
|
|
357
|
+
fun abort() {
|
|
358
|
+
if (aborted) return
|
|
359
|
+
aborted = true
|
|
360
|
+
preview.endAtOnce()
|
|
361
|
+
restore()
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// The preview's picture is there: the screen under the top shows under it, and the bar shows that screen.
|
|
365
|
+
internal fun reveal() {
|
|
366
|
+
val view = target.peekView() ?: return
|
|
367
|
+
targetWasPlaced = view.parent === peekView() && view.visibility == View.VISIBLE
|
|
368
|
+
targetAlpha = view.alpha
|
|
369
|
+
targetAccessibility = view.importantForAccessibility
|
|
370
|
+
revealed = true
|
|
371
|
+
views.reveal(target, top)
|
|
372
|
+
view.alpha = 1f
|
|
373
|
+
topBar.apply(target)
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
private fun restore() {
|
|
377
|
+
views.previewEnded(preview)
|
|
378
|
+
if (backGesture === this) backGesture = null
|
|
379
|
+
if (!revealed || isDestroyed) return
|
|
380
|
+
revealed = false
|
|
381
|
+
if (target in queue.shown && target !== queue.currentChild) {
|
|
382
|
+
val view = target.peekView()
|
|
383
|
+
if (targetWasPlaced && view != null) {
|
|
384
|
+
view.alpha = targetAlpha
|
|
385
|
+
view.importantForAccessibility = targetAccessibility
|
|
386
|
+
} else {
|
|
387
|
+
views.detach(target)
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
// The bar shows the top again, its components appeared again.
|
|
391
|
+
val shown = queue.currentChild
|
|
392
|
+
topBar.apply(shown)
|
|
393
|
+
shown?.let {
|
|
394
|
+
topBar.screenWillAppear(optionsScreen(it))
|
|
395
|
+
topBar.screenDidAppear(optionsScreen(it))
|
|
396
|
+
}
|
|
397
|
+
BackCallbackState.update()
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
260
401
|
/**
|
|
261
402
|
* The back arrow of the bar was pressed: the screen the user sees holds it (`topBar.backButton.popStackOnPress:
|
|
262
403
|
* false`: `ANN.NavigationButtonPressed` with `topBar.backButton.id` or `ApexNavigation.back`); on the first screen
|
|
@@ -338,7 +479,7 @@ class StackController(
|
|
|
338
479
|
|
|
339
480
|
// `mergeOptions` with the stack's id: its own options, what it shows, then the layouts around.
|
|
340
481
|
override fun mergeOptions(options: Options) {
|
|
341
|
-
|
|
482
|
+
mergeOwnOptions(options)
|
|
342
483
|
applyOrKeep(options, null)
|
|
343
484
|
performOnParentController { it.mergeChildOptions(withoutStackGroups(options), this) }
|
|
344
485
|
}
|
|
@@ -460,8 +601,9 @@ class StackController(
|
|
|
460
601
|
|
|
461
602
|
/**
|
|
462
603
|
* The bar's bottom in the window while [child] is under it and it shows, from the stack's place in the window: for
|
|
463
|
-
* the screen on top where the bar is laid out (a move of the bar doesn't count); for another
|
|
464
|
-
*
|
|
604
|
+
* the screen on top that the bar shows, where the bar is laid out (a move of the bar doesn't count); for another
|
|
605
|
+
* child (a prepared one) and for a top the bar hasn't shown yet (in a tab not selected yet, which measures though
|
|
606
|
+
* invisible) as its own options set the bar, so its content doesn't move as the bar takes them.
|
|
465
607
|
*/
|
|
466
608
|
override fun headerBottomOf(child: ViewController<*>): Int? {
|
|
467
609
|
if (!isUnderBar(child)) return super.headerBottomOf(child)
|
|
@@ -471,7 +613,7 @@ class StackController(
|
|
|
471
613
|
val layout = peekView() ?: return null
|
|
472
614
|
// The stack's place at rest, as the screen's own: a modal sliding in or a sheet dragged doesn't move it.
|
|
473
615
|
val top = RestPlace.topInWindow(layout)
|
|
474
|
-
if (entry === queue.currentChild) return topBar.barBottomInStack()?.let { top + it }
|
|
616
|
+
if (entry === queue.currentChild && topBar.shows(entry)) return topBar.barBottomInStack()?.let { top + it }
|
|
475
617
|
val bar = topBar.barOf(entry, options)
|
|
476
618
|
val large = if (largeTitleShown(child)) UiUtils.dpToPx(activity, LargeTitleView.HEIGHT).toInt() else 0
|
|
477
619
|
return top + bar.margin + bar.strip + bar.height + large
|
|
@@ -506,6 +648,7 @@ class StackController(
|
|
|
506
648
|
|
|
507
649
|
override fun destroy() {
|
|
508
650
|
if (isDestroyed) return
|
|
651
|
+
backGesture?.abort()
|
|
509
652
|
queue.destroy()
|
|
510
653
|
preparedPushes()?.discardFor(this)
|
|
511
654
|
fab.destroy()
|
|
@@ -552,15 +695,23 @@ class StackController(
|
|
|
552
695
|
(node as? OptionsScreen)?.optionsScreen ?: node
|
|
553
696
|
|
|
554
697
|
private inner class QueueHost : StackQueue.Host {
|
|
698
|
+
override fun operationAccepted() {
|
|
699
|
+
backGesture?.abort()
|
|
700
|
+
}
|
|
701
|
+
|
|
555
702
|
// The bar takes the options of the new top at once, also without appearance events.
|
|
556
703
|
override fun currentChildChanged() {
|
|
557
704
|
updateBar()
|
|
558
705
|
navigator?.shownScreensChanged(this@StackController)
|
|
559
706
|
}
|
|
560
707
|
|
|
561
|
-
// Before the bar takes the new top's options: the row's picture, and how it shows or hides.
|
|
562
|
-
override fun barTransition(
|
|
563
|
-
|
|
708
|
+
// Before the bar takes the new top's options: the row's picture or the bar's travel, and how it shows or hides.
|
|
709
|
+
override fun barTransition(
|
|
710
|
+
motion: StackDisplay.BarMotion?,
|
|
711
|
+
visibility: StackDisplay.BarVisibility,
|
|
712
|
+
travel: StackDisplay.BarTravel?,
|
|
713
|
+
) {
|
|
714
|
+
if (peekView() != null) topBar.beginRowTransition(motion, queue.currentChild, visibility, travel)
|
|
564
715
|
}
|
|
565
716
|
|
|
566
717
|
// The tab bar of the tabs around goes with the transition; a takeover doesn't bring it to rest.
|
|
@@ -588,8 +739,8 @@ class StackController(
|
|
|
588
739
|
if (peekView() != null) topBar.stage(node)
|
|
589
740
|
}
|
|
590
741
|
|
|
591
|
-
override fun
|
|
592
|
-
(node
|
|
742
|
+
override fun hasReactContent(node: ViewController<*>): Boolean =
|
|
743
|
+
RenderWait.waitedScreens(node).any { it is ComponentViewController }
|
|
593
744
|
|
|
594
745
|
override fun log(text: String) {
|
|
595
746
|
Log.e(NavigationLog.TAG, text)
|
package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackDisplay.kt
CHANGED
|
@@ -38,6 +38,12 @@ internal interface StackDisplay {
|
|
|
38
38
|
*/
|
|
39
39
|
enum class BarMotion { Push, Pop, FadeThrough }
|
|
40
40
|
|
|
41
|
+
/**
|
|
42
|
+
* How the bar goes with a transition of the stack's own (`content`): with its screens. [Forward]: the screen that
|
|
43
|
+
* comes lies over the one that goes (a push, `setStackRoot`); [Back]: the one that goes lies over it (a pop).
|
|
44
|
+
*/
|
|
45
|
+
enum class BarTravel { Forward, Back }
|
|
46
|
+
|
|
41
47
|
/**
|
|
42
48
|
* How the bar shows or hides when the new top's `topBar.visible` differs: at once (no animation, or a transition
|
|
43
49
|
* with elements), or [animated] by the transition's [side] (`animations.push.topBar`, the leaving screen's
|
|
@@ -156,12 +162,31 @@ internal interface StackDisplay {
|
|
|
156
162
|
done: () -> Unit,
|
|
157
163
|
): () -> Unit
|
|
158
164
|
|
|
165
|
+
/** The preview of a back gesture over [top], [target] under it, shows ([finishBackGesture] can end it). */
|
|
166
|
+
fun hasBackPreview(top: ViewController<*>, target: ViewController<*>): Boolean = false
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* The pop of a back gesture whose preview shows ([hasBackPreview]), released: the preview plays the end of [top]
|
|
170
|
+
* going and [target] coming. [topDone] and [targetDone] once each, as [animate]'s; [stop] of one screen ends the
|
|
171
|
+
* preview where it is and its other screen's part.
|
|
172
|
+
*/
|
|
173
|
+
fun finishBackGesture(
|
|
174
|
+
top: ViewController<*>,
|
|
175
|
+
target: ViewController<*>,
|
|
176
|
+
topDone: () -> Unit,
|
|
177
|
+
targetDone: () -> Unit,
|
|
178
|
+
) {
|
|
179
|
+
topDone()
|
|
180
|
+
targetDone()
|
|
181
|
+
}
|
|
182
|
+
|
|
159
183
|
/** Stops the animator of [screen] where it is, without its end: a later transition takes the screen over. */
|
|
160
184
|
fun stop(screen: ViewController<*>)
|
|
161
185
|
|
|
162
186
|
/**
|
|
163
187
|
* The push of a prepared slot screen: [mounted] as the slot's content mounts into the screen's container (or at the
|
|
164
|
-
* limit of 0.5 s), then [start] on the pre-draw of that frame, while [waiting] holds
|
|
188
|
+
* limit of 0.5 s), then [start] on the pre-draw of that frame, while [waiting] holds; the queue starts the
|
|
189
|
+
* transition from there behind the calls JavaScript made before, on a later turn.
|
|
165
190
|
*/
|
|
166
191
|
fun awaitPrepared(screen: ViewController<*>, waiting: () -> Boolean, mounted: () -> Unit, start: () -> Unit)
|
|
167
192
|
}
|