@applicaster/zapp-react-native-ui-components 12.0.0-alpha.4043183114 → 12.0.0-alpha.4155487673

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.
@@ -1,5 +1,5 @@
1
1
  import * as React from "react";
2
- import { join, path, merge } from "ramda";
2
+ import { join, merge, path } from "ramda";
3
3
  import { View } from "react-native";
4
4
 
5
5
  import { Focusable } from "@applicaster/zapp-react-native-ui-components/Components/Focusable";
@@ -14,7 +14,10 @@ import { BaseFocusable } from "../BaseFocusable";
14
14
  import { AccessibilityManager } from "@applicaster/zapp-react-native-utils/appUtils/accessibilityManager";
15
15
 
16
16
  type Props = {
17
- item: ZappEntry;
17
+ item: {
18
+ id: string;
19
+ title: string;
20
+ };
18
21
  index: number;
19
22
  shouldScrollHorizontally: (arg1: [any]) => boolean | null | undefined;
20
23
  shouldScrollVertically: (...args: any) => boolean | null | undefined;
@@ -30,9 +33,10 @@ type Props = {
30
33
  id: string;
31
34
  };
32
35
  selected?: boolean;
33
- CellRenderer: React.FunctionComponent<any> & {
34
- hasFocusableInside: (item: ZappEntry) => boolean;
35
- };
36
+ CellRenderer: React.ComponentType<{
37
+ item: any;
38
+ state: string;
39
+ }> & { hasFocusableInside: (item: Record<string, string>) => boolean };
36
40
  preferredFocus: boolean;
37
41
  navigator: {
38
42
  push: (arg1: Record<any, any>) => void;
@@ -63,6 +67,10 @@ type Props = {
63
67
  behavior: Behavior;
64
68
  };
65
69
 
70
+ type State = {
71
+ hasFocusableInside: boolean;
72
+ };
73
+
66
74
  const baseCellStyles = {
67
75
  height: "100%",
68
76
  display: "flex",
@@ -74,7 +82,7 @@ const touchableStyles = {
74
82
  height: "100%",
75
83
  } as const;
76
84
 
77
- export class CellComponent extends React.Component<Props> {
85
+ export class CellComponent extends React.Component<Props, State> {
78
86
  constructor(props) {
79
87
  super(props);
80
88
  this.onPress = this.onPress.bind(this);
@@ -84,6 +92,10 @@ export class CellComponent extends React.Component<Props> {
84
92
  this.hasReceivedFocus = this.hasReceivedFocus.bind(this);
85
93
  this.scrollVertically = this.scrollVertically.bind(this);
86
94
  this.scrollToIndex = this.scrollToIndex.bind(this);
95
+
96
+ this.state = {
97
+ hasFocusableInside: props.CellRenderer.hasFocusableInside?.(props.item),
98
+ };
87
99
  }
88
100
 
89
101
  setScreenLayout(componentAnchorPointY, screenLayout) {
@@ -139,7 +151,7 @@ export class CellComponent extends React.Component<Props> {
139
151
 
140
152
  const accessibilityManager = AccessibilityManager.getInstance();
141
153
  // Text from DSP should be localized already
142
- accessibilityManager.readText({ text: title.toString() });
154
+ accessibilityManager.readText({ text: title });
143
155
  }
144
156
  }
145
157
  }
@@ -188,6 +200,16 @@ export class CellComponent extends React.Component<Props> {
188
200
  return !isFocusable ? false : focused || focusableFocused;
189
201
  }
190
202
 
203
+ componentDidUpdate(prevProps: Readonly<Props>) {
204
+ if (prevProps.item !== this.props.item) {
205
+ this.setState({
206
+ hasFocusableInside: this.props.CellRenderer.hasFocusableInside?.(
207
+ this.props.item
208
+ ),
209
+ });
210
+ }
211
+ }
212
+
191
213
  render() {
192
214
  const {
193
215
  item,
@@ -216,9 +238,7 @@ export class CellComponent extends React.Component<Props> {
216
238
  this.onFocus(focusable, mouse);
217
239
  };
218
240
 
219
- const hasFocusableInside = CellRenderer.hasFocusableInside?.(item);
220
-
221
- if (hasFocusableInside) {
241
+ if (this.state.hasFocusableInside) {
222
242
  return (
223
243
  <CellWithFocusable
224
244
  CellRenderer={CellRenderer}
@@ -46,7 +46,7 @@ const useCellFocusedState = (
46
46
 
47
47
  type Props = {
48
48
  item: ZappEntry;
49
- CellRenderer: React.FunctionComponent<any>;
49
+ CellRenderer: React.ComponentType<{ item: Object; state: string }>;
50
50
  id: string;
51
51
  groupId: string;
52
52
  onFocus: Function;
@@ -36,9 +36,10 @@ type Props = {
36
36
  component_type: string;
37
37
  };
38
38
  selected: boolean;
39
- CellRenderer: React.FunctionComponent<any> & {
40
- hasFocusableInside: (item: any) => boolean;
41
- };
39
+ CellRenderer: React.ComponentType<{
40
+ item: any;
41
+ state: string;
42
+ }> & { hasFocusableInside: (item: any) => boolean };
42
43
  preferredFocus: boolean;
43
44
  navigator: {
44
45
  push: (arg1: Record<any, any>) => void;
@@ -53,6 +53,7 @@ export function ActionButton(props: Props) {
53
53
  const { item, action, asset, flavour = "flavour_1", cellUUID } = props;
54
54
  const actionContext = useActions(action?.identifier);
55
55
 
56
+ // TODO: add subscription API for action availability
56
57
  const actionDisabled =
57
58
  typeof actionContext?.isActionAvailable === "function" &&
58
59
  !actionContext.isActionAvailable(item);
@@ -68,7 +69,7 @@ export function ActionButton(props: Props) {
68
69
  if (actionDisabled || !actionContext) return;
69
70
 
70
71
  setActionState(actionContext.initialEntryState(item));
71
- }, [actionDisabled, item?.id]);
72
+ }, [actionDisabled, item?.id, actionContext]);
72
73
 
73
74
  const onPress = useCallback(() => {
74
75
  actionContext.invokeAction(item, {
@@ -117,9 +117,6 @@ export const BorderContainerView = (props: Props) => {
117
117
  children,
118
118
  } = props;
119
119
 
120
- const borderStyleForMissingBorder =
121
- style?.borderWidth === 0 || !style?.borderColor ? { borderRadius: 0 } : {};
122
-
123
120
  const padding =
124
121
  borderPosition === "outside"
125
122
  ? {
@@ -131,10 +128,7 @@ export const BorderContainerView = (props: Props) => {
131
128
  : {};
132
129
 
133
130
  return (
134
- <View
135
- {...props}
136
- style={[style, styles.container, borderStyleForMissingBorder]}
137
- >
131
+ <View {...props} style={[style, styles.container]}>
138
132
  <Border style={style} padding={padding} borderPosition={borderPosition} />
139
133
  {children}
140
134
  </View>
@@ -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
+ };
@@ -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,
@@ -37,14 +37,28 @@ function retrieveData(entry, func, args) {
37
37
  */
38
38
 
39
39
  export function configInflater(
40
- entry,
41
- { type, style, additionalProps = {}, data = [], elements }
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 = R.reduce(
44
- (acc, curr) =>
45
- R.assoc(curr.propName, retrieveData(entry, curr.func, curr.args), acc),
46
- additionalProps,
47
- data
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;
@@ -52,6 +52,8 @@ export function masterCellBuilder({
52
52
  const { View } = componentsMap;
53
53
  const elementsBuilder = dataAdapter(cellConfiguration);
54
54
 
55
+ // This is very expensive operation
56
+ // Keep calls to minimum
55
57
  const hasFocusableInside = hasFocusableInsideBuilder(elementsBuilder);
56
58
 
57
59
  /**
@@ -74,8 +76,8 @@ export function masterCellBuilder({
74
76
  const selectedState = screen?.selectedEntry;
75
77
 
76
78
  const entryIsSelected = React.useMemo(
77
- () => selectedState?.id === item?.id,
78
- [selectedState?.id]
79
+ () => !!(selectedState?.id && selectedState?.id === item?.id),
80
+ [selectedState?.id, item?.id]
79
81
  );
80
82
 
81
83
  const elements = React.useMemo(
@@ -84,7 +86,7 @@ export function masterCellBuilder({
84
86
  entry: item,
85
87
  state: getEntryState(state, entryIsSelected),
86
88
  }),
87
- [state, item, entryIsSelected]
89
+ [state, item?.id, entryIsSelected] // Assuming that item won't mutate
88
90
  );
89
91
 
90
92
  const wrapperRef = React.useRef(null);
@@ -1,12 +1,10 @@
1
1
  import { requireNativeComponent, View } from "react-native";
2
2
  import { isAppleTV } from "@applicaster/zapp-react-native-ui-components/Helpers/Platform";
3
3
 
4
- // @TODO define the types
5
4
  export const FocusableGroupNative = isAppleTV()
6
- ? requireNativeComponent<any>("FocusableGroupViewModule")
5
+ ? requireNativeComponent("FocusableGroupViewModule", null)
7
6
  : View;
8
7
 
9
- // @TODO define the types
10
8
  export const FocusableItemNative = isAppleTV()
11
- ? requireNativeComponent<any>("FocusableViewModule")
9
+ ? requireNativeComponent("FocusableViewModule", null)
12
10
  : View;
@@ -1,6 +1,5 @@
1
1
  import * as React from "react";
2
- import * as R from "ramda";
3
- import { useDispatch } from "react-redux";
2
+ import { path, prop } from "ramda";
4
3
  import {
5
4
  findPluginByType,
6
5
  findPluginByIdentifier,
@@ -15,7 +14,6 @@ import { componentsLogger } from "../../Helpers/logger";
15
14
  import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
16
15
  import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks";
17
16
  import { useScreenAnalytics } from "@applicaster/zapp-react-native-utils/analyticsUtils/helpers/hooks";
18
- import { setAppStateHasFinishedTransitioning } from "@applicaster/zapp-react-native-redux/appState";
19
17
 
20
18
  const logger = componentsLogger.addSubsystem("ScreenResolver");
21
19
 
@@ -54,11 +52,8 @@ export function ScreenResolverComponent(props: Props) {
54
52
 
55
53
  const [, setScreenContext] = ZappPipesScreenContext.useZappPipesContext();
56
54
 
57
- const dispatch = useDispatch();
58
-
59
55
  React.useEffect(() => {
60
56
  setScreenContext(rivers[screenId]);
61
- dispatch(setAppStateHasFinishedTransitioning());
62
57
  }, [screenId]);
63
58
 
64
59
  const ScreenPlugin =
@@ -100,14 +95,14 @@ export function ScreenResolverComponent(props: Props) {
100
95
  }
101
96
 
102
97
  const ScreenComponent =
103
- R.path(["module", "Component"], ScreenPlugin) ||
104
- R.prop("module", ScreenPlugin) ||
105
- R.prop("Component", ScreenPlugin) ||
98
+ path(["module", "Component"], ScreenPlugin) ||
99
+ prop("module", ScreenPlugin) ||
100
+ prop("Component", ScreenPlugin) ||
106
101
  ScreenPlugin;
107
102
 
108
103
  const configuration =
109
- R.prop("configuration", ScreenPlugin) ||
110
- R.prop("__plugin_configuration", ScreenComponent);
104
+ prop("configuration", ScreenPlugin) ||
105
+ prop("__plugin_configuration", ScreenComponent);
111
106
 
112
107
  if (ScreenComponent) {
113
108
  return (
@@ -166,21 +166,23 @@ export class TransitionerComponent extends React.PureComponent<Props, State> {
166
166
 
167
167
  transitionWithoutAnimation(resetState) {
168
168
  const { scenes } = this.state;
169
-
170
- const newState = resetState
171
- ? {
172
- scenes: [prepareScene(this.props.children)],
173
- to: {
174
- index: 0,
175
- },
176
- }
177
- : {
178
- scenes: R.update(
179
- scenes.length - 1,
180
- prepareScene(this.props.children),
181
- scenes
182
- ),
183
- };
169
+ const newScene = prepareScene(this.props.children);
170
+ const isLastSceneHook = scenes[scenes.length - 1].key.startsWith("/hook");
171
+
172
+ let newState;
173
+
174
+ if (resetState) {
175
+ newState = {
176
+ scenes: [newScene],
177
+ to: { index: 0 },
178
+ };
179
+ } else if (isLastSceneHook || scenes.length === 1) {
180
+ newState = { scenes: R.update(scenes.length - 1, newScene, scenes) };
181
+ } else {
182
+ newState = {
183
+ scenes: R.compose(R.tail, R.append(newScene))(scenes),
184
+ };
185
+ }
184
186
 
185
187
  this.setState(newState);
186
188
  }
@@ -2,7 +2,7 @@
2
2
  //
3
3
  import * as React from "react";
4
4
 
5
- import { AppState, AppStateStatus } from "react-native";
5
+ import { AppState, AppStateStatus, View } from "react-native";
6
6
  import { TrackedView } from "../TrackedView";
7
7
  import { useDimensions } from "@applicaster/zapp-react-native-utils/reactHooks/layout";
8
8
 
@@ -25,8 +25,9 @@ import { PlayerRole } from "@applicaster/zapp-react-native-utils/appUtils/player
25
25
  import { getAutoplaySettings } from "./utils";
26
26
  import { isString } from "@applicaster/zapp-react-native-utils/stringUtils";
27
27
  import { BufferAnimation } from "../PlayerContainer/BufferAnimation";
28
+ import { useEffect } from "react";
28
29
 
29
- const { log_error } = loggerLiveImageComponent;
30
+ const { log_error, log_debug } = loggerLiveImageComponent;
30
31
 
31
32
  const isMeasurement = (item: ZappEntry) =>
32
33
  isString(item.id) && item.id.startsWith("pre-measurement-");
@@ -56,6 +57,7 @@ const PlayerLiveImageComponent = (props: Props) => {
56
57
  );
57
58
 
58
59
  const ref = React.useRef(null);
60
+ const trackViewRef = React.useRef(null);
59
61
 
60
62
  /**
61
63
  * Debounced setMode function.
@@ -86,6 +88,30 @@ const PlayerLiveImageComponent = (props: Props) => {
86
88
  [mode]
87
89
  );
88
90
 
91
+ const entryToViewIdMapping = React.useRef({});
92
+
93
+ useEffect(() => {
94
+ const nativeTag = trackViewRef.current?._nativeTag?.toString();
95
+
96
+ if (!nativeTag) {
97
+ return;
98
+ }
99
+
100
+ const prevValue = entryToViewIdMapping.current[nativeTag];
101
+
102
+ if (prevValue && prevValue.itemId !== item.id) {
103
+ if (mode === LiveImageType.Video) {
104
+ log_debug(
105
+ "Entry to view association changed, stopping current live image"
106
+ );
107
+
108
+ setMode(LiveImageType.Image);
109
+ }
110
+ }
111
+
112
+ entryToViewIdMapping.current[nativeTag] = { itemId: item.id };
113
+ }, [trackViewRef.current, item.id, mode]);
114
+
89
115
  const { screenConfig, playerPluginId } = props;
90
116
 
91
117
  const liveImageItem: LiveImage = React.useMemo(() => {
@@ -295,28 +321,30 @@ const PlayerLiveImageComponent = (props: Props) => {
295
321
  testId={`tracked-view-${playerId}-${item.title}`}
296
322
  onPositionUpdated={onPositionUpdated}
297
323
  >
298
- {isVideoMode && (
299
- <Player
300
- autoplay={false}
301
- ref={_assignRoot}
302
- entry={item} // Must be passed first in list
303
- style={videoStyles}
304
- playerId={playerId}
305
- muted={muted}
306
- listener={controller?.getListener()}
307
- resizeMode={"cover"}
308
- {...platformSpecificProps}
309
- />
310
- )}
311
- {
312
- <AnimatedInOut
313
- visible={isBackgroundImageVisible}
314
- animationConfig={overlayFadeIn}
315
- staticStyles={style}
316
- >
317
- <Image {...props} resizeMode="cover" style={style} applyMaxSize />
318
- </AnimatedInOut>
319
- }
324
+ <View ref={trackViewRef}>
325
+ {isVideoMode && (
326
+ <Player
327
+ autoplay={false}
328
+ ref={_assignRoot}
329
+ entry={item} // Must be passed first in list
330
+ style={videoStyles}
331
+ playerId={playerId}
332
+ muted={muted}
333
+ listener={controller?.getListener()}
334
+ resizeMode={"cover"}
335
+ {...platformSpecificProps}
336
+ />
337
+ )}
338
+ {
339
+ <AnimatedInOut
340
+ visible={isBackgroundImageVisible}
341
+ animationConfig={overlayFadeIn}
342
+ staticStyles={style}
343
+ >
344
+ <Image {...props} resizeMode="cover" style={style} applyMaxSize />
345
+ </AnimatedInOut>
346
+ }
347
+ </View>
320
348
  </TrackedView>
321
349
  );
322
350
  };
@@ -5,33 +5,35 @@ exports[`PlayerLiveImageComponent should render correctly with default props 1`]
5
5
  onPositionUpdated={[Function]}
6
6
  testId="tracked-view-player1-Test"
7
7
  >
8
- <View
9
- collapsable={false}
10
- style={
11
- Object {
12
- "opacity": 1,
13
- }
14
- }
15
- >
16
- <Image
17
- applyMaxSize={true}
18
- audioMutedByDefault={false}
19
- imageKey="image1"
20
- item={
8
+ <View>
9
+ <View
10
+ collapsable={false}
11
+ style={
21
12
  Object {
22
- "id": "1",
23
- "title": "Test",
24
- "type": Object {
25
- "value": "",
26
- },
13
+ "opacity": 1,
27
14
  }
28
15
  }
29
- onError={[Function]}
30
- playerId="player1"
31
- resizeMode="cover"
32
- screenConfig={Object {}}
33
- style={Object {}}
34
- />
16
+ >
17
+ <Image
18
+ applyMaxSize={true}
19
+ audioMutedByDefault={false}
20
+ imageKey="image1"
21
+ item={
22
+ Object {
23
+ "id": "1",
24
+ "title": "Test",
25
+ "type": Object {
26
+ "value": "",
27
+ },
28
+ }
29
+ }
30
+ onError={[Function]}
31
+ playerId="player1"
32
+ resizeMode="cover"
33
+ screenConfig={Object {}}
34
+ style={Object {}}
35
+ />
36
+ </View>
35
37
  </View>
36
38
  </TrackedView>
37
39
  `;
@@ -349,7 +349,12 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
349
349
  };
350
350
 
351
351
  export const AnimatedScrollModal = ({ children }: Props) => {
352
- const Component = !isTV() ? AnimatedScrollModalComponent : React.Fragment;
352
+ const {
353
+ videoModalState: { visible },
354
+ } = useNavigation();
355
+
356
+ const Component =
357
+ !isTV() && visible ? AnimatedScrollModalComponent : React.Fragment;
353
358
 
354
359
  return <Component>{children}</Component>;
355
360
  };
@@ -155,7 +155,11 @@ export const AnimatedVideoPlayer = ({ children }: Props) => {
155
155
  };
156
156
 
157
157
  export const AnimatedVideoPlayerComponent = ({ children }: Props) => {
158
- const Component = !isTV() ? AnimatedVideoPlayer : React.Fragment;
158
+ const {
159
+ videoModalState: { visible },
160
+ } = useNavigation();
161
+
162
+ const Component = !isTV() && visible ? AnimatedVideoPlayer : React.Fragment;
159
163
 
160
164
  return <Component>{children}</Component>;
161
165
  };
@@ -72,12 +72,34 @@ exports[`PlayerWrapper renders inline 1`] = `
72
72
  testID="test-player-container"
73
73
  />
74
74
  <View
75
+ animationType="componentFade"
75
76
  style={
76
77
  Object {
77
78
  "flex": 1,
78
79
  }
79
80
  }
80
- />
81
+ >
82
+ <View
83
+ configuration={
84
+ Object {
85
+ "tablet_landscape_player_container_background_color": "red",
86
+ "tablet_landscape_sidebar_width": "35%",
87
+ }
88
+ }
89
+ entry={
90
+ Object {
91
+ "id": "test",
92
+ }
93
+ }
94
+ isTabletLandscape={false}
95
+ style={
96
+ Object {
97
+ "flex": 1,
98
+ "paddingTop": 20,
99
+ }
100
+ }
101
+ />
102
+ </View>
81
103
  </View>
82
104
  </RNCSafeAreaView>
83
105
  </RNCSafeAreaProvider>
@@ -158,6 +180,7 @@ exports[`PlayerWrapper renders inline and docked 1`] = `
158
180
  style={
159
181
  Object {
160
182
  "flex": 1,
183
+ "paddingTop": 20,
161
184
  }
162
185
  }
163
186
  />
@@ -254,12 +277,34 @@ exports[`PlayerWrapper renders inline on tablet in landscape orientation 1`] = `
254
277
  />
255
278
  </View>
256
279
  <View
280
+ animationType="componentFade"
257
281
  style={
258
282
  Object {
259
283
  "flex": 1,
260
284
  }
261
285
  }
262
- />
286
+ >
287
+ <View
288
+ configuration={
289
+ Object {
290
+ "tablet_landscape_player_container_background_color": "red",
291
+ "tablet_landscape_sidebar_width": "35%",
292
+ }
293
+ }
294
+ entry={
295
+ Object {
296
+ "id": "test",
297
+ }
298
+ }
299
+ isTabletLandscape={true}
300
+ style={
301
+ Object {
302
+ "flex": 1,
303
+ "paddingTop": 20,
304
+ }
305
+ }
306
+ />
307
+ </View>
263
308
  </View>
264
309
  </RNCSafeAreaView>
265
310
  </RNCSafeAreaProvider>
@@ -340,6 +385,7 @@ exports[`PlayerWrapper renders properly 1`] = `
340
385
  style={
341
386
  Object {
342
387
  "flex": 1,
388
+ "paddingTop": 20,
343
389
  }
344
390
  }
345
391
  />
@@ -16,9 +16,9 @@ exports[`DefaultCellRenderer returns a react component and it renders correctly
16
16
  store={null}
17
17
  style={
18
18
  Object {
19
- "backgroundColor": "#CCC",
19
+ "backgroundColor": "transparent",
20
20
  "margin": 12,
21
- "opacity": 0.6,
21
+ "opacity": 1,
22
22
  "width": 169,
23
23
  }
24
24
  }
@@ -105,7 +105,7 @@ exports[`DefaultCellRenderer returns a react component for LG TVs 1`] = `
105
105
  store={null}
106
106
  style={
107
107
  Object {
108
- "backgroundColor": "rgba(252,70,27,1.0)",
108
+ "backgroundColor": "rgba(47,47,47,1.0)",
109
109
  "borderRadius": 4,
110
110
  "flex": 1,
111
111
  "overflow": "hidden",
@@ -238,7 +238,7 @@ exports[`DefaultCellRenderer returns a react component for Samsung TVs 1`] = `
238
238
  store={null}
239
239
  style={
240
240
  Object {
241
- "backgroundColor": "rgba(252,70,27,1.0)",
241
+ "backgroundColor": "rgba(47,47,47,1.0)",
242
242
  "borderRadius": 4,
243
243
  "flex": 1,
244
244
  "overflow": "hidden",
@@ -5,18 +5,18 @@ import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
5
5
 
6
6
  type ComponentProps = {
7
7
  component: {
8
- id: string;
9
- rules: { item_limit: number; component_cells_selectable: boolean };
10
- component_type: string;
8
+ id: string,
9
+ rules: { item_limit: number, component_cells_selectable: boolean },
10
+ component_type: string,
11
11
  styles: {
12
- cell_style: string;
13
- header: { visible: boolean };
14
- component_cells_selectable: boolean;
15
- };
16
- };
17
- zappPipesData: { url: string; data: { title: string } };
18
- selected: boolean;
19
- assets: { menu_button: string };
12
+ cell_style: string,
13
+ header: { visible: boolean },
14
+ component_cells_selectable: boolean,
15
+ },
16
+ },
17
+ zappPipesData: { url: string, data: { title: string } },
18
+ selected: boolean,
19
+ assets: { menu_button: string },
20
20
  };
21
21
 
22
22
  function withAnalytics(Component) {
package/README.md CHANGED
@@ -78,6 +78,17 @@ export default MyAwesomeComponent;
78
78
  export { MyAwesomeComponent } from "./MyAwesomeComponent";
79
79
  ```
80
80
 
81
+ We provide flow types for component props - please use it to make sure your component will be compliant
82
+
83
+ ```javascript
84
+ import * as React from "react";
85
+ import type { ZappComponentProps } from "../../flow-types"; // in the root of the project
86
+
87
+ export class MyComponent extends React.Component<ZappComponentProps> {
88
+ /* ... */
89
+ }
90
+ ```
91
+
81
92
  ## Connecting my component to Zapp Pipes
82
93
 
83
94
  Zapp App components rely on [Zapp-Pipes](https://github.com/applicaster/zapp-pipes) to load data.
@@ -89,9 +100,10 @@ In order to connect your component to ZappPipes, you simply need to use the `Zap
89
100
  import * as React from "react";
90
101
  import { View, Text } from "react-native";
91
102
  import { zappPipesDataConnector } from "../ZappPipesDataConnector";
103
+ import type { ZappComponentProps } from "../../flow-types";
92
104
 
93
105
  @zappPipesDataConnector
94
- export class MyComponent extends React.Component {
106
+ export class MyComponent extends React.Component<ZappComponentProps> {
95
107
  renderComponent = (data) => {
96
108
  return (
97
109
  <View>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/zapp-react-native-ui-components",
3
- "version": "12.0.0-alpha.4043183114",
3
+ "version": "12.0.0-alpha.4155487673",
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",
@@ -34,10 +34,10 @@
34
34
  "redux-mock-store": "^1.5.3"
35
35
  },
36
36
  "dependencies": {
37
- "@applicaster/applicaster-types": "12.0.0-alpha.4043183114",
38
- "@applicaster/zapp-react-native-bridge": "12.0.0-alpha.4043183114",
39
- "@applicaster/zapp-react-native-redux": "12.0.0-alpha.4043183114",
40
- "@applicaster/zapp-react-native-utils": "12.0.0-alpha.4043183114",
37
+ "@applicaster/applicaster-types": "12.0.0-alpha.4155487673",
38
+ "@applicaster/zapp-react-native-bridge": "12.0.0-alpha.4155487673",
39
+ "@applicaster/zapp-react-native-redux": "12.0.0-alpha.4155487673",
40
+ "@applicaster/zapp-react-native-utils": "12.0.0-alpha.4155487673",
41
41
  "promise": "^8.3.0",
42
42
  "react-router-native": "^5.1.2",
43
43
  "url": "^0.11.0",