@applicaster/zapp-react-native-ui-components 13.0.0-alpha.7019824418 → 13.0.0-alpha.7048001189
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/AudioPlayer.tsx +7 -0
- package/Components/AudioPlayer/helpers.tsx +1 -0
- package/Components/Cell/Cell.tsx +3 -13
- package/Components/Cell/CellWithFocusable.tsx +21 -15
- package/Components/Cell/CellWrapper.tsx +18 -0
- package/Components/Cell/styles.ts +17 -0
- package/Components/ErrorScreen/index.tsx +8 -0
- package/Components/FocusableCell/index.tsx +1 -1
- package/Components/FocusableGroup/FocusableTvOS.tsx +34 -86
- package/Components/FocusableGroup/index.tsx +0 -3
- package/Components/HandlePlayable/HandlePlayable.tsx +21 -27
- package/Components/Layout/TV/NavBarContainer.tsx +2 -1
- package/Components/Layout/TV/ScreenContainer.tsx +8 -1
- package/Components/Layout/TV/ScreenLayoutContextProvider.tsx +5 -0
- package/Components/Layout/TV/__tests__/ScreenContainer.test.tsx +2 -1
- package/Components/Layout/TV/__tests__/__snapshots__/NavBarContainer.test.tsx.snap +1 -0
- package/Components/Layout/TV/__tests__/__snapshots__/ScreenContainer.test.tsx.snap +1 -0
- package/Components/MasterCell/DefaultComponents/ActionButton.tsx +2 -3
- package/Components/MasterCell/DefaultComponents/Image/Image.ios.tsx +4 -3
- package/Components/MasterCell/DefaultComponents/Image/hooks/useImage.ts +11 -7
- package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/const.ts +3 -0
- package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/index.ts +6 -6
- package/Components/MasterCell/SharedUI/ProgressBar/hooks/useFillInPercent.ts +2 -8
- package/Components/MasterCell/utils/behaviorProvider.ts +136 -0
- package/Components/MasterCell/utils/index.ts +8 -134
- package/Components/ModalComponent/BottomSheetModalContent.tsx +38 -15
- package/Components/ModalComponent/Button/Item.tsx +1 -0
- package/Components/ModalComponent/Button/assets.ts +1 -1
- package/Components/ModalComponent/Button/index.tsx +29 -42
- package/Components/ModalComponent/utils.ts +52 -4
- package/Components/OfflineHandler/utils/index.ts +1 -1
- package/Components/PlayerContainer/PlayerContainer.tsx +20 -6
- package/Components/PlayerImageBackground/index.tsx +1 -1
- package/Components/River/ComponentsMap/ComponentsMap.tsx +3 -0
- package/Components/River/ComponentsMap/hooks/useLoadingState.ts +3 -3
- package/Components/Screen/TV/index.web.tsx +5 -6
- package/Components/Screen/hooks.ts +3 -6
- package/Components/TrackedView/index.tsx +1 -0
- package/Components/Transitioner/AnimationManager.js +15 -15
- package/Components/VideoLive/PlayerLiveImageComponent.tsx +4 -0
- package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +1 -0
- package/Components/VideoModal/ModalAnimation/AnimatedPlayerModalWrapper.tsx +1 -1
- package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +33 -19
- package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.tsx +3 -3
- package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +21 -4
- package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +2 -2
- package/Components/VideoModal/PlayerDetails.tsx +8 -5
- package/Components/VideoModal/PlayerWrapper.tsx +26 -3
- package/Components/VideoModal/VideoModal.tsx +19 -4
- package/Components/ZappUIComponent/index.tsx +4 -4
- package/Contexts/FocusableGroupContext/withFocusableContext.tsx +4 -10
- package/Contexts/HeaderOffsetContext/index.tsx +4 -6
- package/Contexts/ScreenContext/index.tsx +3 -10
- package/Contexts/ScreenLayoutContext/index.tsx +5 -3
- package/Decorators/RiverResolver/index.tsx +5 -7
- package/Decorators/ZappPipesDataConnector/index.tsx +4 -30
- package/package.json +5 -9
- package/tsconfig.json +2 -3
- package/.babelrc +0 -8
- package/Components/Cell/CellStyles/FallbackCellStyle/index.js +0 -157
- package/Components/Cell/CellStyles/Hero/index.js +0 -111
- package/Components/Cell/CellStyles/ScreenSelector/index.js +0 -68
- package/Components/Cell/CellStyles/cellStylesResolver.ts +0 -19
- package/Components/Cell/CellStyles/colors.js +0 -40
- package/Components/Cell/CellStyles/index.js +0 -15
- package/Components/Cell/CellWithFocusable.ios.tsx +0 -126
|
@@ -24,6 +24,7 @@ type Props = {
|
|
|
24
24
|
audio_player_rtl?: boolean;
|
|
25
25
|
magic_background?: boolean;
|
|
26
26
|
audio_player_background_image_query?: string;
|
|
27
|
+
audio_player_background_image_default_color?: string;
|
|
27
28
|
start_time?: string;
|
|
28
29
|
end_time?: string;
|
|
29
30
|
};
|
|
@@ -35,6 +36,7 @@ type Props = {
|
|
|
35
36
|
audio_player_rtl?: string;
|
|
36
37
|
magic_background?: string;
|
|
37
38
|
audio_player_background_image_query?: string;
|
|
39
|
+
audio_player_background_image_default_color?: string;
|
|
38
40
|
audio_player_background_image?: string;
|
|
39
41
|
audio_player_artwork_aspect_ratio?: string;
|
|
40
42
|
lg_tv_audio_player_title_font_family?: string;
|
|
@@ -80,6 +82,10 @@ export function AudioPlayer(props: Props) {
|
|
|
80
82
|
"audio_player_background_image_query"
|
|
81
83
|
);
|
|
82
84
|
|
|
85
|
+
const audioPlayerBackgroundImageDefaultColor = getProp(
|
|
86
|
+
"audio_player_background_image_default_color"
|
|
87
|
+
);
|
|
88
|
+
|
|
83
89
|
const isRTL = rtlFlag === "1" || rtlFlag === "true" || rtlFlag === true;
|
|
84
90
|
|
|
85
91
|
const titleFontFamily = getProp(
|
|
@@ -158,6 +164,7 @@ export function AudioPlayer(props: Props) {
|
|
|
158
164
|
channelIcon,
|
|
159
165
|
magicBackground,
|
|
160
166
|
audioPlayerBackgroundImageQuery,
|
|
167
|
+
audioPlayerBackgroundImageDefaultColor,
|
|
161
168
|
};
|
|
162
169
|
}, [getProp]);
|
|
163
170
|
|
package/Components/Cell/Cell.tsx
CHANGED
|
@@ -12,6 +12,7 @@ import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
|
|
|
12
12
|
import { CellWithFocusable } from "./CellWithFocusable";
|
|
13
13
|
import { BaseFocusable } from "../BaseFocusable";
|
|
14
14
|
import { AccessibilityManager } from "@applicaster/zapp-react-native-utils/appUtils/accessibilityManager";
|
|
15
|
+
import { styles } from "./styles";
|
|
15
16
|
|
|
16
17
|
type Props = {
|
|
17
18
|
item: ZappEntry;
|
|
@@ -68,17 +69,6 @@ type State = {
|
|
|
68
69
|
hasFocusableInside: boolean;
|
|
69
70
|
};
|
|
70
71
|
|
|
71
|
-
const baseCellStyles = {
|
|
72
|
-
height: "100%",
|
|
73
|
-
display: "flex",
|
|
74
|
-
flex: 1,
|
|
75
|
-
} as const;
|
|
76
|
-
|
|
77
|
-
const touchableStyles = {
|
|
78
|
-
flex: 1,
|
|
79
|
-
height: "100%",
|
|
80
|
-
} as const;
|
|
81
|
-
|
|
82
72
|
export class CellComponent extends React.Component<Props, State> {
|
|
83
73
|
constructor(props) {
|
|
84
74
|
super(props);
|
|
@@ -252,7 +242,7 @@ export class CellComponent extends React.Component<Props, State> {
|
|
|
252
242
|
<View
|
|
253
243
|
testID={`${component?.id}-${id}`}
|
|
254
244
|
accessible={false}
|
|
255
|
-
style={
|
|
245
|
+
style={styles.touchableCell}
|
|
256
246
|
>
|
|
257
247
|
<Focusable
|
|
258
248
|
id={focusableId}
|
|
@@ -264,7 +254,7 @@ export class CellComponent extends React.Component<Props, State> {
|
|
|
264
254
|
hasReceivedFocus={hasReceivedFocus || this.hasReceivedFocus}
|
|
265
255
|
preferredFocus={preferredFocus}
|
|
266
256
|
offsetUpdater={offsetUpdater}
|
|
267
|
-
style={
|
|
257
|
+
style={styles.baseCell}
|
|
268
258
|
isFocusable={isFocusable}
|
|
269
259
|
skipFocusManagerRegistration={skipFocusManagerRegistration}
|
|
270
260
|
>
|
|
@@ -5,6 +5,8 @@ import { toBooleanWithDefaultFalse } from "@applicaster/zapp-react-native-utils/
|
|
|
5
5
|
|
|
6
6
|
import { useCellState } from "../MasterCell/utils";
|
|
7
7
|
import { FocusableGroup } from "../FocusableGroup";
|
|
8
|
+
import { CellWrapper } from "./CellWrapper";
|
|
9
|
+
import { styles } from "./styles";
|
|
8
10
|
|
|
9
11
|
type Props = {
|
|
10
12
|
item: ZappEntry;
|
|
@@ -21,6 +23,8 @@ type Props = {
|
|
|
21
23
|
focused?: boolean;
|
|
22
24
|
};
|
|
23
25
|
|
|
26
|
+
const addPrefix = (id: string) => `focusable-cell-wrapper-${id}`;
|
|
27
|
+
|
|
24
28
|
export function CellWithFocusable(props: Props) {
|
|
25
29
|
const {
|
|
26
30
|
index,
|
|
@@ -40,7 +44,7 @@ export function CellWithFocusable(props: Props) {
|
|
|
40
44
|
const [isFocused, setIsFocused] = React.useState(false);
|
|
41
45
|
|
|
42
46
|
const state = useCellState({
|
|
43
|
-
|
|
47
|
+
item,
|
|
44
48
|
behavior,
|
|
45
49
|
focused: isFocused || toBooleanWithDefaultFalse(focused),
|
|
46
50
|
});
|
|
@@ -79,7 +83,7 @@ export function CellWithFocusable(props: Props) {
|
|
|
79
83
|
|
|
80
84
|
return (
|
|
81
85
|
<FocusableGroup
|
|
82
|
-
id={
|
|
86
|
+
id={addPrefix(id)}
|
|
83
87
|
testID={"cell-with-focusable-cell-renderer-focusable-group"}
|
|
84
88
|
groupId={groupId}
|
|
85
89
|
preferredFocus={preferredFocus}
|
|
@@ -88,19 +92,21 @@ export function CellWithFocusable(props: Props) {
|
|
|
88
92
|
onBlur={onGroupBlur}
|
|
89
93
|
skipFocusManagerRegistration={skipFocusManagerRegistration}
|
|
90
94
|
>
|
|
91
|
-
<
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
95
|
+
<CellWrapper style={styles.cellWrapper}>
|
|
96
|
+
<CellRenderer
|
|
97
|
+
testID={"cell-with-focusable-cell-renderer"}
|
|
98
|
+
item={item}
|
|
99
|
+
groupId={addPrefix(id)}
|
|
100
|
+
onToggleFocus={handleToggleFocus}
|
|
101
|
+
state={state}
|
|
102
|
+
prefixId={id}
|
|
103
|
+
focusedButtonId={focusedButtonId}
|
|
104
|
+
preferredFocus={true}
|
|
105
|
+
skipFocusManagerRegistration={skipFocusManagerRegistration}
|
|
106
|
+
isFocusable={isFocusable}
|
|
107
|
+
focused={focused}
|
|
108
|
+
/>
|
|
109
|
+
</CellWrapper>
|
|
104
110
|
</FocusableGroup>
|
|
105
111
|
);
|
|
106
112
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { View, ViewStyle } from "react-native";
|
|
3
|
+
import { isTvOSPlatform } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
4
|
+
|
|
5
|
+
const isTvOS = isTvOSPlatform();
|
|
6
|
+
|
|
7
|
+
type Props = {
|
|
8
|
+
style: ViewStyle;
|
|
9
|
+
children: React.ReactNode;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const CellWrapper = ({ style, children }: Props) => {
|
|
13
|
+
if (isTvOS) {
|
|
14
|
+
return <View style={style}>{children}</View>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return <>{children}</>;
|
|
18
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { StyleSheet } from "react-native";
|
|
2
|
+
|
|
3
|
+
export const styles = StyleSheet.create({
|
|
4
|
+
cellWrapper: {
|
|
5
|
+
flex: 0,
|
|
6
|
+
height: "100%",
|
|
7
|
+
},
|
|
8
|
+
baseCell: {
|
|
9
|
+
height: "100%",
|
|
10
|
+
display: "flex",
|
|
11
|
+
flex: 1,
|
|
12
|
+
},
|
|
13
|
+
touchableCell: {
|
|
14
|
+
flex: 1,
|
|
15
|
+
height: "100%",
|
|
16
|
+
},
|
|
17
|
+
});
|
|
@@ -105,6 +105,11 @@ const defaultProps = {
|
|
|
105
105
|
alignItems: "center",
|
|
106
106
|
justifyContent: "center",
|
|
107
107
|
},
|
|
108
|
+
focusedButton: {
|
|
109
|
+
backgroundColor: "#3a3a3a",
|
|
110
|
+
borderColor: "#ffffff",
|
|
111
|
+
borderWidth: 2,
|
|
112
|
+
},
|
|
108
113
|
buttonText: {
|
|
109
114
|
fontFamily: platformSelect({
|
|
110
115
|
ios: "SFProText-Medium",
|
|
@@ -116,6 +121,9 @@ const defaultProps = {
|
|
|
116
121
|
color: "rgba(255, 255, 255, 1)",
|
|
117
122
|
textTransform: "uppercase",
|
|
118
123
|
},
|
|
124
|
+
focusedText: {
|
|
125
|
+
color: "#ffffff",
|
|
126
|
+
},
|
|
119
127
|
},
|
|
120
128
|
};
|
|
121
129
|
|
|
@@ -23,7 +23,7 @@ export function FocusableCell(props: Props) {
|
|
|
23
23
|
behavior,
|
|
24
24
|
} = props;
|
|
25
25
|
|
|
26
|
-
const state = useCellState({
|
|
26
|
+
const state = useCellState({ item, behavior, focused });
|
|
27
27
|
|
|
28
28
|
React.useEffect(() => {
|
|
29
29
|
if (focused && scrollTo && !isAndroid) {
|
|
@@ -1,17 +1,30 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { FocusableGroupNative } from "@applicaster/zapp-react-native-ui-components/Components/NativeFocusables";
|
|
3
3
|
import { BaseFocusable } from "@applicaster/zapp-react-native-ui-components/Components/BaseFocusable";
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
import { createLogger } from "@applicaster/zapp-react-native-utils/logger";
|
|
5
|
+
|
|
6
|
+
const { log_verbose } = createLogger({
|
|
7
|
+
subsystem: "General",
|
|
8
|
+
category: "FocusableGroup",
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
type FocusableGroupNativeEvent = {
|
|
12
|
+
nativeEvent: {
|
|
13
|
+
focusHeading: FocusManager.Direction;
|
|
14
|
+
groupId: string;
|
|
15
|
+
isActive: boolean;
|
|
16
|
+
isFocusDisabled: boolean;
|
|
17
|
+
isFocusingByUser: boolean;
|
|
18
|
+
itemId: string;
|
|
19
|
+
target: number;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
6
22
|
|
|
7
23
|
type Props = {
|
|
8
24
|
id: string;
|
|
9
25
|
children: (arg1: boolean) => React.ComponentType<any>;
|
|
10
|
-
onWillUpdateFocus: (nativeEvent: any) => void;
|
|
11
|
-
onDidUpdateFocus: (nativeEvent: any) => void;
|
|
12
26
|
isFocusDisabled: boolean;
|
|
13
|
-
|
|
14
|
-
resetFocusToInitialValue: boolean;
|
|
27
|
+
isWithMemory: boolean;
|
|
15
28
|
focusGroupRef: React.Component;
|
|
16
29
|
shouldUsePreferredFocus: boolean;
|
|
17
30
|
groupId: string;
|
|
@@ -21,86 +34,26 @@ type Props = {
|
|
|
21
34
|
};
|
|
22
35
|
|
|
23
36
|
export class FocusableGroup extends BaseFocusable<Props> {
|
|
24
|
-
focusableGroupNativeRef: React.Component | null;
|
|
25
|
-
constructor(props) {
|
|
26
|
-
super(props);
|
|
27
|
-
this.focusableGroupNativeRef = null;
|
|
28
|
-
|
|
29
|
-
this.state = {
|
|
30
|
-
isActive: false,
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
this.onWillUpdateFocus = this.onWillUpdateFocus.bind(this);
|
|
34
|
-
this.onDidUpdateFocus = this.onDidUpdateFocus.bind(this);
|
|
35
|
-
this.isGroup = true;
|
|
36
|
-
|
|
37
|
-
this.shouldUsePreferredFocus = this.shouldUsePreferredFocus.bind(this);
|
|
38
|
-
this.measureView = this.measureView.bind(this);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
connectedScreenId() {
|
|
42
|
-
const {
|
|
43
|
-
screenData: { screenId, parentScreenId },
|
|
44
|
-
} = this.props;
|
|
45
|
-
|
|
46
|
-
if (screenId) {
|
|
47
|
-
return null;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return parentScreenId ? `${parentScreenId}-${screenId}` : screenId;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* tells whether the group should give focus to a preferred item when it gains focus from another
|
|
55
|
-
* group
|
|
56
|
-
* @returns {boolean}
|
|
57
|
-
*/
|
|
58
|
-
shouldUsePreferredFocus() {
|
|
59
|
-
return this.props.shouldUsePreferredFocus || false;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* indicates whether the underlying component should claim preferred focus
|
|
64
|
-
* when navigating into the group of this item
|
|
65
|
-
* @returns {boolean}
|
|
66
|
-
*/
|
|
67
|
-
isPreferredFocus() {
|
|
68
|
-
return this.props.preferredFocus || false;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
onWillUpdateFocus({ nativeEvent }) {
|
|
72
|
-
const { isActive } = nativeEvent;
|
|
73
|
-
this.setState({ isActive });
|
|
74
|
-
const { onWillUpdateFocus = noop } = this.props;
|
|
75
|
-
onWillUpdateFocus(nativeEvent);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
onDidUpdateFocus({ nativeEvent }) {
|
|
79
|
-
const { onDidUpdateFocus = noop } = this.props;
|
|
80
|
-
onDidUpdateFocus(nativeEvent);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
setFocusDisabled(isFocusDisabled) {
|
|
84
|
-
if (this.ref) {
|
|
85
|
-
this.ref.current.setNativeProps({
|
|
86
|
-
isFocusDisabled,
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
37
|
render() {
|
|
92
38
|
const {
|
|
93
39
|
children,
|
|
94
40
|
id,
|
|
95
41
|
isFocusDisabled,
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
style,
|
|
42
|
+
isWithMemory,
|
|
43
|
+
style = {},
|
|
99
44
|
groupId,
|
|
100
45
|
...otherProps
|
|
101
46
|
} = this.props;
|
|
102
47
|
|
|
103
|
-
const
|
|
48
|
+
const onGroupFocus = ({ nativeEvent }: FocusableGroupNativeEvent) => {
|
|
49
|
+
log_verbose("FOCUSABLE_GROUP: onGroupFocus", { nativeEvent });
|
|
50
|
+
this.onFocus(this.ref, nativeEvent.focusHeading);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const onGroupBlur = ({ nativeEvent }: FocusableGroupNativeEvent) => {
|
|
54
|
+
log_verbose("FOCUSABLE_GROUP: onGroupBlur", { nativeEvent });
|
|
55
|
+
this.onBlur(this.ref, nativeEvent.focusHeading);
|
|
56
|
+
};
|
|
104
57
|
|
|
105
58
|
return (
|
|
106
59
|
<FocusableGroupNative
|
|
@@ -108,16 +61,11 @@ export class FocusableGroup extends BaseFocusable<Props> {
|
|
|
108
61
|
itemId={id}
|
|
109
62
|
ref={this.ref}
|
|
110
63
|
isFocusDisabled={isFocusDisabled}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
onViewPress={this.onPress}
|
|
116
|
-
onViewBlur={this.onBlur}
|
|
117
|
-
style={focusableStyles}
|
|
64
|
+
isWithMemory={isWithMemory}
|
|
65
|
+
onGroupFocus={onGroupFocus}
|
|
66
|
+
onGroupBlur={onGroupBlur}
|
|
67
|
+
style={style}
|
|
118
68
|
{...otherProps}
|
|
119
|
-
onWillUpdateFocus={this.onWillUpdateFocus}
|
|
120
|
-
onDidUpdateFocus={this.onDidUpdateFocus}
|
|
121
69
|
>
|
|
122
70
|
{children}
|
|
123
71
|
</FocusableGroupNative>
|
|
@@ -16,12 +16,9 @@ type Props = {
|
|
|
16
16
|
prioritiseFocusOn?: number;
|
|
17
17
|
groupId?: string;
|
|
18
18
|
hasTVPreferredFocus?: boolean;
|
|
19
|
-
resetFocusToInitialValue?: boolean;
|
|
20
19
|
onFocus?: () => void;
|
|
21
20
|
onBlur?: () => void;
|
|
22
|
-
onWillUpdateFocus?: (event?: any) => void;
|
|
23
21
|
willReceiveFocus?: (event?: any) => void;
|
|
24
|
-
onDidUpdateFocus?: (event?: any) => void;
|
|
25
22
|
hasLostFocus?: any;
|
|
26
23
|
nextFocusUp?: any;
|
|
27
24
|
nextFocusDown?: any;
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import * as R from "ramda";
|
|
3
|
-
import { ViewStyle } from "react-native";
|
|
4
3
|
import {
|
|
5
4
|
findPluginByType,
|
|
6
5
|
findPluginByIdentifier,
|
|
7
6
|
} from "@applicaster/zapp-react-native-utils/pluginUtils";
|
|
8
|
-
import { useDimensions } from "@applicaster/zapp-react-native-utils/reactHooks/layout";
|
|
9
7
|
import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
|
|
10
|
-
import {
|
|
11
|
-
|
|
8
|
+
import {
|
|
9
|
+
useDimensions,
|
|
10
|
+
useNavigation,
|
|
11
|
+
} from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
12
12
|
|
|
13
13
|
import { BufferAnimation } from "../PlayerContainer/BufferAnimation";
|
|
14
14
|
import { PlayerContainer } from "../PlayerContainer";
|
|
15
|
+
import { useModalSize } from "../VideoModal/hooks";
|
|
15
16
|
|
|
16
17
|
type Props = {
|
|
17
18
|
item: ZappEntry;
|
|
@@ -78,12 +79,6 @@ const getPlayer = (
|
|
|
78
79
|
return getPlayerWithModuleProperties(PlayerModule);
|
|
79
80
|
};
|
|
80
81
|
|
|
81
|
-
const dimensionsContext: "window" | "screen" = platformSelect({
|
|
82
|
-
android_tv: "window",
|
|
83
|
-
amazon: "window",
|
|
84
|
-
default: "screen",
|
|
85
|
-
});
|
|
86
|
-
|
|
87
82
|
type PlayableComponent = {
|
|
88
83
|
Component: React.ComponentType<any>;
|
|
89
84
|
};
|
|
@@ -91,16 +86,11 @@ type PlayableComponent = {
|
|
|
91
86
|
export function HandlePlayable({
|
|
92
87
|
item,
|
|
93
88
|
isModal,
|
|
94
|
-
modalHeight,
|
|
95
|
-
modalWidth,
|
|
96
89
|
mode,
|
|
97
90
|
groupId,
|
|
98
91
|
}: Props): React.ReactElement | null {
|
|
99
92
|
const state = usePickFromState();
|
|
100
93
|
|
|
101
|
-
const { width: screenWidth, height: screenHeight } =
|
|
102
|
-
useDimensions(dimensionsContext);
|
|
103
|
-
|
|
104
94
|
const { closeVideoModal } = useNavigation();
|
|
105
95
|
|
|
106
96
|
const [Player, playerModuleProperties] = getPlayer(item, state);
|
|
@@ -118,9 +108,7 @@ export function HandlePlayable({
|
|
|
118
108
|
if (!isModal) {
|
|
119
109
|
closeVideoModal();
|
|
120
110
|
}
|
|
121
|
-
}, []);
|
|
122
111
|
|
|
123
|
-
React.useEffect(() => {
|
|
124
112
|
const castStateHandler = async () => {
|
|
125
113
|
const castState = await CastPlugin?.getCastState();
|
|
126
114
|
setCasting(castState === "Connected");
|
|
@@ -142,23 +130,29 @@ export function HandlePlayable({
|
|
|
142
130
|
}, []);
|
|
143
131
|
|
|
144
132
|
React.useEffect(() => {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
}
|
|
148
|
-
setPlayable({ Component: PlayerContainer });
|
|
149
|
-
}
|
|
133
|
+
setPlayable({
|
|
134
|
+
Component: casting ? CastPlugin?.CastHandler : PlayerContainer,
|
|
135
|
+
});
|
|
150
136
|
}, [casting]);
|
|
151
137
|
|
|
152
|
-
const
|
|
138
|
+
const { width: screenWidth, height: screenHeight } = useDimensions("window");
|
|
139
|
+
|
|
140
|
+
const modalSize = useModalSize();
|
|
153
141
|
|
|
154
142
|
const style = React.useMemo(
|
|
155
143
|
() => ({
|
|
156
|
-
width: isModal ?
|
|
157
|
-
height: isModal
|
|
144
|
+
width: isModal ? modalSize.width : mode === "PIP" ? "100%" : screenWidth,
|
|
145
|
+
height: isModal
|
|
146
|
+
? modalSize.height
|
|
147
|
+
: mode === "PIP"
|
|
148
|
+
? "100%"
|
|
149
|
+
: screenHeight,
|
|
158
150
|
}),
|
|
159
|
-
[screenWidth, screenHeight,
|
|
151
|
+
[screenWidth, screenHeight, modalSize, isModal, mode]
|
|
160
152
|
);
|
|
161
153
|
|
|
154
|
+
const Component = playable?.Component;
|
|
155
|
+
|
|
162
156
|
if (Component) {
|
|
163
157
|
return (
|
|
164
158
|
<Component
|
|
@@ -174,5 +168,5 @@ export function HandlePlayable({
|
|
|
174
168
|
);
|
|
175
169
|
}
|
|
176
170
|
|
|
177
|
-
return !isModal ? <BufferAnimation videoStyle={style
|
|
171
|
+
return !isModal ? <BufferAnimation videoStyle={style} /> : null;
|
|
178
172
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import {
|
|
2
|
+
import { StyleSheet, View } from "react-native";
|
|
3
3
|
|
|
4
4
|
type Props = {
|
|
5
5
|
children: React.ReactNode;
|
|
@@ -13,6 +13,7 @@ const styles = StyleSheet.create({
|
|
|
13
13
|
top: 0,
|
|
14
14
|
zIndex: 10,
|
|
15
15
|
flex: 1,
|
|
16
|
+
width: "100%",
|
|
16
17
|
},
|
|
17
18
|
themeStyles: {
|
|
18
19
|
// limits the height of the focusable container of the TopMenuBarTV component
|
|
@@ -55,8 +55,11 @@ export const ScreenContainer = React.memo(function ScreenContainer({
|
|
|
55
55
|
ComponentsExtraProps,
|
|
56
56
|
NavBar,
|
|
57
57
|
}: Props) {
|
|
58
|
-
const { screenMarginBottom } =
|
|
58
|
+
const { screenMarginBottom, resetScreenLayout } =
|
|
59
|
+
React.useContext(ScreenLayoutContext);
|
|
60
|
+
|
|
59
61
|
const { currentRoute, screenData } = useNavigation();
|
|
62
|
+
|
|
60
63
|
const screen = useCurrentScreenData();
|
|
61
64
|
|
|
62
65
|
const { marginBottom, backgroundColor, paddingTop, paddingBottom } =
|
|
@@ -65,6 +68,10 @@ export const ScreenContainer = React.memo(function ScreenContainer({
|
|
|
65
68
|
const theme = useTheme();
|
|
66
69
|
const getThemeValue = React.useCallback(R.propOr(0, R.__, theme), [theme]);
|
|
67
70
|
|
|
71
|
+
React.useEffect(() => {
|
|
72
|
+
resetScreenLayout();
|
|
73
|
+
}, [currentRoute]);
|
|
74
|
+
|
|
68
75
|
const fullscreen = React.useCallback(
|
|
69
76
|
displayFullScreen({ currentRoute, screenData }),
|
|
70
77
|
[currentRoute, screenData]
|
|
@@ -60,10 +60,15 @@ export function ScreenLayoutContextProvider(props: {
|
|
|
60
60
|
initialState
|
|
61
61
|
);
|
|
62
62
|
|
|
63
|
+
const resetScreenLayout = React.useCallback(() => {
|
|
64
|
+
setScreenLayout(initialState);
|
|
65
|
+
}, [initialState]);
|
|
66
|
+
|
|
63
67
|
const screenLayoutValue = React.useMemo(
|
|
64
68
|
() => ({
|
|
65
69
|
...screenLayout,
|
|
66
70
|
setScreenLayout,
|
|
71
|
+
resetScreenLayout,
|
|
67
72
|
}),
|
|
68
73
|
[screenLayout]
|
|
69
74
|
);
|
|
@@ -56,11 +56,12 @@ describe("ScreenContainer", () => {
|
|
|
56
56
|
};
|
|
57
57
|
|
|
58
58
|
const setScreenLayout = () => {};
|
|
59
|
+
const resetScreenLayout = () => {};
|
|
59
60
|
|
|
60
61
|
const wrapper = ({ children }) => (
|
|
61
62
|
<WrappedWithProviders>
|
|
62
63
|
<ScreenLayoutContext.Provider
|
|
63
|
-
value={{ ...screenLayout, setScreenLayout }}
|
|
64
|
+
value={{ ...screenLayout, setScreenLayout, resetScreenLayout }}
|
|
64
65
|
>
|
|
65
66
|
<ScreenContainer NavBar={View}>{children}</ScreenContainer>
|
|
66
67
|
</ScreenLayoutContext.Provider>
|
|
@@ -4,7 +4,6 @@ import { TouchableOpacity, ViewStyle } from "react-native";
|
|
|
4
4
|
import { useActions } from "@applicaster/zapp-react-native-utils/reactHooks/actions";
|
|
5
5
|
|
|
6
6
|
import Image from "./Image";
|
|
7
|
-
|
|
8
7
|
type Props = {
|
|
9
8
|
item: ZappEntry | ZappFeed;
|
|
10
9
|
flavour?: "flavour_1" | "flavour_2";
|
|
@@ -69,7 +68,7 @@ export function ActionButton(props: Props) {
|
|
|
69
68
|
if (!((actionDisabled || !actionContext) && actionState !== null)) {
|
|
70
69
|
setActionState(actionContext.initialEntryState(item));
|
|
71
70
|
}
|
|
72
|
-
}, [actionDisabled, item?.id, actionContext, action]);
|
|
71
|
+
}, [actionDisabled, item?.id, actionContext, action, setActionState]);
|
|
73
72
|
|
|
74
73
|
const onPress = useCallback(() => {
|
|
75
74
|
actionContext.invokeAction(item, {
|
|
@@ -85,7 +84,7 @@ export function ActionButton(props: Props) {
|
|
|
85
84
|
setActionState(state);
|
|
86
85
|
});
|
|
87
86
|
}
|
|
88
|
-
}, [item?.id]);
|
|
87
|
+
}, [item?.id, setActionState, actionContext]);
|
|
89
88
|
|
|
90
89
|
if (actionDisabled || !actionContext) return null;
|
|
91
90
|
const AssetComponent = actionState?.asset;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { Image as RnImage, ImageStyle } from "react-native";
|
|
3
|
-
import
|
|
3
|
+
import { equals, omit } from "ramda";
|
|
4
4
|
|
|
5
5
|
import { useImageSource } from "./hooks";
|
|
6
6
|
|
|
@@ -17,7 +17,7 @@ type Props = Record<string, any> & {
|
|
|
17
17
|
withDimensions: (source: Source) => Source;
|
|
18
18
|
};
|
|
19
19
|
|
|
20
|
-
const MemoizedImage = React.memo(RnImage,
|
|
20
|
+
const MemoizedImage = React.memo(RnImage, equals);
|
|
21
21
|
|
|
22
22
|
function Image({
|
|
23
23
|
style,
|
|
@@ -44,11 +44,12 @@ function Image({
|
|
|
44
44
|
|
|
45
45
|
return (
|
|
46
46
|
<MemoizedImage
|
|
47
|
+
key={_source?.uri || "no-image"}
|
|
47
48
|
style={style as ImageStyle}
|
|
48
49
|
onError={React.useCallback(() => setErrorState(true), [])}
|
|
49
50
|
// as we have defaults as "" for placeholder image, we need to pass undefined to source to not throw warnings
|
|
50
51
|
source={_source?.uri ? _source : undefined}
|
|
51
|
-
{...
|
|
52
|
+
{...omit(["source"], otherProps)}
|
|
52
53
|
/>
|
|
53
54
|
);
|
|
54
55
|
}
|