@applicaster/zapp-react-native-ui-components 13.0.0-alpha.7330390362 → 13.0.0-alpha.7620873141

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 (147) hide show
  1. package/Components/AppContainer/__tests__/AppContainer.test.js +4 -6
  2. package/Components/AudioPlayer/AudioPlayer.tsx +7 -0
  3. package/Components/AudioPlayer/__tests__/Runtime.test.js +5 -8
  4. package/Components/AudioPlayer/__tests__/__snapshots__/audioPlayer.test.js.snap +54 -111
  5. package/Components/AudioPlayer/__tests__/__snapshots__/audioPlayerLayout.test.js.snap +36 -20
  6. package/Components/AudioPlayer/__tests__/artWork.test.js +3 -5
  7. package/Components/AudioPlayer/__tests__/audioPlayer.test.js +3 -5
  8. package/Components/AudioPlayer/__tests__/audioPlayerLayout.test.js +7 -8
  9. package/Components/AudioPlayer/__tests__/channel.test.js +3 -5
  10. package/Components/AudioPlayer/__tests__/summary.test.js +3 -5
  11. package/Components/AudioPlayer/__tests__/title.test.js +3 -5
  12. package/Components/AudioPlayer/helpers.tsx +1 -0
  13. package/Components/BaseFocusable/index.tsx +1 -2
  14. package/Components/Cell/Cell.tsx +4 -13
  15. package/Components/Cell/CellWithFocusable.tsx +22 -15
  16. package/Components/Cell/CellWrapper.tsx +18 -0
  17. package/Components/Cell/TvOSCellComponent.tsx +20 -22
  18. package/Components/Cell/index.js +3 -1
  19. package/Components/Cell/styles.ts +17 -0
  20. package/Components/CellRendererResolver/__tests__/cellRendererResolver.test.js +46 -48
  21. package/Components/CellRendererResolver/index.ts +2 -1
  22. package/Components/ComponentResolver/__tests__/__snapshots__/componentResolver.test.js.snap +1 -42
  23. package/Components/ComponentResolver/__tests__/componentResolver.test.js +16 -22
  24. package/Components/ContentScreen/__tests__/contentScreen.test.js +3 -3
  25. package/Components/ErrorScreen/index.tsx +14 -6
  26. package/Components/Focusable/Focusable.tsx +1 -0
  27. package/Components/Focusable/FocusableTvOS.tsx +5 -1
  28. package/Components/Focusable/index.android.tsx +10 -3
  29. package/Components/FocusableCell/index.tsx +1 -1
  30. package/Components/FocusableGroup/FocusableTvOS.tsx +34 -86
  31. package/Components/FocusableGroup/index.tsx +0 -3
  32. package/Components/FocusableList/index.tsx +26 -9
  33. package/Components/FocusableScrollView/index.tsx +43 -13
  34. package/Components/HandlePlayable/HandlePlayable.tsx +21 -27
  35. package/Components/Layout/TV/LayoutBackground.tsx +28 -0
  36. package/Components/Layout/TV/NavBarContainer.tsx +19 -23
  37. package/Components/Layout/TV/ScreenContainer.tsx +8 -2
  38. package/Components/Layout/TV/ScreenLayoutContextProvider.tsx +5 -0
  39. package/Components/Layout/TV/__tests__/ScreenContainer.test.tsx +2 -1
  40. package/Components/Layout/TV/__tests__/__snapshots__/NavBarContainer.test.tsx.snap +3 -2
  41. package/Components/Layout/TV/__tests__/__snapshots__/ScreenContainer.test.tsx.snap +3 -2
  42. package/Components/Layout/TV/__tests__/__snapshots__/index.test.tsx.snap +15 -10
  43. package/Components/Layout/TV/__tests__/index.test.tsx +8 -2
  44. package/Components/Layout/TV/index.tsx +6 -20
  45. package/Components/Layout/TV/index.web.tsx +4 -1
  46. package/Components/MasterCell/DefaultComponents/ActionButton.tsx +2 -3
  47. package/Components/MasterCell/DefaultComponents/Image/Image.android.tsx +0 -6
  48. package/Components/MasterCell/DefaultComponents/Image/Image.ios.tsx +4 -9
  49. package/Components/MasterCell/DefaultComponents/Image/hooks/useImage.ts +11 -7
  50. package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +2 -2
  51. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/const.ts +3 -0
  52. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/index.ts +6 -6
  53. package/Components/MasterCell/SharedUI/ProgressBar/hooks/useFillInPercent.ts +2 -8
  54. package/Components/MasterCell/__tests__/__snapshots__/elementMapper.test.js.snap +4 -12
  55. package/Components/MasterCell/__tests__/__snapshots__/masterCell.test.js.snap +0 -229
  56. package/Components/MasterCell/__tests__/elementMapper.test.js +18 -5
  57. package/Components/MasterCell/__tests__/masterCell.test.js +26 -26
  58. package/Components/MasterCell/utils/behaviorProvider.ts +136 -0
  59. package/Components/MasterCell/utils/index.ts +8 -134
  60. package/Components/ModalComponent/BottomSheetModalContent.tsx +45 -19
  61. package/Components/ModalComponent/Button/Item.tsx +6 -5
  62. package/Components/ModalComponent/Button/assets.ts +1 -1
  63. package/Components/ModalComponent/Button/index.tsx +30 -43
  64. package/Components/ModalComponent/utils.ts +55 -7
  65. package/Components/OfflineHandler/NotificationView/NotificationView.lg.tsx +2 -2
  66. package/Components/OfflineHandler/NotificationView/NotificationView.samsung.tsx +2 -2
  67. package/Components/OfflineHandler/NotificationView/__tests__/index.test.tsx +0 -5
  68. package/Components/OfflineHandler/utils/index.ts +1 -1
  69. package/Components/PlayerContainer/PlayerContainer.tsx +40 -14
  70. package/Components/PlayerContainer/ProgramInfo/index.tsx +2 -2
  71. package/Components/PlayerImageBackground/index.tsx +1 -1
  72. package/Components/River/ComponentsMap/ComponentsMap.tsx +3 -0
  73. package/Components/River/ComponentsMap/hooks/useLoadingState.ts +3 -3
  74. package/Components/River/RiverItem.tsx +2 -1
  75. package/Components/River/TV/index.tsx +6 -1
  76. package/Components/River/__tests__/__snapshots__/river.test.js.snap +20 -82
  77. package/Components/River/__tests__/river.test.js +75 -40
  78. package/Components/RouteManager/__tests__/__snapshots__/routeManager.test.js.snap +11 -4
  79. package/Components/RouteManager/__tests__/routeManager.test.js +29 -14
  80. package/Components/RouteManager/__tests__/testId.test.js +8 -6
  81. package/Components/Screen/TV/index.web.tsx +5 -6
  82. package/Components/Screen/hooks.ts +3 -6
  83. package/Components/Screen/index.tsx +4 -4
  84. package/Components/ScreenResolver/__tests__/screenResolver.test.js +91 -70
  85. package/Components/Tabs/Tab.tsx +5 -3
  86. package/Components/TextInputTv/index.tsx +2 -1
  87. package/Components/TopMarginApplicator/TopMarginApplicator.tsx +2 -3
  88. package/Components/TrackedView/index.tsx +1 -0
  89. package/Components/Transitioner/AnimationManager.js +15 -15
  90. package/Components/Transitioner/Scene.tsx +1 -1
  91. package/Components/Transitioner/Transitioner.tsx +3 -3
  92. package/Components/Transitioner/__tests__/Scene.test.js +25 -14
  93. package/Components/Transitioner/__tests__/__snapshots__/Scene.test.js.snap +12 -68
  94. package/Components/Transitioner/__tests__/__snapshots__/transitioner.test.js.snap +2 -2
  95. package/Components/Transitioner/__tests__/transitioner.test.js +13 -4
  96. package/Components/VideoLive/PlayerLiveImageComponent.tsx +7 -3
  97. package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +1 -0
  98. package/Components/VideoModal/ModalAnimation/AnimatedPlayerModalWrapper.tsx +1 -1
  99. package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +46 -30
  100. package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.tsx +3 -3
  101. package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +45 -20
  102. package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +10 -3
  103. package/Components/VideoModal/ModalAnimation/__tests__/getMoveUpValue.test.ts +108 -0
  104. package/Components/VideoModal/ModalAnimation/const.ts +5 -0
  105. package/Components/VideoModal/ModalAnimation/index.ts +2 -0
  106. package/Components/VideoModal/ModalAnimation/utils.ts +36 -0
  107. package/Components/VideoModal/PlayerDetails.tsx +18 -10
  108. package/Components/VideoModal/PlayerWrapper.tsx +28 -5
  109. package/Components/VideoModal/VideoModal.tsx +19 -4
  110. package/Components/VideoModal/__tests__/__snapshots__/PlayerDetails.test.tsx.snap +2 -40
  111. package/Components/VideoModal/utils.ts +3 -4
  112. package/Components/Viewport/ViewportAware/__tests__/__snapshots__/viewportAware.test.js.snap +24 -36
  113. package/Components/Viewport/ViewportAware/__tests__/viewportAware.test.js +12 -18
  114. package/Components/Viewport/__tests__/utils.test.js +5 -4
  115. package/Components/ZappUIComponent/Placeholder.tsx +3 -1
  116. package/Components/ZappUIComponent/__tests__/{ZappUIComponent.test.js → ZappUIComponent.test.tsx} +26 -10
  117. package/Components/ZappUIComponent/index.tsx +4 -17
  118. package/Components/default-cell-renderer/__tests__/defaultCellRenderer.test.tsx +20 -17
  119. package/Components/default-cell-renderer/viewTrees/tv/DefaultCell/__tests__/DefaultCell.test.tsx +15 -11
  120. package/Contexts/ComponentsMapOffsetContext/index.tsx +49 -0
  121. package/Contexts/FocusableGroupContext/withFocusableContext.tsx +4 -10
  122. package/Contexts/HeaderOffsetContext/index.tsx +4 -6
  123. package/Contexts/ScreenContext/index.tsx +3 -10
  124. package/Contexts/ScreenLayoutContext/index.tsx +5 -3
  125. package/Decorators/Navigator/__tests__/navigator.test.js +16 -16
  126. package/Decorators/Navigator/index.tsx +1 -1
  127. package/Decorators/RiverResolver/__tests__/riverResolver.test.tsx +18 -24
  128. package/Decorators/RiverResolver/index.tsx +6 -8
  129. package/Decorators/ZappPipesDataConnector/__tests__/zappPipesDataConnector.test.js +29 -22
  130. package/Decorators/ZappPipesDataConnector/index.tsx +4 -30
  131. package/package.json +7 -11
  132. package/tsconfig.json +2 -3
  133. package/.babelrc +0 -8
  134. package/Components/Cell/CellStyles/FallbackCellStyle/index.js +0 -157
  135. package/Components/Cell/CellStyles/Hero/index.js +0 -111
  136. package/Components/Cell/CellStyles/ScreenSelector/index.js +0 -68
  137. package/Components/Cell/CellStyles/cellStylesResolver.ts +0 -19
  138. package/Components/Cell/CellStyles/colors.js +0 -40
  139. package/Components/Cell/CellStyles/index.js +0 -15
  140. package/Components/Cell/CellWithFocusable.ios.tsx +0 -126
  141. package/Components/CellRendererResolver/__tests__/__snapshots__/cellRendererResolver.test.js.snap +0 -53
  142. package/Components/RouteManager/__tests__/__snapshots__/testId.test.js.snap +0 -17
  143. package/Components/ScreenResolver/__tests__/__snapshots__/screenResolver.test.js.snap +0 -17
  144. package/Components/ZappUIComponent/__tests__/__snapshots__/ZappUIComponent.test.js.snap +0 -91
  145. package/Components/default-cell-renderer/__tests__/__snapshots__/defaultCellRenderer.test.tsx.snap +0 -338
  146. package/Decorators/Navigator/__tests__/__snapshots__/navigator.test.js.snap +0 -18
  147. package/Decorators/RiverResolver/__tests__/__snapshots__/riverResolver.test.tsx.snap +0 -28
