@applicaster/zapp-react-native-ui-components 15.0.0-alpha.1257410812 → 15.0.0-alpha.1305114721

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 (100) hide show
  1. package/Components/GeneralContentScreen/GeneralContentScreen.tsx +39 -28
  2. package/Components/GeneralContentScreen/__tests__/GeneralContentScreen.test.tsx +104 -0
  3. package/Components/GeneralContentScreen/utils/__tests__/getScreenDataSource.test.ts +19 -0
  4. package/Components/GeneralContentScreen/utils/getScreenDataSource.ts +9 -0
  5. package/Components/HandlePlayable/HandlePlayable.tsx +16 -29
  6. package/Components/HandlePlayable/utils.ts +31 -0
  7. package/Components/HookRenderer/HookRenderer.tsx +40 -10
  8. package/Components/HookRenderer/__tests__/HookRenderer.test.tsx +60 -0
  9. package/Components/Layout/TV/NavBarContainer.tsx +1 -10
  10. package/Components/Layout/TV/__tests__/__snapshots__/NavBarContainer.test.tsx.snap +7 -12
  11. package/Components/Layout/TV/__tests__/__snapshots__/ScreenContainer.test.tsx.snap +7 -12
  12. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/model.test.ts +80 -0
  13. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/placement.test.ts +187 -0
  14. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/selectors.test.ts +45 -0
  15. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/style.test.ts +49 -0
  16. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/model.ts +47 -0
  17. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/placement.ts +170 -0
  18. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/selectors.ts +26 -0
  19. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/style.ts +29 -0
  20. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/types.ts +37 -0
  21. package/Components/MasterCell/DefaultComponents/Button.tsx +0 -15
  22. package/Components/MasterCell/DefaultComponents/LiveImage/__tests__/prepareEntry.test.ts +352 -0
  23. package/Components/MasterCell/DefaultComponents/LiveImage/executePreloadHooks.ts +136 -0
  24. package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +33 -16
  25. package/Components/MasterCell/DefaultComponents/PressableView.tsx +196 -0
  26. package/Components/MasterCell/DefaultComponents/Text/index.tsx +2 -6
  27. package/Components/MasterCell/DefaultComponents/index.ts +2 -0
  28. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/Asset.ts +46 -0
  29. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/Button.ts +126 -0
  30. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/ButtonContainerView.ts +23 -0
  31. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/Spacer.ts +16 -0
  32. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/TextLabel.ts +67 -0
  33. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/TextLabelsContainer.ts +32 -0
  34. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/__tests__/PressableView.test.tsx +191 -0
  35. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/__tests__/builders.test.ts +140 -0
  36. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/__tests__/index.test.ts +222 -0
  37. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/helpers.ts +105 -0
  38. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/index.ts +104 -0
  39. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/utils/__tests__/insertButtons.test.ts +118 -0
  40. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/utils/index.ts +73 -0
  41. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/__tests__/index.test.ts +86 -0
  42. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/index.ts +35 -52
  43. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/utils/__tests__/getPluginIdentifier.test.ts +92 -103
  44. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/utils/index.ts +37 -148
  45. package/Components/MasterCell/elementMapper.tsx +1 -0
  46. package/Components/OfflineHandler/NotificationView/NotificationView.lg.tsx +17 -9
  47. package/Components/OfflineHandler/NotificationView/NotificationView.samsung.tsx +16 -8
  48. package/Components/OfflineHandler/NotificationView/utils.ts +34 -0
  49. package/Components/PlayerContainer/PlayerContainer.tsx +1 -18
  50. package/Components/PreloaderWrapper/__tests__/index.test.tsx +26 -0
  51. package/Components/PreloaderWrapper/index.tsx +15 -0
  52. package/Components/River/ComponentsMap/ComponentsMap.tsx +16 -0
  53. package/Components/River/RefreshControl.tsx +36 -13
  54. package/Components/River/RiverItem.tsx +26 -20
  55. package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +2 -0
  56. package/Components/River/__tests__/componentsMap.test.js +38 -0
  57. package/Components/Screen/__tests__/Screen.test.tsx +1 -0
  58. package/Components/Screen/hooks.ts +73 -3
  59. package/Components/Screen/index.tsx +7 -1
  60. package/Components/ScreenFeedLoader/ScreenFeedLoader.tsx +46 -0
  61. package/Components/ScreenFeedLoader/__tests__/ScreenFeedLoader.test.tsx +94 -0
  62. package/Components/ScreenFeedLoader/index.ts +1 -0
  63. package/Components/ScreenResolver/__tests__/screenResolver.test.js +24 -0
  64. package/Components/ScreenResolver/hooks/index.ts +3 -0
  65. package/Components/ScreenResolver/hooks/useGetComponent.ts +15 -0
  66. package/Components/ScreenResolver/hooks/useScreenComponentResolver.tsx +90 -0
  67. package/Components/ScreenResolver/index.tsx +15 -117
  68. package/Components/ScreenResolver/utils/__tests__/getScreenTypeProps.test.ts +45 -0
  69. package/Components/ScreenResolver/utils/getScreenTypeProps.ts +43 -0
  70. package/Components/ScreenResolver/utils/index.ts +1 -0
  71. package/Components/ScreenResolver/withDefaultScreenContext.tsx +16 -0
  72. package/Components/ScreenResolverFeedProvider/ScreenResolverFeedProvider.tsx +25 -0
  73. package/Components/ScreenResolverFeedProvider/__tests__/ScreenResolverFeedProvider.test.tsx +44 -0
  74. package/Components/ScreenResolverFeedProvider/index.ts +1 -0
  75. package/Components/Tabs/TabContent.tsx +7 -4
  76. package/Components/Transitioner/Scene.tsx +9 -15
  77. package/Components/VideoLive/LiveImageManager.ts +199 -54
  78. package/Components/VideoLive/PlayerLiveImageComponent.tsx +31 -33
  79. package/Components/VideoLive/__tests__/PlayerLiveImageComponent.test.tsx +2 -17
  80. package/Components/Viewport/ViewportAware/__tests__/viewportAware.test.js +0 -2
  81. package/Components/Viewport/ViewportAware/index.tsx +16 -7
  82. package/Components/ZappUIComponent/index.tsx +12 -6
  83. package/Components/default-cell-renderer/viewTrees/mobile/index.ts +0 -3
  84. package/Components/index.js +1 -1
  85. package/Contexts/ScreenContext/__tests__/index.test.tsx +57 -0
  86. package/Contexts/ScreenContext/index.tsx +71 -19
  87. package/Contexts/ZappPipesContext/ZappPipesContextFactory.tsx +18 -7
  88. package/Decorators/ZappPipesDataConnector/ResolverSelector.tsx +25 -7
  89. package/Decorators/ZappPipesDataConnector/__tests__/ResolverSelector.test.tsx +212 -5
  90. package/Decorators/ZappPipesDataConnector/__tests__/UrlFeedResolver.test.tsx +39 -21
  91. package/Decorators/ZappPipesDataConnector/resolvers/UrlFeedResolver.tsx +18 -7
  92. package/events/index.ts +2 -0
  93. package/events/scrollEndReached.ts +15 -0
  94. package/package.json +5 -5
  95. package/Components/MasterCell/DefaultComponents/Text/utils/__tests__/withAdjustedLineHeight.test.ts +0 -46
  96. package/Components/MasterCell/DefaultComponents/Text/utils/index.ts +0 -21
  97. package/Components/PlayerContainer/ErrorDisplay/ErrorDisplay.tsx +0 -57
  98. package/Components/PlayerContainer/ErrorDisplay/index.ts +0 -9
  99. package/Components/PlayerContainer/useRestrictMobilePlayback.tsx +0 -101
  100. /package/Components/HookRenderer/{index.tsx → index.ts} +0 -0
