@applicaster/zapp-react-native-ui-components 12.0.0-alpha.5606245605 → 12.0.0-alpha.5675222257
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/Cell/Cell.tsx +2 -2
- package/Components/Cell/CellWithFocusable.tsx +21 -14
- package/Components/Cell/TvOSCellComponent.tsx +2 -2
- package/Components/FocusableCell/index.tsx +7 -7
- package/Components/HookRenderer/index.tsx +1 -3
- package/Components/Image/utils/index.ts +21 -11
- package/Components/Layout/TV/__tests__/index.test.tsx +1 -13
- package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +14 -1
- package/Components/MasterCell/DefaultComponents/Toggle.tsx +5 -1
- package/Components/MasterCell/utils/index.ts +18 -7
- package/Components/PlayerContainer/PlayerContainer.tsx +56 -29
- package/Components/PlayerImageBackground/index.tsx +34 -8
- package/Components/River/__tests__/componentsMap.test.js +7 -0
- package/Components/Screen/__tests__/Screen.test.tsx +5 -1
- package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +10 -2
- package/Components/Screen/index.tsx +15 -13
- package/Components/Tabs/TV/styles.ts +1 -1
- package/Components/VideoLive/__tests__/PlayerLiveImageComponent.test.tsx +25 -5
- package/Components/VideoModal/ModalAnimation/AnimatedPlayerModalWrapper.tsx +78 -0
- package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +335 -0
- package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.tsx +144 -0
- package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +438 -0
- package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +143 -0
- package/Components/VideoModal/ModalAnimation/index.ts +15 -0
- package/Components/VideoModal/ModalAnimation/utils.ts +299 -0
- package/Components/VideoModal/PlayerWrapper.tsx +64 -41
- package/Components/VideoModal/VideoModal.tsx +8 -25
- package/Components/VideoModal/__tests__/PlayerWrapper.test.tsx +6 -1
- package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +246 -166
- package/Components/VideoModal/utils.ts +3 -3
- package/Decorators/ComponentsMapWrapper/withComponentsMapProvider.tsx +7 -2
- package/package.json +5 -5
- package/Components/VideoModal/hooks/usePosition.ts +0 -50
package/Components/Cell/Cell.tsx
CHANGED
|
@@ -202,7 +202,7 @@ export class CellComponent extends React.Component<Props> {
|
|
|
202
202
|
groupId,
|
|
203
203
|
isFocusable = true,
|
|
204
204
|
skipFocusManagerRegistration,
|
|
205
|
-
behavior
|
|
205
|
+
behavior,
|
|
206
206
|
} = this.props;
|
|
207
207
|
|
|
208
208
|
const { id } = item;
|
|
@@ -263,7 +263,7 @@ export class CellComponent extends React.Component<Props> {
|
|
|
263
263
|
item,
|
|
264
264
|
focused: this.isCellFocused(focused),
|
|
265
265
|
scrollTo: this.scrollToIndex(event),
|
|
266
|
-
behavior
|
|
266
|
+
behavior,
|
|
267
267
|
}}
|
|
268
268
|
/>
|
|
269
269
|
);
|
|
@@ -35,18 +35,18 @@ const useCellFocusedState = (groupId: string, id: string) => {
|
|
|
35
35
|
};
|
|
36
36
|
|
|
37
37
|
type Props = {
|
|
38
|
-
item: ZappEntry
|
|
39
|
-
CellRenderer: React.ComponentType<{ item: Object
|
|
40
|
-
id: string
|
|
41
|
-
groupId: string
|
|
42
|
-
onFocus: Function
|
|
43
|
-
index: number
|
|
44
|
-
scrollTo: Function
|
|
45
|
-
preferredFocus?: boolean
|
|
46
|
-
skipFocusManagerRegistration?: boolean
|
|
47
|
-
isFocusable?: boolean
|
|
48
|
-
behavior: Behavior
|
|
49
|
-
selected?: boolean
|
|
38
|
+
item: ZappEntry;
|
|
39
|
+
CellRenderer: React.ComponentType<{ item: Object; state: string }>;
|
|
40
|
+
id: string;
|
|
41
|
+
groupId: string;
|
|
42
|
+
onFocus: Function;
|
|
43
|
+
index: number;
|
|
44
|
+
scrollTo: Function;
|
|
45
|
+
preferredFocus?: boolean;
|
|
46
|
+
skipFocusManagerRegistration?: boolean;
|
|
47
|
+
isFocusable?: boolean;
|
|
48
|
+
behavior: Behavior;
|
|
49
|
+
selected?: boolean;
|
|
50
50
|
};
|
|
51
51
|
|
|
52
52
|
export function CellWithFocusable(props: Props) {
|
|
@@ -62,11 +62,18 @@ export function CellWithFocusable(props: Props) {
|
|
|
62
62
|
skipFocusManagerRegistration,
|
|
63
63
|
isFocusable,
|
|
64
64
|
behavior,
|
|
65
|
-
selected
|
|
65
|
+
selected,
|
|
66
66
|
} = props;
|
|
67
67
|
|
|
68
68
|
const isFocused = useCellFocusedState(groupId, id);
|
|
69
|
-
|
|
69
|
+
|
|
70
|
+
const state = useCellState({
|
|
71
|
+
id: item.id,
|
|
72
|
+
behavior,
|
|
73
|
+
focused: isFocused,
|
|
74
|
+
selected,
|
|
75
|
+
});
|
|
76
|
+
|
|
70
77
|
const [focusedButtonId, setFocusedButtonId] = React.useState(undefined);
|
|
71
78
|
|
|
72
79
|
// for horizontal scrolling
|
|
@@ -249,7 +249,7 @@ export class TvOSCellComponent extends React.Component<Props, State> {
|
|
|
249
249
|
hasReceivedFocus,
|
|
250
250
|
groupId,
|
|
251
251
|
isFocusable,
|
|
252
|
-
behavior
|
|
252
|
+
behavior,
|
|
253
253
|
} = this.props;
|
|
254
254
|
|
|
255
255
|
const { id } = item;
|
|
@@ -310,7 +310,7 @@ export class TvOSCellComponent extends React.Component<Props, State> {
|
|
|
310
310
|
item,
|
|
311
311
|
focused: this.props.focused || selectedCell || focused,
|
|
312
312
|
scrollTo: this.scrollTo,
|
|
313
|
-
behavior
|
|
313
|
+
behavior,
|
|
314
314
|
}}
|
|
315
315
|
/>
|
|
316
316
|
);
|
|
@@ -3,12 +3,12 @@ import { Platform } from "react-native";
|
|
|
3
3
|
import { useCellState } from "../MasterCell/utils";
|
|
4
4
|
|
|
5
5
|
type Props = {
|
|
6
|
-
index: number
|
|
7
|
-
item: ZappEntry
|
|
8
|
-
focused: boolean
|
|
9
|
-
scrollTo?: (index: number) => void
|
|
10
|
-
CellRenderer: React.ComponentType<{ item: Object
|
|
11
|
-
behavior: Behavior
|
|
6
|
+
index: number;
|
|
7
|
+
item: ZappEntry;
|
|
8
|
+
focused: boolean;
|
|
9
|
+
scrollTo?: (index: number) => void;
|
|
10
|
+
CellRenderer: React.ComponentType<{ item: Object; state: string }>;
|
|
11
|
+
behavior: Behavior;
|
|
12
12
|
};
|
|
13
13
|
|
|
14
14
|
const isAndroid = Platform.OS === "android";
|
|
@@ -20,7 +20,7 @@ export function FocusableCell(props: Props) {
|
|
|
20
20
|
CellRenderer,
|
|
21
21
|
focused,
|
|
22
22
|
scrollTo = null,
|
|
23
|
-
behavior
|
|
23
|
+
behavior,
|
|
24
24
|
} = props;
|
|
25
25
|
|
|
26
26
|
const state = useCellState({ id: item.id, behavior, focused });
|
|
@@ -1,19 +1,29 @@
|
|
|
1
|
+
import FastImage, { Source } from "@applicaster/react-native-fast-image";
|
|
1
2
|
import { useMemo } from "react";
|
|
3
|
+
import { ImageRequireSource } from "react-native";
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
function getSourceCache(cache: Source["cache"]) {
|
|
6
|
+
return cache || FastImage.cacheControl.web;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const useImageSource = (source?: Source | ImageRequireSource) => {
|
|
4
10
|
return useMemo(() => {
|
|
5
|
-
if (
|
|
6
|
-
|
|
11
|
+
if (source) {
|
|
12
|
+
if (typeof source === "number") {
|
|
13
|
+
return source;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return {
|
|
17
|
+
uri: source.uri,
|
|
18
|
+
headers: source.headers,
|
|
19
|
+
priority: source.priority,
|
|
20
|
+
cache: getSourceCache(source?.cache),
|
|
21
|
+
maxWidth: source.maxWidth,
|
|
22
|
+
maxHeight: source.maxHeight,
|
|
23
|
+
};
|
|
7
24
|
}
|
|
8
25
|
|
|
9
|
-
return
|
|
10
|
-
uri: source.uri,
|
|
11
|
-
headers: source.headers,
|
|
12
|
-
priority: source.priority,
|
|
13
|
-
cache: source.cache,
|
|
14
|
-
maxWidth: source.maxWidth,
|
|
15
|
-
maxHeight: source.maxHeight,
|
|
16
|
-
};
|
|
26
|
+
return undefined;
|
|
17
27
|
}, [
|
|
18
28
|
...(typeof source === "object"
|
|
19
29
|
? [
|
|
@@ -12,19 +12,7 @@ jest.mock("@applicaster/quick-brick-core/App/ActionSetters", () => ({
|
|
|
12
12
|
useRiverInitialState: () => ({}),
|
|
13
13
|
}));
|
|
14
14
|
|
|
15
|
-
jest.mock("@applicaster/zapp-react-native-utils/reactHooks/screen"
|
|
16
|
-
useCurrentScreenData: jest.fn(() => ({
|
|
17
|
-
navigations: [
|
|
18
|
-
{
|
|
19
|
-
category: "menu",
|
|
20
|
-
navigation_type: "menu",
|
|
21
|
-
styles: {
|
|
22
|
-
hide_secondary_level_menu: false,
|
|
23
|
-
},
|
|
24
|
-
},
|
|
25
|
-
],
|
|
26
|
-
})),
|
|
27
|
-
}));
|
|
15
|
+
jest.mock("@applicaster/zapp-react-native-utils/reactHooks/screen");
|
|
28
16
|
|
|
29
17
|
const Layout = require("..").default;
|
|
30
18
|
|
|
@@ -177,10 +177,23 @@ const getPlayerConfig = (player_screen_id, actionIdentifier) => {
|
|
|
177
177
|
const positionAbsolute: ViewStyle = { position: "absolute" };
|
|
178
178
|
|
|
179
179
|
const LiveImageComponent = (props: LiveImageProps) => {
|
|
180
|
-
const {
|
|
180
|
+
const {
|
|
181
|
+
item,
|
|
182
|
+
style: componentStyle,
|
|
183
|
+
cellUUID,
|
|
184
|
+
imageKey,
|
|
185
|
+
actionIdentifier,
|
|
186
|
+
state,
|
|
187
|
+
} = props;
|
|
181
188
|
|
|
182
189
|
const component = useUIComponentContext();
|
|
183
190
|
|
|
191
|
+
// Fix for blinking on state change
|
|
192
|
+
const style = React.useMemo(
|
|
193
|
+
() => ({ ...componentStyle, backgroundColor: "transparent" }),
|
|
194
|
+
[componentStyle]
|
|
195
|
+
);
|
|
196
|
+
|
|
184
197
|
const componentType = React.useMemo(
|
|
185
198
|
() => getPropComponentType(component),
|
|
186
199
|
[component?.id]
|
|
@@ -23,7 +23,11 @@ export const Toggle = (props: Props) => {
|
|
|
23
23
|
iosBackgroundColor,
|
|
24
24
|
} = style;
|
|
25
25
|
|
|
26
|
-
const isSelected = React.useMemo(
|
|
26
|
+
const isSelected = React.useMemo(
|
|
27
|
+
() => cellState === "selected",
|
|
28
|
+
[item?.id, cellState]
|
|
29
|
+
);
|
|
30
|
+
|
|
27
31
|
const actionContext = useActions(action?.identifier);
|
|
28
32
|
|
|
29
33
|
const [actionState, setActionState] = useState(
|
|
@@ -125,13 +125,24 @@ export const useFilterChildren = <
|
|
|
125
125
|
|
|
126
126
|
const filteredChildren = children.filter((child) => {
|
|
127
127
|
const item = child.props.item;
|
|
128
|
-
const
|
|
128
|
+
const actionIdentifier = child.props.pluginIdentifier;
|
|
129
|
+
const action = actions.actions[actionIdentifier];
|
|
130
|
+
|
|
129
131
|
// context value of specific plugin
|
|
130
|
-
|
|
132
|
+
if (action?.module && action.module.context) {
|
|
133
|
+
const currentValue = action.module.context._currentValue;
|
|
134
|
+
|
|
135
|
+
return currentValue?.isActionAvailable
|
|
136
|
+
? currentValue.isActionAvailable(item)
|
|
137
|
+
: true;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
masterCellLogger.error({
|
|
141
|
+
message: `Action plugin for ${actionIdentifier} could not be found, check the configuration of your action button`,
|
|
142
|
+
data: { item, action: child.props.pluginIdentifier },
|
|
143
|
+
});
|
|
131
144
|
|
|
132
|
-
return
|
|
133
|
-
? currentValue.isActionAvailable(item)
|
|
134
|
-
: true;
|
|
145
|
+
return false;
|
|
135
146
|
});
|
|
136
147
|
|
|
137
148
|
return filteredChildren;
|
|
@@ -285,8 +296,8 @@ export const useBehaviorUpdate = (behavior: Behavior) => {
|
|
|
285
296
|
}
|
|
286
297
|
}
|
|
287
298
|
}, [behavior]);
|
|
288
|
-
|
|
289
|
-
|
|
299
|
+
|
|
300
|
+
useEffect(() => {
|
|
290
301
|
if (!behavior) {
|
|
291
302
|
return;
|
|
292
303
|
}
|
|
@@ -54,6 +54,8 @@ import { toNumber } from "@applicaster/zapp-react-native-utils/numberUtils";
|
|
|
54
54
|
import { usePlayNextOverlay } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayNextOverlay";
|
|
55
55
|
import { PlayNextState } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/OverlayObserver/OverlaysObserver";
|
|
56
56
|
|
|
57
|
+
import { useModalAnimationContext } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
|
|
58
|
+
|
|
57
59
|
type Props = {
|
|
58
60
|
Player: React.ComponentType<any>;
|
|
59
61
|
PlayerLoadingView?: React.ComponentType<any>; // 👀 we are not receiving this prop
|
|
@@ -145,34 +147,30 @@ const renderApplePlayer = ({
|
|
|
145
147
|
}) => {
|
|
146
148
|
const { title, summary } = item || {};
|
|
147
149
|
|
|
148
|
-
if (!
|
|
150
|
+
if (!isAppleTV() || !player) {
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (isAudioContent) {
|
|
155
|
+
return (
|
|
156
|
+
<AudioPlayer
|
|
157
|
+
audio_item={item}
|
|
158
|
+
plugin_configuration={pluginConfiguration}
|
|
159
|
+
/>
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (!playNextData && player.isPaused() && player.isAd() === false) {
|
|
149
164
|
return null;
|
|
150
165
|
}
|
|
151
166
|
|
|
152
167
|
return (
|
|
153
|
-
|
|
154
|
-
{
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
<ProgramInfo
|
|
160
|
-
title={title}
|
|
161
|
-
subtitle={summary}
|
|
162
|
-
plugin_configuration={pluginConfiguration}
|
|
163
|
-
videoStyle={videoStyle}
|
|
164
|
-
/>
|
|
165
|
-
)}
|
|
166
|
-
</>
|
|
167
|
-
)}
|
|
168
|
-
|
|
169
|
-
{isAudioContent && (
|
|
170
|
-
<AudioPlayer
|
|
171
|
-
audio_item={item}
|
|
172
|
-
plugin_configuration={pluginConfiguration}
|
|
173
|
-
/>
|
|
174
|
-
)}
|
|
175
|
-
</>
|
|
168
|
+
<ProgramInfo
|
|
169
|
+
title={title}
|
|
170
|
+
subtitle={summary}
|
|
171
|
+
plugin_configuration={pluginConfiguration}
|
|
172
|
+
videoStyle={videoStyle}
|
|
173
|
+
/>
|
|
176
174
|
);
|
|
177
175
|
};
|
|
178
176
|
|
|
@@ -339,6 +337,18 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
339
337
|
}
|
|
340
338
|
}, [item?.id, item?.extensions?.resumeTime, player]);
|
|
341
339
|
|
|
340
|
+
const onVideoFullscreenPlayerWillPresent = React.useCallback(() => {
|
|
341
|
+
playerManager.invokeHandler("toggleFullscreen", {
|
|
342
|
+
fullscreen: true,
|
|
343
|
+
});
|
|
344
|
+
}, []);
|
|
345
|
+
|
|
346
|
+
const onVideoFullscreenPlayerWillDismiss = React.useCallback(() => {
|
|
347
|
+
playerManager.invokeHandler("toggleFullscreen", {
|
|
348
|
+
fullscreen: false,
|
|
349
|
+
});
|
|
350
|
+
}, []);
|
|
351
|
+
|
|
342
352
|
// Util methods
|
|
343
353
|
const toggleFullscreen = (event) => {
|
|
344
354
|
const { fullscreen = false } = event || {};
|
|
@@ -381,17 +391,27 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
381
391
|
id: playerContainerId,
|
|
382
392
|
listener: {
|
|
383
393
|
onVideoEnd,
|
|
384
|
-
onError
|
|
385
|
-
onLoad
|
|
394
|
+
onError,
|
|
395
|
+
onLoad,
|
|
386
396
|
onPlayerClose: close,
|
|
387
397
|
onPlayerDetached: close,
|
|
398
|
+
onVideoFullscreenPlayerWillDismiss,
|
|
399
|
+
onVideoFullscreenPlayerWillPresent,
|
|
388
400
|
},
|
|
389
401
|
});
|
|
390
402
|
|
|
391
403
|
return () => {
|
|
392
404
|
player.removeListener(playerContainerId);
|
|
393
405
|
};
|
|
394
|
-
}, [
|
|
406
|
+
}, [
|
|
407
|
+
player,
|
|
408
|
+
onVideoEnd,
|
|
409
|
+
onError,
|
|
410
|
+
onLoad,
|
|
411
|
+
close,
|
|
412
|
+
onVideoFullscreenPlayerWillDismiss,
|
|
413
|
+
onVideoFullscreenPlayerWillPresent,
|
|
414
|
+
]);
|
|
395
415
|
|
|
396
416
|
useEffect(() => {
|
|
397
417
|
// TODO: We should not use playerManager here to connect buttons to player container
|
|
@@ -580,6 +600,9 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
580
600
|
pluginConfiguration,
|
|
581
601
|
};
|
|
582
602
|
|
|
603
|
+
const { isActiveGesture, startComponentsAnimation } =
|
|
604
|
+
useModalAnimationContext();
|
|
605
|
+
|
|
583
606
|
return (
|
|
584
607
|
<PlayerStateContext.Provider value={value}>
|
|
585
608
|
<PlayerContainerContextProvider
|
|
@@ -621,9 +644,13 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
621
644
|
}}
|
|
622
645
|
focused={isInlineTV ? true : undefined}
|
|
623
646
|
autoplay={true}
|
|
624
|
-
controls={
|
|
647
|
+
controls={false}
|
|
625
648
|
disableCastAction={disableCastAction}
|
|
626
|
-
docked={
|
|
649
|
+
docked={
|
|
650
|
+
navigator.isVideoModalDocked() &&
|
|
651
|
+
!startComponentsAnimation &&
|
|
652
|
+
!isActiveGesture
|
|
653
|
+
}
|
|
627
654
|
entry={item}
|
|
628
655
|
fullscreen={mode === VideoModalMode.FULLSCREEN}
|
|
629
656
|
inline={inline}
|
|
@@ -1,38 +1,64 @@
|
|
|
1
1
|
import React, { PropsWithChildren } from "react";
|
|
2
|
-
import { ImageBackground } from "react-native";
|
|
2
|
+
import { ImageBackground, View } from "react-native";
|
|
3
3
|
|
|
4
4
|
import { imageSrcFromMediaItem } from "@applicaster/zapp-react-native-utils/configurationUtils";
|
|
5
|
+
import {
|
|
6
|
+
AnimationComponent,
|
|
7
|
+
ComponentAnimationType,
|
|
8
|
+
useModalAnimationContext,
|
|
9
|
+
PlayerAnimationStateEnum,
|
|
10
|
+
} from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
|
|
5
11
|
|
|
6
12
|
type Props = PropsWithChildren<{
|
|
7
13
|
entry: ZappEntry;
|
|
8
14
|
style?: { [K: string]: any };
|
|
9
15
|
imageStyle?: { [K: string]: any };
|
|
10
16
|
imageKey?: string;
|
|
17
|
+
defaultImageDimensions?: { [K: string]: any };
|
|
11
18
|
}>;
|
|
12
19
|
|
|
20
|
+
const imageSize = { width: "100%", height: "100%" };
|
|
21
|
+
|
|
13
22
|
const PlayerImageBackgroundComponent = ({
|
|
14
23
|
entry,
|
|
15
24
|
children,
|
|
16
25
|
style,
|
|
17
26
|
imageStyle,
|
|
18
27
|
imageKey,
|
|
28
|
+
defaultImageDimensions,
|
|
19
29
|
}: Props) => {
|
|
20
30
|
const source = React.useMemo(
|
|
21
31
|
() => ({ uri: imageSrcFromMediaItem(entry, imageKey) }),
|
|
22
32
|
[imageKey, entry]
|
|
23
33
|
);
|
|
24
34
|
|
|
35
|
+
const { playerAnimationState } = useModalAnimationContext();
|
|
36
|
+
|
|
25
37
|
if (!source) return <>{children}</>;
|
|
26
38
|
|
|
27
39
|
return (
|
|
28
|
-
<
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
40
|
+
<View
|
|
41
|
+
style={
|
|
42
|
+
playerAnimationState === PlayerAnimationStateEnum.maximaze
|
|
43
|
+
? defaultImageDimensions
|
|
44
|
+
: style
|
|
45
|
+
}
|
|
33
46
|
>
|
|
34
|
-
|
|
35
|
-
|
|
47
|
+
<AnimationComponent
|
|
48
|
+
style={style}
|
|
49
|
+
animationType={ComponentAnimationType.player}
|
|
50
|
+
additionalData={defaultImageDimensions}
|
|
51
|
+
>
|
|
52
|
+
<ImageBackground
|
|
53
|
+
resizeMode="cover"
|
|
54
|
+
style={imageSize}
|
|
55
|
+
imageStyle={imageStyle}
|
|
56
|
+
source={source}
|
|
57
|
+
>
|
|
58
|
+
{children}
|
|
59
|
+
</ImageBackground>
|
|
60
|
+
</AnimationComponent>
|
|
61
|
+
</View>
|
|
36
62
|
);
|
|
37
63
|
};
|
|
38
64
|
|
|
@@ -6,6 +6,12 @@ import configureStore from "redux-mock-store";
|
|
|
6
6
|
|
|
7
7
|
import * as themeUtils from "@applicaster/zapp-react-native-utils/theme";
|
|
8
8
|
|
|
9
|
+
// silences the errors related to React-native-gesture-handler in tests
|
|
10
|
+
jest.mock(
|
|
11
|
+
"@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation",
|
|
12
|
+
() => () => null
|
|
13
|
+
);
|
|
14
|
+
|
|
9
15
|
jest.mock("react-native-safe-area-context", () => ({
|
|
10
16
|
useSafeAreaInsets: () => ({ top: 50 }),
|
|
11
17
|
}));
|
|
@@ -83,6 +89,7 @@ jest.mock("@applicaster/zapp-react-native-utils/reactHooks/navigation", () => ({
|
|
|
83
89
|
useNavigation: jest.fn(() => ({ currentRoute: "/river/A1234" })),
|
|
84
90
|
useRoute: jest.fn(() => ({ pathname: "/river/A1234", screenData })),
|
|
85
91
|
useProfilerLogging: jest.fn(),
|
|
92
|
+
useIsScreenActive: jest.fn().mockReturnValue(true),
|
|
86
93
|
}));
|
|
87
94
|
|
|
88
95
|
jest.mock("@applicaster/zapp-react-native-utils/reactHooks/screen", () => ({
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { View } from "react-native";
|
|
3
|
-
import {
|
|
3
|
+
import { act, create } from "react-test-renderer";
|
|
4
4
|
|
|
5
5
|
const Mocked_RouteManager = jest.fn((props) => (
|
|
6
6
|
<View testID="routeManager" {...props} />
|
|
@@ -69,12 +69,16 @@ jest.mock("@applicaster/zapp-react-native-utils/reactHooks/navigation", () => ({
|
|
|
69
69
|
isNavBarVisible: mockIsNavBarVisible,
|
|
70
70
|
useRoute: jest.fn(() => ({
|
|
71
71
|
pathname: "/river/testId",
|
|
72
|
+
screenData: { id: "testId" },
|
|
72
73
|
})),
|
|
73
74
|
useNavigation: jest.fn(() => ({
|
|
74
75
|
canGoBack: () => false,
|
|
75
76
|
currentRoute: "/river/testId",
|
|
77
|
+
activeRiver: { id: "testId" },
|
|
78
|
+
screenData: { id: "testId" },
|
|
76
79
|
data: { screen: { id: "testId" } },
|
|
77
80
|
})),
|
|
81
|
+
useIsScreenActive: jest.fn().mockReturnValue(true),
|
|
78
82
|
}));
|
|
79
83
|
|
|
80
84
|
jest.mock("@applicaster/zapp-react-native-redux/hooks", () => ({
|
|
@@ -19,7 +19,11 @@ exports[`<Screen Component /> when the navbar should be hidden renders correctly
|
|
|
19
19
|
<View>
|
|
20
20
|
<View
|
|
21
21
|
pathname="/river/testId"
|
|
22
|
-
screenData={
|
|
22
|
+
screenData={
|
|
23
|
+
Object {
|
|
24
|
+
"id": "testId",
|
|
25
|
+
}
|
|
26
|
+
}
|
|
23
27
|
testID="routeManager"
|
|
24
28
|
/>
|
|
25
29
|
</View>
|
|
@@ -45,7 +49,11 @@ exports[`<Screen Component /> when the navbar should show renders correctly 1`]
|
|
|
45
49
|
<View>
|
|
46
50
|
<View
|
|
47
51
|
pathname="/river/testId"
|
|
48
|
-
screenData={
|
|
52
|
+
screenData={
|
|
53
|
+
Object {
|
|
54
|
+
"id": "testId",
|
|
55
|
+
}
|
|
56
|
+
}
|
|
49
57
|
testID="routeManager"
|
|
50
58
|
/>
|
|
51
59
|
</View>
|
|
@@ -23,6 +23,17 @@ import { RouteManager } from "../RouteManager";
|
|
|
23
23
|
import { useScreenConfiguration } from "../River/useScreenConfiguration";
|
|
24
24
|
import { useScreenOrientationHandler } from "./orientationHandler";
|
|
25
25
|
|
|
26
|
+
const getScreenId = (
|
|
27
|
+
screenData: LegacyNavigationScreenData,
|
|
28
|
+
fallbackRiver: ZappRiver
|
|
29
|
+
) => {
|
|
30
|
+
return screenData?.targetScreen
|
|
31
|
+
? screenData?.targetScreen?.id ?? fallbackRiver.id
|
|
32
|
+
: "screen_id" in screenData
|
|
33
|
+
? screenData.screen_id
|
|
34
|
+
: fallbackRiver.id;
|
|
35
|
+
};
|
|
36
|
+
|
|
26
37
|
function colorIsNotTransparent(color) {
|
|
27
38
|
const layers = R.compose(
|
|
28
39
|
R.map(R.trim),
|
|
@@ -41,17 +52,11 @@ function isValidColor(string) {
|
|
|
41
52
|
}
|
|
42
53
|
|
|
43
54
|
type Props = {
|
|
44
|
-
pathname: string;
|
|
45
|
-
screenData: Record<string, any>;
|
|
46
55
|
setToggleMenu: () => void;
|
|
47
56
|
setCloseMenu: () => void;
|
|
48
57
|
};
|
|
49
58
|
|
|
50
|
-
export function Screen({
|
|
51
|
-
setToggleMenu,
|
|
52
|
-
setCloseMenu,
|
|
53
|
-
screenData: _screenData,
|
|
54
|
-
}: Props) {
|
|
59
|
+
export function Screen({ setToggleMenu, setCloseMenu }: Props) {
|
|
55
60
|
const theme = useTheme<BaseThemePropertiesMobile>();
|
|
56
61
|
const navigation = useNavigation();
|
|
57
62
|
const { plugins } = usePickFromState(["plugins"]);
|
|
@@ -68,10 +73,7 @@ export function Screen({
|
|
|
68
73
|
const routeData = useRoute();
|
|
69
74
|
|
|
70
75
|
const currentRiver = useScreenData(
|
|
71
|
-
(routeData.screenData
|
|
72
|
-
? (routeData.screenData as ZappRiver)?.targetScreen?.id ??
|
|
73
|
-
navigation.activeRiver.id
|
|
74
|
-
: (routeData.screenData as ZappRiver)?.screen_id
|
|
76
|
+
getScreenId(routeData.screenData, navigation.activeRiver)
|
|
75
77
|
);
|
|
76
78
|
|
|
77
79
|
const { title } = useNavbarState();
|
|
@@ -135,9 +137,9 @@ export function Screen({
|
|
|
135
137
|
{...{ ...(navBarProps as MobileNavBarPluginProps), id: pathname }}
|
|
136
138
|
/>
|
|
137
139
|
|
|
138
|
-
<OfflineFallbackScreen screenData={
|
|
140
|
+
<OfflineFallbackScreen screenData={targetScreenData}>
|
|
139
141
|
{/* @TODO RouteManager doesn't use props, can they be removed ? */}
|
|
140
|
-
<RouteManager pathname={pathname} screenData={
|
|
142
|
+
<RouteManager pathname={pathname} screenData={screenData} />
|
|
141
143
|
</OfflineFallbackScreen>
|
|
142
144
|
</View>
|
|
143
145
|
</ScreenContextProvider>
|
|
@@ -4,8 +4,13 @@ import { render } from "@testing-library/react-native";
|
|
|
4
4
|
import * as PlayerFactory from "@applicaster/zapp-react-native-utils/appUtils/playerManager/playerFactory";
|
|
5
5
|
import { Player } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/player";
|
|
6
6
|
import { ThemeContext } from "@applicaster/zapp-react-native-utils/theme";
|
|
7
|
+
import * as navigationHooks from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
|
|
7
8
|
|
|
8
9
|
import { PlayerLiveImage } from "../PlayerLiveImageComponent";
|
|
10
|
+
import * as useNavigationHooks from "@applicaster/zapp-react-native-utils/reactHooks/navigation/useNavigation";
|
|
11
|
+
|
|
12
|
+
import { Provider } from "react-redux";
|
|
13
|
+
import configureStore from "redux-mock-store";
|
|
9
14
|
|
|
10
15
|
const seekTo = jest.fn();
|
|
11
16
|
|
|
@@ -18,12 +23,25 @@ jest.mock(
|
|
|
18
23
|
})
|
|
19
24
|
);
|
|
20
25
|
|
|
26
|
+
jest
|
|
27
|
+
.spyOn(useNavigationHooks, "useNavigation")
|
|
28
|
+
.mockImplementation(() => ({ videoModalState: { visible: false } }));
|
|
29
|
+
|
|
30
|
+
jest.mock("@applicaster/zapp-react-native-utils/reactHooks/navigation");
|
|
31
|
+
|
|
32
|
+
const mockStore = configureStore();
|
|
33
|
+
|
|
34
|
+
const store = mockStore({ appData: {} });
|
|
35
|
+
|
|
21
36
|
const Wrapper = ({ children }: { children: React.ReactChildren }) => (
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
37
|
+
/* @ts-ignore */
|
|
38
|
+
<Provider store={store}>
|
|
39
|
+
<ThemeContext.Provider
|
|
40
|
+
value={{ themes: { myTheme: {} }, selectedThemeId: "myTheme" }}
|
|
41
|
+
>
|
|
42
|
+
{children}
|
|
43
|
+
</ThemeContext.Provider>
|
|
44
|
+
</Provider>
|
|
27
45
|
);
|
|
28
46
|
|
|
29
47
|
describe("PlayerLiveImageComponent", () => {
|
|
@@ -46,6 +64,8 @@ describe("PlayerLiveImageComponent", () => {
|
|
|
46
64
|
controller: new Player({}),
|
|
47
65
|
Component: () => null,
|
|
48
66
|
}));
|
|
67
|
+
|
|
68
|
+
jest.spyOn(navigationHooks, "useIsScreenActive").mockReturnValue(true);
|
|
49
69
|
});
|
|
50
70
|
|
|
51
71
|
it("should render correctly with default props", () => {
|