@applicaster/zapp-react-native-ui-components 13.0.0-alpha.8865907528 → 13.0.0-alpha.9053464934
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 +3 -5
- 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 +18 -14
- package/Components/Cell/CellWrapper.ts +5 -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 +3 -6
- package/Components/FocusableGroup/index.tsx +0 -1
- package/Components/HandlePlayable/HandlePlayable.tsx +14 -27
- package/Components/MasterCell/DefaultComponents/Image/Image.ios.tsx +4 -3
- package/Components/MasterCell/DefaultComponents/Image/hooks/useImage.ts +11 -7
- package/Components/MasterCell/elementMapper.tsx +2 -1
- package/Components/MasterCell/utils/behaviorProvider.ts +4 -1
- package/Components/MasterCell/utils/index.ts +6 -6
- package/Components/ModalComponent/Button/assets.ts +1 -1
- package/Components/OfflineHandler/utils/index.ts +1 -1
- package/Components/PlayerContainer/PlayerContainer.tsx +9 -5
- package/Components/PlayerImageBackground/index.tsx +4 -24
- package/Components/River/ComponentsMap/ComponentsMap.tsx +4 -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/VideoLive/animationUtils.ts +3 -3
- 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 +17 -4
- package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +2 -2
- package/Components/VideoModal/VideoModal.tsx +2 -2
- package/Decorators/ConfigurationWrapper/withConfigurationProvider.tsx +2 -2
- package/Decorators/RiverResolver/index.tsx +5 -7
- package/Decorators/ZappPipesDataConnector/index.tsx +2 -1
- package/package.json +5 -6
- 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
|
@@ -4,11 +4,9 @@ import { usePrevious } from "@applicaster/zapp-react-native-utils/reactHooks/uti
|
|
|
4
4
|
import { toBooleanWithDefaultFalse } from "@applicaster/zapp-react-native-utils/booleanUtils";
|
|
5
5
|
import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
|
|
6
6
|
|
|
7
|
-
type AnimatedInterpolatedStyle =
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
// | Animated.AnimatedInterpolation
|
|
11
|
-
// | [{ [Key: string]: Animated.AnimatedInterpolation }];
|
|
7
|
+
type AnimatedInterpolatedStyle =
|
|
8
|
+
| Animated.AnimatedInterpolation
|
|
9
|
+
| [{ [Key: string]: Animated.AnimatedInterpolation }];
|
|
12
10
|
|
|
13
11
|
type AnimationConfig = {
|
|
14
12
|
duration: number;
|
|
@@ -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;
|
|
@@ -40,7 +42,7 @@ export function CellWithFocusable(props: Props) {
|
|
|
40
42
|
const [isFocused, setIsFocused] = React.useState(false);
|
|
41
43
|
|
|
42
44
|
const state = useCellState({
|
|
43
|
-
|
|
45
|
+
item,
|
|
44
46
|
behavior,
|
|
45
47
|
focused: isFocused || toBooleanWithDefaultFalse(focused),
|
|
46
48
|
});
|
|
@@ -88,19 +90,21 @@ export function CellWithFocusable(props: Props) {
|
|
|
88
90
|
onBlur={onGroupBlur}
|
|
89
91
|
skipFocusManagerRegistration={skipFocusManagerRegistration}
|
|
90
92
|
>
|
|
91
|
-
<
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
93
|
+
<CellWrapper style={styles.cellWrapper}>
|
|
94
|
+
<CellRenderer
|
|
95
|
+
testID={"cell-with-focusable-cell-renderer"}
|
|
96
|
+
item={item}
|
|
97
|
+
groupId={`focusable-cell-wrapper-${id}`}
|
|
98
|
+
onToggleFocus={handleToggleFocus}
|
|
99
|
+
state={state}
|
|
100
|
+
prefixId={id}
|
|
101
|
+
focusedButtonId={focusedButtonId}
|
|
102
|
+
preferredFocus={true}
|
|
103
|
+
skipFocusManagerRegistration={skipFocusManagerRegistration}
|
|
104
|
+
isFocusable={isFocusable}
|
|
105
|
+
focused={focused}
|
|
106
|
+
/>
|
|
107
|
+
</CellWrapper>
|
|
104
108
|
</FocusableGroup>
|
|
105
109
|
);
|
|
106
110
|
}
|
|
@@ -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) {
|
|
@@ -24,8 +24,7 @@ type Props = {
|
|
|
24
24
|
id: string;
|
|
25
25
|
children: (arg1: boolean) => React.ComponentType<any>;
|
|
26
26
|
isFocusDisabled: boolean;
|
|
27
|
-
|
|
28
|
-
isPreferredFocusDisabled: boolean;
|
|
27
|
+
isWithMemory: boolean;
|
|
29
28
|
focusGroupRef: React.Component;
|
|
30
29
|
shouldUsePreferredFocus: boolean;
|
|
31
30
|
groupId: string;
|
|
@@ -40,8 +39,7 @@ export class FocusableGroup extends BaseFocusable<Props> {
|
|
|
40
39
|
children,
|
|
41
40
|
id,
|
|
42
41
|
isFocusDisabled,
|
|
43
|
-
|
|
44
|
-
isPreferredFocusDisabled,
|
|
42
|
+
isWithMemory,
|
|
45
43
|
style = {},
|
|
46
44
|
groupId,
|
|
47
45
|
...otherProps
|
|
@@ -63,8 +61,7 @@ export class FocusableGroup extends BaseFocusable<Props> {
|
|
|
63
61
|
itemId={id}
|
|
64
62
|
ref={this.ref}
|
|
65
63
|
isFocusDisabled={isFocusDisabled}
|
|
66
|
-
|
|
67
|
-
isPreferredFocusDisabled={isPreferredFocusDisabled}
|
|
64
|
+
isWithMemory={isWithMemory}
|
|
68
65
|
onGroupFocus={onGroupFocus}
|
|
69
66
|
onGroupBlur={onGroupBlur}
|
|
70
67
|
style={style}
|
|
@@ -1,14 +1,14 @@
|
|
|
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";
|
|
@@ -78,12 +78,6 @@ const getPlayer = (
|
|
|
78
78
|
return getPlayerWithModuleProperties(PlayerModule);
|
|
79
79
|
};
|
|
80
80
|
|
|
81
|
-
const dimensionsContext: "window" | "screen" = platformSelect({
|
|
82
|
-
android_tv: "window",
|
|
83
|
-
amazon: "window",
|
|
84
|
-
default: "screen",
|
|
85
|
-
});
|
|
86
|
-
|
|
87
81
|
type PlayableComponent = {
|
|
88
82
|
Component: React.ComponentType<any>;
|
|
89
83
|
};
|
|
@@ -91,16 +85,11 @@ type PlayableComponent = {
|
|
|
91
85
|
export function HandlePlayable({
|
|
92
86
|
item,
|
|
93
87
|
isModal,
|
|
94
|
-
modalHeight,
|
|
95
|
-
modalWidth,
|
|
96
88
|
mode,
|
|
97
89
|
groupId,
|
|
98
90
|
}: Props): React.ReactElement | null {
|
|
99
91
|
const state = usePickFromState();
|
|
100
92
|
|
|
101
|
-
const { width: screenWidth, height: screenHeight } =
|
|
102
|
-
useDimensions(dimensionsContext);
|
|
103
|
-
|
|
104
93
|
const { closeVideoModal } = useNavigation();
|
|
105
94
|
|
|
106
95
|
const [Player, playerModuleProperties] = getPlayer(item, state);
|
|
@@ -118,9 +107,7 @@ export function HandlePlayable({
|
|
|
118
107
|
if (!isModal) {
|
|
119
108
|
closeVideoModal();
|
|
120
109
|
}
|
|
121
|
-
}, []);
|
|
122
110
|
|
|
123
|
-
React.useEffect(() => {
|
|
124
111
|
const castStateHandler = async () => {
|
|
125
112
|
const castState = await CastPlugin?.getCastState();
|
|
126
113
|
setCasting(castState === "Connected");
|
|
@@ -142,23 +129,23 @@ export function HandlePlayable({
|
|
|
142
129
|
}, []);
|
|
143
130
|
|
|
144
131
|
React.useEffect(() => {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
}
|
|
148
|
-
setPlayable({ Component: PlayerContainer });
|
|
149
|
-
}
|
|
132
|
+
setPlayable({
|
|
133
|
+
Component: casting ? CastPlugin?.CastHandler : PlayerContainer,
|
|
134
|
+
});
|
|
150
135
|
}, [casting]);
|
|
151
136
|
|
|
152
|
-
const
|
|
137
|
+
const { width: screenWidth, height: screenHeight } = useDimensions("window");
|
|
153
138
|
|
|
154
139
|
const style = React.useMemo(
|
|
155
140
|
() => ({
|
|
156
|
-
width: isModal ?
|
|
157
|
-
height: isModal ?
|
|
141
|
+
width: isModal ? "100%" : mode === "PIP" ? "100%" : screenWidth,
|
|
142
|
+
height: isModal ? "100%" : mode === "PIP" ? "100%" : screenHeight,
|
|
158
143
|
}),
|
|
159
|
-
[screenWidth, screenHeight,
|
|
144
|
+
[screenWidth, screenHeight, isModal, mode]
|
|
160
145
|
);
|
|
161
146
|
|
|
147
|
+
const Component = playable?.Component;
|
|
148
|
+
|
|
162
149
|
if (Component) {
|
|
163
150
|
return (
|
|
164
151
|
<Component
|
|
@@ -174,5 +161,5 @@ export function HandlePlayable({
|
|
|
174
161
|
);
|
|
175
162
|
}
|
|
176
163
|
|
|
177
|
-
return !isModal ? <BufferAnimation videoStyle={style
|
|
164
|
+
return !isModal ? <BufferAnimation videoStyle={style} /> : null;
|
|
178
165
|
}
|
|
@@ -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
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import
|
|
2
|
+
import { path } from "ramda";
|
|
3
3
|
|
|
4
4
|
import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
5
5
|
import { useActions } from "@applicaster/zapp-react-native-utils/reactHooks/actions";
|
|
@@ -7,9 +7,13 @@ import { extractAsset } from "./utils";
|
|
|
7
7
|
|
|
8
8
|
type Return = { uri: string } | null;
|
|
9
9
|
|
|
10
|
+
const getSourceContext = path(["source", "context"]);
|
|
11
|
+
const getSourceUri = path(["source", "uri"]);
|
|
12
|
+
const getState = path(["state"]);
|
|
13
|
+
|
|
10
14
|
export const useImageSource = ({ uri, entry, otherProps }): Return => {
|
|
11
|
-
const uriContext =
|
|
12
|
-
const uriState =
|
|
15
|
+
const uriContext = getSourceContext(otherProps);
|
|
16
|
+
const uriState = getState(otherProps);
|
|
13
17
|
|
|
14
18
|
const action = useActions(uriContext);
|
|
15
19
|
|
|
@@ -34,7 +38,7 @@ export const useImageSource = ({ uri, entry, otherProps }): Return => {
|
|
|
34
38
|
return { uri };
|
|
35
39
|
}
|
|
36
40
|
|
|
37
|
-
const uriFromSource =
|
|
41
|
+
const uriFromSource = getSourceUri(otherProps);
|
|
38
42
|
|
|
39
43
|
if (uriFromSource) {
|
|
40
44
|
return { uri: uriFromSource };
|
|
@@ -56,7 +60,7 @@ const getSource = (uri, showDefault, placeholderImage, otherProps) => {
|
|
|
56
60
|
return { uri };
|
|
57
61
|
}
|
|
58
62
|
|
|
59
|
-
const uriFromSource =
|
|
63
|
+
const uriFromSource = getSourceUri(otherProps);
|
|
60
64
|
|
|
61
65
|
if (uriFromSource) {
|
|
62
66
|
return { uri: uriFromSource };
|
|
@@ -72,8 +76,8 @@ export const useImageSourceWithDefault = ({
|
|
|
72
76
|
placeholderImage,
|
|
73
77
|
otherProps,
|
|
74
78
|
}): Return => {
|
|
75
|
-
const uriContext =
|
|
76
|
-
const uriState =
|
|
79
|
+
const uriContext = getSourceContext(otherProps);
|
|
80
|
+
const uriState = getState(otherProps);
|
|
77
81
|
|
|
78
82
|
const action = useActions(uriContext);
|
|
79
83
|
|
|
@@ -73,6 +73,7 @@ export function elementMapper(
|
|
|
73
73
|
: {};
|
|
74
74
|
|
|
75
75
|
const componentProps = {
|
|
76
|
+
key,
|
|
76
77
|
style,
|
|
77
78
|
skipButtons: otherProps?.skipButtons,
|
|
78
79
|
emitAsyncElementRegistrate: otherProps?.emitAsyncElementRegistrate,
|
|
@@ -90,7 +91,7 @@ export function elementMapper(
|
|
|
90
91
|
const fn = mapElementWithKey(elementMapper(components, otherProps));
|
|
91
92
|
|
|
92
93
|
return (
|
|
93
|
-
<Component
|
|
94
|
+
<Component {...componentProps}>
|
|
94
95
|
{focusableTypes.has(type) && elements.length > 0
|
|
95
96
|
? elements.map(fn)
|
|
96
97
|
: null}
|
|
@@ -6,6 +6,7 @@ import React, { useEffect } from "react";
|
|
|
6
6
|
import { usePlayer } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayer";
|
|
7
7
|
import { BehaviorSubject } from "rxjs";
|
|
8
8
|
import { masterCellLogger } from "../logger";
|
|
9
|
+
import get from "lodash/get";
|
|
9
10
|
|
|
10
11
|
const parseContextKey = (key: string): string | null => {
|
|
11
12
|
if (!key?.startsWith("@{ctx/")) return null;
|
|
@@ -72,11 +73,13 @@ export const useBehaviorUpdate = (behavior: Behavior) => {
|
|
|
72
73
|
// We cant use async in this function (its inside render),
|
|
73
74
|
// so we rely on useBehaviorUpdate to update current value and trigger re-render
|
|
74
75
|
export const isCellSelected = (
|
|
75
|
-
|
|
76
|
+
item: ZappEntry,
|
|
76
77
|
behavior?: Behavior
|
|
77
78
|
): boolean => {
|
|
78
79
|
if (!behavior) return false;
|
|
79
80
|
|
|
81
|
+
const id = behavior.selector ? get(item, behavior.selector) : item.id;
|
|
82
|
+
|
|
80
83
|
if (behavior.selection_source === "now_playing") {
|
|
81
84
|
const player = playerManager.getActivePlayer();
|
|
82
85
|
|
|
@@ -190,24 +190,24 @@ export const getFocusedButtonId = (focusable) => {
|
|
|
190
190
|
});
|
|
191
191
|
};
|
|
192
192
|
|
|
193
|
-
export const isSelected = (
|
|
194
|
-
return isCellSelected(
|
|
193
|
+
export const isSelected = (item: ZappEntry, behavior?: Behavior) => {
|
|
194
|
+
return isCellSelected(item, behavior);
|
|
195
195
|
};
|
|
196
196
|
|
|
197
197
|
export const useCellState = ({
|
|
198
|
-
|
|
198
|
+
item,
|
|
199
199
|
behavior,
|
|
200
200
|
focused,
|
|
201
201
|
}: {
|
|
202
|
-
|
|
202
|
+
item: ZappEntry;
|
|
203
203
|
behavior: Behavior;
|
|
204
204
|
focused: boolean;
|
|
205
205
|
}): CellState => {
|
|
206
206
|
const lastUpdate = useBehaviorUpdate(behavior);
|
|
207
207
|
|
|
208
208
|
const _isSelected = useMemo(
|
|
209
|
-
() => isSelected(
|
|
210
|
-
[behavior,
|
|
209
|
+
() => isSelected(item, behavior),
|
|
210
|
+
[behavior, item, lastUpdate]
|
|
211
211
|
);
|
|
212
212
|
|
|
213
213
|
return getCellState({ focused, selected: _isSelected });
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
/* eslint-disable max-len */
|
|
2
2
|
|
|
3
3
|
export const defaultSelectedAsset: string =
|
|
4
|
-
"data:image/png;base64,
|
|
4
|
+
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAYAAABV7bNHAAAACXBIWXMAACE4AAAhOAFFljFgAAAA+0lEQVR4nO3a3QnCQBBF4ZRiSXZgKVqKnVnCQBpQwb0QJA752ZjszPlg3/JwOU8b2K4DAAAAAAAAkIOZnczsvPeOQypxHmb27Pv+sveeQxnG0SFSMRaHSIUXJ32kKXHKue+99e+I4yCOgzgO4jiI4yCOgzgO4jiajfMedd366t50nK3/b0LE2SpSqDi1I4WMUytSs3G6z/jbhOGLIzUdR7aKFCKO1I4UKo7UihQyjqyNFDqOLI2UIo7MjZQqjkyNVL7LFUdmRMoXRypEihtHVkSKH0cWRMoTR2ZEyhdHJkTKG0ecSMSRkUjE+TaIRJxfeFQJAAAAAAAANOwFT0Mt2UgcaMoAAAAASUVORK5CYII=";
|
|
@@ -57,7 +57,7 @@ export const useNotificationHeight = () => {
|
|
|
57
57
|
|
|
58
58
|
const navBarHeight = platformSelect({ ios: 44, android: 56 });
|
|
59
59
|
|
|
60
|
-
const statusHeight =
|
|
60
|
+
const statusHeight = insets.top;
|
|
61
61
|
const notificationHeight = statusHeight + navBarHeight;
|
|
62
62
|
|
|
63
63
|
return { statusHeight, notificationHeight };
|
|
@@ -335,9 +335,9 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
335
335
|
|
|
336
336
|
const resumeTime = Number(item?.extensions?.resumeTime);
|
|
337
337
|
|
|
338
|
-
//
|
|
338
|
+
// Сhecking that the player itself knows where to start playing, and there is no need to call seekTo after returning from the Сhromecast
|
|
339
339
|
if (
|
|
340
|
-
|
|
340
|
+
!playerManager.getActivePlayer()?.hasResumePosition() &&
|
|
341
341
|
!isNaN(resumeTime)
|
|
342
342
|
) {
|
|
343
343
|
player?.seekTo(resumeTime);
|
|
@@ -514,6 +514,12 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
514
514
|
useEffect(() => {
|
|
515
515
|
playerEvent("source_changed", { item });
|
|
516
516
|
|
|
517
|
+
return () => {
|
|
518
|
+
playerEvent("player_did_close", { item });
|
|
519
|
+
};
|
|
520
|
+
}, [item?.id, Player]);
|
|
521
|
+
|
|
522
|
+
useEffect(() => {
|
|
517
523
|
if (!isModal) {
|
|
518
524
|
showNavBar(false);
|
|
519
525
|
}
|
|
@@ -523,13 +529,11 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
523
529
|
}
|
|
524
530
|
|
|
525
531
|
return () => {
|
|
526
|
-
playerEvent("player_did_close", { item });
|
|
527
|
-
|
|
528
532
|
if (!isModal) {
|
|
529
533
|
showNavBar(true);
|
|
530
534
|
}
|
|
531
535
|
};
|
|
532
|
-
}, [showNavBar,
|
|
536
|
+
}, [showNavBar, isModal, Player]);
|
|
533
537
|
|
|
534
538
|
useEffect(() => {
|
|
535
539
|
if (prevItemId && !R.equals(prevItemId, item?.id)) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { PropsWithChildren
|
|
1
|
+
import React, { PropsWithChildren } from "react";
|
|
2
2
|
import { ImageBackground, View } from "react-native";
|
|
3
3
|
|
|
4
4
|
import { imageSrcFromMediaItem } from "@applicaster/zapp-react-native-utils/configurationUtils";
|
|
@@ -12,7 +12,6 @@ import {
|
|
|
12
12
|
type Props = PropsWithChildren<{
|
|
13
13
|
entry: ZappEntry;
|
|
14
14
|
style?: { [K: string]: any };
|
|
15
|
-
docked?: boolean;
|
|
16
15
|
imageStyle?: { [K: string]: any };
|
|
17
16
|
imageKey?: string;
|
|
18
17
|
defaultImageDimensions?: { [K: string]: any };
|
|
@@ -24,7 +23,6 @@ const PlayerImageBackgroundComponent = ({
|
|
|
24
23
|
entry,
|
|
25
24
|
children,
|
|
26
25
|
style,
|
|
27
|
-
docked,
|
|
28
26
|
imageStyle,
|
|
29
27
|
imageKey,
|
|
30
28
|
defaultImageDimensions,
|
|
@@ -36,42 +34,24 @@ const PlayerImageBackgroundComponent = ({
|
|
|
36
34
|
|
|
37
35
|
const { playerAnimationState } = useModalAnimationContext();
|
|
38
36
|
|
|
39
|
-
const [lastNonNullAnimationState, setLastNonNullAnimationState] =
|
|
40
|
-
useState(playerAnimationState);
|
|
41
|
-
|
|
42
|
-
useEffect(() => {
|
|
43
|
-
if (playerAnimationState !== null) {
|
|
44
|
-
setLastNonNullAnimationState(playerAnimationState);
|
|
45
|
-
}
|
|
46
|
-
}, [playerAnimationState]);
|
|
47
|
-
|
|
48
37
|
if (!source) return <>{children}</>;
|
|
49
38
|
|
|
50
|
-
const imageBackgroundStyle =
|
|
51
|
-
lastNonNullAnimationState !== PlayerAnimationStateEnum.minimize && !docked
|
|
52
|
-
? defaultImageDimensions
|
|
53
|
-
: imageSize;
|
|
54
|
-
|
|
55
39
|
return (
|
|
56
40
|
<View
|
|
57
41
|
style={
|
|
58
|
-
playerAnimationState === PlayerAnimationStateEnum.
|
|
42
|
+
playerAnimationState === PlayerAnimationStateEnum.maximize
|
|
59
43
|
? defaultImageDimensions
|
|
60
44
|
: style
|
|
61
45
|
}
|
|
62
46
|
>
|
|
63
47
|
<AnimationComponent
|
|
64
|
-
style={
|
|
65
|
-
playerAnimationState === PlayerAnimationStateEnum.maximaze
|
|
66
|
-
? defaultImageDimensions
|
|
67
|
-
: style
|
|
68
|
-
}
|
|
48
|
+
style={style}
|
|
69
49
|
animationType={ComponentAnimationType.player}
|
|
70
50
|
additionalData={defaultImageDimensions}
|
|
71
51
|
>
|
|
72
52
|
<ImageBackground
|
|
73
53
|
resizeMode="cover"
|
|
74
|
-
style={
|
|
54
|
+
style={imageSize}
|
|
75
55
|
imageStyle={imageStyle}
|
|
76
56
|
source={source}
|
|
77
57
|
>
|
|
@@ -34,6 +34,7 @@ type Props = {
|
|
|
34
34
|
getStaticComponentFeed: any;
|
|
35
35
|
pullToRefreshPipesV1RefreshingStateUpdater: () => boolean;
|
|
36
36
|
refreshingPipesV1?: boolean;
|
|
37
|
+
stickyHeaderIndices?: number[];
|
|
37
38
|
};
|
|
38
39
|
|
|
39
40
|
const styles = StyleSheet.create({
|
|
@@ -61,6 +62,7 @@ function ComponentsMapComponent(props: Props) {
|
|
|
61
62
|
// TODO: Remove when pipes v1 is deprecated.
|
|
62
63
|
pullToRefreshPipesV1RefreshingStateUpdater,
|
|
63
64
|
refreshingPipesV1,
|
|
65
|
+
stickyHeaderIndices,
|
|
64
66
|
} = props;
|
|
65
67
|
|
|
66
68
|
const flatListRef = React.useRef<FlatList | null>(null);
|
|
@@ -274,11 +276,13 @@ function ComponentsMapComponent(props: Props) {
|
|
|
274
276
|
overScrollMode={Platform.OS === "android" ? "never" : "auto"}
|
|
275
277
|
scrollIndicatorInsets={scrollIndicatorInsets}
|
|
276
278
|
extraData={feed}
|
|
279
|
+
stickyHeaderIndices={stickyHeaderIndices}
|
|
277
280
|
onLayout={handleOnLayout}
|
|
278
281
|
removeClippedSubviews
|
|
279
282
|
initialNumToRender={3}
|
|
280
283
|
maxToRenderPerBatch={10}
|
|
281
284
|
windowSize={12}
|
|
285
|
+
listKey={riverId}
|
|
282
286
|
keyExtractor={keyExtractor}
|
|
283
287
|
renderItem={renderRiverItem}
|
|
284
288
|
data={riverComponents}
|