@applicaster/zapp-react-native-ui-components 16.0.0-rc.12 → 16.0.0-rc.120
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/Components/AudioPlayer/tv/__tests__/audioPlayer.test.js +19 -0
- package/Components/AudioPlayer/tv/__tests__/index.test.tsx +120 -0
- package/Components/AudioPlayer/tv/index.tsx +5 -1
- package/Components/Cell/Cell.tsx +3 -6
- package/Components/Cell/TvOSCellComponent.tsx +0 -1
- package/Components/CellRendererResolver/index.ts +1 -1
- package/Components/FocusableGroup/FocusableTvOS.tsx +11 -7
- package/Components/GeneralContentScreen/GeneralContentScreenHookAdapter.tsx +54 -0
- package/Components/GeneralContentScreen/__tests__/GeneralContentScreenHookAdapter.test.tsx +64 -0
- package/Components/GeneralContentScreen/__tests__/HookContentFocusGroup.web.test.tsx +91 -0
- package/Components/GeneralContentScreen/hookAdapter/__tests__/networkService.test.ts +74 -0
- package/Components/GeneralContentScreen/hookAdapter/__tests__/runInBackground.test.ts +139 -0
- package/Components/GeneralContentScreen/hookAdapter/__tests__/skipExpression.test.ts +294 -0
- package/Components/GeneralContentScreen/hookAdapter/__tests__/validationHelper.test.ts +188 -0
- package/Components/GeneralContentScreen/hookAdapter/logger.ts +6 -0
- package/Components/GeneralContentScreen/hookAdapter/networkService.ts +53 -0
- package/Components/GeneralContentScreen/hookAdapter/runInBackground.ts +48 -0
- package/Components/GeneralContentScreen/hookAdapter/skipExpression.ts +252 -0
- package/Components/GeneralContentScreen/hookAdapter/validationHelper.ts +90 -0
- package/Components/GeneralContentScreen/hookFocus/index.tsx +13 -0
- package/Components/GeneralContentScreen/hookFocus/index.web.tsx +69 -0
- package/Components/GeneralContentScreen/index.ts +2 -0
- package/Components/Layout/FullWidthRow.tsx +38 -0
- package/Components/LinkHandler/LinkHandler.tsx +2 -7
- package/Components/MasterCell/DefaultComponents/ActionButton.tsx +5 -1
- package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/placement.test.ts +47 -21
- package/Components/MasterCell/DefaultComponents/ActionButtonsCore/components/ActionButtonController.tsx +19 -4
- package/Components/MasterCell/DefaultComponents/ActionButtonsCore/components/__tests__/ActionButtonController.test.tsx +43 -1
- package/Components/MasterCell/DefaultComponents/ActionButtonsCore/placement.ts +34 -6
- package/Components/MasterCell/DefaultComponents/Button.tsx +1 -0
- package/Components/MasterCell/DefaultComponents/Image/hoc/utils/__tests__/withDimensions.test.ts +420 -125
- package/Components/MasterCell/DefaultComponents/Image/hoc/utils/index.ts +114 -19
- package/Components/MasterCell/DefaultComponents/Image/hoc/withDimensions.tsx +19 -8
- package/Components/MasterCell/DefaultComponents/ImageContainer/index.tsx +5 -3
- package/Components/MasterCell/DefaultComponents/LiveImage/executePreloadHooks.ts +2 -4
- package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +14 -6
- package/Components/MasterCell/DefaultComponents/PressableView.tsx +29 -9
- package/Components/MasterCell/DefaultComponents/Text/hooks/useText.ts +4 -0
- package/Components/MasterCell/DefaultComponents/Toggle.tsx +36 -14
- package/Components/MasterCell/DefaultComponents/__tests__/Toggle.test.tsx +167 -0
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/ActionButton.tsx +154 -100
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/AssetComponent.tsx +15 -4
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/Button.ts +56 -22
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/Spacer.ts +6 -4
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/TextLabelsContainer.ts +3 -1
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/__tests__/PressableView.test.tsx +34 -21
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/__tests__/index.test.ts +15 -4
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/index.ts +23 -16
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/utils/__tests__/insertButtons.test.ts +8 -3
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/utils/index.ts +2 -2
- package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/utils/__tests__/insertButtonsBetweenLabels.test.ts +45 -13
- package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/utils/index.ts +2 -2
- package/Components/MasterCell/SharedUI/CollapsibleTextContainer/__tests__/factory.test.ts +32 -0
- package/Components/MasterCell/__tests__/masterCell.test.js +60 -0
- package/Components/MasterCell/contexts/PressedStateContext.ts +3 -0
- package/Components/MasterCell/dataAdapter.ts +15 -5
- package/Components/MasterCell/hooks/index.ts +2 -0
- package/Components/MasterCell/hooks/usePressedState.ts +4 -0
- package/Components/MasterCell/index.tsx +57 -8
- package/Components/MasterCell/utils/__tests__/resolveColor.test.js +169 -132
- package/Components/MasterCell/utils/__tests__/resolveColorForProp.test.js +92 -0
- package/Components/MasterCell/utils/__tests__/withoutFocusedState.test.js +20 -0
- package/Components/MasterCell/utils/index.ts +103 -46
- package/Components/ModalComponent/ActionsBottomSheet/ActionButton.tsx +56 -0
- package/Components/ModalComponent/ActionsBottomSheet/__tests__/openActionsBottomSheet.test.ts +38 -0
- package/Components/ModalComponent/ActionsBottomSheet/boundActionButton.tsx +24 -0
- package/Components/ModalComponent/ActionsBottomSheet/index.ts +9 -0
- package/Components/ModalComponent/ActionsBottomSheet/openActionsBottomSheet.ts +61 -0
- package/Components/ModalComponent/AudioPlayer/Components/Button.tsx +392 -0
- package/Components/ModalComponent/AudioPlayer/Components/Header.tsx +772 -0
- package/Components/ModalComponent/AudioPlayer/Components/Input.tsx +728 -0
- package/Components/ModalComponent/AudioPlayer/Components/Item.tsx +1028 -0
- package/Components/ModalComponent/AudioPlayer/Components/NowPlayingHeaderSection.tsx +205 -0
- package/Components/ModalComponent/AudioPlayer/Components/__tests__/Item.test.tsx +164 -0
- package/Components/ModalComponent/AudioPlayer/Components/__tests__/NowPlayingHeaderSection.test.tsx +36 -0
- package/Components/ModalComponent/AudioPlayer/Components/index.ts +9 -0
- package/Components/ModalComponent/AudioPlayer/utils/__tests__/mergeStyles.test.ts +433 -0
- package/Components/ModalComponent/AudioPlayer/utils/mergeStyles.ts +563 -0
- package/Components/ModalComponent/BottomSheetDragArea.tsx +33 -0
- package/Components/ModalComponent/BottomSheetModalContent.tsx +440 -50
- package/Components/ModalComponent/Button/index.tsx +5 -3
- package/Components/ModalComponent/Header/CloseButton.tsx +12 -0
- package/Components/ModalComponent/Header/__tests__/CloseButton.test.tsx +72 -0
- package/Components/ModalComponent/Header/index.tsx +20 -7
- package/Components/ModalComponent/Header/utils.ts +1 -1
- package/Components/ModalComponent/ModalBlocksStyleContext.tsx +10 -0
- package/Components/ModalComponent/SortableList.tsx +156 -0
- package/Components/ModalComponent/SortableList.web.tsx +34 -0
- package/Components/ModalComponent/TextInputContent.tsx +135 -0
- package/Components/ModalComponent/__tests__/BottomSheetDragArea.test.tsx +74 -0
- package/Components/ModalComponent/__tests__/BottomSheetModalContent.test.tsx +343 -0
- package/Components/ModalComponent/__tests__/SortableList.web.test.tsx +16 -0
- package/Components/ModalComponent/__tests__/TextInputContent.test.tsx +169 -0
- package/Components/ModalComponent/__tests__/showTextInput.test.ts +120 -0
- package/Components/ModalComponent/index.tsx +18 -9
- package/Components/ModalComponent/presets/__tests__/getCell.test.ts +90 -0
- package/Components/ModalComponent/presets/dynamicCollectionCell.tsx +78 -0
- package/Components/ModalComponent/presets/index.ts +27 -0
- package/Components/ModalComponent/presets/selectableCell.tsx +28 -0
- package/Components/ModalComponent/presets/standardCell.tsx +41 -0
- package/Components/ModalComponent/presets/types.ts +35 -0
- package/Components/ModalComponent/showTextInput.ts +54 -0
- package/Components/ModalComponent/utils.ts +82 -21
- package/Components/OfflineHandler/__tests__/__snapshots__/index.test.tsx.snap +4 -85
- package/Components/OfflineHandler/__tests__/index.test.tsx +186 -17
- package/Components/OfflineHandler/hooks.ts +111 -0
- package/Components/OfflineHandler/index.tsx +91 -75
- package/Components/OfflineHandler/utils/index.ts +1 -13
- package/Components/PlayerContainer/PlayerContainer.tsx +28 -11
- package/Components/PlayerContainer/ProgramInfo/index.tsx +3 -4
- package/Components/PlayerContainer/__tests__/PlayerContainer.test.tsx +337 -0
- package/Components/PreloaderWrapper/index.tsx +1 -1
- package/Components/River/ComponentsMap/ComponentsMap.tsx +91 -62
- package/Components/River/River.tsx +4 -0
- package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +142 -89
- package/Components/River/__tests__/componentsMap.test.js +8 -3
- package/Components/River/__tests__/resultCallback.test.tsx +47 -0
- package/Components/Screen/__tests__/Screen.test.tsx +24 -0
- package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +2 -0
- package/Components/Screen/index.tsx +13 -4
- package/Components/Screen/navigationHandler.ts +8 -8
- package/Components/ScreenFeedLoader/ScreenFeedLoader.tsx +5 -3
- package/Components/ScreenResolverFeedProvider/ScreenResolverFeedProvider.tsx +1 -1
- package/Components/ScreenRevealManager/ScreenRevealManager.ts +18 -2
- package/Components/ScreenRevealManager/__tests__/ScreenRevealManager.test.ts +36 -0
- package/Components/ScreenRevealManager/__tests__/withScreenRevealManager.test.tsx +56 -0
- package/Components/ScreenRevealManager/withScreenRevealManager.tsx +21 -4
- package/Components/TopCutoffOverlay/index.tsx +2 -2
- package/Components/Transitioner/AnimationManager.js +1 -1
- package/Components/Transitioner/Scene.tsx +4 -3
- package/Components/Transitioner/Transitioner.tsx +98 -49
- package/Components/Transitioner/__tests__/transitioner.test.js +372 -3
- package/Components/VideoLive/LiveImageManager.ts +9 -3
- package/Components/VideoLive/__tests__/LiveImageManager.test.ts +59 -0
- package/Components/VideoModal/PlayerWrapper.tsx +4 -1
- package/Components/VideoModal/__tests__/PlayerWrapper.test.tsx +1 -0
- package/Components/VideoModal/__tests__/playerWrapperStyle.test.ts +58 -0
- package/Components/VideoModal/__tests__/playerWrapperUtils.test.ts +16 -0
- package/Components/VideoModal/playerWrapperStyle.ts +21 -3
- package/Components/VideoModal/playerWrapperUtils.ts +7 -1
- package/Components/ZappFrameworkComponents/BarView/BarView.tsx +12 -5
- package/Components/ZappFrameworkComponents/BarView/__tests__/BarView.test.tsx +2 -2
- package/Contexts/CachedDimensionsContext/__tests__/index.test.ts +154 -0
- package/Contexts/CachedDimensionsContext/index.ts +17 -2
- package/Contexts/ModalNavigationContext/__tests__/index.test.tsx +15 -0
- package/Contexts/ModalNavigationContext/index.tsx +2 -2
- package/Decorators/ZappPipesDataConnector/__tests__/screenToolbox.test.ts +347 -0
- package/Decorators/ZappPipesDataConnector/__tests__/screenToolboxUnavailable.test.ts +53 -0
- package/Decorators/ZappPipesDataConnector/index.tsx +19 -4
- package/Decorators/ZappPipesDataConnector/screenToolbox.ts +384 -0
- package/Helpers/ComponentCellSelectionHelper/index.js +0 -6
- package/Helpers/index.js +0 -39
- package/Hooks/useEntryActionsExpander.ts +63 -0
- package/assets/empty-Info.png +0 -0
- package/package.json +6 -5
- package/Components/OfflineHandler/NotificationView/NotificationView.lg.tsx +0 -112
- package/Components/OfflineHandler/NotificationView/NotificationView.samsung.tsx +0 -107
- package/Components/OfflineHandler/NotificationView/NotificationView.tsx +0 -153
- package/Components/OfflineHandler/NotificationView/__tests__/index.test.tsx +0 -66
- package/Components/OfflineHandler/NotificationView/utils.ts +0 -34
- package/Components/Screen/utils.ts +0 -16
- package/Helpers/Analytics/index.js +0 -95
- /package/Components/BackgroundImage/{BackgroundImage.tv.android.tsx → BackgroundImage.android.tv.tsx} +0 -0
- /package/Components/BackgroundImage/{BackgroundImage.tv.ios.tsx → BackgroundImage.ios.tv.tsx} +0 -0
- /package/Components/MasterCell/DefaultComponents/ButtonContainerView/{index.tv.android.tsx → index.android.tv.tsx} +0 -0
- /package/Decorators/ZappPipesDataConnector/__tests__/{Hero.js → Hero.tsx} +0 -0
|
@@ -21,11 +21,23 @@ export const SHOWN = 1; // opacity = 1
|
|
|
21
21
|
type Props = {
|
|
22
22
|
componentsToRender: ZappUIComponent[];
|
|
23
23
|
backgroundColor?: string;
|
|
24
|
+
/**
|
|
25
|
+
* Renders every component at once instead of revealing them a few at a time.
|
|
26
|
+
*
|
|
27
|
+
* For a screen that builds its own components and holds all of them already -
|
|
28
|
+
* a form, say - staggering buys nothing and costs: each rebuild of the list
|
|
29
|
+
* tears it back down to the first few and lets the rest crawl in again.
|
|
30
|
+
*
|
|
31
|
+
* This is a flag rather than a count on purpose. A count would have to be
|
|
32
|
+
* re-read whenever the number of components changes, while "do not stagger"
|
|
33
|
+
* stays true whatever the screen ends up holding.
|
|
34
|
+
*/
|
|
35
|
+
disableIncrementalLoading?: boolean;
|
|
24
36
|
};
|
|
25
37
|
|
|
26
38
|
export const withScreenRevealManager = (Component) => {
|
|
27
39
|
return function WithScreenRevealManager(props: Props) {
|
|
28
|
-
const { componentsToRender } = props;
|
|
40
|
+
const { componentsToRender, disableIncrementalLoading } = props;
|
|
29
41
|
|
|
30
42
|
const [isContentReadyToBeShown, setIsContentReadyToBeShown] =
|
|
31
43
|
React.useState(false);
|
|
@@ -42,7 +54,8 @@ export const withScreenRevealManager = (Component) => {
|
|
|
42
54
|
() =>
|
|
43
55
|
new ScreenRevealManager(
|
|
44
56
|
componentsToRender,
|
|
45
|
-
handleSetIsContentReadyToBeShown
|
|
57
|
+
handleSetIsContentReadyToBeShown,
|
|
58
|
+
disableIncrementalLoading ? componentsToRender.length : undefined
|
|
46
59
|
)
|
|
47
60
|
);
|
|
48
61
|
|
|
@@ -72,7 +85,7 @@ export const withScreenRevealManager = (Component) => {
|
|
|
72
85
|
|
|
73
86
|
if (isFirstComponentScreenPicker(componentsToRender)) {
|
|
74
87
|
// for screen-picker with have additional internal ComponentsMap, no need to add this wrapper
|
|
75
|
-
return <Component {...props} />;
|
|
88
|
+
return <Component {...props} initialNumberToLoad={1} />;
|
|
76
89
|
}
|
|
77
90
|
|
|
78
91
|
return (
|
|
@@ -80,7 +93,11 @@ export const withScreenRevealManager = (Component) => {
|
|
|
80
93
|
<Component
|
|
81
94
|
{...props}
|
|
82
95
|
initialNumberToLoad={
|
|
83
|
-
|
|
96
|
+
// Recomputed on every render, so the count follows the components
|
|
97
|
+
// even though the manager settled its own expectation at mount.
|
|
98
|
+
disableIncrementalLoading
|
|
99
|
+
? componentsToRender.length
|
|
100
|
+
: managerRef.current.numberOfComponentsWaitToLoadBeforePresent
|
|
84
101
|
}
|
|
85
102
|
onLoadFinishedFromScreenRevealManager={
|
|
86
103
|
managerRef.current.onLoadFinished
|
|
@@ -7,7 +7,7 @@ import { useMarginTop } from "./hooks";
|
|
|
7
7
|
|
|
8
8
|
interface IProps {
|
|
9
9
|
targetScreenId?: string;
|
|
10
|
-
children
|
|
10
|
+
children: React.ReactElement | null;
|
|
11
11
|
applyTopCutoff?: boolean;
|
|
12
12
|
}
|
|
13
13
|
|
|
@@ -21,7 +21,7 @@ export const TopCutoffOverlay: React.FC<IProps> = ({
|
|
|
21
21
|
targetScreenId,
|
|
22
22
|
children,
|
|
23
23
|
applyTopCutoff = true,
|
|
24
|
-
}
|
|
24
|
+
}) => {
|
|
25
25
|
const cutoffHeight = useMarginTop(targetScreenId);
|
|
26
26
|
|
|
27
27
|
const { backgroundColor: screenBackgroundColor } =
|
|
@@ -66,7 +66,7 @@ export class AnimationManager {
|
|
|
66
66
|
*
|
|
67
67
|
* @param {object} to contains style to animate and scenes index
|
|
68
68
|
* @param {string} action push|back
|
|
69
|
-
* @param {number} stepsBack number of steps back
|
|
69
|
+
* @param {number} [stepsBack] number of steps back, used by the back action only
|
|
70
70
|
*/
|
|
71
71
|
stateForAction({ to, scenes }, action, stepsBack) {
|
|
72
72
|
let rootIndex = to.index;
|
|
@@ -17,13 +17,14 @@ const fullWidthDimensions = {
|
|
|
17
17
|
type Props = {
|
|
18
18
|
children: any;
|
|
19
19
|
style: any;
|
|
20
|
-
pointerEvents
|
|
21
|
-
overlayStyle
|
|
22
|
-
animating
|
|
20
|
+
pointerEvents?: ViewProps["pointerEvents"];
|
|
21
|
+
overlayStyle?: ViewStyle;
|
|
22
|
+
animating?: boolean;
|
|
23
23
|
contentStyle: ViewStyle;
|
|
24
24
|
pathname: string;
|
|
25
25
|
isActive: boolean;
|
|
26
26
|
screenData: NavigationScreenData;
|
|
27
|
+
screenUniqueId?: string;
|
|
27
28
|
};
|
|
28
29
|
|
|
29
30
|
export function CurrentScreenContextProvider({
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { View } from "react-native";
|
|
3
|
-
import { append, compose, identity,
|
|
3
|
+
import { append, compose, identity, tail, update } from "ramda";
|
|
4
4
|
|
|
5
5
|
import { AnimationManager } from "./AnimationManager";
|
|
6
6
|
import { Scene } from "./Scene";
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
shouldSkipAnimationForPreviousWebViewScene,
|
|
11
11
|
} from "./utils";
|
|
12
12
|
import { v4 as uuid_v4 } from "uuid";
|
|
13
|
+
import { isScreenActiveForRoute } from "@applicaster/zapp-react-native-utils/reactHooks/navigation/useIsScreenActive";
|
|
13
14
|
|
|
14
15
|
export const NAV_ACTION_PUSH = "PUSH";
|
|
15
16
|
|
|
@@ -17,11 +18,23 @@ export const NAV_ACTION_REPLACE = "REPLACE";
|
|
|
17
18
|
|
|
18
19
|
export const NAV_ACTION_BACK = "POP";
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
const RIVER_SEGMENT_REGEX = /river\//g;
|
|
22
|
+
|
|
23
|
+
// Number of "river/" segments in the route, i.e. its depth in the navigation stack
|
|
24
|
+
function countRiverSegments(route?: string): number {
|
|
25
|
+
return (route?.match(RIVER_SEGMENT_REGEX) || []).length;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// The screen element rendered for the current route
|
|
29
|
+
type SceneChild = React.ReactElement<{
|
|
30
|
+
pathname: string;
|
|
31
|
+
screenData: NavigationScreenData;
|
|
32
|
+
}>;
|
|
33
|
+
|
|
34
|
+
type TransitionerScene = {
|
|
35
|
+
children: SceneChild;
|
|
36
|
+
key: string;
|
|
37
|
+
screenUniqueId: string;
|
|
25
38
|
};
|
|
26
39
|
|
|
27
40
|
/**
|
|
@@ -30,7 +43,7 @@ type SceneProps = {
|
|
|
30
43
|
* @param {Object} children
|
|
31
44
|
* @returns { children: Object, key: string }
|
|
32
45
|
*/
|
|
33
|
-
function prepareScene(children) {
|
|
46
|
+
function prepareScene(children: SceneChild): TransitionerScene {
|
|
34
47
|
return {
|
|
35
48
|
children,
|
|
36
49
|
key: children.props.pathname,
|
|
@@ -44,22 +57,26 @@ function prepareScene(children) {
|
|
|
44
57
|
* @param {any} props Component's props
|
|
45
58
|
* @param {any} state Component's state
|
|
46
59
|
*/
|
|
47
|
-
function scenesForBackTransition(
|
|
60
|
+
function scenesForBackTransition(
|
|
61
|
+
props: Pick<Props, "children">,
|
|
62
|
+
{ scenes }: Pick<State, "scenes">
|
|
63
|
+
): TransitionerScene[] {
|
|
48
64
|
return scenes.length > 1
|
|
49
65
|
? identity(scenes)
|
|
50
66
|
: [prepareScene(props.children), scenes[0]];
|
|
51
67
|
}
|
|
52
68
|
|
|
53
|
-
const isModalClosed = (navigator) => {
|
|
54
|
-
return !!isNil(navigator?.modalData);
|
|
55
|
-
};
|
|
56
|
-
|
|
57
69
|
type Props = {
|
|
58
70
|
transitionConfig: any;
|
|
59
|
-
|
|
71
|
+
isRTL?: boolean;
|
|
72
|
+
children: SceneChild;
|
|
60
73
|
navigator: {
|
|
61
74
|
previousAction: string;
|
|
62
75
|
currentRoute: string;
|
|
76
|
+
videoModalState?: {
|
|
77
|
+
visible?: boolean;
|
|
78
|
+
mode?: string;
|
|
79
|
+
};
|
|
63
80
|
screenData: {
|
|
64
81
|
[key: string]: any;
|
|
65
82
|
};
|
|
@@ -77,13 +94,12 @@ type Props = {
|
|
|
77
94
|
};
|
|
78
95
|
|
|
79
96
|
type State = {
|
|
80
|
-
animatedValue: any;
|
|
81
97
|
animating: boolean;
|
|
82
98
|
duration: number;
|
|
83
99
|
easing: any;
|
|
84
100
|
from: any;
|
|
85
101
|
to: any;
|
|
86
|
-
scenes:
|
|
102
|
+
scenes: TransitionerScene[];
|
|
87
103
|
};
|
|
88
104
|
|
|
89
105
|
const styles = {
|
|
@@ -91,11 +107,18 @@ const styles = {
|
|
|
91
107
|
} as const;
|
|
92
108
|
|
|
93
109
|
export class TransitionerComponent extends React.PureComponent<Props, State> {
|
|
110
|
+
private animationManager: AnimationManager;
|
|
111
|
+
|
|
112
|
+
private transitionId: number;
|
|
113
|
+
|
|
94
114
|
constructor(props: Props) {
|
|
95
115
|
super(props);
|
|
96
116
|
|
|
97
117
|
this.animationManager = new AnimationManager(props);
|
|
98
118
|
|
|
119
|
+
// Bumped by every animated transition; end callbacks of older ones are ignored
|
|
120
|
+
this.transitionId = 0;
|
|
121
|
+
|
|
99
122
|
this.state = {
|
|
100
123
|
scenes: [prepareScene(props.children)], // starting with index: 0
|
|
101
124
|
...this.animationManager.initialState(),
|
|
@@ -112,29 +135,36 @@ export class TransitionerComponent extends React.PureComponent<Props, State> {
|
|
|
112
135
|
* and trigger push animation with callbacks.
|
|
113
136
|
*/
|
|
114
137
|
pushTransitionStart() {
|
|
138
|
+
const transitionId = ++this.transitionId;
|
|
139
|
+
|
|
115
140
|
this.setState(
|
|
116
141
|
{
|
|
117
|
-
|
|
142
|
+
// Append right after the visible scene: stateForAction(PUSH) animates to.index + 1
|
|
143
|
+
scenes: [
|
|
144
|
+
...this.state.scenes.slice(0, this.state.to.index + 1),
|
|
145
|
+
prepareScene(this.props.children),
|
|
146
|
+
],
|
|
118
147
|
...this.animationManager.stateForAction(this.state, NAV_ACTION_PUSH),
|
|
119
148
|
},
|
|
120
149
|
() => {
|
|
121
|
-
this.animationManager.animate(this.state,
|
|
150
|
+
this.animationManager.animate(this.state, () =>
|
|
151
|
+
this.pushTransitionEnd(transitionId)
|
|
152
|
+
);
|
|
122
153
|
}
|
|
123
154
|
);
|
|
124
155
|
}
|
|
125
156
|
|
|
126
157
|
/**
|
|
127
158
|
* Trigger back animation.
|
|
128
|
-
* The
|
|
159
|
+
* The scenes after the target one are removed in the "backTransitionEnd" callback,
|
|
129
160
|
* only after the animation is complete.
|
|
130
161
|
*/
|
|
131
|
-
backTransitionStart() {
|
|
132
|
-
const
|
|
162
|
+
backTransitionStart(previousRoute: string) {
|
|
163
|
+
const transitionId = ++this.transitionId;
|
|
133
164
|
const currentRoute = this.props.navigator?.currentRoute;
|
|
134
165
|
|
|
135
166
|
const diffLengthRoutes =
|
|
136
|
-
(previousRoute
|
|
137
|
-
(currentRoute?.match(/river\//g) || []).length;
|
|
167
|
+
countRiverSegments(previousRoute) - countRiverSegments(currentRoute);
|
|
138
168
|
|
|
139
169
|
const stepsBack =
|
|
140
170
|
diffLengthRoutes && diffLengthRoutes > 0 ? diffLengthRoutes : 1;
|
|
@@ -150,30 +180,32 @@ export class TransitionerComponent extends React.PureComponent<Props, State> {
|
|
|
150
180
|
},
|
|
151
181
|
() => {
|
|
152
182
|
this.animationManager.animate(this.state, () =>
|
|
153
|
-
this.backTransitionEnd(
|
|
183
|
+
this.backTransitionEnd(transitionId)
|
|
154
184
|
);
|
|
155
185
|
}
|
|
156
186
|
);
|
|
157
187
|
}
|
|
158
188
|
|
|
159
|
-
shouldSkipAnimationForRoute(route) {
|
|
189
|
+
shouldSkipAnimationForRoute(route: string) {
|
|
160
190
|
// We are skipping animations for some routes, likes hooks & the player mainly
|
|
161
191
|
|
|
162
192
|
return route.includes("/playable") || route.includes("/hook");
|
|
163
193
|
}
|
|
164
194
|
|
|
165
|
-
shouldResetStateForRoute(route) {
|
|
195
|
+
shouldResetStateForRoute(route: string) {
|
|
166
196
|
// We are resetting the transitioner state for root routes
|
|
167
197
|
|
|
168
|
-
return (route
|
|
198
|
+
return countRiverSegments(route) === 1;
|
|
169
199
|
}
|
|
170
200
|
|
|
171
|
-
transitionWithoutAnimation(resetState) {
|
|
172
|
-
|
|
201
|
+
transitionWithoutAnimation(resetState?: boolean) {
|
|
202
|
+
// Scenes after the visible one are only leaving (back animation in flight),
|
|
203
|
+
// so the new scene replaces the one being backed to
|
|
204
|
+
const scenes = this.state.scenes.slice(0, this.state.to.index + 1);
|
|
173
205
|
const newScene = prepareScene(this.props.children);
|
|
174
206
|
const isLastSceneHook = scenes[scenes.length - 1].key.startsWith("/hook");
|
|
175
207
|
|
|
176
|
-
let newState
|
|
208
|
+
let newState: Pick<State, "scenes"> | Pick<State, "scenes" | "to">;
|
|
177
209
|
|
|
178
210
|
if (resetState) {
|
|
179
211
|
newState = {
|
|
@@ -241,7 +273,7 @@ export class TransitionerComponent extends React.PureComponent<Props, State> {
|
|
|
241
273
|
break;
|
|
242
274
|
|
|
243
275
|
case NAV_ACTION_BACK: {
|
|
244
|
-
this.backTransitionStart();
|
|
276
|
+
this.backTransitionStart(previousRoute);
|
|
245
277
|
break;
|
|
246
278
|
}
|
|
247
279
|
|
|
@@ -263,28 +295,37 @@ export class TransitionerComponent extends React.PureComponent<Props, State> {
|
|
|
263
295
|
}
|
|
264
296
|
}
|
|
265
297
|
|
|
266
|
-
// Sets state.animating to false
|
|
267
|
-
|
|
298
|
+
// Sets state.animating to false,
|
|
299
|
+
// unless a newer transition has started since this one
|
|
300
|
+
pushTransitionEnd(transitionId: number) {
|
|
301
|
+
if (transitionId !== this.transitionId) return;
|
|
302
|
+
|
|
268
303
|
this.setState({
|
|
269
304
|
animating: false,
|
|
270
305
|
});
|
|
271
306
|
}
|
|
272
307
|
|
|
273
308
|
// Sets state.animating to false
|
|
274
|
-
// and
|
|
275
|
-
|
|
276
|
-
|
|
309
|
+
// and drops every scene after the target one. Reads the latest state,
|
|
310
|
+
// so it's correct however many backs were merged into this animation.
|
|
311
|
+
// Ignored if a newer transition has started since this one
|
|
312
|
+
backTransitionEnd(transitionId: number) {
|
|
313
|
+
if (transitionId !== this.transitionId) return;
|
|
314
|
+
|
|
315
|
+
this.setState(({ scenes, to }) => ({
|
|
277
316
|
animating: false,
|
|
278
|
-
scenes:
|
|
279
|
-
});
|
|
317
|
+
scenes: scenes.slice(0, to.index + 1),
|
|
318
|
+
}));
|
|
280
319
|
}
|
|
281
320
|
|
|
282
321
|
// On initial state, both "to" and "from" point to a single scene
|
|
283
322
|
// so only a single scene should be rendered,
|
|
284
323
|
// instead of dangerous nulls or duplicates.
|
|
285
324
|
renderSingleScene({ scenes, to }) {
|
|
286
|
-
const { contentStyle } = this.props;
|
|
287
|
-
|
|
325
|
+
const { contentStyle, navigator, children } = this.props;
|
|
326
|
+
|
|
327
|
+
const { currentRoute, videoModalState } = navigator;
|
|
328
|
+
const screenData = children.props.screenData;
|
|
288
329
|
const pathname = scenes[to.index].key;
|
|
289
330
|
|
|
290
331
|
return (
|
|
@@ -293,7 +334,11 @@ export class TransitionerComponent extends React.PureComponent<Props, State> {
|
|
|
293
334
|
<Scene
|
|
294
335
|
{...{ style: to?.style || {} }}
|
|
295
336
|
pathname={pathname}
|
|
296
|
-
isActive={
|
|
337
|
+
isActive={isScreenActiveForRoute(
|
|
338
|
+
pathname,
|
|
339
|
+
currentRoute,
|
|
340
|
+
videoModalState
|
|
341
|
+
)}
|
|
297
342
|
contentStyle={contentStyle}
|
|
298
343
|
key={scenes[to.index].key}
|
|
299
344
|
screenUniqueId={scenes[to.index].screenUniqueId}
|
|
@@ -311,16 +356,19 @@ export class TransitionerComponent extends React.PureComponent<Props, State> {
|
|
|
311
356
|
// Looks redundant, but when written like this
|
|
312
357
|
// we do not need to pass or generate keys.
|
|
313
358
|
renderScenes({ scenes, from, to }) {
|
|
314
|
-
const { contentStyle } = this.props;
|
|
359
|
+
const { contentStyle, navigator } = this.props;
|
|
360
|
+
|
|
361
|
+
const { currentRoute, videoModalState } = navigator;
|
|
315
362
|
|
|
316
363
|
const fromScene = scenes[from.index] && (
|
|
317
364
|
<Scene
|
|
318
365
|
key={scenes[from.index].key}
|
|
319
366
|
pathname={scenes[from.index].key}
|
|
320
|
-
isActive={
|
|
321
|
-
scenes[from.index].key
|
|
322
|
-
|
|
323
|
-
|
|
367
|
+
isActive={isScreenActiveForRoute(
|
|
368
|
+
scenes[from.index].key,
|
|
369
|
+
currentRoute,
|
|
370
|
+
videoModalState
|
|
371
|
+
)}
|
|
324
372
|
style={from.style}
|
|
325
373
|
pointerEvents="none"
|
|
326
374
|
overlayStyle={from.overlayStyle}
|
|
@@ -336,10 +384,11 @@ export class TransitionerComponent extends React.PureComponent<Props, State> {
|
|
|
336
384
|
const toScene = scenes[to.index] && (
|
|
337
385
|
<Scene
|
|
338
386
|
pathname={scenes[to.index].key}
|
|
339
|
-
isActive={
|
|
340
|
-
scenes[to.index].key
|
|
341
|
-
|
|
342
|
-
|
|
387
|
+
isActive={isScreenActiveForRoute(
|
|
388
|
+
scenes[to.index].key,
|
|
389
|
+
currentRoute,
|
|
390
|
+
videoModalState
|
|
391
|
+
)}
|
|
343
392
|
key={scenes[to.index].key}
|
|
344
393
|
style={to.style}
|
|
345
394
|
overlayStyle={to.overlayStyle}
|