@applicaster/zapp-react-native-ui-components 12.0.0-alpha.9233494544 → 12.0.0-alpha.9241554284
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/BaseFocusable/index.tsx +3 -3
- package/Components/Cell/Cell.tsx +30 -13
- package/Components/Cell/CellWithFocusable.tsx +6 -4
- package/Components/Cell/TvOSCellComponent.tsx +3 -7
- package/Components/Focusable/Focusable.tsx +6 -1
- package/Components/FocusableGroup/index.tsx +10 -2
- package/Components/Layout/TV/ScreenContainer.tsx +79 -5
- package/Components/Layout/TV/__tests__/ScreenContainer.test.tsx +38 -28
- package/Components/Layout/TV/__tests__/__snapshots__/ScreenContainer.test.tsx.snap +25 -13
- package/Components/Layout/TV/__tests__/__snapshots__/index.test.tsx.snap +10 -50
- package/Components/Layout/TV/__tests__/index.test.tsx +20 -75
- package/Components/Layout/TV/index.tsx +29 -181
- package/Components/Layout/TV/index.web.tsx +33 -0
- package/Components/Layout/index.tsx +15 -11
- package/Components/MasterCell/DefaultComponents/ActionButton.tsx +4 -1
- package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +86 -116
- package/Components/MasterCell/DefaultComponents/DynamicBadge.tsx +4 -2
- package/Components/MasterCell/DefaultComponents/FocusableView/index.tsx +4 -1
- package/Components/MasterCell/DefaultComponents/ImageBorderContainer/index.ts +57 -0
- package/Components/MasterCell/DefaultComponents/ImageContainer/index.tsx +5 -1
- package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +20 -0
- package/Components/MasterCell/DefaultComponents/Text/index.tsx +14 -2
- package/Components/MasterCell/DefaultComponents/__tests__/text.test.tsx +24 -9
- package/Components/MasterCell/DefaultComponents/index.ts +2 -0
- package/Components/MasterCell/DefaultComponents/tv/ButtonContainerView/index.android.tsx +4 -1
- package/Components/MasterCell/DefaultComponents/tv/ButtonContainerView/index.tsx +10 -2
- package/Components/MasterCell/SharedUI/CollapsibleTextContainer/index.ts +1 -3
- package/Components/MasterCell/SharedUI/ProgressBar/hooks/useFillInPercent.ts +7 -1
- package/Components/MasterCell/dataAdapter.ts +21 -7
- package/Components/MasterCell/hooks/useAsyncRendering/index.ts +1 -1
- package/Components/MasterCell/index.tsx +5 -3
- package/Components/MasterCell/utils/__tests__/insertBetween.test.js +9 -0
- package/Components/MasterCell/utils/index.ts +17 -30
- package/Components/MeasurmentsPortal/BasicMeasurementsPortal.tsx +11 -7
- package/Components/MeasurmentsPortal/MeasurementsPortal.tsx +10 -1
- package/Components/Navigator/StackNavigator.tsx +57 -0
- package/Components/Navigator/index.ts +1 -0
- package/Components/PlayerContainer/PlayerContainer.tsx +3 -0
- package/Components/River/ComponentsMap/ComponentsMap.tsx +24 -17
- package/Components/River/RefreshControl.tsx +55 -1
- package/Components/River/TV/River.tsx +0 -22
- package/Components/RouteManager/index.tsx +2 -2
- package/Components/Screen/TV/hooks/index.ts +3 -0
- package/Components/Screen/TV/hooks/useInitialFocus.ts +70 -0
- package/Components/Screen/TV/hooks/useRestoreFocus.ts +22 -0
- package/Components/Screen/TV/index.web.tsx +40 -44
- package/Components/Screen/__tests__/Screen.test.tsx +3 -49
- package/Components/Screen/index.tsx +55 -76
- package/Components/Screen/navigationHandler.ts +5 -0
- package/Components/Screen/orientationHandler.ts +18 -7
- package/Components/Screen/utils.ts +16 -0
- package/Components/ScreenResolver/index.tsx +6 -11
- package/Components/Transitioner/Scene.tsx +40 -26
- package/Components/Transitioner/Transitioner.tsx +46 -48
- package/Components/Transitioner/__tests__/Scene.test.js +7 -0
- package/Components/Transitioner/__tests__/__snapshots__/Scene.test.js.snap +12 -4
- package/Components/Transitioner/__tests__/__snapshots__/transitioner.test.js.snap +2 -0
- package/Components/VideoLive/LiveImageManager.ts +28 -1
- package/Components/VideoLive/PlayerLiveImageComponent.tsx +52 -24
- package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +26 -24
- package/Components/VideoModal/ModalAnimation/AnimatedPlayerModalWrapper.tsx +2 -14
- package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +79 -45
- package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.tsx +47 -33
- package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +121 -86
- package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +44 -5
- package/Components/VideoModal/ModalAnimation/utils.ts +7 -4
- package/Components/VideoModal/PlayerDetails.tsx +3 -3
- package/Components/VideoModal/PlayerWrapper.tsx +67 -60
- package/Components/VideoModal/VideoModal.tsx +17 -17
- package/Components/VideoModal/__tests__/PlayerWrapper.test.tsx +7 -0
- package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +80 -14
- package/Components/VideoModal/hooks/useModalSize.ts +10 -12
- package/Components/VideoModal/utils.ts +5 -2
- package/Components/Viewport/ViewportTracker/ViewportTracker.tsx +31 -40
- package/Components/default-cell-renderer/__tests__/__snapshots__/defaultCellRenderer.test.tsx.snap +4 -4
- package/Contexts/FocusableGroupContext/FocusableGroupContext.ts +3 -0
- package/Contexts/FocusableGroupContext/FocusableGroupContextProvider.tsx +16 -0
- package/Contexts/FocusableGroupContext/__tests__/FocusableGroupContextProvider.test.tsx +22 -0
- package/Contexts/FocusableGroupContext/__tests__/withFocusableContext.test.tsx +26 -0
- package/Contexts/FocusableGroupContext/index.ts +7 -0
- package/Contexts/FocusableGroupContext/withFocusableContext.tsx +17 -0
- package/Contexts/ScreenContext/index.tsx +2 -2
- package/Contexts/ScreenDataContext/index.tsx +20 -0
- package/events/index.ts +1 -0
- package/package.json +5 -5
- package/Components/Layout/TV/TransitionOverlay.tsx +0 -64
- /package/Components/FocusableGroup/{index.android.js → index.android.ts} +0 -0
- /package/Components/FocusableGroup/{index.ios.js → index.ios.ts} +0 -0
|
@@ -7,50 +7,28 @@ type BorderPosition = "inside" | "outside" | "center";
|
|
|
7
7
|
interface Props {
|
|
8
8
|
style: ImageStyle | ViewStyle;
|
|
9
9
|
borderPosition: BorderPosition;
|
|
10
|
+
borderPaddingTop: number;
|
|
11
|
+
borderPaddingRight: number;
|
|
12
|
+
borderPaddingBottom: number;
|
|
13
|
+
borderPaddingLeft: number;
|
|
10
14
|
children: React.ReactNode;
|
|
11
15
|
}
|
|
12
16
|
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
if (typeof value === "string" && value.endsWith("%")) {
|
|
29
|
-
return true;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return false;
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
const calculateContainerSpacing = ({
|
|
36
|
-
spacingKey,
|
|
37
|
-
style,
|
|
38
|
-
additionalSpacing,
|
|
39
|
-
}: {
|
|
40
|
-
spacingKey: typeof MARGINS[number] | typeof PADDINGS[number];
|
|
41
|
-
style: ImageStyle | ViewStyle;
|
|
42
|
-
additionalSpacing: number;
|
|
43
|
-
}) => {
|
|
44
|
-
return {
|
|
45
|
-
[spacingKey]:
|
|
46
|
-
toNumberWithDefaultZero(style[spacingKey]) + additionalSpacing,
|
|
47
|
-
};
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
const getContainerBorderWidth = (
|
|
51
|
-
borderPosition: BorderPosition,
|
|
52
|
-
borderWidth
|
|
53
|
-
) => {
|
|
17
|
+
const COLOR_TRANSPARENT = "transparent";
|
|
18
|
+
|
|
19
|
+
const styles = StyleSheet.create({
|
|
20
|
+
container: {
|
|
21
|
+
overflow: "visible",
|
|
22
|
+
borderWidth: 0,
|
|
23
|
+
borderColor: COLOR_TRANSPARENT,
|
|
24
|
+
},
|
|
25
|
+
border: {
|
|
26
|
+
...StyleSheet.absoluteFillObject,
|
|
27
|
+
zIndex: 1,
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const getBorderPadding = (borderPosition: BorderPosition, borderWidth) => {
|
|
54
32
|
switch (borderPosition) {
|
|
55
33
|
case "inside":
|
|
56
34
|
return 0;
|
|
@@ -63,104 +41,96 @@ const getContainerBorderWidth = (
|
|
|
63
41
|
}
|
|
64
42
|
};
|
|
65
43
|
|
|
66
|
-
const
|
|
67
|
-
switch (borderPosition) {
|
|
68
|
-
case "inside":
|
|
69
|
-
return borderWidth;
|
|
70
|
-
case "center":
|
|
71
|
-
return borderWidth / 2;
|
|
72
|
-
case "outside":
|
|
73
|
-
return 0;
|
|
74
|
-
default:
|
|
75
|
-
return 0;
|
|
76
|
-
}
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
const InsideBorder = ({
|
|
44
|
+
const Border = ({
|
|
80
45
|
style,
|
|
46
|
+
padding,
|
|
81
47
|
borderPosition,
|
|
82
48
|
}: {
|
|
83
49
|
style: ViewStyle;
|
|
50
|
+
padding: ViewStyle;
|
|
84
51
|
borderPosition: BorderPosition;
|
|
85
52
|
}) => {
|
|
86
|
-
if (borderPosition
|
|
53
|
+
if (!borderPosition) {
|
|
87
54
|
return null;
|
|
88
55
|
}
|
|
89
56
|
|
|
90
|
-
const
|
|
91
|
-
|
|
57
|
+
const borderWidth = toNumberWithDefaultZero(style.borderWidth);
|
|
58
|
+
const containerPadding = getBorderPadding(borderPosition, borderWidth);
|
|
59
|
+
|
|
60
|
+
const initialBorderRadius = toNumberWithDefaultZero(style.borderRadius);
|
|
61
|
+
const paddingTop = toNumberWithDefaultZero(padding.paddingTop);
|
|
62
|
+
const paddingRight = toNumberWithDefaultZero(padding.paddingRight);
|
|
63
|
+
const paddingBottom = toNumberWithDefaultZero(padding.paddingBottom);
|
|
64
|
+
const paddingLeft = toNumberWithDefaultZero(padding.paddingLeft);
|
|
65
|
+
|
|
66
|
+
const borderRadiusStyle = initialBorderRadius
|
|
67
|
+
? {
|
|
68
|
+
borderTopLeftRadius:
|
|
69
|
+
initialBorderRadius +
|
|
70
|
+
containerPadding +
|
|
71
|
+
Math.min(paddingTop, paddingLeft),
|
|
72
|
+
borderTopRightRadius:
|
|
73
|
+
initialBorderRadius +
|
|
74
|
+
containerPadding +
|
|
75
|
+
Math.min(paddingTop, paddingRight),
|
|
76
|
+
borderBottomLeftRadius:
|
|
77
|
+
initialBorderRadius +
|
|
78
|
+
containerPadding +
|
|
79
|
+
Math.min(paddingBottom, paddingLeft),
|
|
80
|
+
borderBottomRightRadius:
|
|
81
|
+
initialBorderRadius +
|
|
82
|
+
containerPadding +
|
|
83
|
+
Math.min(paddingBottom, paddingRight),
|
|
84
|
+
}
|
|
85
|
+
: {
|
|
86
|
+
borderTopLeftRadius: 0,
|
|
87
|
+
borderTopRightRadius: 0,
|
|
88
|
+
borderBottomLeftRadius: 0,
|
|
89
|
+
borderBottomRightRadius: 0,
|
|
90
|
+
};
|
|
92
91
|
|
|
93
92
|
return (
|
|
94
93
|
<View
|
|
94
|
+
pointerEvents="none"
|
|
95
95
|
style={{
|
|
96
|
-
...
|
|
97
|
-
|
|
96
|
+
...styles.border,
|
|
97
|
+
right: -containerPadding - paddingRight,
|
|
98
|
+
bottom: -containerPadding - paddingBottom,
|
|
99
|
+
left: -containerPadding - paddingLeft,
|
|
100
|
+
top: -containerPadding - paddingTop,
|
|
101
|
+
borderWidth,
|
|
98
102
|
borderColor: style.borderColor,
|
|
99
|
-
|
|
103
|
+
...borderRadiusStyle,
|
|
100
104
|
}}
|
|
101
105
|
/>
|
|
102
106
|
);
|
|
103
107
|
};
|
|
104
108
|
|
|
105
109
|
export const BorderContainerView = (props: Props) => {
|
|
106
|
-
const {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
const updatedPaddings = PADDINGS.reduce((acc, padding) => {
|
|
127
|
-
const paddingValue = calculateContainerSpacing({
|
|
128
|
-
spacingKey: padding,
|
|
129
|
-
style,
|
|
130
|
-
additionalSpacing: spacing,
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
return { ...acc, ...paddingValue };
|
|
134
|
-
}, {});
|
|
135
|
-
|
|
136
|
-
const updatedWidth = style.width
|
|
137
|
-
? isPercentageValue(style.width)
|
|
138
|
-
? style.width
|
|
139
|
-
: toNumberWithDefaultZero(style.width) - spacing * 2
|
|
140
|
-
: undefined;
|
|
141
|
-
|
|
142
|
-
const updatedHeight = style.height
|
|
143
|
-
? isPercentageValue(style.height)
|
|
144
|
-
? style.height
|
|
145
|
-
: toNumberWithDefaultZero(style.height) - spacing * 2
|
|
146
|
-
: undefined;
|
|
147
|
-
|
|
148
|
-
const containerStyle = {
|
|
149
|
-
borderWidth: getContainerBorderWidth(borderPosition, borderWidth),
|
|
150
|
-
padding: spacing,
|
|
151
|
-
...updatedMargins,
|
|
152
|
-
...updatedPaddings,
|
|
153
|
-
width: updatedWidth,
|
|
154
|
-
height: updatedHeight,
|
|
155
|
-
};
|
|
110
|
+
const {
|
|
111
|
+
borderPosition,
|
|
112
|
+
borderPaddingTop,
|
|
113
|
+
borderPaddingRight,
|
|
114
|
+
borderPaddingBottom,
|
|
115
|
+
borderPaddingLeft,
|
|
116
|
+
style,
|
|
117
|
+
children,
|
|
118
|
+
} = props;
|
|
119
|
+
|
|
120
|
+
const padding =
|
|
121
|
+
borderPosition === "outside"
|
|
122
|
+
? {
|
|
123
|
+
paddingTop: borderPaddingTop,
|
|
124
|
+
paddingRight: borderPaddingRight,
|
|
125
|
+
paddingBottom: borderPaddingBottom,
|
|
126
|
+
paddingLeft: borderPaddingLeft,
|
|
127
|
+
}
|
|
128
|
+
: {};
|
|
156
129
|
|
|
157
130
|
return (
|
|
158
|
-
<View {...props} style={[style,
|
|
131
|
+
<View {...props} style={[style, styles.container]} pointerEvents="box-none">
|
|
132
|
+
<Border style={style} padding={padding} borderPosition={borderPosition} />
|
|
159
133
|
{children}
|
|
160
|
-
<InsideBorder
|
|
161
|
-
style={{ ...style, ...borderStyleForMissingBorder }}
|
|
162
|
-
borderPosition={borderPosition}
|
|
163
|
-
/>
|
|
164
134
|
</View>
|
|
165
135
|
);
|
|
166
136
|
};
|
|
@@ -4,6 +4,7 @@ import { usePlayer } from "@applicaster/zapp-react-native-utils/appUtils/playerM
|
|
|
4
4
|
|
|
5
5
|
type DynamicBadgeProps = {
|
|
6
6
|
cellUUID?: string;
|
|
7
|
+
uri?: string;
|
|
7
8
|
};
|
|
8
9
|
|
|
9
10
|
const DynamicBadgeComponent = (props: DynamicBadgeProps) => {
|
|
@@ -12,11 +13,12 @@ const DynamicBadgeComponent = (props: DynamicBadgeProps) => {
|
|
|
12
13
|
// TODO: Initial value should depends on player state (playing or not)
|
|
13
14
|
const [showImage, setShowImage] = React.useState(true);
|
|
14
15
|
const player = usePlayer(playerId);
|
|
16
|
+
const uri = props?.uri;
|
|
15
17
|
|
|
16
18
|
React.useEffect(() => {
|
|
17
19
|
if (playerId && player) {
|
|
18
20
|
return player.addListener({
|
|
19
|
-
id:
|
|
21
|
+
id: `dynamic-badges-${uri}`,
|
|
20
22
|
listener: {
|
|
21
23
|
onPlayerClose: () => {
|
|
22
24
|
setShowImage(true);
|
|
@@ -35,7 +37,7 @@ const DynamicBadgeComponent = (props: DynamicBadgeProps) => {
|
|
|
35
37
|
} else {
|
|
36
38
|
setShowImage(true);
|
|
37
39
|
}
|
|
38
|
-
}, [player]);
|
|
40
|
+
}, [player, uri]);
|
|
39
41
|
|
|
40
42
|
if (!showImage) {
|
|
41
43
|
return null;
|
|
@@ -4,6 +4,7 @@ import { Focusable } from "@applicaster/zapp-react-native-ui-components/Componen
|
|
|
4
4
|
import { useActions } from "@applicaster/zapp-react-native-utils/reactHooks/actions";
|
|
5
5
|
import * as R from "ramda";
|
|
6
6
|
import { getXray } from "@applicaster/zapp-react-native-utils/logger";
|
|
7
|
+
import { toBooleanWithDefaultFalse } from "@applicaster/zapp-react-native-utils/booleanUtils";
|
|
7
8
|
|
|
8
9
|
const { Logger } = getXray();
|
|
9
10
|
|
|
@@ -35,7 +36,9 @@ export function FocusableView({ style, children, item, ...otherProps }: Props) {
|
|
|
35
36
|
|
|
36
37
|
const focusableId = getFocusableId(prefixId, suffixId);
|
|
37
38
|
|
|
38
|
-
const focused =
|
|
39
|
+
const focused =
|
|
40
|
+
focusableId === focusedButtonId ||
|
|
41
|
+
toBooleanWithDefaultFalse(otherProps.focused);
|
|
39
42
|
|
|
40
43
|
const additionalStyles = focused ? focusedStyles : normalStyles;
|
|
41
44
|
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { ImageStyle } from "react-native";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
getImageContainerMarginStyles,
|
|
5
|
+
ifElseFocusedSelected,
|
|
6
|
+
} from "@applicaster/zapp-react-native-utils/cellUtils";
|
|
7
|
+
import { toNumberWithDefaultZero } from "@applicaster/zapp-react-native-utils/numberUtils";
|
|
8
|
+
|
|
9
|
+
export const ImageBorderContainer = ({
|
|
10
|
+
value,
|
|
11
|
+
state,
|
|
12
|
+
imageStyles,
|
|
13
|
+
}: {
|
|
14
|
+
value: (key: string) => string;
|
|
15
|
+
state: CellState;
|
|
16
|
+
imageStyles: ImageStyle;
|
|
17
|
+
}) => {
|
|
18
|
+
return {
|
|
19
|
+
type: "BorderContainerView",
|
|
20
|
+
style: {
|
|
21
|
+
...getImageContainerMarginStyles({ value }),
|
|
22
|
+
position: "absolute",
|
|
23
|
+
top: 0,
|
|
24
|
+
zIndex: 1,
|
|
25
|
+
borderWidth: value("image_border_size"),
|
|
26
|
+
borderColor: ifElseFocusedSelected(
|
|
27
|
+
state,
|
|
28
|
+
value("image_focused_border_color"),
|
|
29
|
+
value("image_selected_border_color"),
|
|
30
|
+
value("image_focused_selected_border_color"),
|
|
31
|
+
value("image_border_color")
|
|
32
|
+
),
|
|
33
|
+
borderRadius: toNumberWithDefaultZero(value("image_corner_radius")),
|
|
34
|
+
},
|
|
35
|
+
additionalProps: {
|
|
36
|
+
borderPosition: value("image_border_position"),
|
|
37
|
+
borderPaddingTop: toNumberWithDefaultZero(
|
|
38
|
+
value("image_border_padding_top")
|
|
39
|
+
),
|
|
40
|
+
borderPaddingRight: toNumberWithDefaultZero(
|
|
41
|
+
value("image_border_padding_right")
|
|
42
|
+
),
|
|
43
|
+
borderPaddingBottom: toNumberWithDefaultZero(
|
|
44
|
+
value("image_border_padding_bottom")
|
|
45
|
+
),
|
|
46
|
+
borderPaddingLeft: toNumberWithDefaultZero(
|
|
47
|
+
value("image_border_padding_left")
|
|
48
|
+
),
|
|
49
|
+
},
|
|
50
|
+
elements: [
|
|
51
|
+
{
|
|
52
|
+
type: "View",
|
|
53
|
+
style: imageStyles,
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
};
|
|
57
|
+
};
|
|
@@ -2,6 +2,7 @@ import React from "react";
|
|
|
2
2
|
import { isVideoPreviewEnabled } from "@applicaster/zapp-react-native-ui-components/Components/MasterCell/utils";
|
|
3
3
|
import { LiveImage } from "../LiveImage";
|
|
4
4
|
import PureImage from "../Image";
|
|
5
|
+
import { useIsScreenActive } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
5
6
|
|
|
6
7
|
type Props = {
|
|
7
8
|
enable_video_preview: boolean;
|
|
@@ -9,7 +10,10 @@ type Props = {
|
|
|
9
10
|
};
|
|
10
11
|
|
|
11
12
|
export const ImageContainer = (props: Props) => {
|
|
12
|
-
const
|
|
13
|
+
const isActive = useIsScreenActive();
|
|
14
|
+
|
|
15
|
+
const Component =
|
|
16
|
+
isVideoPreviewEnabled(props) && isActive ? LiveImage : PureImage;
|
|
13
17
|
|
|
14
18
|
return <Component {...props} />;
|
|
15
19
|
};
|
|
@@ -108,6 +108,26 @@ const prepareEntry = (entry) => {
|
|
|
108
108
|
};
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
+
const previewPlayback =
|
|
112
|
+
entry.extensions?.["brightcove"]?.["preview_playback"];
|
|
113
|
+
|
|
114
|
+
if (previewPlayback) {
|
|
115
|
+
return {
|
|
116
|
+
...entry,
|
|
117
|
+
extensions: {
|
|
118
|
+
...entry.extensions,
|
|
119
|
+
brightcove: {
|
|
120
|
+
...entry?.extensions?.["brightcove"],
|
|
121
|
+
video_id: previewPlayback,
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (entry.extensions?.["brightcove"]?.["video_id"]) {
|
|
128
|
+
return entry;
|
|
129
|
+
}
|
|
130
|
+
|
|
111
131
|
const src = entry.content?.src;
|
|
112
132
|
|
|
113
133
|
if (!src) {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { Text } from "react-native";
|
|
3
3
|
import { omit } from "ramda";
|
|
4
|
-
import { isNilOrEmpty } from "@applicaster/zapp-react-native-utils/reactUtils/helpers";
|
|
5
4
|
import {
|
|
6
5
|
textTransform,
|
|
7
6
|
dateFormat,
|
|
@@ -9,6 +8,9 @@ import {
|
|
|
9
8
|
|
|
10
9
|
import { useTextLabel, withFocusedStyles } from "./hooks";
|
|
11
10
|
import { withScaledLineHeight } from "./utils";
|
|
11
|
+
import { toNumber } from "@applicaster/zapp-react-native-utils/numberUtils";
|
|
12
|
+
import { MeasurementPortalContext } from "../../../MeasurmentsPortal";
|
|
13
|
+
import { isNilOrEmpty } from "@applicaster/zapp-react-native-utils/reactUtils/helpers";
|
|
12
14
|
|
|
13
15
|
type Props = {
|
|
14
16
|
style: any;
|
|
@@ -32,14 +34,24 @@ const _Text = ({
|
|
|
32
34
|
...otherProps
|
|
33
35
|
}: Props) => {
|
|
34
36
|
const _label = useTextLabel({ label, entry });
|
|
37
|
+
const isMeasurement = React.useContext(MeasurementPortalContext);
|
|
35
38
|
|
|
36
39
|
if (isNilOrEmpty(_label)) {
|
|
37
40
|
return null;
|
|
38
41
|
}
|
|
39
42
|
|
|
43
|
+
// set maximum possible height for the text in case of measurement
|
|
44
|
+
const height =
|
|
45
|
+
isMeasurement && otherProps.numberOfLines && style.lineHeight
|
|
46
|
+
? toNumber(otherProps.numberOfLines) * toNumber(style.lineHeight)
|
|
47
|
+
: undefined;
|
|
48
|
+
|
|
40
49
|
return (
|
|
41
50
|
<Text
|
|
42
|
-
style={
|
|
51
|
+
style={[
|
|
52
|
+
withScaledLineHeight(withFocusedStyles({ style, otherProps })),
|
|
53
|
+
{ height },
|
|
54
|
+
]}
|
|
43
55
|
{...withoutLabel(otherProps)}
|
|
44
56
|
>
|
|
45
57
|
{dateTransformEnabled
|
|
@@ -1,11 +1,23 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import
|
|
2
|
+
import RN from "react-native";
|
|
3
3
|
import { Provider } from "react-redux";
|
|
4
4
|
import TestRenderer from "react-test-renderer";
|
|
5
|
-
import
|
|
6
|
-
import CustomText from "../Text";
|
|
5
|
+
import configureStoreFn from "redux-mock-store";
|
|
7
6
|
|
|
8
|
-
const
|
|
7
|
+
const mockUseIsRTL = jest.fn(() => true);
|
|
8
|
+
const mockGetIsRTL = jest.fn(() => true);
|
|
9
|
+
const mockUseLocalizedStrings = jest.fn(() => ({}));
|
|
10
|
+
const mockGetUILanguage = jest.fn(() => "he-HE");
|
|
11
|
+
|
|
12
|
+
jest.mock("@applicaster/zapp-react-native-utils/localizationUtils", () => ({
|
|
13
|
+
useIsRTL: mockUseIsRTL,
|
|
14
|
+
getIsRTL: mockGetIsRTL,
|
|
15
|
+
useLocalizedStrings: mockUseLocalizedStrings,
|
|
16
|
+
getUILanguage: mockGetUILanguage,
|
|
17
|
+
}));
|
|
18
|
+
|
|
19
|
+
const CustomText = require("../Text").default;
|
|
20
|
+
const mockStore = configureStoreFn();
|
|
9
21
|
|
|
10
22
|
const defaultProps = {
|
|
11
23
|
entry: {},
|
|
@@ -22,7 +34,7 @@ const getRenderedText = (label: string, store: any) => {
|
|
|
22
34
|
</Provider>
|
|
23
35
|
);
|
|
24
36
|
|
|
25
|
-
return testRenderer.root.findByType(Text).props.children;
|
|
37
|
+
return testRenderer.root.findByType(RN.Text).props.children;
|
|
26
38
|
};
|
|
27
39
|
|
|
28
40
|
describe("RTL app: Hebrew text contains english word", () => {
|
|
@@ -34,7 +46,7 @@ describe("RTL app: Hebrew text contains english word", () => {
|
|
|
34
46
|
remoteConfigurations: { localizations: { he: {} } },
|
|
35
47
|
appData: {
|
|
36
48
|
languageCode: "he",
|
|
37
|
-
countryCode: "
|
|
49
|
+
countryCode: "IL",
|
|
38
50
|
},
|
|
39
51
|
});
|
|
40
52
|
|
|
@@ -47,18 +59,22 @@ describe("RTL app: Hebrew text contains english word", () => {
|
|
|
47
59
|
|
|
48
60
|
it("Hebrew text contains not first english word", () => {
|
|
49
61
|
const renderedText = getRenderedText(textWithNotFirstEnglishWord, store);
|
|
50
|
-
|
|
51
62
|
expect(renderedText).toEqual(textWithNotFirstEnglishWord);
|
|
52
63
|
});
|
|
53
64
|
|
|
54
65
|
it("Hebrew text doesn't contain english word", () => {
|
|
55
66
|
const renderedText = getRenderedText(textWithoutEnglishWord, store);
|
|
56
|
-
|
|
57
67
|
expect(renderedText).toEqual(textWithoutEnglishWord);
|
|
58
68
|
});
|
|
59
69
|
});
|
|
60
70
|
|
|
61
71
|
describe("LTR app: English text", () => {
|
|
72
|
+
beforeAll(() => {
|
|
73
|
+
mockUseIsRTL.mockReturnValue(false);
|
|
74
|
+
mockGetIsRTL.mockReturnValue(false);
|
|
75
|
+
mockGetUILanguage.mockReturnValue("en-US");
|
|
76
|
+
});
|
|
77
|
+
|
|
62
78
|
const englishText = "Test sentence";
|
|
63
79
|
|
|
64
80
|
const store = mockStore({
|
|
@@ -71,7 +87,6 @@ describe("LTR app: English text", () => {
|
|
|
71
87
|
|
|
72
88
|
it("English text", () => {
|
|
73
89
|
const renderedText = getRenderedText(englishText, store);
|
|
74
|
-
|
|
75
90
|
expect(renderedText).toEqual(englishText);
|
|
76
91
|
});
|
|
77
92
|
});
|
|
@@ -15,6 +15,7 @@ import { BorderContainerView } from "./BorderContainerView";
|
|
|
15
15
|
import { CellBadge } from "./CellBadge";
|
|
16
16
|
import { TvActionButtons } from "./tv/TvActionButtons";
|
|
17
17
|
import { ButtonContainerView } from "./tv/ButtonContainerView";
|
|
18
|
+
import { ImageBorderContainer } from "./ImageBorderContainer";
|
|
18
19
|
|
|
19
20
|
export const defaultComponents = {
|
|
20
21
|
View,
|
|
@@ -28,6 +29,7 @@ export const defaultComponents = {
|
|
|
28
29
|
ProgressBar,
|
|
29
30
|
Toggle,
|
|
30
31
|
LiveImage,
|
|
32
|
+
ImageBorderContainer,
|
|
31
33
|
BorderContainerView,
|
|
32
34
|
DynamicBadge,
|
|
33
35
|
SecondaryImage,
|
|
@@ -61,7 +61,10 @@ export function ButtonContainerView({
|
|
|
61
61
|
<View style={applyRTLStylesIfNeeded(style, isRTL)}>
|
|
62
62
|
{insertBetween(
|
|
63
63
|
(index) => (
|
|
64
|
-
<HorizontalSeparator
|
|
64
|
+
<HorizontalSeparator
|
|
65
|
+
key={`separator_${index}`}
|
|
66
|
+
width={horizontalGutter}
|
|
67
|
+
/>
|
|
65
68
|
),
|
|
66
69
|
cloneElementsWithIds(buttonIds, filteredChildren)
|
|
67
70
|
)}
|
|
@@ -7,6 +7,10 @@ import type {
|
|
|
7
7
|
ContainerProps,
|
|
8
8
|
ContainerChildren,
|
|
9
9
|
} from "./types";
|
|
10
|
+
import {
|
|
11
|
+
useIsRTL,
|
|
12
|
+
applyRTLStylesIfNeeded,
|
|
13
|
+
} from "@applicaster/zapp-react-native-utils/localizationUtils";
|
|
10
14
|
|
|
11
15
|
const HorizontalSeparator = ({ width }: HorizontalSeparatorProps) => (
|
|
12
16
|
<View style={{ width }} />
|
|
@@ -17,6 +21,7 @@ export function ButtonContainerView({
|
|
|
17
21
|
children,
|
|
18
22
|
...otherProps
|
|
19
23
|
}: ContainerProps) {
|
|
24
|
+
const isRTL = useIsRTL();
|
|
20
25
|
const horizontalGutter = R.pathOr(0, ["horizontalGutter"], otherProps);
|
|
21
26
|
|
|
22
27
|
const filteredChildren = useFilterChildren<ContainerChildren>(children);
|
|
@@ -26,10 +31,13 @@ export function ButtonContainerView({
|
|
|
26
31
|
}
|
|
27
32
|
|
|
28
33
|
return (
|
|
29
|
-
<View style={style}>
|
|
34
|
+
<View style={applyRTLStylesIfNeeded(style, isRTL)}>
|
|
30
35
|
{insertBetween(
|
|
31
36
|
(index) => (
|
|
32
|
-
<HorizontalSeparator
|
|
37
|
+
<HorizontalSeparator
|
|
38
|
+
key={`separator_${index}`}
|
|
39
|
+
width={horizontalGutter}
|
|
40
|
+
/>
|
|
33
41
|
),
|
|
34
42
|
filteredChildren
|
|
35
43
|
)}
|
|
@@ -51,9 +51,7 @@ export const CollapsibleTextContainer = ({
|
|
|
51
51
|
func: (data) => {
|
|
52
52
|
return getColorFromData({
|
|
53
53
|
data,
|
|
54
|
-
|
|
55
|
-
key: "background_color",
|
|
56
|
-
defaultColor: additionalStyles.backgroundColor,
|
|
54
|
+
valueFromLayout: additionalStyles.backgroundColor,
|
|
57
55
|
});
|
|
58
56
|
},
|
|
59
57
|
propName: "backgroundColor",
|
|
@@ -5,6 +5,7 @@ import * as R from "ramda";
|
|
|
5
5
|
|
|
6
6
|
import { useActions } from "@applicaster/zapp-react-native-utils/reactHooks/actions";
|
|
7
7
|
import { normalizeProgressValue } from "./utils";
|
|
8
|
+
import { useIsScreenActive } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
8
9
|
|
|
9
10
|
const ACTION_NAME = "continue-watching";
|
|
10
11
|
const DEFAULT_FILL = 0;
|
|
@@ -27,6 +28,7 @@ const getProgressValue = (
|
|
|
27
28
|
|
|
28
29
|
export const useFillInPercent = (entry: ZappEntry): number => {
|
|
29
30
|
const action = useActions(ACTION_NAME);
|
|
31
|
+
const isActive = useIsScreenActive();
|
|
30
32
|
|
|
31
33
|
const [fillInPercent, setFillInPercent] =
|
|
32
34
|
React.useState<number>(DEFAULT_FILL);
|
|
@@ -39,6 +41,10 @@ export const useFillInPercent = (entry: ZappEntry): number => {
|
|
|
39
41
|
}, []);
|
|
40
42
|
|
|
41
43
|
React.useEffect(() => {
|
|
44
|
+
if (!isActive) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
42
48
|
// refresh progress in UI when it was changed in CW
|
|
43
49
|
const unsubscribe = action?.addDataSourceListener?.(() => {
|
|
44
50
|
getProgressValue(action, entry, (progress) => {
|
|
@@ -49,7 +55,7 @@ export const useFillInPercent = (entry: ZappEntry): number => {
|
|
|
49
55
|
return () => {
|
|
50
56
|
unsubscribe?.();
|
|
51
57
|
};
|
|
52
|
-
}, []);
|
|
58
|
+
}, [isActive]);
|
|
53
59
|
|
|
54
60
|
return fillInPercent;
|
|
55
61
|
};
|
|
@@ -37,14 +37,28 @@ function retrieveData(entry, func, args) {
|
|
|
37
37
|
*/
|
|
38
38
|
|
|
39
39
|
export function configInflater(
|
|
40
|
-
entry,
|
|
41
|
-
{
|
|
40
|
+
entry: any,
|
|
41
|
+
{
|
|
42
|
+
type,
|
|
43
|
+
style,
|
|
44
|
+
additionalProps = {},
|
|
45
|
+
data = [],
|
|
46
|
+
elements,
|
|
47
|
+
}: {
|
|
48
|
+
type: any;
|
|
49
|
+
style: any;
|
|
50
|
+
additionalProps?: Record<string, any>;
|
|
51
|
+
data?: Array<{ propName: string; func: Function; args: any[] }>;
|
|
52
|
+
elements?: any[];
|
|
53
|
+
}
|
|
42
54
|
) {
|
|
43
|
-
const props =
|
|
44
|
-
(acc, curr) =>
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
55
|
+
const props = data.reduce(
|
|
56
|
+
(acc, curr) => {
|
|
57
|
+
acc[curr.propName] = retrieveData(entry, curr.func, curr.args);
|
|
58
|
+
|
|
59
|
+
return acc;
|
|
60
|
+
},
|
|
61
|
+
{ ...additionalProps }
|
|
48
62
|
);
|
|
49
63
|
|
|
50
64
|
let adjustedElements;
|