@applicaster/zapp-react-native-ui-components 12.0.0-rc.4 → 12.0.0-rc.40
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/AnimatedInOut/index.tsx +18 -10
- package/Components/AudioPlayer/AudioPlayer.tsx +9 -1
- package/Components/AudioPlayer/__tests__/__snapshots__/audioPlayer.test.js.snap +5 -0
- package/Components/AudioPlayer/helpers.tsx +1 -0
- package/Components/Cell/Cell.tsx +2 -2
- package/Components/Cell/CellWithFocusable.tsx +21 -14
- package/Components/Cell/TvOSCellComponent.tsx +2 -2
- package/Components/ErrorScreen/index.tsx +1 -1
- package/Components/FocusableCell/index.tsx +7 -7
- package/Components/FocusableList/FocusableChild.ts +24 -14
- package/Components/FocusableList/FocusableItem.tsx +1 -1
- package/Components/FocusableList/FocusableListItemWrapper.tsx +76 -0
- package/Components/FocusableList/hooks/useCellState.android.ts +3 -1
- package/Components/FocusableList/index.tsx +26 -25
- package/Components/GeneralContentScreen/GeneralContentScreen.tsx +11 -8
- package/Components/HandlePlayable/HandlePlayable.tsx +1 -1
- package/Components/HookRenderer/index.tsx +1 -6
- package/Components/Image/Image.android.tsx +11 -2
- package/Components/Image/Image.tsx +18 -2
- package/Components/Image/utils/index.ts +39 -0
- package/Components/Layout/TV/__tests__/index.test.tsx +1 -34
- package/Components/Layout/TV/index.tsx +20 -36
- package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +0 -1
- package/Components/MasterCell/DefaultComponents/CellBadge/index.tsx +21 -8
- package/Components/MasterCell/DefaultComponents/Image/Image.android.tsx +9 -26
- package/Components/MasterCell/DefaultComponents/Image/hooks/useImageSize.ts +65 -0
- package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +3 -1
- package/Components/MasterCell/DefaultComponents/SecondaryImage/Image.tsx +3 -2
- package/Components/MasterCell/DefaultComponents/Toggle.tsx +5 -1
- package/Components/MasterCell/SharedUI/CollapsibleTextContainer/index.ts +8 -10
- package/Components/ModalComponent/BottomSheetModalContent.tsx +121 -0
- package/Components/ModalComponent/Button/Item.tsx +82 -0
- package/Components/ModalComponent/Button/ItemIcon.tsx +60 -0
- package/Components/ModalComponent/Button/ItemLabel.tsx +101 -0
- package/Components/ModalComponent/Button/assets.ts +4 -0
- package/Components/ModalComponent/Button/index.tsx +111 -0
- package/Components/ModalComponent/Header/CloseButton.tsx +59 -0
- package/Components/ModalComponent/Header/Title.tsx +70 -0
- package/Components/ModalComponent/Header/assets.ts +4 -0
- package/Components/ModalComponent/Header/index.tsx +71 -0
- package/Components/ModalComponent/Header/utils.ts +79 -0
- package/Components/ModalComponent/index.tsx +38 -0
- package/Components/ModalComponent/utils.ts +126 -0
- package/Components/PlayerContainer/ErrorDisplay/ErrorDisplay.tsx +4 -7
- package/Components/PlayerContainer/PlayerContainer.tsx +52 -28
- package/Components/PlayerContainer/ProgramInfo/index.tsx +3 -1
- package/Components/River/ComponentsMap/ComponentsMap.tsx +25 -0
- package/Components/River/River.tsx +8 -5
- package/Components/River/TV/River.tsx +2 -2
- package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +1 -1
- package/Components/River/__tests__/componentsMap.test.js +1 -0
- package/Components/River/useScreenConfiguration.ts +5 -6
- package/Components/RouteManager/__tests__/__snapshots__/routeManager.test.js.snap +1 -0
- package/Components/RouteManager/__tests__/routeManager.test.js +9 -2
- package/Components/RouteManager/index.tsx +5 -3
- package/Components/Screen/__tests__/Screen.test.tsx +48 -36
- package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +20 -6
- package/Components/Screen/__tests__/navigationHandler.test.ts +1 -178
- package/Components/Screen/index.tsx +91 -43
- package/Components/Screen/navigationHandler.ts +0 -82
- package/Components/Screen/orientationHandler.ts +1 -1
- package/Components/ScreenResolver/index.tsx +1 -1
- package/Components/Tabs/TV/styles.ts +1 -1
- package/Components/TrackedView/index.tsx +6 -3
- package/Components/VideoLive/LiveImageManager.ts +42 -13
- package/Components/VideoLive/PlayerLiveImageComponent.tsx +81 -72
- package/Components/VideoLive/__tests__/PlayerLiveImageComponent.test.tsx +30 -3
- package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +22 -27
- package/Components/VideoModal/PlayerDetails.tsx +3 -0
- package/Components/VideoModal/PlayerWrapper.tsx +66 -63
- package/Components/VideoModal/__tests__/PlayerDetails.test.tsx +0 -2
- package/Components/VideoModal/__tests__/PlayerWrapper.test.tsx +4 -4
- package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +202 -162
- package/Components/VideoModal/hooks/useModalSize.ts +13 -4
- package/Components/Viewport/ViewportAware/__tests__/viewportAware.test.js +26 -21
- package/Components/Viewport/ViewportTracker/__tests__/viewportTracker.test.js +4 -5
- package/Components/ZappUIComponent/index.tsx +22 -12
- package/Components/index.js +2 -0
- package/Contexts/ScreenContext/index.tsx +1 -4
- package/Decorators/ComponentsMapWrapper/withComponentsMapProvider.tsx +7 -2
- package/Decorators/RiverResolver/index.tsx +0 -4
- package/Decorators/index.tsx +0 -4
- package/package.json +5 -6
|
@@ -6,17 +6,24 @@ exports[`<Screen Component /> when the navbar should be hidden renders correctly
|
|
|
6
6
|
Object {
|
|
7
7
|
"backgroundColor": "blue",
|
|
8
8
|
"flex": 1,
|
|
9
|
+
"paddingTop": 0,
|
|
9
10
|
}
|
|
10
11
|
}
|
|
11
12
|
>
|
|
12
13
|
<View
|
|
13
|
-
|
|
14
|
+
id="/river/testId"
|
|
15
|
+
selected="testId"
|
|
14
16
|
testID="navBar"
|
|
17
|
+
title=""
|
|
15
18
|
/>
|
|
16
19
|
<View>
|
|
17
20
|
<View
|
|
18
|
-
pathname="/
|
|
19
|
-
screenData={
|
|
21
|
+
pathname="/river/testId"
|
|
22
|
+
screenData={
|
|
23
|
+
Object {
|
|
24
|
+
"id": "testId",
|
|
25
|
+
}
|
|
26
|
+
}
|
|
20
27
|
testID="routeManager"
|
|
21
28
|
/>
|
|
22
29
|
</View>
|
|
@@ -29,17 +36,24 @@ exports[`<Screen Component /> when the navbar should show renders correctly 1`]
|
|
|
29
36
|
Object {
|
|
30
37
|
"backgroundColor": "blue",
|
|
31
38
|
"flex": 1,
|
|
39
|
+
"paddingTop": 0,
|
|
32
40
|
}
|
|
33
41
|
}
|
|
34
42
|
>
|
|
35
43
|
<View
|
|
36
|
-
|
|
44
|
+
id="/river/testId"
|
|
45
|
+
selected="testId"
|
|
37
46
|
testID="navBar"
|
|
47
|
+
title=""
|
|
38
48
|
/>
|
|
39
49
|
<View>
|
|
40
50
|
<View
|
|
41
|
-
pathname="/
|
|
42
|
-
screenData={
|
|
51
|
+
pathname="/river/testId"
|
|
52
|
+
screenData={
|
|
53
|
+
Object {
|
|
54
|
+
"id": "testId",
|
|
55
|
+
}
|
|
56
|
+
}
|
|
43
57
|
testID="routeManager"
|
|
44
58
|
/>
|
|
45
59
|
</View>
|
|
@@ -1,183 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isMenuVisible } from "../navigationHandler";
|
|
2
2
|
|
|
3
3
|
describe("NavigationHandler", () => {
|
|
4
|
-
describe("isNavBarVisible", () => {
|
|
5
|
-
it("returns false when the route is a player route", () => {
|
|
6
|
-
const navBarVisible = isNavBarVisible(
|
|
7
|
-
"/playable/some_vod_item",
|
|
8
|
-
{},
|
|
9
|
-
undefined,
|
|
10
|
-
false
|
|
11
|
-
);
|
|
12
|
-
|
|
13
|
-
expect(navBarVisible).toBe(false);
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
it("returns false when the next screen is the QB search screen", () => {
|
|
17
|
-
const navBarVisible = isNavBarVisible(
|
|
18
|
-
"/river/A1234",
|
|
19
|
-
{
|
|
20
|
-
type: "qb_search_screen",
|
|
21
|
-
},
|
|
22
|
-
undefined,
|
|
23
|
-
false
|
|
24
|
-
);
|
|
25
|
-
|
|
26
|
-
expect(navBarVisible).toBe(false);
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
describe("when screen is a hook", () => {
|
|
30
|
-
it("returns true if the `showNavBar` flag is set to true", () => {
|
|
31
|
-
const navBarVisible = isNavBarVisible(
|
|
32
|
-
"",
|
|
33
|
-
{
|
|
34
|
-
hookPlugin: {
|
|
35
|
-
module: {
|
|
36
|
-
showNavBar: true,
|
|
37
|
-
},
|
|
38
|
-
},
|
|
39
|
-
},
|
|
40
|
-
undefined,
|
|
41
|
-
false
|
|
42
|
-
);
|
|
43
|
-
|
|
44
|
-
expect(navBarVisible).toBe(true);
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it("returns true if presentFullScreen flag is set to false", () => {
|
|
48
|
-
const navBarVisible = isNavBarVisible(
|
|
49
|
-
"",
|
|
50
|
-
{
|
|
51
|
-
hookPlugin: {
|
|
52
|
-
module: {
|
|
53
|
-
presentFullScreen: false,
|
|
54
|
-
},
|
|
55
|
-
},
|
|
56
|
-
},
|
|
57
|
-
undefined,
|
|
58
|
-
false
|
|
59
|
-
);
|
|
60
|
-
|
|
61
|
-
expect(navBarVisible).toBe(true);
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
it("returns false if presentFullScreen flag is set to true", () => {
|
|
65
|
-
const navBarVisible = isNavBarVisible(
|
|
66
|
-
"",
|
|
67
|
-
{
|
|
68
|
-
hookPlugin: {
|
|
69
|
-
module: {
|
|
70
|
-
presentFullScreen: true,
|
|
71
|
-
},
|
|
72
|
-
},
|
|
73
|
-
},
|
|
74
|
-
undefined,
|
|
75
|
-
false
|
|
76
|
-
);
|
|
77
|
-
|
|
78
|
-
expect(navBarVisible).toBe(false);
|
|
79
|
-
});
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
it("returns false if the screen's general settings allow screen presentation", () => {
|
|
83
|
-
const navBarVisible = isNavBarVisible(
|
|
84
|
-
"",
|
|
85
|
-
{
|
|
86
|
-
general: {
|
|
87
|
-
allow_screen_plugin_presentation: true,
|
|
88
|
-
},
|
|
89
|
-
},
|
|
90
|
-
undefined,
|
|
91
|
-
false
|
|
92
|
-
);
|
|
93
|
-
|
|
94
|
-
expect(navBarVisible).toBe(false);
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
it("returns false if the screen's general settings hide app nav bar", () => {
|
|
98
|
-
const navBarVisible = isNavBarVisible(
|
|
99
|
-
"",
|
|
100
|
-
{
|
|
101
|
-
general: {
|
|
102
|
-
hide_app_nav_bar: true,
|
|
103
|
-
},
|
|
104
|
-
},
|
|
105
|
-
undefined,
|
|
106
|
-
false
|
|
107
|
-
);
|
|
108
|
-
|
|
109
|
-
expect(navBarVisible).toBe(false);
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
it("returns false if it's secondary nav bar and hide_secondary_level_menu is true", () => {
|
|
113
|
-
const navBarVisible = isNavBarVisible(
|
|
114
|
-
"",
|
|
115
|
-
{
|
|
116
|
-
navigations: [
|
|
117
|
-
{
|
|
118
|
-
styles: {
|
|
119
|
-
hide_secondary_level_menu: true,
|
|
120
|
-
},
|
|
121
|
-
},
|
|
122
|
-
],
|
|
123
|
-
},
|
|
124
|
-
undefined,
|
|
125
|
-
true
|
|
126
|
-
);
|
|
127
|
-
|
|
128
|
-
expect(navBarVisible).toBe(false);
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
it("returns true if it's secondary nav bar and hide_secondary_level_menu is false", () => {
|
|
132
|
-
const navBarVisible = isNavBarVisible(
|
|
133
|
-
"",
|
|
134
|
-
{
|
|
135
|
-
navigations: [
|
|
136
|
-
{
|
|
137
|
-
styles: {
|
|
138
|
-
hide_secondary_level_menu: false,
|
|
139
|
-
},
|
|
140
|
-
},
|
|
141
|
-
],
|
|
142
|
-
},
|
|
143
|
-
undefined,
|
|
144
|
-
true
|
|
145
|
-
);
|
|
146
|
-
|
|
147
|
-
expect(navBarVisible).toBe(true);
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
it("returns true if it's first level menu and hide_secondary_level_menu is true", () => {
|
|
151
|
-
const navBarVisible = isNavBarVisible(
|
|
152
|
-
"",
|
|
153
|
-
{
|
|
154
|
-
navigations: [
|
|
155
|
-
{
|
|
156
|
-
styles: {
|
|
157
|
-
hide_secondary_level_menu: false,
|
|
158
|
-
},
|
|
159
|
-
},
|
|
160
|
-
],
|
|
161
|
-
},
|
|
162
|
-
undefined,
|
|
163
|
-
false
|
|
164
|
-
);
|
|
165
|
-
|
|
166
|
-
expect(navBarVisible).toBe(true);
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
it("returns true otherwise", () => {
|
|
170
|
-
const navBarVisible = isNavBarVisible(
|
|
171
|
-
"",
|
|
172
|
-
{ navigations: [] },
|
|
173
|
-
undefined,
|
|
174
|
-
false
|
|
175
|
-
);
|
|
176
|
-
|
|
177
|
-
expect(navBarVisible).toBe(true);
|
|
178
|
-
});
|
|
179
|
-
});
|
|
180
|
-
|
|
181
4
|
describe("isMenuVisible", () => {
|
|
182
5
|
it("returns false when the route is a player route", () => {
|
|
183
6
|
const menuVisible = isMenuVisible("/playable/some_vod_item", {});
|
|
@@ -1,36 +1,37 @@
|
|
|
1
1
|
/// <reference types="@applicaster/applicaster-types" />
|
|
2
|
-
import React
|
|
2
|
+
import React from "react";
|
|
3
3
|
import * as R from "ramda";
|
|
4
4
|
import { View } from "react-native";
|
|
5
|
-
import { RouteManager } from "../RouteManager";
|
|
6
|
-
import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
|
|
7
|
-
import { useScreenOrientationHandler } from "./orientationHandler";
|
|
8
|
-
import { useScreenConfiguration } from "../River/useScreenConfiguration";
|
|
9
|
-
import { useCurrentScreenData } from "@applicaster/zapp-react-native-utils/reactHooks/screen";
|
|
10
|
-
import type { ZappNavigationProps } from "@applicaster/zapp-react-native-flow-types/index";
|
|
11
5
|
import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
|
|
6
|
+
|
|
7
|
+
import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
|
|
8
|
+
import { getComponentModule } from "@applicaster/zapp-react-native-utils/pluginUtils";
|
|
9
|
+
import { getNavigationPropsV2 } from "@applicaster/zapp-react-native-utils/navigationUtils";
|
|
10
|
+
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
11
|
+
import {
|
|
12
|
+
useDimensions,
|
|
13
|
+
useRoute,
|
|
14
|
+
useCurrentScreenData,
|
|
15
|
+
useNavbarState,
|
|
16
|
+
useScreenData,
|
|
17
|
+
useNavigation,
|
|
18
|
+
} from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
19
|
+
import { getNavigationPluginModule } from "@applicaster/zapp-react-native-app/App/Layout/layoutHelpers";
|
|
20
|
+
|
|
12
21
|
import { ScreenContextProvider } from "../../Contexts/ScreenContext";
|
|
22
|
+
import { RouteManager } from "../RouteManager";
|
|
23
|
+
import { useScreenConfiguration } from "../River/useScreenConfiguration";
|
|
24
|
+
import { useScreenOrientationHandler } from "./orientationHandler";
|
|
13
25
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
toggleMenu: () => void;
|
|
24
|
-
openMenu: () => void;
|
|
25
|
-
setOpenMenu: () => void;
|
|
26
|
-
closeMenu: () => void;
|
|
27
|
-
setCloseMenu: () => void;
|
|
28
|
-
dimensions: { window: number };
|
|
29
|
-
navigator: ZappNavigationProps;
|
|
30
|
-
bottomTabBarHeight: number;
|
|
31
|
-
isRTL: boolean;
|
|
32
|
-
category: string;
|
|
33
|
-
} & QuickBrickAppNavigator;
|
|
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;
|
|
34
35
|
};
|
|
35
36
|
|
|
36
37
|
function colorIsNotTransparent(color) {
|
|
@@ -50,25 +51,65 @@ function isValidColor(string) {
|
|
|
50
51
|
return string && string !== "transparent" && colorIsNotTransparent(string);
|
|
51
52
|
}
|
|
52
53
|
|
|
53
|
-
|
|
54
|
-
|
|
54
|
+
type Props = {
|
|
55
|
+
setToggleMenu: () => void;
|
|
56
|
+
setCloseMenu: () => void;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export function Screen({ setToggleMenu, setCloseMenu }: Props) {
|
|
60
|
+
const theme = useTheme<BaseThemePropertiesMobile>();
|
|
61
|
+
const navigation = useNavigation();
|
|
55
62
|
const { plugins } = usePickFromState(["plugins"]);
|
|
56
63
|
|
|
57
|
-
|
|
64
|
+
// Gets the data for the current screen configuration
|
|
65
|
+
const currentScreenData = useCurrentScreenData();
|
|
66
|
+
const { backgroundColor } = useScreenConfiguration(currentScreenData.id);
|
|
67
|
+
const insets = useSafeAreaInsets();
|
|
68
|
+
|
|
69
|
+
const { width: screenWidth } = useDimensions("screen", {
|
|
70
|
+
fullDimensions: true,
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
const routeData = useRoute();
|
|
74
|
+
|
|
75
|
+
const currentRiver = useScreenData(
|
|
76
|
+
getScreenId(routeData.screenData, navigation.activeRiver)
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
const { title } = useNavbarState();
|
|
80
|
+
|
|
81
|
+
const navBarProps = React.useMemo(
|
|
82
|
+
() => ({
|
|
83
|
+
...getNavigationPropsV2({
|
|
84
|
+
currentRiver,
|
|
85
|
+
title,
|
|
86
|
+
category: "nav_bar",
|
|
87
|
+
}),
|
|
88
|
+
setToggleMenu,
|
|
89
|
+
setCloseMenu,
|
|
90
|
+
}),
|
|
91
|
+
[currentRiver, setCloseMenu, setToggleMenu]
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
const NavBar = React.useMemo(
|
|
58
95
|
() =>
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
96
|
+
getNavigationPluginModule(
|
|
97
|
+
"nav_bar",
|
|
98
|
+
currentRiver,
|
|
99
|
+
plugins
|
|
100
|
+
) as React.ComponentType<MobileNavBarPluginProps>,
|
|
101
|
+
[]
|
|
64
102
|
);
|
|
65
103
|
|
|
66
|
-
const {
|
|
104
|
+
const { screenData, pathname } = routeData;
|
|
67
105
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
106
|
+
const offlinePlugin = getComponentModule({
|
|
107
|
+
plugins,
|
|
108
|
+
components: {},
|
|
109
|
+
componentType: "offline-experience",
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
const { OfflineFallbackScreen } = offlinePlugin;
|
|
72
113
|
|
|
73
114
|
const style = React.useMemo(
|
|
74
115
|
() => ({
|
|
@@ -76,21 +117,28 @@ export function Screen(props: Props) {
|
|
|
76
117
|
backgroundColor: isValidColor(backgroundColor)
|
|
77
118
|
? backgroundColor
|
|
78
119
|
: theme.app_background_color,
|
|
120
|
+
paddingTop: 0,
|
|
121
|
+
// paddingBottom: insets.bottom, // Should be applied directly by UI plugin
|
|
122
|
+
// paddingLeft: insets.left, // Should be applied directly by UI plugin
|
|
123
|
+
// paddingRight: insets.right, // Should be applied directly by UI plugin
|
|
79
124
|
}),
|
|
80
|
-
[theme.app_background_color, backgroundColor]
|
|
125
|
+
[insets, screenWidth, theme.app_background_color, backgroundColor]
|
|
81
126
|
);
|
|
82
127
|
|
|
83
128
|
const targetScreenData =
|
|
84
|
-
currentScreenData || screenData?.targetScreen || screenData;
|
|
129
|
+
currentScreenData || (screenData as any)?.targetScreen || screenData;
|
|
85
130
|
|
|
86
131
|
useScreenOrientationHandler({ screenData: targetScreenData });
|
|
87
132
|
|
|
88
133
|
return (
|
|
89
134
|
<ScreenContextProvider pathname={pathname}>
|
|
90
135
|
<View style={style}>
|
|
91
|
-
<NavBar
|
|
136
|
+
<NavBar
|
|
137
|
+
{...{ ...(navBarProps as MobileNavBarPluginProps), id: pathname }}
|
|
138
|
+
/>
|
|
92
139
|
|
|
93
140
|
<OfflineFallbackScreen screenData={screenData}>
|
|
141
|
+
{/* @TODO RouteManager doesn't use props, can they be removed ? */}
|
|
94
142
|
<RouteManager pathname={pathname} screenData={screenData} />
|
|
95
143
|
</OfflineFallbackScreen>
|
|
96
144
|
</View>
|
|
@@ -1,85 +1,3 @@
|
|
|
1
|
-
import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* This function helps to decide wether the navbar should be presented on the screen
|
|
5
|
-
* based on route and / or screen Data
|
|
6
|
-
*
|
|
7
|
-
* Currently the scenarios include
|
|
8
|
-
* - players => false
|
|
9
|
-
* - search screen plugin => false
|
|
10
|
-
* - hooks with `showNavBar: true` or `presentFullScreen` not set to true, defaults to no navbar for hook screens
|
|
11
|
-
* - screens with `allow_screen_plugin_presentation` in general property => false
|
|
12
|
-
*
|
|
13
|
-
* @param {String} route current route of the screen
|
|
14
|
-
* @param {Object} screenData payload associated with the currently presented screen
|
|
15
|
-
* @returns {Boolean}
|
|
16
|
-
*/
|
|
17
|
-
export function isNavBarVisible(
|
|
18
|
-
route,
|
|
19
|
-
screenData,
|
|
20
|
-
showNavBar,
|
|
21
|
-
canGoBack,
|
|
22
|
-
videoModalState: QuickBrickVideoModalState | null = null
|
|
23
|
-
) {
|
|
24
|
-
/* screenData is not actual navigator.data
|
|
25
|
-
* or navigator.screenData,
|
|
26
|
-
* but navigator.data.screen */
|
|
27
|
-
if (route.includes("playable")) {
|
|
28
|
-
return false;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
if (
|
|
32
|
-
videoModalState?.mode === "FULLSCREEN" &&
|
|
33
|
-
videoModalState?.visible === true
|
|
34
|
-
) {
|
|
35
|
-
return false;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
if (screenData?.type === "qb_search_screen" && !isTV()) {
|
|
39
|
-
return false;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/* Match if screen is Hook */
|
|
43
|
-
if (route.startsWith("/hooks/")) {
|
|
44
|
-
const module = screenData?.module;
|
|
45
|
-
|
|
46
|
-
if (module?.presentFullScreen) {
|
|
47
|
-
return false;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return module?.showNavBar ?? false;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
if (screenData?.hookPlugin) {
|
|
54
|
-
const hookPlugin = screenData?.hookPlugin?.module;
|
|
55
|
-
|
|
56
|
-
return (
|
|
57
|
-
hookPlugin?.showNavBar || hookPlugin?.presentFullScreen !== true || false
|
|
58
|
-
);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
if (
|
|
62
|
-
screenData?.general?.allow_screen_plugin_presentation ||
|
|
63
|
-
screenData?.general?.hide_app_nav_bar
|
|
64
|
-
) {
|
|
65
|
-
return false;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const hideSecondaryLevel = screenData?.navigations?.some(
|
|
69
|
-
(navigation) => navigation.styles?.hide_secondary_level_menu
|
|
70
|
-
);
|
|
71
|
-
|
|
72
|
-
if (canGoBack && hideSecondaryLevel) {
|
|
73
|
-
return false;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if (typeof showNavBar === "boolean" && !showNavBar) {
|
|
77
|
-
return false;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
return true;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
1
|
/**
|
|
84
2
|
* This function helps to decide wether the menu should be presented on the screen
|
|
85
3
|
* based on route and / or screen Data
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
|
|
9
9
|
import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
|
|
10
10
|
import { findPluginByType } from "@applicaster/zapp-react-native-utils/pluginUtils";
|
|
11
|
-
import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks
|
|
11
|
+
import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
12
12
|
import { ZappHookModalContext } from "../../Contexts";
|
|
13
13
|
import { HookModalContextT } from "../../Contexts/ZappHookModalContext";
|
|
14
14
|
|
|
@@ -17,9 +17,12 @@ type TrackedViewProps = {
|
|
|
17
17
|
export const TrackedView = memo(function TrackedView(props: TrackedViewProps) {
|
|
18
18
|
const children = props.children;
|
|
19
19
|
|
|
20
|
-
const onPositionUpdated = useCallback(
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
const onPositionUpdated = useCallback(
|
|
21
|
+
(event: TrackedViewNativeProps) => {
|
|
22
|
+
props.onPositionUpdated(event.nativeEvent);
|
|
23
|
+
},
|
|
24
|
+
[props.onPositionUpdated]
|
|
25
|
+
);
|
|
23
26
|
|
|
24
27
|
if (isTV()) {
|
|
25
28
|
return <View {...(props as any)}>{children}</View>;
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
import { setUserCellPlayerMutedPreference } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/userCellPlayerMutedPreference";
|
|
7
7
|
import { loggerLiveImageManager } from "./loggerHelper";
|
|
8
8
|
import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
9
|
+
import { Component } from "react";
|
|
9
10
|
|
|
10
11
|
const { log_debug, log_info, log_error } = loggerLiveImageManager;
|
|
11
12
|
|
|
@@ -36,7 +37,8 @@ type Position = {
|
|
|
36
37
|
type LiveImageProps = {
|
|
37
38
|
player: Player;
|
|
38
39
|
playerId: string;
|
|
39
|
-
setMode
|
|
40
|
+
setMode?: (type: LiveImageType) => void;
|
|
41
|
+
component: Component;
|
|
40
42
|
// TODO: ...primary, powerCell, tvGallery, etc.
|
|
41
43
|
// type: string;
|
|
42
44
|
};
|
|
@@ -164,7 +166,7 @@ export class LiveImageManager implements PlayerLifecycleListener {
|
|
|
164
166
|
|
|
165
167
|
// Fake close event, because we unmount native view
|
|
166
168
|
item.player?.onPlayerClose();
|
|
167
|
-
item.setMode(LiveImageType.Image);
|
|
169
|
+
item.setMode?.(LiveImageType.Image);
|
|
168
170
|
|
|
169
171
|
if (item === this.currentlyPlaying) {
|
|
170
172
|
this.currentlyPlaying = null;
|
|
@@ -191,8 +193,7 @@ export class LiveImageManager implements PlayerLifecycleListener {
|
|
|
191
193
|
}
|
|
192
194
|
|
|
193
195
|
this.currentlyPlaying = item;
|
|
194
|
-
|
|
195
|
-
item.setMode(LiveImageType.Video);
|
|
196
|
+
item.setMode?.(LiveImageType.Video);
|
|
196
197
|
|
|
197
198
|
if (item.player.playerState.isReadyToPlay) {
|
|
198
199
|
item.player.play();
|
|
@@ -209,6 +210,11 @@ export class LiveImageManager implements PlayerLifecycleListener {
|
|
|
209
210
|
this.pauseItem(item);
|
|
210
211
|
};
|
|
211
212
|
|
|
213
|
+
public onLiveImageCompleted = (_item: LiveImage) => {
|
|
214
|
+
// TODO: Notify listeners that player has died
|
|
215
|
+
// Do not try look for new playable, otherwise you will restart video finish to play
|
|
216
|
+
};
|
|
217
|
+
|
|
212
218
|
public muteAll = () => {
|
|
213
219
|
log_debug("muteAll");
|
|
214
220
|
|
|
@@ -235,6 +241,14 @@ export class LiveImageManager implements PlayerLifecycleListener {
|
|
|
235
241
|
const playerItem = this.findNextPlayableItem();
|
|
236
242
|
|
|
237
243
|
if (playerItem) {
|
|
244
|
+
if (!playerItem.isFullyVisible) {
|
|
245
|
+
log_error(
|
|
246
|
+
`checkPlayerPosition: trying to start playback currently invisible item: ${playerInfo(
|
|
247
|
+
playerItem.player
|
|
248
|
+
)}`
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
|
|
238
252
|
// Will also check if it's item that already playing
|
|
239
253
|
this.playLiveImage(playerItem);
|
|
240
254
|
}
|
|
@@ -242,7 +256,6 @@ export class LiveImageManager implements PlayerLifecycleListener {
|
|
|
242
256
|
|
|
243
257
|
onPrimaryPlayerClosed = () => {
|
|
244
258
|
const playerItem = this.findNextPlayableItem();
|
|
245
|
-
|
|
246
259
|
log_info("onPrimaryPlayerClosed: starting to play visible live-image");
|
|
247
260
|
|
|
248
261
|
this.currentlyPlaying = null;
|
|
@@ -356,12 +369,12 @@ export class LiveImageManager implements PlayerLifecycleListener {
|
|
|
356
369
|
// TODO: This branch was used when we had play button to toggle replay.
|
|
357
370
|
// Now we mute button instead but we keep it just in case.
|
|
358
371
|
if (IS_ALLOWED_REPLAY && !isTV() && isCurrentItemEnded) {
|
|
359
|
-
this.currentlyPlaying
|
|
360
|
-
this.currentlyPlaying
|
|
372
|
+
this.currentlyPlaying?.player.seekTo(0);
|
|
373
|
+
this.currentlyPlaying?.player.pause();
|
|
361
374
|
|
|
362
375
|
// TODO: ...Maybe player some other item
|
|
363
376
|
} else {
|
|
364
|
-
item.setMode(LiveImageType.Image);
|
|
377
|
+
item.setMode?.(LiveImageType.Image);
|
|
365
378
|
}
|
|
366
379
|
|
|
367
380
|
// Prevent receiving onEnd event from both `close` and `end` player events
|
|
@@ -377,10 +390,25 @@ export class LiveImageManager implements PlayerLifecycleListener {
|
|
|
377
390
|
};
|
|
378
391
|
|
|
379
392
|
onLiveImageError = (item: LiveImage, error: Error) => {
|
|
380
|
-
item.setMode(LiveImageType.Image);
|
|
393
|
+
item.setMode?.(LiveImageType.Image);
|
|
381
394
|
|
|
382
|
-
|
|
395
|
+
const currentItem = this.currentlyPlaying;
|
|
396
|
+
|
|
397
|
+
log_debug(
|
|
398
|
+
`onLiveImageError: error: ${error.message}, live-image ${playerInfo(
|
|
399
|
+
item.player
|
|
400
|
+
)}, currentPlayingId: ${
|
|
401
|
+
this.currentlyPlaying?.playerId
|
|
402
|
+
}, primaryPlayerId: ${this.primaryPlayer?.playerId}`
|
|
403
|
+
);
|
|
404
|
+
|
|
405
|
+
if (currentItem === item) {
|
|
383
406
|
this.currentlyPlaying = null;
|
|
407
|
+
|
|
408
|
+
log_debug(
|
|
409
|
+
`onLiveImageError: currentitem: ${currentItem.playerId} was removed`
|
|
410
|
+
);
|
|
411
|
+
|
|
384
412
|
// TODO: ...Maybe player some other item
|
|
385
413
|
}
|
|
386
414
|
|
|
@@ -389,8 +417,8 @@ export class LiveImageManager implements PlayerLifecycleListener {
|
|
|
389
417
|
event: {
|
|
390
418
|
item,
|
|
391
419
|
error,
|
|
392
|
-
playerId:
|
|
393
|
-
primaryPlayerId:
|
|
420
|
+
playerId: currentItem?.playerId,
|
|
421
|
+
primaryPlayerId: currentItem?.playerId,
|
|
394
422
|
},
|
|
395
423
|
});
|
|
396
424
|
};
|
|
@@ -446,12 +474,13 @@ export class LiveImage implements QuickBrickPlayer.SharedPlayerCallBacks {
|
|
|
446
474
|
};
|
|
447
475
|
|
|
448
476
|
readonly playerId: string;
|
|
477
|
+
readonly component: Component;
|
|
449
478
|
|
|
450
479
|
constructor(props: LiveImageProps) {
|
|
451
480
|
this.player = props.player;
|
|
452
481
|
this.setMode = props.setMode;
|
|
453
482
|
this.playerId = this.player.playerId;
|
|
454
|
-
|
|
483
|
+
this.component = props.component;
|
|
455
484
|
this.player.addListener({ id: "live-image", listener: this });
|
|
456
485
|
}
|
|
457
486
|
|