@applicaster/zapp-react-native-ui-components 14.0.0-alpha.3881160800 → 14.0.0-alpha.4009339136

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.
Files changed (30) hide show
  1. package/Components/AnimatedInOut/index.tsx +3 -5
  2. package/Components/AudioPlayer/tv/Artwork.tsx +3 -2
  3. package/Components/AudioPlayer/tv/Channel.tsx +7 -7
  4. package/Components/AudioPlayer/tv/Layout.tsx +100 -93
  5. package/Components/AudioPlayer/tv/Runtime.tsx +7 -1
  6. package/Components/AudioPlayer/tv/Summary.tsx +6 -2
  7. package/Components/AudioPlayer/tv/Title.tsx +6 -2
  8. package/Components/AudioPlayer/tv/__tests__/__snapshots__/Runtime.test.js.snap +2 -2
  9. package/Components/AudioPlayer/tv/__tests__/__snapshots__/audioPlayer.test.js.snap +20 -26
  10. package/Components/AudioPlayer/tv/__tests__/__snapshots__/channel.test.js.snap +8 -17
  11. package/Components/AudioPlayer/tv/__tests__/__snapshots__/summary.test.js.snap +1 -2
  12. package/Components/AudioPlayer/tv/__tests__/__snapshots__/title.test.js.snap +1 -2
  13. package/Components/AudioPlayer/tv/index.tsx +6 -0
  14. package/Components/Focusable/FocusableTvOS.tsx +3 -3
  15. package/Components/HandlePlayable/HandlePlayable.tsx +8 -14
  16. package/Components/MasterCell/elementMapper.tsx +2 -1
  17. package/Components/MasterCell/index.tsx +1 -1
  18. package/Components/OfflineHandler/NotificationView/__tests__/index.test.tsx +18 -13
  19. package/Components/OfflineHandler/__tests__/__snapshots__/index.test.tsx.snap +0 -9
  20. package/Components/PlayerContainer/PlayerContainer.tsx +1 -1
  21. package/Components/River/ComponentsMap/ComponentsMap.tsx +1 -0
  22. package/Components/River/TV/withTVEventHandler.tsx +1 -1
  23. package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +0 -2
  24. package/Components/Touchable/__tests__/__snapshots__/touchable.test.tsx.snap +0 -34
  25. package/Components/Transitioner/__tests__/__snapshots__/Scene.test.js.snap +9 -15
  26. package/Components/VideoLive/animationUtils.ts +3 -3
  27. package/Components/Viewport/ViewportAware/__tests__/viewportAware.test.js +16 -12
  28. package/Components/Viewport/ViewportTracker/__tests__/viewportTracker.test.js +24 -84
  29. package/Decorators/ConfigurationWrapper/withConfigurationProvider.tsx +2 -2
  30. package/package.json +6 -5
@@ -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 = any;
8
-
9
- // type AnimatedInterpolatedStyle =
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;
@@ -1,5 +1,6 @@
1
1
  import React from "react";
2
- import { View, Image, StyleSheet } from "react-native";
2
+ import { View, StyleSheet } from "react-native";
3
+ import { QBImage } from "@applicaster/zapp-react-native-ui-components/Components/Image";
3
4
  import { toNumberWithDefaultZero } from "@applicaster/zapp-react-native-utils/numberUtils";
4
5
 