@@ -1,152 +1,123 @@
1
- import { getPluginIdentifier } from "..";
1
+ import { getPluginIdentifier, memoizedGetPluginIdentifier } from "..";
2
2
 
3
3
  describe("getPluginIdentifier", () => {
4
4
  const prefix = "tv_buttons";
5
5
 
6
- it("returns the first valid plugin identifier", () => {
7
- const configuration = {
8
- tv_buttons_button_1_other: "value",
9
- tv_buttons_button_1_assign_action:
10
- "tv_buttons_button_1_assign_action_value",
11
- tv_buttons_button_2_assign_action:
12
- "tv_buttons_button_2_assign_action_value",
13
- };
14
-
15
- const index = 0;
16
- const result = getPluginIdentifier(configuration, prefix, index);
17
-
18
- expect(result).toEqual(configuration.tv_buttons_button_1_assign_action);
6
+ beforeAll(() => {
7
+ memoizedGetPluginIdentifier.clear();
19
8
  });
20
9
 
21
- it("returns the second valid plugin identifier", () => {
10
+ it("returns the requested slot action identifier", () => {
11
+ expect.assertions(2);
12
+
22
13
  const configuration = {
23
- tv_buttons_button_1_other: "value_1",
24
14
  tv_buttons_button_1_assign_action:
25
15
  "tv_buttons_button_1_assign_action_value",
26
- tv_buttons_button_2_other: "value_2",
27
- tv_buttons_button_2_assign_action:
28
- "tv_buttons_button_2_assign_action_value",
16
+ tv_buttons_button_3_assign_action:
17
+ "tv_buttons_button_3_assign_action_value",
29
18
  };
30
19
 
31
- const index = 1;
32
- const result = getPluginIdentifier(configuration, prefix, index);
33
-
34
- expect(result).toEqual(configuration.tv_buttons_button_2_assign_action);
35
- });
20
+ const slot = 3;
21
+ const result = getPluginIdentifier(configuration, prefix, slot);
36
22
 
37
- it("returns undefined when there are no assign_action keys", () => {
38
- const configuration = {};
39
- const index = 0;
40
-
41
- const result = getPluginIdentifier(configuration, prefix, index);
42
-
43
- expect(result).toBeUndefined();
44
- });
45
-
46
- it("skips undefined values and returns the correct plugin identifier", () => {
47
- const configuration = {
48
- tv_buttons_button_1_assign_action: "tv_buttons_button_1_assign_action",
49
- tv_buttons_button_2_assign_action: undefined,
50
- tv_buttons_button_3_assign_action: "tv_buttons_button_3_assign_action",
51
- };
52
-
53
- const index = 1;
54
- const result = getPluginIdentifier(configuration, prefix, index);
23
+ const memoizedResult = memoizedGetPluginIdentifier(
24
+ configuration,
25
+ prefix,
26
+ slot
27
+ );
55
28
 
56
29
  expect(result).toEqual(configuration.tv_buttons_button_3_assign_action);
30
+ expect(memoizedResult).toEqual(result);
57
31
  });
58
32
 
59
- it("handles missing intermediate keys and returns the correct plugin identifier", () => {
33
+ it("returns undefined for a disabled or missing slot", () => {
34
+ expect.assertions(2);
35
+
60
36
  const configuration = {
61
37
  tv_buttons_button_1_assign_action: "tv_buttons_button_1_assign_action",
62
- tv_buttons_button_3_assign_action: "tv_buttons_button_3_assign_action",
63
38
  };
64
39
 
65
- const index = 1;
66
- const result = getPluginIdentifier(configuration, prefix, index);
40
+ const slot = 2;
41
+ const result = getPluginIdentifier(configuration, prefix, slot);
67
42
 
68
- expect(result).toEqual(configuration.tv_buttons_button_3_assign_action);
43
+ const memoizedResult = memoizedGetPluginIdentifier(
44
+ configuration,
45
+ prefix,
46
+ slot
47
+ );
48
+
49
+ expect(result).toBeUndefined();
50
+ expect(memoizedResult).toEqual(result);
69
51
  });
70
52
 
71
- it("skips empty string values and returns the first non-empty assign_action", () => {
53
+ it("returns undefined for empty string values", () => {
54
+ expect.assertions(2);
55
+
72
56
  const configuration = {
73
- tv_buttons_button_1_assign_action: "",
74
- tv_buttons_button_2_assign_action: "tv_buttons_button_2_assign_action",
57
+ tv_buttons_button_2_assign_action: "",
75
58
  };
76
59
 
77
- const index = 0;
78
- const result = getPluginIdentifier(configuration, prefix, index);
60
+ const slot = 2;
79
61
 
80
- expect(result).toEqual(configuration.tv_buttons_button_2_assign_action);
81
- });
62
+ const result = getPluginIdentifier(configuration, prefix, slot);
82
63
 
83
- it("returns undefined for negative index", () => {
84
- const configuration = {
85
- tv_buttons_button_1_assign_action: "a",
86
- tv_buttons_button_2_assign_action: "b",
87
- };
88
-
89
- const index = -1;
90
- const result = getPluginIdentifier(configuration, prefix, index);
64
+ const memoizedResult = memoizedGetPluginIdentifier(
65
+ configuration,
66
+ prefix,
67
+ slot
68
+ );
91
69
 
92
70
  expect(result).toBeUndefined();
71
+ expect(memoizedResult).toBeUndefined();
93
72
  });
94
73
 
95
- it("returns undefined for out-of-bounds index", () => {
74
+ it("returns undefined for negative slots", () => {
75
+ expect.assertions(2);
76
+
96
77
  const configuration = {
97
78
  tv_buttons_button_1_assign_action: "a",
98
79
  tv_buttons_button_2_assign_action: "b",
99
80
  };
100
81
 
101
- const index = 5;
102
- const result = getPluginIdentifier(configuration, prefix, index);
103
-
104
- expect(result).toBeUndefined();
105
- });
106
-
107
- it("ignores keys with wrong prefix or format", () => {
108
- const configuration = {
109
- tv_buttons_button_1_assign_action: "a",
110
- tv_buttons_wrongprefix_2_assign_action: "b",
111
- tv_buttons_button_x_assign_action: "c",
112
- };
82
+ const slot = -1;
83
+ const result = getPluginIdentifier(configuration, prefix, slot);
113
84
 
114
- const index = 1;
115
- const result = getPluginIdentifier(configuration, prefix, index);
85
+ const memoizedResult = memoizedGetPluginIdentifier(
86
+ configuration,
87
+ prefix,
88
+ slot
89
+ );
116
90
 
117
91
  expect(result).toBeUndefined();
92
+ expect(memoizedResult).toBeUndefined();
118
93
  });
119
94
 
120
- it("returns undefined if all assign_actions are null or empty", () => {
121
- const configuration = {
122
- tv_buttons_button_1_assign_action: null,
123
- tv_buttons_button_2_assign_action: undefined,
124
- tv_buttons_button_3_assign_action: "",
125
- };
95
+ it("handles non-string values by returning the configured slot value", () => {
96
+ expect.assertions(2);
126
97
 
127
- const index = 0;
128
- const result = getPluginIdentifier(configuration, prefix, index);
129
-
130
- expect(result).toBeUndefined();
131
- });
132
-
133
- it("handles non-string values correctly", () => {
134
98
  const configuration = {
135
- tv_buttons_button_1_assign_action: 123,
136
99
  tv_buttons_button_2_assign_action: true,
137
- tv_buttons_button_3_assign_action: { nested: "value" },
138
100
  };
139
101
 
140
- expect(getPluginIdentifier(configuration, prefix, 0)).toEqual(123);
141
- expect(getPluginIdentifier(configuration, prefix, 1)).toEqual(true);
102
+ const slot = 2;
103
+ const result = getPluginIdentifier(configuration, prefix, slot);
104
+
105
+ const memoizedResult = memoizedGetPluginIdentifier(
106
+ configuration,
107
+ prefix,
108
+ slot
109
+ );
142
110
 
143
- expect(getPluginIdentifier(configuration, prefix, 2)).toEqual({
144
- nested: "value",
145
- });
111
+ expect(result).toBe(true);
112
+ expect(memoizedResult).toBe(true);
146
113
  });
147
114
  });
148
115
 
149
116
  describe("getPluginIdentifier - when configuration has duplicate values", () => {
117
+ beforeAll(() => {
118
+ memoizedGetPluginIdentifier.clear();
119
+ });
120
+
150
121
  const prefix = "tv_buttons";
151
122
 
152
123
  const configuration = {
@@ -154,17 +125,35 @@ describe("getPluginIdentifier - when configuration has duplicate values", () =>
154
125
  tv_buttons_button_2_assign_action: "navigation_action",
155
126
  };
156
127
 
157
- it("returns the first plugin identifier when values are identical", () => {
158
- const index = 0;
159
- const result = getPluginIdentifier(configuration, prefix, index);
128
+ it("returns the requested slot even when values are identical", () => {
129
+ expect.assertions(2);
130
+
131
+ const slot = 1;
132
+ const result = getPluginIdentifier(configuration, prefix, slot);
133
+
134
+ const memoizedResult = memoizedGetPluginIdentifier(
135
+ configuration,
136
+ prefix,
137
+ slot
138
+ );
160
139
 
161
140
  expect(result).toEqual(configuration.tv_buttons_button_1_assign_action);
141
+ expect(memoizedResult).toEqual(result);
162
142
  });
163
143
 
164
- it("returns the second plugin identifier when values are identical", () => {
165
- const index = 1;
166
- const result = getPluginIdentifier(configuration, prefix, index);
144
+ it("returns the second slot when values are identical", () => {
145
+ expect.assertions(2);
146
+
147
+ const slot = 2;
148
+ const result = getPluginIdentifier(configuration, prefix, slot);
149
+
150
+ const memoizedResult = memoizedGetPluginIdentifier(
151
+ configuration,
152
+ prefix,
153
+ slot
154
+ );
167
155
 
168
156
  expect(result).toEqual(configuration.tv_buttons_button_2_assign_action);
157
+ expect(memoizedResult).toEqual(result);
169
158
  });
170
159
  });
@@ -1,179 +1,68 @@
1
- import * as R from "ramda";
2
1
  import memoizee from "memoizee";
3
-
4
2
  import { isWeb } from "@applicaster/zapp-react-native-utils/reactUtils";
3
+ import { getEnabledButtonSlots } from "../../../ActionButtonsCore/selectors";
4
+ import {
5
+ insertBetweenLabelContainers,
6
+ insertBetweenLabels,
7
+ } from "../../../ActionButtonsCore/placement";
5
8
 
6
9
  export const getButtonsCount = (
7
10
  configuration: Record<string, unknown>,
8
11
  prefix: string
9
12
  ): number => {
10
- const button1Key = `${prefix}_button_1_button_enabled`;
11
- const button2Key = `${prefix}_button_2_button_enabled`;
12
- const button3Key = `${prefix}_button_3_button_enabled`;
13
-
14
- return R.toPairs(configuration).filter(
15
- ([key, value]) =>
16
- [button1Key, button2Key, button3Key].includes(key) && value
17
- ).length;
13
+ return getEnabledButtonSlots(configuration, `${prefix}_button`).length;
18
14
  };
19
15
 
20
16
  export const getPluginIdentifier = (
21
17
  configuration: Record<string, unknown>,
22
18
  prefix: string,
23
- index: number
19
+ slot: number
24
20
  ): string | undefined => {
25
- const re = new RegExp(`${prefix}_button_\\d_assign_action`);
26
- let count = 0;
27
-
28
- for (const [key, value] of Object.entries(configuration)) {
29
- if (
30
- key.startsWith(`${prefix}_button`) &&
31
- re.test(key) &&
32
- value != null &&
33
- value !== ""
34
- ) {
35
- if (count === index) return value as string;
36
- count++;
37
- }
38
- }
39
-
40
- return undefined;
41
- };
21
+ const value = configuration[
22
+ `${prefix}_button_${slot}_assign_action`
23
+ ] as string;
42
24
 
43
- export const memoizedGetPluginIdentifier = memoizee(getPluginIdentifier, {
44
- primitive: true,
45
- });
46
-
47
- type Label = {
48
- name: string;
49
- };
50
-
51
- type LabelContainer = {
52
- elements: Array<Label>;
25
+ return value == null || value === "" ? undefined : value;
53
26
  };
54
27
 
55
- type LabelExtraContainer = {
56
- elements: Array<LabelContainer>;
57
- };
58
-
59
- const withButtons = (labelName, buttons, labels) => {
60
- return labels.reduce((acc, label) => {
61
- if (label.name === labelName) {
62
- return [...acc, label, buttons];
63
- }
64
-
65
- return [...acc, label];
66
- }, []);
67
- };
68
-
69
- const withButtonsInContainer = (labelName, buttons, views) => {
70
- return views.map((view) => {
71
- return {
72
- ...view,
73
- elements: view.elements.reduce((acc, label) => {
74
- if (label.name === labelName) {
75
- return [...acc, label, buttons];
76
- }
77
-
78
- return [...acc, label];
79
- }, []),
80
- };
81
- });
82
- };
28
+ export const memoizedGetPluginIdentifier = memoizee(getPluginIdentifier);
83
29
 
84
30
  export const insertButtonsBetweenLabels = (
85
31
  configuration: Record<string, unknown>,
86
32
  buttons,
87
- labels: Label[] = []
88
- ) => {
89
- if (R.isNil(buttons)) {
90
- return labels;
91
- }
92
-
93
- const position = R.pathOr(
94
- undefined,
95
- ["tv_buttons_container_position"],
96
- configuration
33
+ labels = []
34
+ ) =>
35
+ insertBetweenLabels(
36
+ {
37
+ position: configuration.tv_buttons_container_position as
38
+ | string
39
+ | undefined,
40
+ allowOnTop: true,
41
+ appendWhenMissing: true,
42
+ },
43
+ buttons,
44
+ labels
97
45
  );
98
46
 
99
- if (position === "on_top") {
100
- return [buttons, ...labels];
101
- }
102
-
103
- const labelsWithButtons = withButtons(position, buttons, labels);
104
-
105
- if (R.equals(labelsWithButtons, labels)) {
106
- // put buttons after all labels by default
107
- return [...labels, buttons];
108
- }
109
-
110
- return labelsWithButtons;
111
- };
112
-
113
47
  export const insertButtonsBetweenLabelContainers = (
114
48
  configuration: Record<string, unknown>,
115
49
  buttons,
116
- labelContainers: Array<LabelExtraContainer> = []
117
- ) => {
118
- if (R.isNil(buttons)) {
119
- return labelContainers;
120
- }
121
-
122
- if (R.isEmpty(labelContainers)) {
123
- return [buttons];
124
- }
125
-
126
- const position = R.pathOr(
127
- undefined,
128
- ["tv_buttons_container_position"],
129
- configuration
50
+ labelContainers = []
51
+ ) =>
52
+ insertBetweenLabelContainers(
53
+ {
54
+ position: configuration.tv_buttons_container_position as
55
+ | string
56
+ | undefined,
57
+ allowOnTop: true,
58
+ appendWhenMissing: true,
59
+ },
60
+ buttons,
61
+ labelContainers
130
62
  );
131
63
 
132
- if (position === "on_top") {
133
- const firstContainerLabels = R.lensPath([0, "elements"]);
134
-
135
- return R.over(firstContainerLabels, R.prepend(buttons), labelContainers);
136
- }
137
-
138
- const labelContainersWithButtons = labelContainers.map((labelContainer) => {
139
- return {
140
- ...labelContainer,
141
- elements: withButtonsInContainer(
142
- position,
143
- buttons,
144
- labelContainer.elements
145
- ),
146
- };
147
- });
148
-
149
- if (R.equals(labelContainersWithButtons, labelContainers)) {
150
- // put buttons in last container
151
- const lastContainerLabels = R.lensPath([
152
- labelContainers.length - 1,
153
- "elements",
154
- ]);
155
-
156
- return R.over(lastContainerLabels, R.append(buttons), labelContainers);
157
- }
158
-
159
- return labelContainersWithButtons;
160
- };
161
-
162
- export const mapSelfAlignment = (horizontalPosition) => {
163
- switch (horizontalPosition) {
164
- case "left":
165
- return "flex-start";
166
- case "right":
167
- return "flex-end";
168
- case "center":
169
- return "center";
170
- default:
171
- return "flex-start";
172
- }
173
- };
174
-
175
64
  export const getTextTransform = (textTransform: string) => {
176
- if (R.isNil(textTransform) || R.isEmpty(textTransform)) {
65
+ if (textTransform == null || textTransform === "") {
177
66
  return "none";
178
67
  }
179
68
 
@@ -19,6 +19,7 @@ const focusableTypes = new Set([
19
19
  "View",
20
20
  "ButtonContainerView",
21
21
  "FocusableView",
22
+ "PressableView",
22
23
  "CollapsibleTextContainer",
23
24
  "BorderContainerView",
24
25
  ]);
@@ -1,4 +1,6 @@
1
1
  import * as React from "react";
2
+ import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
3
+ import { useNetworkStatusLocalizations } from "./utils";
2
4
 
3
5
  type Props = {
4
6
  children?: React.ReactNode;
@@ -10,13 +12,6 @@ type Props = {
10
12
 
11
13
  const NOTIF_DURATION = 4500;
12
14
 
13
- export const ONLINE_MSG = "You are back online";
14
-
15
- export const OFFLINE_MSG = "No internet connection";
16
-
17
- const EXTRA_OFFLINE_MSG = "Please check your connection";
18
- const EXTRA_ONLINE_MSG = "Feel free to continue where you left off";
19
-
20
15
  const styles: Record<any, React.CSSProperties> = {
21
16
  body: {
22
17
  position: "absolute",
@@ -47,6 +42,9 @@ const styles: Record<any, React.CSSProperties> = {
47
42
  export const NotificationView = (props: Props) => {
48
43
  const { children, hidden, dismiss, previousOnline, online } = props;
49
44
 
45
+ const theme = useTheme<BaseThemePropertiesTV>();
46
+ const storedLocalizations = useNetworkStatusLocalizations();
47
+
50
48
  const [open, setOpen] = React.useState<boolean | null>(null);
51
49
 
52
50
  const timeout = React.useRef<NodeJS.Timeout>();
@@ -84,8 +82,18 @@ export const NotificationView = (props: Props) => {
84
82
  }, [hidden, online]);
85
83
 
86
84
  const showOnlineMsg = wentOnline || online;
87
- const MSG = showOnlineMsg ? ONLINE_MSG : OFFLINE_MSG;
88
- const EXTRA_MSG = showOnlineMsg ? EXTRA_ONLINE_MSG : EXTRA_OFFLINE_MSG;
85
+
86
+ const MSG = showOnlineMsg
87
+ ? (theme?.online_notification_title ??
88
+ storedLocalizations?.online_notification_title)
89
+ : (theme?.offline_notification_title ??
90
+ storedLocalizations?.offline_notification_title);
91
+
92
+ const EXTRA_MSG = showOnlineMsg
93
+ ? (theme?.online_notification_subtitle ??
94
+ storedLocalizations?.online_notification_subtitle)
95
+ : (theme?.offline_notification_subtitle ??
96
+ storedLocalizations?.offline_notification_subtitle);
89
97
 
90
98
  return (
91
99
  <div onClick={onClose}>
@@ -1,4 +1,6 @@
1
1
  import * as React from "react";
2
+ import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
3
+ import { useNetworkStatusLocalizations } from "./utils";
2
4
 
3
5
  type Props = {
4
6
  children?: React.ReactNode;
@@ -9,12 +11,6 @@ type Props = {
9
11
 
10
12
  const DURATION_TO_HIDE_AFTER_BACK_TO_ONLINE = 4500; // ms
11
13
 
12
- const ONLINE_TITLE = "You are back online";
13
- const ONLINE_SUBTITLE = "Feel free to continue where you left off";
14
-
15
- const OFFLINE_TITLE = "No internet connection";
16
- const OFFLINE_SUBTITLE = "Please check your connection";
17
-
18
14
  const styles: Record<any, React.CSSProperties> = {
19
15
  body: {
20
16
  position: "absolute",
@@ -47,6 +43,9 @@ let timer: NodeJS.Timeout;
47
43
  export const NotificationView = (props: Props) => {
48
44
  const { children, dismiss, previousOnline = true, online } = props;
49
45
 
46
+ const theme = useTheme<BaseThemePropertiesTV>();
47
+ const storedLocalizations = useNetworkStatusLocalizations();
48
+
50
49
  const [shown, setShown] = React.useState<boolean>(false);
51
50
 
52
51
  const onClose = () => {
@@ -79,8 +78,17 @@ export const NotificationView = (props: Props) => {
79
78
  }
80
79
  }, [online, previousOnline]);
81
80
 
82
- const title = online ? ONLINE_TITLE : OFFLINE_TITLE;
83
- const subtitle = online ? ONLINE_SUBTITLE : OFFLINE_SUBTITLE;
81
+ const title = online
82
+ ? (theme?.online_notification_title ??
83
+ storedLocalizations?.online_notification_title)
84
+ : (theme?.offline_notification_title ??
85
+ storedLocalizations?.offline_notification_title);
86
+
87
+ const subtitle = online
88
+ ? (theme?.online_notification_subtitle ??
89
+ storedLocalizations?.online_notification_subtitle)
90
+ : (theme?.offline_notification_subtitle ??
91
+ storedLocalizations?.offline_notification_subtitle);
84
92
 
85
93
  return (
86
94
  <div onClick={onClose}>
@@ -0,0 +1,34 @@
1
+ import * as React from "react";
2
+ import { sessionStorage } from "@applicaster/zapp-react-native-bridge/ZappStorage/SessionStorage";
3
+
4
+ export const NETWORK_STATUS_LOCALIZATIONS_KEY = "network_status_localizations";
5
+
6
+ export const THEME_STORAGE_NAMESPACE = "quick-brick-theme";
7
+
8
+ export function useNetworkStatusLocalizations() {
9
+ const [storedLocalizations, setStoredLocalizations] = React.useState<Record<
10
+ string,
11
+ string
12
+ > | null>(null);
13
+
14
+ React.useEffect(() => {
15
+ async function loadStoredLocalizations() {
16
+ try {
17
+ const stored = await sessionStorage.getItem(
18
+ NETWORK_STATUS_LOCALIZATIONS_KEY,
19
+ THEME_STORAGE_NAMESPACE
20
+ );
21
+
22
+ if (stored) {
23
+ setStoredLocalizations(stored);
24
+ }
25
+ } catch (error) {
26
+ console.error("Error loading network status localizations", error);
27
+ }
28
+ }
29
+
30
+ loadStoredLocalizations();
31
+ }, []);
32
+
33
+ return storedLocalizations;
34
+ }
@@ -46,7 +46,6 @@ import {
46
46
  PlayerContainerContextProvider,
47
47
  } from "./PlayerContainerContext";
48
48
  import { FocusableGroup } from "@applicaster/zapp-react-native-ui-components/Components/FocusableGroup";
49
- import { ErrorDisplay } from "./ErrorDisplay";
50
49
  import { PlayerFocusableWrapperView } from "./WappersView/PlayerFocusableWrapperView";
51
50
  import { FocusableGroupMainContainerId } from "./index";
52
51
  import { isPlayable } from "@applicaster/zapp-react-native-utils/navigationUtils/itemTypeMatchers";
@@ -61,7 +60,6 @@ import {
61
60
  PlayerNativeSendCommand,
62
61
  } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/playerNativeCommand";
63
62
  import { useAppData } from "@applicaster/zapp-react-native-redux";
64
- import { useRestrictMobilePlayback } from "./useRestrictMobilePlayback";
65
63
 
66
64
  type Props = {
67
65
  Player: React.ComponentType<any>;
@@ -274,13 +272,6 @@ const PlayerContainerComponent = (props: Props) => {
274
272
  );
275
273
  }, [playerManager.isRegistered()]);
276
274
 
277
- const { isRestricted } = useRestrictMobilePlayback({
278
- player,
279
- entry: item,
280
- pluginConfiguration,
281
- close,
282
- });
283
-
284
275
  const playEntry = (entry) => navigator.replaceTop(entry, { mode });
285
276
 
286
277
  const onPlayNextPerformNextVideoPlay = React.useCallback(() => {
@@ -347,12 +338,6 @@ const PlayerContainerComponent = (props: Props) => {
347
338
  playerContainerLogger.error(errorObj);
348
339
 
349
340
  setState({ error: errorObj });
350
-
351
- if (!isTvOS) {
352
- setTimeout(() => {
353
- close();
354
- }, 800);
355
- }
356
341
  },
357
342
  [close]
358
343
  );
@@ -670,7 +655,7 @@ const PlayerContainerComponent = (props: Props) => {
670
655
  <PlayerFocusableWrapperView
671
656
  nextFocusDown={context.bottomFocusableId}
672
657
  >
673
- {isRestricted ? null : (
658
+ {!Player ? null : (
674
659
  <Player
675
660
  source={{
676
661
  uri,
@@ -703,8 +688,6 @@ const PlayerContainerComponent = (props: Props) => {
703
688
  </Player>
704
689
  )}
705
690
  </PlayerFocusableWrapperView>
706
-
707
- {state.error ? <ErrorDisplay error={state.error} /> : null}
708
691
  </View>
709
692
  {/* Components container */}
710
693
  {isInlineTV && context.showComponentsContainer ? (