@@ -4,7 +4,6 @@ import { Item, ItemProps } from "./Item";
4
4
  import { ItemIcon, ItemIconProps } from "./ItemIcon";
5
5
  import { ItemLabel, ItemLabelProps } from "./ItemLabel";
6
6
  import { defaultSelectedAsset } from "./assets";
7
- import * as assets from "./assets";
8
7
 
9
8
  type ButtonProps = {
10
9
  configuration: any;
@@ -17,6 +16,9 @@ type ButtonProps = {
17
16
  labelBaseProps?: ItemLabelProps;
18
17
  disabled?: boolean;
19
18
  label?: string | Record<string, string>;
19
+ iconPlacement?: "left" | "right";
20
+ selectedItemIcon?: ItemIconProps["asset"];
21
+ defaultItemIcon?: ItemIconProps["asset"];
20
22
  };
21
23
 
22
24
  const styles = StyleSheet.create({
@@ -33,52 +35,32 @@ export function Button({
33
35
  configuration,
34
36
  width,
35
37
  iconBaseProps,
36
- itemBaseProps,
38
+ itemBaseProps: itemProps,
37
39
  labelBaseProps,
38
40
  label,
41
+ iconPlacement = "left",
42
+ defaultItemIcon,
43
+ selectedItemIcon,
39
44
  disabled = false,
40
45
  }: ButtonProps) {
41
46
  const [focused, setFocused] = useState(false);
42
47
 
43
- const selected = useMemo(
44
- () => selectedItem && item.value === selectedItem?.value,
45
- [selectedItem, selectedItem]
46
- );
47
-
48
- const itemProps = useMemo<ItemProps>(
49
- () => ({
50
- ...itemBaseProps,
51
- width,
52
- }),
53
- [configuration, width]
54
- );
48
+ const selected = selectedItem && item.value === selectedItem?.value;
55
49
 
56
- const itemIconProps = useMemo<ItemIconProps>(
57
- () => ({
58
- ...iconBaseProps,
59
- asset: configuration[item.asset] ?? assets[item.asset] ?? item.asset,
60
- }),
61
- [configuration, item.asset]
50
+ const itemIconPropsAssets = useMemo<ItemIconProps["asset"]>(
51
+ () => configuration[item.asset] ?? item.asset ?? defaultItemIcon,
52
+ [item.asset, defaultItemIcon]
62
53
  );
63
54
 
64
- const selectedItemIconProps = useMemo<ItemIconProps>(
65
- () => ({
66
- ...iconBaseProps,
67
- asset:
68
- configuration["modal_bottom_sheet_item_selected_icon"] ||
69
- defaultSelectedAsset,
70
- marginRight: 10,
71
- }),
72
- [configuration]
55
+ const selectedItemIconPropsAssets = useMemo<ItemIconProps["asset"]>(
56
+ () => selectedItemIcon || defaultSelectedAsset,
57
+ [selectedItemIcon]
73
58
  );
74
59
 
75
- const itemLabelProps = useMemo<ItemLabelProps>(
76
- () => ({
77
- ...labelBaseProps,
78
- label: label ?? configuration[item?.label] ?? item?.label ?? null,
79
- }),
80
- [configuration, item?.label]
81
- );
60
+ const renderItemIcon =
61
+ itemIconPropsAssets && itemIconPropsAssets.length > 0 ? (
62
+ <ItemIcon {...iconBaseProps} asset={itemIconPropsAssets} />
63
+ ) : null;
82
64
 
83
65
  if (disabled) return null;
84
66
 
@@ -92,18 +74,23 @@ export function Button({
92
74
  >
93
75
  <Item {...itemProps} focused={focused} selected={selected}>
94
76
  <View style={styles.label_icon_container}>
95
- {itemIconProps.asset && itemIconProps.asset.length > 0 && (
96
- <ItemIcon {...itemIconProps} />
97
- )}
98
- {itemLabelProps.label && (
77
+ {iconPlacement === "left" && renderItemIcon}
78
+
79
+ {label ? (
99
80
  <ItemLabel
100
- {...itemLabelProps}
81
+ {...labelBaseProps}
82
+ label={label ?? null}
101
83
  focused={focused}
102
84
  selected={selected}
103
85
  />
104
- )}
86
+ ) : null}
105
87
  </View>
106
- {selected && <ItemIcon {...selectedItemIconProps} />}
88
+
89
+ {selected ? (
90
+ <ItemIcon {...iconBaseProps} asset={selectedItemIconPropsAssets} />
91
+ ) : (
92
+ iconPlacement === "right" && renderItemIcon
93
+ )}
107
94
  </Item>
108
95
  </TouchableOpacity>
109
96
  </View>
@@ -1,15 +1,18 @@
1
1
  import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
2
- import { PluginConfiguration } from "./index";
2
+ import { PluginConfiguration } from "./";
3
+ import { ItemIconProps } from "./Button/ItemIcon";
4
+ import { ItemLabelProps } from "./Button/ItemLabel";
5
+ import { ItemProps } from "./Button/Item";
3
6
 
4
7
  export function defaultItemProps(
5
8
  config: PluginConfiguration,
6
9
  maxWidth: number
7
- ) {
10
+ ): ItemProps {
8
11
  const {
9
12
  modal_bottom_sheet_item_background_color,
10
13
  modal_bottom_sheet_item_focus_background_color,
11
14
  modal_bottom_sheet_item_selected_background_color,
12
- modal_bottom_sheet_item_focusected_background_color,
15
+ modal_bottom_sheet_item_focused_selected_background_color,
13
16
  modal_bottom_sheet_item_corner_radius,
14
17
  modal_bottom_sheet_item_margin_bottom,
15
18
  modal_bottom_sheet_item_margin_left,
@@ -25,8 +28,8 @@ export function defaultItemProps(
25
28
  backgroundColor: modal_bottom_sheet_item_background_color,
26
29
  focusedBackgroundColor: modal_bottom_sheet_item_focus_background_color,
27
30
  selectedBackgroundColor: modal_bottom_sheet_item_selected_background_color,
28
- focusectedBackgroundColor:
29
- modal_bottom_sheet_item_focusected_background_color,
31
+ focusedSelectedBackgroundColor:
32
+ modal_bottom_sheet_item_focused_selected_background_color,
30
33
  borderRadius: modal_bottom_sheet_item_corner_radius,
31
34
  marginBottom: modal_bottom_sheet_item_margin_bottom,
32
35
  marginTop: modal_bottom_sheet_item_margin_top,
@@ -43,7 +46,7 @@ export function defaultItemProps(
43
46
  export function defaultItemLabelProps(
44
47
  config: PluginConfiguration,
45
48
  sheetWidth: number
46
- ) {
49
+ ): ItemLabelProps {
47
50
  const {
48
51
  modal_bottom_sheet_item_label_android_letter_spacing,
49
52
  modal_bottom_sheet_item_label_ios_letter_spacing,
@@ -103,7 +106,9 @@ export function defaultItemLabelProps(
103
106
  };
104
107
  }
105
108
 
106
- export function defaultItemIconProps(config: PluginConfiguration) {
109
+ export function defaultItemIconProps(
110
+ config: PluginConfiguration
111
+ ): ItemIconProps {
107
112
  const {
108
113
  modal_bottom_sheet_item_icon_height,
109
114
  modal_bottom_sheet_item_icon_width,
@@ -124,3 +129,46 @@ export function defaultItemIconProps(config: PluginConfiguration) {
124
129
  marginRight: modal_bottom_sheet_item_icon_margin_right,
125
130
  };
126
131
  }
132
+
133
+ export function getItemIconProps(
134
+ theme: PluginConfiguration,
135
+ iconProps?: ((theme: PluginConfiguration) => ItemIconProps) | ItemIconProps
136
+ ) {
137
+ if (iconProps) {
138
+ return typeof iconProps === "function" ? iconProps(theme) : iconProps;
139
+ }
140
+
141
+ return defaultItemIconProps(theme);
142
+ }
143
+
144
+ export function getItemLabelProps(
145
+ theme: PluginConfiguration,
146
+ width: number,
147
+ labelProps?:
148
+ | ((theme: PluginConfiguration, width: number) => ItemLabelProps)
149
+ | ItemLabelProps
150
+ ) {
151
+ if (labelProps) {
152
+ return typeof labelProps === "function"
153
+ ? labelProps(theme, width)
154
+ : labelProps;
155
+ }
156
+
157
+ return defaultItemLabelProps(theme, width);
158
+ }
159
+
160
+ export function getItemProps(
161
+ theme: PluginConfiguration,
162
+ width: number,
163
+ itemProps?:
164
+ | ((theme: PluginConfiguration, width: number) => ItemProps)
165
+ | ItemProps
166
+ ) {
167
+ if (itemProps) {
168
+ return typeof itemProps === "function"
169
+ ? itemProps(theme, width)
170
+ : itemProps;
171
+ }
172
+
173
+ return defaultItemProps(theme, width);
174
+ }
@@ -90,7 +90,7 @@ export const NotificationView = (props: Props) => {
90
90
  return (
91
91
  <div onClick={onClose}>
92
92
  {children}
93
- {open && (
93
+ {open ? (
94
94
  <div style={styles.body}>
95
95
  <div style={styles.title}>
96
96
  <h2>{MSG}</h2>
@@ -98,7 +98,7 @@ export const NotificationView = (props: Props) => {
98
98
 
99
99
  <h4 style={styles.subtitle}>{EXTRA_MSG}</h4>
100
100
  </div>
101
- )}
101
+ ) : null}
102
102
  </div>
103
103
  );
104
104
  };
@@ -85,7 +85,7 @@ export const NotificationView = (props: Props) => {
85
85
  return (
86
86
  <div onClick={onClose}>
87
87
  {children}
88
- {shown && (
88
+ {shown ? (
89
89
  <div style={styles.body}>
90
90
  <div style={styles.title}>
91
91
  <h2>{title}</h2>
@@ -93,7 +93,7 @@ export const NotificationView = (props: Props) => {
93
93
 
94
94
  <h4 style={styles.subtitle}>{subtitle}</h4>
95
95
  </div>
96
- )}
96
+ ) : null}
97
97
  </div>
98
98
  );
99
99
  };
@@ -1,7 +1,6 @@
1
1
  import React from "react";
2
2
  import { Text, Animated } from "react-native";
3
3
 
4
- import { shallow } from "enzyme";
5
4
  import renderer from "react-test-renderer";
6
5
 
7
6
  jest.useFakeTimers();
@@ -40,10 +39,6 @@ const {
40
39
  } = require("../NotificationView");
41
40
 
42
41
  describe("NotificationView", () => {
43
- it("renders", () => {
44
- shallow(<NotificationView dismiss={dismiss} />);
45
- });
46
-
47
42
  it("Show online message when Online", () => {
48
43
  const component = renderer.create(
49
44
  <NotificationView online dismiss={dismiss} />
@@ -57,7 +57,7 @@ export const useNotificationHeight = () => {
57
57
 
58
58
  const navBarHeight = platformSelect({ ios: 44, android: 56 });
59
59
 
60
- const statusHeight = Platform.OS === "android" ? 0 : insets.top;
60
+ const statusHeight = insets.top;
61
61
  const notificationHeight = statusHeight + navBarHeight;
62
62
 
63
63
  return { statusHeight, notificationHeight };
@@ -1,17 +1,18 @@
1
1
  import * as React from "react";
2
+ import { useEffect, useReducer } from "react";
2
3
  // @ts-ignore
3
- import { View, ViewStyle, TVMenuControl } from "react-native";
4
+ import { TVMenuControl, View, ViewStyle } from "react-native";
4
5
  import * as R from "ramda";
5
6
  import uuid from "uuid/v4";
6
7
  import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils/playerManager";
7
8
  import {
8
9
  isApplePlatform,
9
- platformSelect,
10
10
  isTV,
11
+ platformSelect,
12
+ isAndroidTVPlatform,
11
13
  } from "@applicaster/zapp-react-native-utils/reactUtils";
12
14
 
13
15
  import { TVEventHandlerComponent } from "@applicaster/zapp-react-native-tvos-ui-components/Components/TVEventHandlerComponent";
14
- import { useEffect, useReducer } from "react";
15
16
  import { usePrevious } from "@applicaster/zapp-react-native-utils/reactHooks/utils";
16
17
  import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
17
18
  import {
@@ -29,10 +30,10 @@ import {
29
30
  import { ProgramInfo } from "./ProgramInfo";
30
31
  import { AudioPlayer } from "../AudioPlayer";
31
32
  import {
32
- playerContainerLogger,
33
33
  log_debug,
34
34
  log_info,
35
35
  log_warning,
36
+ playerContainerLogger,
36
37
  } from "./logger";
37
38
  import { usePlayer } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayer";
38
39
  import { useSetNavbarState } from "@applicaster/zapp-react-native-utils/reactHooks/screen/useScreenContext";
@@ -53,8 +54,8 @@ import { usePlayNextOverlay } from "@applicaster/zapp-react-native-utils/appUtil
53
54
  import { PlayNextState } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/OverlayObserver/OverlaysObserver";
54
55
 
55
56
  import {
56
- useModalAnimationContext,
57
57
  PlayerAnimationStateEnum,
58
+ useModalAnimationContext,
58
59
  } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
59
60
 
60
61
  type Props = {
@@ -93,6 +94,20 @@ export type PlayNextData = {
93
94
 
94
95
  const focusableBottomContainerId = "player-container-bottom";
95
96
 
97
+ const isAndroidTV = isAndroidTVPlatform();
98
+
99
+ const withBorderHack = () => {
100
+ if (isAndroidTV) {
101
+ /* @HACK: see GH#7269 */
102
+ return {
103
+ borderWidth: 1,
104
+ borderColor: "transparent",
105
+ };
106
+ }
107
+
108
+ return {};
109
+ };
110
+
96
111
  // Styles
97
112
  const webStyles = {
98
113
  focusableGroup: {
@@ -335,9 +350,9 @@ const PlayerContainerComponent = (props: Props) => {
335
350
 
336
351
  const resumeTime = Number(item?.extensions?.resumeTime);
337
352
 
338
- // TODO: This is temp hack, will be removed on next pr with player refactoring
353
+ // Сhecking that the player itself knows where to start playing, and there is no need to call seekTo after returning from the Сhromecast
339
354
  if (
340
- !!playerManager.getActivePlayer()?.getContinueWatchingOffset === false &&
355
+ !playerManager.getActivePlayer()?.hasResumePosition() &&
341
356
  !isNaN(resumeTime)
342
357
  ) {
343
358
  player?.seekTo(resumeTime);
@@ -514,6 +529,12 @@ const PlayerContainerComponent = (props: Props) => {
514
529
  useEffect(() => {
515
530
  playerEvent("source_changed", { item });
516
531
 
532
+ return () => {
533
+ playerEvent("player_did_close", { item });
534
+ };
535
+ }, [item?.id, Player]);
536
+
537
+ useEffect(() => {
517
538
  if (!isModal) {
518
539
  showNavBar(false);
519
540
  }
@@ -523,13 +544,11 @@ const PlayerContainerComponent = (props: Props) => {
523
544
  }
524
545
 
525
546
  return () => {
526
- playerEvent("player_did_close", { item });
527
-
528
547
  if (!isModal) {
529
548
  showNavBar(true);
530
549
  }
531
550
  };
532
- }, [showNavBar, /* added as suggested: */ item?.id, isModal, Player]);
551
+ }, [showNavBar, isModal, Player]);
533
552
 
534
553
  useEffect(() => {
535
554
  if (prevItemId && !R.equals(prevItemId, item?.id)) {
@@ -640,7 +659,14 @@ const PlayerContainerComponent = (props: Props) => {
640
659
  testID={"player-screen-container"}
641
660
  >
642
661
  {/* Player container */}
643
- <View style={styles.playerWrapper} testID={"player-wrapper"}>
662
+ <View
663
+ style={[
664
+ styles.playerWrapper,
665
+ // eslint-disable-next-line react-native/no-inline-styles, react-native/no-color-literals
666
+ withBorderHack(),
667
+ ]}
668
+ testID={"player-wrapper"}
669
+ >
644
670
  <PlayerFocusableWrapperView
645
671
  nextFocusDown={context.bottomFocusableId}
646
672
  >
@@ -683,10 +709,10 @@ const PlayerContainerComponent = (props: Props) => {
683
709
 
684
710
  {renderRestPlayers(restPlayerProps)}
685
711
 
686
- {state.error && <ErrorDisplay error={state.error} />}
712
+ {state.error ? <ErrorDisplay error={state.error} /> : null}
687
713
  </View>
688
714
  {/* Components container */}
689
- {isInlineTV && context.showComponentsContainer && (
715
+ {isInlineTV && context.showComponentsContainer ? (
690
716
  <View
691
717
  style={styles.inlineRiver}
692
718
  testID={"inline-river-component-wrapper"}
@@ -717,7 +743,7 @@ const PlayerContainerComponent = (props: Props) => {
717
743
  )}
718
744
  </ComponentFocusableWrapperView>
719
745
  </View>
720
- )}
746
+ ) : null}
721
747
  </View>
722
748
  </FocusableGroup>
723
749
  </TVEventHandlerComponent>
@@ -114,12 +114,12 @@ function ProgramInfoComponent({
114
114
  return (
115
115
  <View style={container}>
116
116
  <View style={programStyles.programInfo.container}>
117
- {logo && (
117
+ {logo ? (
118
118
  <Image
119
119
  source={{ uri: logo }}
120
120
  style={programStyles.programInfo.logo}
121
121
  />
122
- )}
122
+ ) : null}
123
123
  {!isAudioContent && transportInfo}
124
124
  </View>
125
125
  </View>
@@ -39,7 +39,7 @@ const PlayerImageBackgroundComponent = ({
39
39
  return (
40
40
  <View
41
41
  style={
42
- playerAnimationState === PlayerAnimationStateEnum.maximaze
42
+ playerAnimationState === PlayerAnimationStateEnum.maximize
43
43
  ? defaultImageDimensions
44
44
  : style
45
45
  }
@@ -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,6 +276,7 @@ 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}
@@ -28,10 +28,10 @@ type Return = {
28
28
  // TODO: Take this value from Zapp configuration, when feature is added to GeneralScreen
29
29
  const SHOULD_FAIL_ON_COMPONENT_LOADING = false;
30
30
 
31
- const createLoadingStateObservable = () =>
31
+ const createLoadingStateObservable = (count: number) =>
32
32
  new BehaviorSubject<LoadingState>({
33
33
  index: -1,
34
- done: false,
34
+ done: count === 0,
35
35
  waitForAllComponents: SHOULD_FAIL_ON_COMPONENT_LOADING,
36
36
  });
37
37
 
@@ -43,7 +43,7 @@ export const useLoadingState = (
43
43
  const [loadingError, setLoadingError] = React.useState(null);
44
44
 
45
45
  const loadingState = useRefWithInitialValue<BehaviorSubject<LoadingState>>(
46
- createLoadingStateObservable
46
+ () => createLoadingStateObservable(count)
47
47
  );
48
48
 
49
49
  const arePreviousComponentsLoaded = React.useCallback((index) => {
@@ -1,5 +1,6 @@
1
1
  import React, { useEffect } from "react";
2
2
  import * as R from "ramda";
3
+ import { isGroup } from "@applicaster/zapp-react-native-utils/componentsUtils";
3
4
 
4
5
  import { applyDecorators } from "../../Decorators";
5
6
 
@@ -112,7 +113,7 @@ function RiverItemComponent(props: RiverItemType) {
112
113
  jsOnly: true,
113
114
  });
114
115
 
115
- if (!CellRenderer && item.component_type !== "group-qb") {
116
+ if (!CellRenderer && !isGroup(item)) {
116
117
  riverLogger.warning({
117
118
  message: "Cell Renderer is null - will fallback to default cell",
118
119
  data: { item, CellRenderer },
@@ -1,4 +1,9 @@
1
+ import { compose } from "ramda";
1
2
  import { River as RiverComponent } from "./River";
2
3
  import { withTvEventHandler } from "./withTVEventHandler";
4
+ import { withComponentsMapOffsetContext } from "../../../Contexts/ComponentsMapOffsetContext";
3
5
 
4
- export const River = withTvEventHandler(RiverComponent);
6
+ export const River = compose(
7
+ withTvEventHandler,
8
+ withComponentsMapOffsetContext
9
+ )(RiverComponent);
@@ -1,89 +1,27 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
- exports[`When River has a general_content type <River /> renders correctly 1`] = `
4
- <ContextProvider
5
- value={null}
6
- >
7
- <RiverWithData
8
- appData={
9
- {
10
- "layoutVersion": "v1",
11
- }
12
- }
13
- dispatch={[Function]}
14
- rivers={
15
- {
16
- "A1234": {
17
- "home": true,
18
- "id": "A1234",
19
- "name": "foo",
20
- "type": "general_content",
21
- "ui_components": [
22
- {
23
- "component_type": "hero",
24
- },
25
- {
26
- "component_type": "grid",
27
- },
28
- ],
29
- },
30
- "B4567": {
31
- "id": "B4567",
32
- },
33
- "C0987": {
34
- "home": false,
35
- "id": "C0987",
36
- "name": "Some-Screen-Plugin",
37
- "type": "some-screen-plugin",
38
- "ui_components": [],
39
- },
40
- }
41
- }
42
- screenId="A1234"
43
- store={
44
- {
45
- "clearActions": [Function],
46
- "dispatch": [Function],
47
- "getActions": [Function],
48
- "getState": [Function],
49
- "replaceReducer": [Function],
50
- "subscribe": [Function],
51
- }
52
- }
53
- />
54
- </ContextProvider>
55
- `;
56
-
57
- exports[`When River has a general_content type <RiverComponent /> renders correctly 1`] = `
58
- <GeneralContentScreen
59
- groupId="ZF-C4"
60
- screenId="A1234"
61
- />
62
- `;
63
-
64
- exports[`When River has any other type other than general_content <RiverComponent /> renders correctly 1`] = `
65
- <WithProvider
66
- screenData={
3
+ exports[`When River has a general_content type renders River component correctly 1`] = `
4
+ <View
5
+ onLayout={[Function]}
6
+ style={
67
7
  {
68
- "groupId": undefined,
69
- "home": false,
70
- "id": "C0987",
71
- "name": "Some-Screen-Plugin",
72
- "type": "some-screen-plugin",
73
- "ui_components": [],
8
+ "flex": 1,
74
9
  }
75
10
  }
76
- screenId="C0987"
77
- screenType="some-screen-plugin"
78
- />
79
- `;
80
-
81
- exports[`When River has feed url <RiverComponent /> renders correctly 1`] = `
82
- <Connect(FeedLoaderComponent)
83
- feedUrl="https://some-feed-url.net"
84
- refreshCallback={[Function]}
85
- refreshing={false}
11
+ testID="on-layout-view"
86
12
  >
87
- <Component />
88
- </Connect(FeedLoaderComponent)>
13
+ <View
14
+ style={
15
+ {
16
+ "display": "none",
17
+ "flex": 1,
18
+ }
19
+ }
20
+ >
21
+ <View
22
+ screenId="A1234"
23
+ testID="general-content-screen"
24
+ />
25
+ </View>
26
+ </View>
89
27
  `;