5
6
  const styles = StyleSheet.create({
@@ -29,7 +30,7 @@ export function Artwork({ srcImage, config }: Props) {
29
30
 
30
31
  return (
31
32
  <View style={styles.container}>
32
- <Image
33
+ <QBImage
33
34
  fadeDuration={0}
34
35
  source={{ uri: srcImage }}
35
36
  style={[styles.image, { borderRadius }]}
@@ -1,5 +1,6 @@
1
1
  import React from "react";
2
- import { View, Image } from "react-native";
2
+ import { Image } from "react-native";
3
+ import { isNilOrEmpty } from "@applicaster/zapp-react-native-utils/reactUtils/helpers";
3
4
 
4
5
  type Props = {
5
6
  srcImage: string;
@@ -15,17 +16,16 @@ type Props = {
15
16
  const imageStyles = {
16
17
  width: 128,
17
18
  height: 72,
18
- };
19
19
 
20
- const containerStyles = {
21
- ...imageStyles,
22
20
  marginBottom: 30,
23
21
  };
24
22
 
25
23
  export function Channel({ srcImage }: Props) {
24
+ if (isNilOrEmpty(srcImage)) {
25
+ return null;
26
+ }
27
+
26
28
  return (
27
- <View style={containerStyles}>
28
- <Image fadeDuration={0} source={{ uri: srcImage }} style={imageStyles} />
29
- </View>
29
+ <Image fadeDuration={0} source={{ uri: srcImage }} style={imageStyles} />
30
30
  );
31
31
  }
@@ -1,5 +1,5 @@
1
1
  import * as React from "react";
2
- import { View, ImageBackground, ViewStyle } from "react-native";
2
+ import { ImageBackground, View, ViewStyle } from "react-native";
3
3
 
4
4
  import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
5
5
 
@@ -11,6 +11,7 @@ type Props = {
11
11
  config: {
12
12
  titleColor: string;
13
13
  summaryColor: string;
14
+ backgroundImageOverlay?: string;
14
15
  backgroundColor: string;
15
16
  backgroundImage: Option<string>;
16
17
  isRTL: boolean;
@@ -20,13 +21,40 @@ type Props = {
20
21
  style: ViewStyle;
21
22
  };
22
23
 
24
+ const backgroundImgStyles = platformSelect({
25
+ tvos: {
26
+ width: "100%",
27
+ height: "100%",
28
+ alignItems: "center",
29
+ justifyContent: "center",
30
+ },
31
+ android_tv: {
32
+ width: "100%",
33
+ height: "100%",
34
+ alignItems: "center",
35
+ justifyContent: "center",
36
+ },
37
+ web: {
38
+ position: "absolute",
39
+ margin: "auto",
40
+ display: "flex",
41
+ flexWrap: "wrap",
42
+ width: "100%",
43
+ height: "100%",
44
+ flex: 1,
45
+ alignItems: "center",
46
+ justifyContent: "center",
47
+ },
48
+ });
49
+
23
50
  export function AudioPlayerTVLayout({
24
51
  artwork,
25
52
  config,
26
53
  children,
27
54
  style,
28
55
  }: Props) {
29
- const { isRTL, backgroundColor, backgroundImage } = config;
56
+ const { backgroundColor, backgroundImage, backgroundImageOverlay, isRTL } =
57
+ config;
30
58
 
31
59
  const backgroundImageSource = { uri: backgroundImage };
32
60
 
@@ -34,108 +62,87 @@ export function AudioPlayerTVLayout({
34
62
  ? "transparent"
35
63
  : backgroundColor;
36
64
 
37
- const mainContainerStyles = platformSelect({
65
+ const textContainerStyles = platformSelect({
38
66
  tvos: {
39
- width: "100%",
40
- height: "100%",
41
- alignItems: "center",
42
67
  justifyContent: "center",
43
- flexDirection: directionStyles(isRTL).flexDirection,
44
- backgroundColor: backgroundColorStyle,
68
+ alignItems: directionStyles(isRTL).justifyContent,
45
69
  },
46
70
  android_tv: {
47
- width: "100%",
48
- height: "100%",
49
- alignItems: "center",
50
71
  justifyContent: "center",
51
- flexDirection: directionStyles(isRTL).flexDirection,
52
- backgroundColor: backgroundColorStyle,
72
+ alignItems: directionStyles(isRTL).justifyContent,
53
73
  },
54
74
  web: {
55
- width: 1920,
56
- height: 1080,
57
- alignItems: "center",
58
- justifyContent: "center",
59
- flexDirection: directionStyles(isRTL).flexDirection,
60
- backgroundColor: backgroundColorStyle,
61
- },
62
- native: {
63
- backgroundColor: backgroundColorStyle,
64
- overflow: "hidden",
65
- ...style,
66
- },
67
- samsung_tv: {
68
- position: "absolute",
69
- margin: "auto",
70
- display: "flex",
71
- flexWrap: "wrap",
72
- width: "100vw",
73
- flex: 1,
74
- alignItems: "center",
75
- justifyContent: "center",
76
- flexDirection: directionStyles(isRTL).flexDirection,
77
- backgroundColor: backgroundColorStyle,
78
- },
79
- lg_tv: {
80
- position: "absolute",
81
- margin: "auto",
82
- display: "flex",
83
- flexWrap: "wrap",
84
- width: "100vw",
85
- flex: 1,
86
- alignItems: "center",
87
75
  justifyContent: "center",
88
- flexDirection: directionStyles(isRTL).flexDirection,
89
- backgroundColor: backgroundColorStyle,
76
+ alignItems: directionStyles(isRTL).justifyContent,
90
77
  },
91
78
  });
92
79
 
93
- const backgroundImgStyles = platformSelect({
94
- tvos: {
95
- width: "100%",
96
- height: "100%",
97
- alignItems: "center",
98
- justifyContent: "center",
99
- },
100
- android_tv: {
101
- width: "100%",
102
- height: "100%",
103
- alignItems: "center",
104
- justifyContent: "center",
105
- },
106
- web: {
107
- position: "absolute",
108
- margin: "auto",
109
- display: "flex",
110
- flexWrap: "wrap",
111
- width: "100%",
112
- height: "100%",
113
- flex: 1,
114
- alignItems: "center",
115
- justifyContent: "center",
116
- },
117
- });
80
+ const mainContainerStyles = React.useMemo(
81
+ () =>
82
+ platformSelect({
83
+ tvos: {
84
+ width: "100%",
85
+ height: "100%",
86
+ alignItems: "center",
87
+ justifyContent: "center",
88
+ flexDirection: directionStyles(isRTL).flexDirection,
89
+ backgroundColor: backgroundColorStyle,
90
+ },
91
+ android_tv: {
92
+ width: "100%",
93
+ height: "100%",
94
+ alignItems: "center",
95
+ justifyContent: "center",
96
+ flexDirection: directionStyles(isRTL).flexDirection,
97
+ backgroundColor: backgroundColorStyle,
98
+ },
99
+ web: {
100
+ width: 1920,
101
+ height: 1080,
102
+ alignItems: "center",
103
+ justifyContent: "center",
104
+ flexDirection: directionStyles(isRTL).flexDirection,
105
+ backgroundColor: backgroundColorStyle,
106
+ },
107
+ native: {
108
+ backgroundColor: backgroundColorStyle,
109
+ overflow: "hidden",
110
+ ...style,
111
+ },
112
+ samsung_tv: {
113
+ position: "absolute",
114
+ margin: "auto",
115
+ display: "flex",
116
+ flexWrap: "wrap",
117
+ height: "100vh",
118
+ width: "100vw",
119
+ alignItems: "center",
120
+ justifyContent: "center",
121
+ flexDirection: directionStyles(isRTL).flexDirection,
122
+ backgroundColor: backgroundColorStyle,
123
+ },
124
+ lg_tv: {
125
+ position: "absolute",
126
+ margin: "auto",
127
+ display: "flex",
128
+ flexWrap: "wrap",
129
+ height: "100vh",
130
+ width: "100vw",
131
+ alignItems: "center",
132
+ justifyContent: "center",
133
+ flexDirection: directionStyles(isRTL).flexDirection,
134
+ backgroundColor: backgroundColorStyle,
135
+ },
136
+ }),
137
+ [backgroundColorStyle, isRTL, style]
138
+ );
118
139
 
119
- const textContainerStyles = platformSelect({
120
- tvos: {
121
- width: 600,
122
- height: 362,
123
- marginHorizontal: 24,
124
- alignItems: directionStyles(isRTL).justifyContent,
125
- },
126
- android_tv: {
127
- width: 600,
128
- height: 362,
129
- marginHorizontal: 24,
130
- alignItems: directionStyles(isRTL).justifyContent,
131
- },
132
- web: {
133
- margin: 10,
134
- height: "100vh",
135
- alignItems: directionStyles(isRTL).justifyContent,
136
- justifyContent: "center",
137
- },
138
- });
140
+ const backgroundOverlayStyles = React.useMemo(
141
+ () => ({
142
+ backgroundColor: backgroundImageOverlay,
143
+ }),
144
+ [backgroundImageOverlay]
145
+ );
139
146
 
140
147
  if (backgroundImage) {
141
148
  return (
@@ -144,7 +151,7 @@ export function AudioPlayerTVLayout({
144
151
  style={backgroundImgStyles}
145
152
  resizeMode="cover"
146
153
  >
147
- <View style={mainContainerStyles}>
154
+ <View style={[mainContainerStyles, backgroundOverlayStyles]}>
148
155
  <Artwork srcImage={artwork} config={config} />
149
156
  <View style={textContainerStyles}>{children}</View>
150
157
  </View>
@@ -1,6 +1,8 @@
1
1
  import React from "react";
2
2
  import { View, Text, ViewStyle, TextStyle } from "react-native";
3
3
  import { toNumberWithDefault } from "@applicaster/zapp-react-native-utils/numberUtils";
4
+ import { isNilOrEmpty } from "@applicaster/zapp-react-native-utils/reactUtils/helpers";
5
+
4
6
  import { directionStyles } from "./helpers";
5
7
 
6
8
  type Props = {
@@ -19,7 +21,6 @@ type Props = {
19
21
 
20
22
  const containerStyles = ({ isRTL }) => ({
21
23
  width: 600,
22
- height: 40,
23
24
  justifyContent: directionStyles(isRTL)
24
25
  .justifyContent as ViewStyle["justifyContent"],
25
26
  });
@@ -38,11 +39,16 @@ const textStyles = ({
38
39
  });
39
40
 
40
41
  export function Runtime({ start_time, end_time, config }: Props) {
42
+ if (isNilOrEmpty(start_time) && isNilOrEmpty(end_time)) {
43
+ return null;
44
+ }
45
+
41
46
  return (
42
47
  <View style={containerStyles({ isRTL: config.isRTL })}>
43
48
  {!!start_time && !!end_time && (
44
49
  <Text
45
50
  style={textStyles(config) as TextStyle}
51
+ numberOfLines={1}
46
52
  >{`${start_time} - ${end_time}`}</Text>
47
53
  )}
48
54
  </View>
@@ -1,6 +1,7 @@
1
1
  import React from "react";
2
2
  import { View, Text, TextStyle, StyleSheet } from "react-native";
3
3
  import { toNumberWithDefault } from "@applicaster/zapp-react-native-utils/numberUtils";
4
+ import { isNilOrEmpty } from "@applicaster/zapp-react-native-utils/reactUtils/helpers";
4
5
 
5
6
  type Props = {
6
7
  config: {
@@ -18,7 +19,6 @@ type Props = {
18
19
  const styles = StyleSheet.create({
19
20
  container: {
20
21
  width: 600,
21
- height: 80,
22
22
  marginBottom: 30,
23
23
  },
24
24
  });
@@ -38,9 +38,13 @@ const textStyles = ({
38
38
  });
39
39
 
40
40
  export function Summary({ summary, config }: Props) {
41
+ if (isNilOrEmpty(summary)) {
42
+ return null;
43
+ }
44
+
41
45
  return (
42
46
  <View style={styles.container}>
43
- <Text style={textStyles(config)} numberOfLines={2}>
47
+ <Text style={textStyles(config)} numberOfLines={3}>
44
48
  {summary}
45
49
  </Text>
46
50
  </View>
@@ -1,6 +1,7 @@
1
1
  import React from "react";
2
2
  import { View, Text, TextStyle, StyleSheet } from "react-native";
3
3
  import { toNumberWithDefault } from "@applicaster/zapp-react-native-utils/numberUtils";
4
+ import { isNilOrEmpty } from "@applicaster/zapp-react-native-utils/reactUtils/helpers";
4
5
 
5
6
  type Props = {
6
7
  config: {
@@ -18,7 +19,6 @@ type Props = {
18
19
  const styles = StyleSheet.create({
19
20
  container: {
20
21
  width: 600,
21
- height: 100,
22
22
  marginBottom: 12,
23
23
  },
24
24
  });
@@ -32,9 +32,13 @@ const textStyles = ({ titleColor, isRTL, titleFontFamily, titleFontSize }) => ({
32
32
  });
33
33
 
34
34
  export function Title({ title, config }: Props) {
35
+ if (isNilOrEmpty(title)) {
36
+ return null;
37
+ }
38
+
35
39
  return (
36
40
  <View style={styles.container}>
37
- <Text style={textStyles(config)} numberOfLines={2}>
41
+ <Text style={textStyles(config)} numberOfLines={3}>
38
42
  {title}
39
43
  </Text>
40
44
  </View>
@@ -4,13 +4,13 @@ exports[`<Runtime /> LTR renders correctly 1`] = `
4
4
  <View
5
5
  style={
6
6
  {
7
- "height": 40,
8
7
  "justifyContent": "flex-start",
9
8
  "width": 600,
10
9
  }
11
10
  }
12
11
  >
13
12
  <Text
13
+ numberOfLines={1}
14
14
  style={
15
15
  {
16
16
  "alignItems": "flex-end",
@@ -33,13 +33,13 @@ exports[`<Runtime /> RTL renders correctly 1`] = `
33
33
  <View
34
34
  style={
35
35
  {
36
- "height": 40,
37
36
  "justifyContent": "flex-end",
38
37
  "width": 600,
39
38
  }
40
39
  }
41
40
  >
42
41
  <Text
42
+ numberOfLines={1}
43
43
  style={
44
44
  {
45
45
  "alignItems": "flex-start",
@@ -30,10 +30,15 @@ exports[`<AudioPlayerTV /> renders correctly 1`] = `
30
30
  />
31
31
  <View
32
32
  style={
33
- {
34
- "backgroundColor": "transparent",
35
- "overflow": "hidden",
36
- }
33
+ [
34
+ {
35
+ "backgroundColor": "transparent",
36
+ "overflow": "hidden",
37
+ },
38
+ {
39
+ "backgroundColor": undefined,
40
+ },
41
+ ]
37
42
  }
38
43
  >
39
44
  <View
@@ -65,7 +70,13 @@ exports[`<AudioPlayerTV /> renders correctly 1`] = `
65
70
  />
66
71
  </View>
67
72
  <View>
68
- <View
73
+ <Image
74
+ fadeDuration={0}
75
+ source={
76
+ {
77
+ "uri": "https://example.com",
78
+ }
79
+ }
69
80
  style={
70
81
  {
71
82
  "height": 72,
@@ -73,33 +84,17 @@ exports[`<AudioPlayerTV /> renders correctly 1`] = `
73
84
  "width": 128,
74
85
  }
75
86
  }
76
- >
77
- <Image
78
- fadeDuration={0}
79
- source={
80
- {
81
- "uri": "https://example.com",
82
- }
83
- }
84
- style={
85
- {
86
- "height": 72,
87
- "width": 128,
88
- }
89
- }
90
- />
91
- </View>
87
+ />
92
88
  <View
93
89
  style={
94
90
  {
95
- "height": 100,
96
91
  "marginBottom": 12,
97
92
  "width": 600,
98
93
  }
99
94
  }
100
95
  >
101
96
  <Text
102
- numberOfLines={2}
97
+ numberOfLines={3}
103
98
  style={
104
99
  {
105
100
  "color": "white",
@@ -116,14 +111,13 @@ exports[`<AudioPlayerTV /> renders correctly 1`] = `
116
111
  <View
117
112
  style={
118
113
  {
119
- "height": 80,
120
114
  "marginBottom": 30,
121
115
  "width": 600,
122
116
  }
123
117
  }
124
118
  >
125
119
  <Text
126
- numberOfLines={2}
120
+ numberOfLines={3}
127
121
  style={
128
122
  {
129
123
  "color": "white",
@@ -141,13 +135,13 @@ exports[`<AudioPlayerTV /> renders correctly 1`] = `
141
135
  <View
142
136
  style={
143
137
  {
144
- "height": 40,
145
138
  "justifyContent": "flex-end",
146
139
  "width": 600,
147
140
  }
148
141
  }
149
142
  >
150
143
  <Text
144
+ numberOfLines={1}
151
145
  style={
152
146
  {
153
147
  "alignItems": "flex-start",
@@ -1,7 +1,13 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
3
  exports[`<Channel /> renders correctly 1`] = `
4
- <View
4
+ <Image
5
+ fadeDuration={0}
6
+ source={
7
+ {
8
+ "uri": "https://example.com",
9
+ }
10
+ }
5
11
  style={
6
12
  {
7
13
  "height": 72,
@@ -9,20 +15,5 @@ exports[`<Channel /> renders correctly 1`] = `
9
15
  "width": 128,
10
16
  }
11
17
  }
12
- >
13
- <Image
14
- fadeDuration={0}
15
- source={
16
- {
17
- "uri": "https://example.com",
18
- }
19
- }
20
- style={
21
- {
22
- "height": 72,
23
- "width": 128,
24
- }
25
- }
26
- />
27
- </View>
18
+ />
28
19
  `;
@@ -4,14 +4,13 @@ exports[`<Summary /> renders correctly 1`] = `
4
4
  <View
5
5
  style={
6
6
  {
7
- "height": 80,
8
7
  "marginBottom": 30,
9
8
  "width": 600,
10
9
  }
11
10
  }
12
11
  >
13
12
  <Text
14
- numberOfLines={2}
13
+ numberOfLines={3}
15
14
  style={
16
15
  {
17
16
  "color": "white",
@@ -4,14 +4,13 @@ exports[`<Title /> renders correctly 1`] = `
4
4
  <View
5
5
  style={
6
6
  {
7
- "height": 100,
8
7
  "marginBottom": 12,
9
8
  "width": 600,
10
9
  }
11
10
  }
12
11
  >
13
12
  <Text
14
- numberOfLines={2}
13
+ numberOfLines={3}
15
14
  style={
16
15
  {
17
16
  "color": "white",
@@ -35,6 +35,11 @@ export function AudioPlayerTV(props: Props) {
35
35
  const backgroundImage = getProp("audio_player_background_image");
36
36
  const channelIcon = getProp("audio_player_channel_icon");
37
37
  const rtlFlag = getProp("audio_player_rtl");
38
+
39
+ const backgroundImageOverlay = getProp(
40
+ "audio_player_background_image_overlay"
41
+ );
42
+
38
43
  const artworkBorderRadius = getProp("audio_player_artwork_border_radius");
39
44
 
40
45
  const isRTL = rtlFlag === "1" || rtlFlag === "true" || rtlFlag === true;
@@ -113,6 +118,7 @@ export function AudioPlayerTV(props: Props) {
113
118
  runTimeFontSize,
114
119
  channelIcon,
115
120
  artworkBorderRadius,
121
+ backgroundImageOverlay,
116
122
  };
117
123
  }, [getProp]);
118
124
 
@@ -16,9 +16,9 @@ function noop() {}
16
16
  type Props = {
17
17
  id: string;
18
18
  groupId: string;
19
- onPress?: (nativeEvent: any) => void;
20
- onFocus?: (nativeEvent: any) => void;
21
- onBlur?: (nativeEvent: any) => void;
19
+ onPress?: (nativeEvent: React.SyntheticEvent) => void;
20
+ onFocus?: (nativeEvent: React.SyntheticEvent) => void;
21
+ onBlur?: (nativeEvent: React.SyntheticEvent) => void;
22
22
  children: (focused?: boolean) => React.ReactNode;
23
23
  isParallaxDisabled: boolean;
24
24
  preferredFocus?: boolean;
@@ -13,7 +13,6 @@ import {
13
13
  import { BufferAnimation } from "../PlayerContainer/BufferAnimation";
14
14
  import { PlayerContainer } from "../PlayerContainer";
15
15
  import { useModalSize } from "../VideoModal/hooks";
16
- import { ViewStyle } from "react-native";
17
16
 
18
17
  type Props = {
19
18
  item: ZappEntry;
@@ -141,19 +140,14 @@ export function HandlePlayable({
141
140
  const modalSize = useModalSize();
142
141
 
143
142
  const style = React.useMemo(
144
- () =>
145
- ({
146
- width: isModal
147
- ? modalSize.width
148
- : mode === "PIP"
149
- ? "100%"
150
- : screenWidth,
151
- height: isModal
152
- ? modalSize.height
153
- : mode === "PIP"
154
- ? "100%"
155
- : screenHeight,
156
- }) as ViewStyle,
143
+ () => ({
144
+ width: isModal ? modalSize.width : mode === "PIP" ? "100%" : screenWidth,
145
+ height: isModal
146
+ ? modalSize.height
147
+ : mode === "PIP"
148
+ ? "100%"
149
+ : screenHeight,
150
+ }),
157
151
  [screenWidth, screenHeight, modalSize, isModal, mode]
158
152
  );
159
153
 
@@ -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 key={key} {...componentProps}>
94
+ <Component {...componentProps}>
94
95
  {focusableTypes.has(type) && elements.length > 0
95
96
  ? elements.map(fn)
96
97
  : null}
@@ -86,7 +86,7 @@ export function masterCellBuilder({
86
86
  entry: item,
87
87
  state: getEntryState(state, entryIsSelected),
88
88
  }),
89
- [state, item?.id, entryIsSelected] // Assuming that item won't mutate
89
+ [state, item, entryIsSelected] // Assuming that item won't mutate
90
90
  );
91
91
 
92
92
  const wrapperRef = React.useRef(null);
@@ -1,12 +1,9 @@
1
1
  import React from "react";
2
2
  import { Text, Animated } from "react-native";
3
- import { render } from "@testing-library/react-native";
4
3
 
5
- import {
6
- NotificationView,
7
- onlinePhrase,
8
- offlinePhrase,
9
- } from "../NotificationView";
4
+ import renderer from "react-test-renderer";
5
+
6
+ jest.useFakeTimers();
10
7
 
11
8
  jest.mock("@applicaster/zapp-react-native-redux/hooks", () => ({
12
9
  usePickFromState: () => ({
@@ -35,31 +32,39 @@ jest.mock("react-native-safe-area-context", () => ({
35
32
 
36
33
  const dismiss = jest.fn();
37
34
 
35
+ const {
36
+ NotificationView,
37
+ onlinePhrase,
38
+ offlinePhrase,
39
+ } = require("../NotificationView");
40
+
38
41
  describe("NotificationView", () => {
39
42
  it("Show online message when Online", () => {
40
- const component = render(<NotificationView online dismiss={dismiss} />);
43
+ const component = renderer.create(
44
+ <NotificationView online dismiss={dismiss} />
45
+ );
41
46
 
42
- expect(component.UNSAFE_getByType(Text).props.children).toBe(onlinePhrase);
47
+ expect(component.root.findByType(Text).props.children).toBe(onlinePhrase);
43
48
  });
44
49
 
45
50
  it("Show offline message when Online", () => {
46
- const component = render(
51
+ const component = renderer.create(
47
52
  <NotificationView online={false} dismiss={dismiss} />
48
53
  );
49
54
 
50
- expect(component.UNSAFE_getByType(Text).props.children).toBe(offlinePhrase);
55
+ expect(component.root.findByType(Text).props.children).toBe(offlinePhrase);
51
56
  });
52
57
 
53
58
  it("When hidden is false to true notification is visible", () => {
54
- const component = render(
59
+ const component = renderer.create(
55
60
  <NotificationView online={false} hidden={false} dismiss={dismiss} />
56
61
  );
57
62
 
58
- component.rerender(
63
+ component.update(
59
64
  <NotificationView online={false} hidden={true} dismiss={dismiss} />
60
65
  );
61
66
 
62
- const animatedView = component.UNSAFE_getByType(Animated.View);
67
+ const animatedView = component.root.findByType(Animated.View);
63
68
  const animatedViewStyles = animatedView.props.style;
64
69
 
65
70
  expect(animatedViewStyles.opacity).toBe(1);
@@ -21,15 +21,6 @@ exports[`OfflineHandler renders 1`] = `
21
21
  }
22
22
  >
23
23
  <View
24
- accessibilityState={
25
- {
26
- "busy": undefined,
27
- "checked": undefined,
28
- "disabled": undefined,
29
- "expanded": undefined,
30
- "selected": undefined,
31
- }
32
- }
33
24
  accessible={true}
34
25
  collapsable={false}
35
26
  focusable={true}
@@ -627,7 +627,7 @@ const PlayerContainerComponent = (props: Props) => {
627
627
  <PlayerContainerContext.Consumer>
628
628
  {(context) => (
629
629
  <TVEventHandlerComponent
630
- tvEventHandler={(event) =>
630
+ tvEventHandler={(_component, event) =>
631
631
  playerRemoteHandler(event, context.isLanguageOverlayVisible)
632
632
  }
633
633
  >
@@ -286,6 +286,7 @@ function ComponentsMapComponent(props: Props) {
286
286
  initialNumToRender={3}
287
287
  maxToRenderPerBatch={10}
288
288
  windowSize={12}
289
+ listKey={riverId}
289
290
  keyExtractor={keyExtractor}
290
291
  renderItem={renderRiverItem}
291
292
  data={riverComponents}
@@ -8,7 +8,7 @@ export const withTvEventHandler = (Component) => {
8
8
  return function WithTVEventHandler(props) {
9
9
  const navigator = useNavigation();
10
10
 
11
- const remoteHandler = (event) => {
11
+ const remoteHandler = (_, event) => {
12
12
  const { eventType } = event;
13
13
 
14
14
  const canGoBack = navigator.canGoBack();
@@ -159,7 +159,6 @@ exports[`componentsMap renders renders components map correctly 1`] = `
159
159
  >
160
160
  <View>
161
161
  <View
162
- onFocusCapture={[Function]}
163
162
  onLayout={[Function]}
164
163
  style={null}
165
164
  >
@@ -175,7 +174,6 @@ exports[`componentsMap renders renders components map correctly 1`] = `
175
174
  </View>
176
175
  </View>
177
176
  <View
178
- onFocusCapture={[Function]}
179
177
  onLayout={[Function]}
180
178
  style={null}
181
179
  >
@@ -3,23 +3,6 @@
3
3
  exports[`<Touchable /> when not running in automated tests environment renders correctly 1`] = `
4
4
  <View
5
5
  accessibilityLabel="some-test-id"
6
- accessibilityState={
7
- {
8
- "busy": undefined,
9
- "checked": undefined,
10
- "disabled": undefined,
11
- "expanded": undefined,
12
- "selected": undefined,
13
- }
14
- }
15
- accessibilityValue={
16
- {
17
- "max": undefined,
18
- "min": undefined,
19
- "now": undefined,
20
- "text": undefined,
21
- }
22
- }
23
6
  accessible={true}
24
7
  collapsable={false}
25
8
  focusable={true}
@@ -46,23 +29,6 @@ exports[`<Touchable /> when not running in automated tests environment renders c
46
29
  exports[`<Touchable /> when running in automated tests environment has accessible flag set to false 1`] = `
47
30
  <View
48
31
  accessibilityLabel="some-test-id"
49
- accessibilityState={
50
- {
51
- "busy": undefined,
52
- "checked": undefined,
53
- "disabled": undefined,
54
- "expanded": undefined,
55
- "selected": undefined,
56
- }
57
- }
58
- accessibilityValue={
59
- {
60
- "max": undefined,
61
- "min": undefined,
62
- "now": undefined,
63
- "text": undefined,
64
- }
65
- }
66
32
  accessible={false}
67
33
  collapsable={false}
68
34
  focusable={true}
@@ -6,21 +6,15 @@ exports[`<Scene /> renders correctly 1`] = `
6
6
  collapsable={false}
7
7
  pointerEvents="auto"
8
8
  style={
9
- [
10
- {
11
- "flex": 1,
12
- },
13
- {
14
- "paddingBottom": 49,
15
- },
16
- {
17
- "fontScale": 2,
18
- "height": 1334,
19
- "scale": 2,
20
- "statusBarHeight": null,
21
- "width": 750,
22
- },
23
- ]
9
+ {
10
+ "flex": 1,
11
+ "fontScale": 2,
12
+ "height": 1334,
13
+ "paddingBottom": 49,
14
+ "scale": 2,
15
+ "statusBarHeight": null,
16
+ "width": 750,
17
+ }
24
18
  }
25
19
  />
26
20
  </View>
@@ -1,8 +1,8 @@
1
1
  import { Animated, Easing, EasingFunction, StyleProp } from "react-native";
2
2
 
3
3
  type AnimatedInterpolatedStyle =
4
- | Animated.AnimatedInterpolation<number>
5
- | [{ [Key: string]: Animated.AnimatedInterpolation<number> }];
4
+ | Animated.AnimatedInterpolation
5
+ | [{ [Key: string]: Animated.AnimatedInterpolation }];
6
6
 
7
7
  type AnimationConfig = {
8
8
  duration: number;
@@ -31,7 +31,7 @@ const interpolate = (
31
31
  animatedValue: Animated.Value,
32
32
  from: number = 0,
33
33
  to: number = 1
34
- ): Animated.AnimatedInterpolation<number> =>
34
+ ): Animated.AnimatedInterpolation =>
35
35
  animatedValue.interpolate({
36
36
  inputRange: [0, 1],
37
37
  outputRange: [from, to],
@@ -2,7 +2,7 @@
2
2
 
3
3
  import * as React from "react";
4
4
 
5
- import { act, render } from "@testing-library/react-native";
5
+ import { act, create as render } from "react-test-renderer";
6
6
 
7
7
  import { ViewportAware } from "../";
8
8
  import { ViewportTracker } from "../../ViewportTracker";
@@ -12,17 +12,21 @@ import ReactNative from "react-native";
12
12
 
13
13
  jest.useFakeTimers();
14
14
 
15
- const { ScrollView } = ReactNative;
16
-
17
- jest.spyOn(ReactNative, "findNodeHandle").mockImplementation(() => 1234);
15
+ jest.mock("react-native/Libraries/ReactNative/UIManager", () => {
16
+ return {
17
+ ...jest.requireActual("react-native/Libraries/ReactNative/NativeUIManager"),
18
+ measureLayout: (handle, parent, error, success) => {
19
+ success(100, 100, 400, 400);
20
+ },
21
+ };
22
+ });
18
23
 
19
- ReactNative.UIManager.measureLayout = jest.fn(
20
- (handle, parent, error, success) => {
21
- success(100, 100, 400, 400);
22
- }
23
- );
24
+ jest.mock("react-native/Libraries/Renderer/shims/ReactNative", () => ({
25
+ ...jest.requireActual("react-native/Libraries/Renderer/shims/ReactNative"),
26
+ findNodeHandle: () => 1234,
27
+ }));
24
28
 
25
- ReactNative.findNodeHandle = () => 1234;
29
+ const { ScrollView } = ReactNative;
26
30
 
27
31
  const viewportEventsManager = new ViewportEvents(true);
28
32
 
@@ -134,7 +138,7 @@ describe("<ViewportAware />", () => {
134
138
  expect(wrapper.toJSON()).toMatchSnapshot();
135
139
  expect(onViewportEnter).toHaveBeenCalled();
136
140
 
137
- const scrollviews = wrapper.UNSAFE_getAllByType(ScrollView);
141
+ const scrollviews = wrapper.root.findAllByType(ScrollView);
138
142
  expect(scrollviews).toBeArray();
139
143
  expect(scrollviews).toHaveProperty("length", 2);
140
144
 
@@ -175,7 +179,7 @@ describe("<ViewportAware />", () => {
175
179
 
176
180
  expect(wrapper.toJSON()).toMatchSnapshot();
177
181
 
178
- const scrollviews = wrapper.UNSAFE_getAllByType(ScrollView);
182
+ const scrollviews = wrapper.root.findAllByType(ScrollView);
179
183
  expect(scrollviews).toBeArray();
180
184
  expect(scrollviews).toHaveProperty("length", 2);
181
185
 
@@ -1,19 +1,14 @@
1
1
  import * as React from "react";
2
- import { act, render } from "@testing-library/react-native";
2
+ import { ScrollView } from "react-native";
3
+ import TestRenderer, { act } from "react-test-renderer";
3
4
  import { ViewportEvents } from "../../ViewportEvents";
4
- import ReactNative from "react-native";
5
-
6
- const { ScrollView } = ReactNative;
7
5
 
8
6
  const TestComponent = () => <ScrollView />;
9
7
 
10
- jest.spyOn(ReactNative, "findNodeHandle").mockImplementation(() => 1234);
11
-
12
- ReactNative.UIManager.measureLayout = jest.fn(
13
- (handle, parent, error, success) => {
14
- success(100, 100, 400, 400);
15
- }
16
- );
8
+ jest.mock("react-native/Libraries/Renderer/shims/ReactNative", () => ({
9
+ ...jest.requireActual("react-native/Libraries/Renderer/shims/ReactNative"),
10
+ findNodeHandle: () => 1234,
11
+ }));
17
12
 
18
13
  const viewportEventsManager = new ViewportEvents(true);
19
14
 
@@ -28,49 +23,32 @@ const event = {
28
23
  };
29
24
 
30
25
  describe("<ViewportTracker />", () => {
26
+ // eslint-disable-next-line react/prop-types
27
+ const ReactWrapper = ({ children }) => (
28
+ <ViewportTracker viewportEventsManager={viewportEventsManager}>
29
+ <ScrollView>{children}</ScrollView>
30
+ </ViewportTracker>
31
+ );
32
+
33
+ const wrapper = TestRenderer.create(
34
+ <ReactWrapper>
35
+ <TestComponent />
36
+ </ReactWrapper>
37
+ );
38
+
39
+ const scrollView = wrapper.root.findByType(ScrollView);
40
+
31
41
  beforeEach(() => {
32
42
  viewportEventSpy.mockClear();
33
43
  });
34
44
 
35
45
  it("renders correctly", () => {
36
- // eslint-disable-next-line react/prop-types
37
- const ReactWrapper = ({ children }) => (
38
- <ViewportTracker viewportEventsManager={viewportEventsManager}>
39
- <ScrollView>{children}</ScrollView>
40
- </ViewportTracker>
41
- );
42
-
43
- const wrapper = render(
44
- <ReactWrapper>
45
- <TestComponent />
46
- </ReactWrapper>
47
- );
48
-
49
- const scrollView = wrapper.UNSAFE_getByType(ScrollView);
50
-
51
46
  expect(wrapper.toJSON()).toMatchSnapshot();
52
47
  expect(scrollView.props).toMatchSnapshot();
53
48
  });
54
49
 
55
50
  it("notifies viewport listeners when layout changes", () => {
56
- // eslint-disable-next-line react/prop-types
57
- const ReactWrapper = ({ children }) => (
58
- <ViewportTracker viewportEventsManager={viewportEventsManager}>
59
- <ScrollView>{children}</ScrollView>
60
- </ViewportTracker>
61
- );
62
-
63
- const wrapper = render(
64
- <ReactWrapper>
65
- <TestComponent />
66
- </ReactWrapper>
67
- );
68
-
69
- const scrollView = wrapper.UNSAFE_getByType(ScrollView);
70
-
71
- act(() => {
72
- scrollView.props.onLayout(event);
73
- });
51
+ act(() => scrollView.props.onLayout(event));
74
52
 
75
53
  expect(viewportEventSpy).toHaveBeenCalledWith(
76
54
  expect.objectContaining({
@@ -85,50 +63,12 @@ describe("<ViewportTracker />", () => {
85
63
  });
86
64
 
87
65
  it("notifies viewport listeners when content scrolls", () => {
88
- // eslint-disable-next-line react/prop-types
89
- const ReactWrapper = ({ children }) => (
90
- <ViewportTracker viewportEventsManager={viewportEventsManager}>
91
- <ScrollView>{children}</ScrollView>
92
- </ViewportTracker>
93
- );
94
-
95
- const wrapper = render(
96
- <ReactWrapper>
97
- <TestComponent />
98
- </ReactWrapper>
99
- );
100
-
101
- const scrollView = wrapper.UNSAFE_getByType(ScrollView);
102
-
103
- act(() => {
104
- scrollView.props.onLayout(event);
105
- scrollView.props.onScroll(event);
106
- });
107
-
66
+ act(() => scrollView.props.onScroll(event));
108
67
  expect(viewportEventSpy).toHaveBeenCalled();
109
68
  });
110
69
 
111
70
  it("notifies viewport listeners when content size changes", () => {
112
- // eslint-disable-next-line react/prop-types
113
- const ReactWrapper = ({ children }) => (
114
- <ViewportTracker viewportEventsManager={viewportEventsManager}>
115
- <ScrollView>{children}</ScrollView>
116
- </ViewportTracker>
117
- );
118
-
119
- const wrapper = render(
120
- <ReactWrapper>
121
- <TestComponent />
122
- </ReactWrapper>
123
- );
124
-
125
- const scrollView = wrapper.UNSAFE_getByType(ScrollView);
126
-
127
- act(() => {
128
- scrollView.props.onLayout(event);
129
- scrollView.props.onContentSizeChange(100, 100);
130
- });
131
-
71
+ act(() => scrollView.props.onContentSizeChange(100, 100));
132
72
  expect(viewportEventSpy).toHaveBeenCalled();
133
73
  });
134
74
  });
@@ -21,13 +21,13 @@ const prepareConfiguration = (
21
21
  keys: [string]
22
22
  ) => R.compose(R.evolve(keysMap), R.pickAll(keys))(configuration);
23
23
 
24
- const configurationKeys = R.keys(keysMap);
25
-
26
24
  export function withConfigurationProvider(Component: React.ComponentType<any>) {
27
25
  return function WithConfigurationProvider(props: Props) {
28
26
  const styles = props?.screenData?.styles;
29
27
  const general = props?.screenData?.general;
30
28
 
29
+ const configurationKeys = React.useMemo(() => R.keys(keysMap), []);
30
+
31
31
  const configuration = React.useMemo(
32
32
  () => prepareConfiguration({ ...general, ...styles }, configurationKeys),
33
33
  []
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/zapp-react-native-ui-components",
3
- "version": "14.0.0-alpha.3881160800",
3
+ "version": "14.0.0-alpha.4009339136",
4
4
  "description": "Applicaster Zapp React Native ui components for the Quick Brick App",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -31,10 +31,10 @@
31
31
  "redux-mock-store": "^1.5.3"
32
32
  },
33
33
  "dependencies": {
34
- "@applicaster/applicaster-types": "14.0.0-alpha.3881160800",
35
- "@applicaster/zapp-react-native-bridge": "14.0.0-alpha.3881160800",
36
- "@applicaster/zapp-react-native-redux": "14.0.0-alpha.3881160800",
37
- "@applicaster/zapp-react-native-utils": "14.0.0-alpha.3881160800",
34
+ "@applicaster/applicaster-types": "14.0.0-alpha.4009339136",
35
+ "@applicaster/zapp-react-native-bridge": "14.0.0-alpha.4009339136",
36
+ "@applicaster/zapp-react-native-redux": "14.0.0-alpha.4009339136",
37
+ "@applicaster/zapp-react-native-utils": "14.0.0-alpha.4009339136",
38
38
  "promise": "^8.3.0",
39
39
  "url": "^0.11.0",
40
40
  "uuid": "^3.3.2"
@@ -45,6 +45,7 @@
45
45
  "immer": "*",
46
46
  "react": "*",
47
47
  "react-native": "*",
48
+ "react-native-safe-area-context": "*",
48
49
  "react-native-svg": "*",
49
50
  "uglify-js": "*",
50
51
  "validate-color": "*",