@applicaster/zapp-react-native-ui-components 15.0.0-rc.99 → 15.1.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Components/BaseFocusable/index.ios.ts +2 -12
- package/Components/Cell/FocusableWrapper.tsx +0 -3
- package/Components/Cell/TvOSCellComponent.tsx +0 -5
- package/Components/Focusable/Focusable.tsx +2 -4
- package/Components/Focusable/FocusableTvOS.tsx +1 -18
- package/Components/Focusable/__tests__/__snapshots__/FocusableTvOS.test.tsx.snap +0 -1
- package/Components/FocusableGroup/FocusableTvOS.tsx +1 -30
- package/Components/GeneralContentScreen/GeneralContentScreen.tsx +39 -28
- package/Components/GeneralContentScreen/__tests__/GeneralContentScreen.test.tsx +104 -0
- package/Components/GeneralContentScreen/utils/__tests__/getScreenDataSource.test.ts +19 -0
- package/Components/GeneralContentScreen/utils/__tests__/useCurationAPI.test.js +1 -1
- package/Components/GeneralContentScreen/utils/getScreenDataSource.ts +9 -0
- package/Components/HandlePlayable/HandlePlayable.tsx +24 -42
- package/Components/HandlePlayable/utils.ts +31 -0
- package/Components/HookRenderer/HookRenderer.tsx +40 -10
- package/Components/HookRenderer/__tests__/HookRenderer.test.tsx +60 -0
- package/Components/Layout/TV/LayoutBackground.tsx +2 -5
- package/Components/Layout/TV/ScreenContainer.tsx +6 -2
- package/Components/Layout/TV/__tests__/__snapshots__/index.test.tsx.snap +5 -0
- package/Components/Layout/TV/index.tsx +4 -3
- package/Components/Layout/TV/index.web.tsx +4 -3
- package/Components/LinkHandler/LinkHandler.tsx +2 -2
- package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +10 -4
- package/Components/MasterCell/DefaultComponents/Image/Image.android.tsx +1 -5
- package/Components/MasterCell/DefaultComponents/Image/Image.ios.tsx +3 -11
- package/Components/MasterCell/DefaultComponents/Image/Image.web.tsx +1 -9
- package/Components/MasterCell/DefaultComponents/Image/hooks/useImage.ts +14 -15
- package/Components/MasterCell/DefaultComponents/LiveImage/__tests__/prepareEntry.test.ts +352 -0
- package/Components/MasterCell/DefaultComponents/LiveImage/executePreloadHooks.ts +136 -0
- package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +34 -16
- package/Components/MasterCell/DefaultComponents/SecondaryImage/hooks/__tests__/useGetImageDimensions.test.ts +6 -7
- package/Components/MasterCell/DefaultComponents/Text/index.tsx +2 -6
- package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/index.ts +2 -6
- package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/utils/__tests__/getPluginIdentifier.test.ts +11 -233
- package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/utils/index.ts +15 -19
- package/Components/Navigator/StackNavigator.tsx +6 -0
- package/Components/OfflineHandler/NotificationView/NotificationView.tsx +2 -2
- package/Components/OfflineHandler/NotificationView/__tests__/index.test.tsx +18 -17
- package/Components/OfflineHandler/__tests__/index.test.tsx +18 -27
- package/Components/PlayerContainer/PlayerContainer.tsx +14 -32
- package/Components/PreloaderWrapper/__tests__/index.test.tsx +26 -0
- package/Components/PreloaderWrapper/index.tsx +15 -0
- package/Components/River/ComponentsMap/ComponentsMap.tsx +3 -4
- package/Components/River/ComponentsMap/hooks/__tests__/useLoadingState.test.ts +1 -1
- package/Components/River/RefreshControl.tsx +9 -3
- package/Components/River/RiverItem.tsx +26 -20
- package/Components/River/TV/River.tsx +14 -31
- package/Components/River/TV/index.tsx +4 -8
- package/Components/River/TV/withTVEventHandler.tsx +36 -0
- package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +0 -1
- package/Components/River/__tests__/componentsMap.test.js +0 -38
- package/Components/Screen/TV/index.web.tsx +2 -4
- package/Components/Screen/__tests__/Screen.test.tsx +43 -65
- package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +44 -68
- package/Components/Screen/hooks.ts +76 -5
- package/Components/Screen/index.tsx +10 -3
- package/Components/Screen/orientationHandler.ts +3 -3
- package/Components/ScreenFeedLoader/ScreenFeedLoader.tsx +46 -0
- package/Components/ScreenFeedLoader/__tests__/ScreenFeedLoader.test.tsx +94 -0
- package/Components/ScreenFeedLoader/index.ts +1 -0
- package/Components/ScreenResolver/__tests__/screenResolver.test.js +24 -0
- package/Components/ScreenResolver/hooks/index.ts +3 -0
- package/Components/ScreenResolver/hooks/useGetComponent.ts +15 -0
- package/Components/ScreenResolver/hooks/useScreenComponentResolver.tsx +90 -0
- package/Components/ScreenResolver/index.tsx +9 -115
- package/Components/ScreenResolver/utils/__tests__/getScreenTypeProps.test.ts +45 -0
- package/Components/ScreenResolver/utils/getScreenTypeProps.ts +43 -0
- package/Components/ScreenResolver/utils/index.ts +1 -0
- package/Components/ScreenResolver/withDefaultScreenContext.tsx +16 -0
- package/Components/ScreenResolverFeedProvider/ScreenResolverFeedProvider.tsx +25 -0
- package/Components/ScreenResolverFeedProvider/__tests__/ScreenResolverFeedProvider.test.tsx +44 -0
- package/Components/ScreenResolverFeedProvider/index.ts +1 -0
- package/Components/ScreenRevealManager/ScreenRevealManager.ts +8 -40
- package/Components/ScreenRevealManager/__tests__/ScreenRevealManager.test.ts +69 -86
- package/Components/ScreenRevealManager/withScreenRevealManager.tsx +4 -1
- package/Components/Tabs/TabContent.tsx +4 -7
- package/Components/Transitioner/Scene.tsx +9 -15
- package/Components/Transitioner/index.js +3 -3
- package/Components/VideoLive/LiveImageManager.ts +199 -54
- package/Components/VideoLive/PlayerLiveImageComponent.tsx +31 -33
- package/Components/VideoLive/__tests__/PlayerLiveImageComponent.test.tsx +2 -17
- package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +5 -5
- package/Components/VideoModal/hooks/__tests__/useDelayedPlayerDetails.test.ts +7 -15
- package/Components/VideoModal/utils.ts +9 -12
- package/Components/Viewport/ViewportEvents/__tests__/viewportEvents.test.js +1 -1
- package/Components/ZappFrameworkComponents/BarView/BarView.tsx +6 -4
- package/Components/ZappFrameworkComponents/BarView/__tests__/BarView.test.tsx +2 -2
- package/Components/ZappUIComponent/index.tsx +12 -6
- package/Components/index.js +1 -1
- package/Contexts/ScreenContext/__tests__/index.test.tsx +57 -0
- package/Contexts/ScreenContext/index.tsx +64 -26
- package/Contexts/ScreenTrackedViewPositionsContext/__tests__/index.test.tsx +1 -1
- package/Contexts/ZappPipesContext/ZappPipesContextFactory.tsx +18 -7
- package/Decorators/Analytics/index.tsx +5 -6
- package/Decorators/ConfigurationWrapper/__tests__/__snapshots__/withConfigurationProvider.test.tsx.snap +0 -1
- package/Decorators/ConfigurationWrapper/const.ts +0 -1
- package/Decorators/ZappPipesDataConnector/ResolverSelector.tsx +25 -7
- package/Decorators/ZappPipesDataConnector/__tests__/ResolverSelector.test.tsx +212 -5
- package/Decorators/ZappPipesDataConnector/__tests__/zappPipesDataConnector.test.js +1 -1
- package/Decorators/ZappPipesDataConnector/index.tsx +2 -2
- package/Decorators/ZappPipesDataConnector/resolvers/StaticFeedResolver.tsx +1 -1
- package/Helpers/DataSourceHelper/index.js +19 -0
- package/package.json +5 -5
- package/Components/MasterCell/DefaultComponents/Text/utils/__tests__/withAdjustedLineHeight.test.ts +0 -46
- package/Components/MasterCell/DefaultComponents/Text/utils/index.ts +0 -21
- package/Components/PlayerContainer/ErrorDisplay/ErrorDisplay.tsx +0 -57
- package/Components/PlayerContainer/ErrorDisplay/index.ts +0 -9
- package/Components/PlayerContainer/useRestrictMobilePlayback.tsx +0 -101
- package/Components/River/TV/utils/__tests__/toStringOrEmpty.test.ts +0 -30
- package/Components/River/TV/utils/index.ts +0 -4
- package/Components/River/TV/withFocusableGroupForContent.tsx +0 -71
- package/Helpers/DataSourceHelper/__tests__/itemLimitForData.test.ts +0 -80
- package/Helpers/DataSourceHelper/index.ts +0 -19
- /package/Components/HookRenderer/{index.tsx → index.ts} +0 -0
|
@@ -1,15 +1,9 @@
|
|
|
1
|
-
import { getPluginIdentifier
|
|
1
|
+
import { getPluginIdentifier } from "..";
|
|
2
2
|
|
|
3
3
|
describe("getPluginIdentifier", () => {
|
|
4
4
|
const prefix = "tv_buttons";
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
memoizedGetPluginIdentifier.clear();
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
it("returns the first valid plugin identifier", () => {
|
|
11
|
-
expect.assertions(2);
|
|
12
|
-
|
|
6
|
+
it("get first plugin identifier", () => {
|
|
13
7
|
const configuration = {
|
|
14
8
|
tv_buttons_button_1_other: "value",
|
|
15
9
|
tv_buttons_button_1_assign_action:
|
|
@@ -19,21 +13,13 @@ describe("getPluginIdentifier", () => {
|
|
|
19
13
|
};
|
|
20
14
|
|
|
21
15
|
const index = 0;
|
|
22
|
-
const result = getPluginIdentifier(configuration, prefix, index);
|
|
23
16
|
|
|
24
|
-
const
|
|
25
|
-
configuration,
|
|
26
|
-
prefix,
|
|
27
|
-
index
|
|
28
|
-
);
|
|
17
|
+
const result = getPluginIdentifier(configuration, prefix, index);
|
|
29
18
|
|
|
30
19
|
expect(result).toEqual(configuration.tv_buttons_button_1_assign_action);
|
|
31
|
-
expect(memoizedResult).toEqual(result);
|
|
32
20
|
});
|
|
33
21
|
|
|
34
|
-
it("
|
|
35
|
-
expect.assertions(2);
|
|
36
|
-
|
|
22
|
+
it("get second plugin identifier", () => {
|
|
37
23
|
const configuration = {
|
|
38
24
|
tv_buttons_button_1_other: "value_1",
|
|
39
25
|
tv_buttons_button_1_assign_action:
|
|
@@ -44,216 +30,24 @@ describe("getPluginIdentifier", () => {
|
|
|
44
30
|
};
|
|
45
31
|
|
|
46
32
|
const index = 1;
|
|
47
|
-
const result = getPluginIdentifier(configuration, prefix, index);
|
|
48
33
|
|
|
49
|
-
const
|
|
50
|
-
configuration,
|
|
51
|
-
prefix,
|
|
52
|
-
index
|
|
53
|
-
);
|
|
34
|
+
const result = getPluginIdentifier(configuration, prefix, index);
|
|
54
35
|
|
|
55
36
|
expect(result).toEqual(configuration.tv_buttons_button_2_assign_action);
|
|
56
|
-
expect(memoizedResult).toEqual(result);
|
|
57
37
|
});
|
|
58
38
|
|
|
59
|
-
it("
|
|
60
|
-
expect.assertions(2);
|
|
61
|
-
|
|
39
|
+
it("get undefined if no assign_actions at all", () => {
|
|
62
40
|
const configuration = {};
|
|
63
|
-
const index = 0;
|
|
64
|
-
|
|
65
|
-
const result = getPluginIdentifier(configuration, prefix, index);
|
|
66
|
-
|
|
67
|
-
const memoizedResult = memoizedGetPluginIdentifier(
|
|
68
|
-
configuration,
|
|
69
|
-
prefix,
|
|
70
|
-
index
|
|
71
|
-
);
|
|
72
|
-
|
|
73
|
-
expect(result).toBeUndefined();
|
|
74
|
-
expect(memoizedResult).toBeUndefined();
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
it("skips undefined values and returns the correct plugin identifier", () => {
|
|
78
|
-
expect.assertions(2);
|
|
79
|
-
|
|
80
|
-
const configuration = {
|
|
81
|
-
tv_buttons_button_1_assign_action: "tv_buttons_button_1_assign_action",
|
|
82
|
-
tv_buttons_button_2_assign_action: undefined,
|
|
83
|
-
tv_buttons_button_3_assign_action: "tv_buttons_button_3_assign_action",
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
const index = 1;
|
|
87
|
-
const result = getPluginIdentifier(configuration, prefix, index);
|
|
88
|
-
|
|
89
|
-
const memoizedResult = memoizedGetPluginIdentifier(
|
|
90
|
-
configuration,
|
|
91
|
-
prefix,
|
|
92
|
-
index
|
|
93
|
-
);
|
|
94
|
-
|
|
95
|
-
expect(result).toEqual(configuration.tv_buttons_button_3_assign_action);
|
|
96
|
-
expect(memoizedResult).toEqual(result);
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
it("handles missing intermediate keys and returns the correct plugin identifier", () => {
|
|
100
|
-
expect.assertions(2);
|
|
101
|
-
|
|
102
|
-
const configuration = {
|
|
103
|
-
tv_buttons_button_1_assign_action: "tv_buttons_button_1_assign_action",
|
|
104
|
-
tv_buttons_button_3_assign_action: "tv_buttons_button_3_assign_action",
|
|
105
|
-
};
|
|
106
|
-
|
|
107
|
-
const index = 1;
|
|
108
|
-
const result = getPluginIdentifier(configuration, prefix, index);
|
|
109
|
-
|
|
110
|
-
const memoizedResult = memoizedGetPluginIdentifier(
|
|
111
|
-
configuration,
|
|
112
|
-
prefix,
|
|
113
|
-
index
|
|
114
|
-
);
|
|
115
|
-
|
|
116
|
-
expect(result).toEqual(configuration.tv_buttons_button_3_assign_action);
|
|
117
|
-
expect(memoizedResult).toEqual(result);
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
it("skips empty string values and returns the first non-empty assign_action", () => {
|
|
121
|
-
expect.assertions(2);
|
|
122
|
-
|
|
123
|
-
const configuration = {
|
|
124
|
-
tv_buttons_button_1_assign_action: "",
|
|
125
|
-
tv_buttons_button_2_assign_action: "tv_buttons_button_2_assign_action",
|
|
126
|
-
};
|
|
127
41
|
|
|
128
42
|
const index = 0;
|
|
129
|
-
const result = getPluginIdentifier(configuration, prefix, index);
|
|
130
|
-
|
|
131
|
-
const memoizedResult = memoizedGetPluginIdentifier(
|
|
132
|
-
configuration,
|
|
133
|
-
prefix,
|
|
134
|
-
index
|
|
135
|
-
);
|
|
136
|
-
|
|
137
|
-
expect(result).toEqual(configuration.tv_buttons_button_2_assign_action);
|
|
138
|
-
expect(memoizedResult).toEqual(result);
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
it("returns undefined for negative index", () => {
|
|
142
|
-
expect.assertions(2);
|
|
143
|
-
|
|
144
|
-
const configuration = {
|
|
145
|
-
tv_buttons_button_1_assign_action: "a",
|
|
146
|
-
tv_buttons_button_2_assign_action: "b",
|
|
147
|
-
};
|
|
148
43
|
|
|
149
|
-
const index = -1;
|
|
150
44
|
const result = getPluginIdentifier(configuration, prefix, index);
|
|
151
45
|
|
|
152
|
-
const memoizedResult = memoizedGetPluginIdentifier(
|
|
153
|
-
configuration,
|
|
154
|
-
prefix,
|
|
155
|
-
index
|
|
156
|
-
);
|
|
157
|
-
|
|
158
46
|
expect(result).toBeUndefined();
|
|
159
|
-
expect(memoizedResult).toBeUndefined();
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
it("returns undefined for out-of-bounds index", () => {
|
|
163
|
-
expect.assertions(2);
|
|
164
|
-
|
|
165
|
-
const configuration = {
|
|
166
|
-
tv_buttons_button_1_assign_action: "a",
|
|
167
|
-
tv_buttons_button_2_assign_action: "b",
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
const index = 5;
|
|
171
|
-
const result = getPluginIdentifier(configuration, prefix, index);
|
|
172
|
-
|
|
173
|
-
const memoizedResult = memoizedGetPluginIdentifier(
|
|
174
|
-
configuration,
|
|
175
|
-
prefix,
|
|
176
|
-
index
|
|
177
|
-
);
|
|
178
|
-
|
|
179
|
-
expect(result).toBeUndefined();
|
|
180
|
-
expect(memoizedResult).toBeUndefined();
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
it("ignores keys with wrong prefix or format", () => {
|
|
184
|
-
expect.assertions(2);
|
|
185
|
-
|
|
186
|
-
const configuration = {
|
|
187
|
-
tv_buttons_button_1_assign_action: "a",
|
|
188
|
-
tv_buttons_wrongprefix_2_assign_action: "b",
|
|
189
|
-
tv_buttons_button_x_assign_action: "c",
|
|
190
|
-
};
|
|
191
|
-
|
|
192
|
-
const index = 1;
|
|
193
|
-
const result = getPluginIdentifier(configuration, prefix, index);
|
|
194
|
-
|
|
195
|
-
const memoizedResult = memoizedGetPluginIdentifier(
|
|
196
|
-
configuration,
|
|
197
|
-
prefix,
|
|
198
|
-
index
|
|
199
|
-
);
|
|
200
|
-
|
|
201
|
-
expect(result).toBeUndefined();
|
|
202
|
-
expect(memoizedResult).toBeUndefined();
|
|
203
|
-
});
|
|
204
|
-
|
|
205
|
-
it("returns undefined if all assign_actions are null or empty", () => {
|
|
206
|
-
expect.assertions(2);
|
|
207
|
-
|
|
208
|
-
const configuration = {
|
|
209
|
-
tv_buttons_button_1_assign_action: null,
|
|
210
|
-
tv_buttons_button_2_assign_action: undefined,
|
|
211
|
-
tv_buttons_button_3_assign_action: "",
|
|
212
|
-
};
|
|
213
|
-
|
|
214
|
-
const index = 0;
|
|
215
|
-
const result = getPluginIdentifier(configuration, prefix, index);
|
|
216
|
-
|
|
217
|
-
const memoizedResult = memoizedGetPluginIdentifier(
|
|
218
|
-
configuration,
|
|
219
|
-
prefix,
|
|
220
|
-
index
|
|
221
|
-
);
|
|
222
|
-
|
|
223
|
-
expect(result).toBeUndefined();
|
|
224
|
-
expect(memoizedResult).toBeUndefined();
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
it("handles non-string values correctly", () => {
|
|
228
|
-
expect.assertions(6);
|
|
229
|
-
|
|
230
|
-
const configuration = {
|
|
231
|
-
tv_buttons_button_1_assign_action: 123,
|
|
232
|
-
tv_buttons_button_2_assign_action: true,
|
|
233
|
-
tv_buttons_button_3_assign_action: { nested: "value" },
|
|
234
|
-
};
|
|
235
|
-
|
|
236
|
-
expect(getPluginIdentifier(configuration, prefix, 0)).toEqual(123);
|
|
237
|
-
expect(getPluginIdentifier(configuration, prefix, 1)).toEqual(true);
|
|
238
|
-
|
|
239
|
-
expect(getPluginIdentifier(configuration, prefix, 2)).toEqual({
|
|
240
|
-
nested: "value",
|
|
241
|
-
});
|
|
242
|
-
|
|
243
|
-
expect(memoizedGetPluginIdentifier(configuration, prefix, 0)).toEqual(123);
|
|
244
|
-
expect(memoizedGetPluginIdentifier(configuration, prefix, 1)).toEqual(true);
|
|
245
|
-
|
|
246
|
-
expect(memoizedGetPluginIdentifier(configuration, prefix, 2)).toEqual({
|
|
247
|
-
nested: "value",
|
|
248
|
-
});
|
|
249
47
|
});
|
|
250
48
|
});
|
|
251
49
|
|
|
252
|
-
describe("getPluginIdentifier - when configuration has
|
|
253
|
-
beforeAll(() => {
|
|
254
|
-
memoizedGetPluginIdentifier.clear();
|
|
255
|
-
});
|
|
256
|
-
|
|
50
|
+
describe("getPluginIdentifier - when configuration has same values for different keys", () => {
|
|
257
51
|
const prefix = "tv_buttons";
|
|
258
52
|
|
|
259
53
|
const configuration = {
|
|
@@ -261,35 +55,19 @@ describe("getPluginIdentifier - when configuration has duplicate values", () =>
|
|
|
261
55
|
tv_buttons_button_2_assign_action: "navigation_action",
|
|
262
56
|
};
|
|
263
57
|
|
|
264
|
-
it("
|
|
265
|
-
expect.assertions(2);
|
|
266
|
-
|
|
58
|
+
it("get first plugin identifier", () => {
|
|
267
59
|
const index = 0;
|
|
268
|
-
const result = getPluginIdentifier(configuration, prefix, index);
|
|
269
60
|
|
|
270
|
-
const
|
|
271
|
-
configuration,
|
|
272
|
-
prefix,
|
|
273
|
-
index
|
|
274
|
-
);
|
|
61
|
+
const result = getPluginIdentifier(configuration, prefix, index);
|
|
275
62
|
|
|
276
63
|
expect(result).toEqual(configuration.tv_buttons_button_1_assign_action);
|
|
277
|
-
expect(memoizedResult).toEqual(result);
|
|
278
64
|
});
|
|
279
65
|
|
|
280
|
-
it("
|
|
281
|
-
expect.assertions(2);
|
|
282
|
-
|
|
66
|
+
it("get second plugin identifier", () => {
|
|
283
67
|
const index = 1;
|
|
284
|
-
const result = getPluginIdentifier(configuration, prefix, index);
|
|
285
68
|
|
|
286
|
-
const
|
|
287
|
-
configuration,
|
|
288
|
-
prefix,
|
|
289
|
-
index
|
|
290
|
-
);
|
|
69
|
+
const result = getPluginIdentifier(configuration, prefix, index);
|
|
291
70
|
|
|
292
71
|
expect(result).toEqual(configuration.tv_buttons_button_2_assign_action);
|
|
293
|
-
expect(memoizedResult).toEqual(result);
|
|
294
72
|
});
|
|
295
73
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as R from "ramda";
|
|
2
|
-
import memoizee from "memoizee";
|
|
3
2
|
|
|
4
3
|
import { isWeb } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
4
|
+
import { isNotNil } from "@applicaster/zapp-react-native-utils/reactUtils/helpers";
|
|
5
5
|
|
|
6
6
|
export const getButtonsCount = (
|
|
7
7
|
configuration: Record<string, unknown>,
|
|
@@ -21,26 +21,22 @@ export const getPluginIdentifier = (
|
|
|
21
21
|
configuration: Record<string, unknown>,
|
|
22
22
|
prefix: string,
|
|
23
23
|
index: number
|
|
24
|
-
): string
|
|
25
|
-
const
|
|
26
|
-
|
|
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
|
-
}
|
|
24
|
+
): string => {
|
|
25
|
+
const match = `${prefix}_button_\\d_assign_action`;
|
|
26
|
+
const re = new RegExp(match);
|
|
39
27
|
|
|
40
|
-
|
|
41
|
-
};
|
|
28
|
+
const rejectNils = R.compose(R.path([index]), R.filter(isNotNil));
|
|
42
29
|
|
|
43
|
-
|
|
30
|
+
return rejectNils(
|
|
31
|
+
R.toPairs(configuration)
|
|
32
|
+
.filter(([key]) => R.startsWith(`${prefix}_button`, key))
|
|
33
|
+
.map(([key, value]) => {
|
|
34
|
+
const matched = key.match(re);
|
|
35
|
+
|
|
36
|
+
return matched ? value : undefined;
|
|
37
|
+
})
|
|
38
|
+
);
|
|
39
|
+
};
|
|
44
40
|
|
|
45
41
|
type Label = {
|
|
46
42
|
name: string;
|
|
@@ -6,11 +6,16 @@ import { getPathAttributes } from "@applicaster/zapp-react-native-utils/navigati
|
|
|
6
6
|
import { FocusableGroup } from "@applicaster/zapp-react-native-ui-components/Components/FocusableGroup";
|
|
7
7
|
import { ScreenDataContext } from "@applicaster/zapp-react-native-ui-components/Contexts/ScreenDataContext";
|
|
8
8
|
import { PathnameContext } from "@applicaster/zapp-react-native-ui-components/Contexts/PathnameContext";
|
|
9
|
+
import { StyleSheet } from "react-native";
|
|
9
10
|
|
|
10
11
|
import { Screen } from "../Screen/TV/index.web";
|
|
11
12
|
import { isLast } from "@applicaster/zapp-react-native-utils/arrayUtils";
|
|
12
13
|
import { ScreenContextProvider } from "../../Contexts/ScreenContext";
|
|
13
14
|
|
|
15
|
+
const styles = StyleSheet.create({
|
|
16
|
+
container: { flex: 1 },
|
|
17
|
+
});
|
|
18
|
+
|
|
14
19
|
type Components = {
|
|
15
20
|
NavBar: React.ComponentType<any>;
|
|
16
21
|
Background: React.ComponentType<any>;
|
|
@@ -41,6 +46,7 @@ export const StackNavigator = ({ Components }: Props) => {
|
|
|
41
46
|
preferredFocus={isLast(index, mainStack.length)}
|
|
42
47
|
excludeFromFocusSearching
|
|
43
48
|
key={routeId}
|
|
49
|
+
style={styles.container}
|
|
44
50
|
>
|
|
45
51
|
<ScreenDataContext.Provider value={state}>
|
|
46
52
|
<PathnameContext.Provider value={route}>
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
TouchableWithoutFeedback,
|
|
9
9
|
} from "react-native";
|
|
10
10
|
|
|
11
|
-
import {
|
|
11
|
+
import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
|
|
12
12
|
import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
13
13
|
import { textTransform } from "@applicaster/zapp-react-native-utils/cellUtils";
|
|
14
14
|
import { useNotificationHeight } from "../utils";
|
|
@@ -46,7 +46,7 @@ export const NotificationView = ({
|
|
|
46
46
|
online = true,
|
|
47
47
|
dismiss,
|
|
48
48
|
}: Props) => {
|
|
49
|
-
const plugins =
|
|
49
|
+
const { plugins } = usePickFromState(["plugins"]);
|
|
50
50
|
const { statusHeight, notificationHeight } = useNotificationHeight();
|
|
51
51
|
|
|
52
52
|
const offlinePlugin = R.find(
|
|
@@ -8,24 +8,25 @@ import {
|
|
|
8
8
|
offlinePhrase,
|
|
9
9
|
} from "../NotificationView";
|
|
10
10
|
|
|
11
|
-
jest.mock("@applicaster/zapp-react-native-redux", () => ({
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
11
|
+
jest.mock("@applicaster/zapp-react-native-redux/hooks", () => ({
|
|
12
|
+
usePickFromState: () => ({
|
|
13
|
+
plugins: [
|
|
14
|
+
{
|
|
15
|
+
name: "offline experience",
|
|
16
|
+
identifier: "offline-experience",
|
|
17
|
+
type: "general",
|
|
18
|
+
module: {
|
|
19
|
+
useOfflineExperienceConfiguration: () => ({
|
|
20
|
+
configurationFields: {},
|
|
21
|
+
localizations: {
|
|
22
|
+
offline_toast_message: "No internet connection",
|
|
23
|
+
online_toast_message: "You are back online",
|
|
24
|
+
},
|
|
25
|
+
}),
|
|
26
|
+
},
|
|
26
27
|
},
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
],
|
|
29
|
+
}),
|
|
29
30
|
}));
|
|
30
31
|
|
|
31
32
|
jest.mock("react-native-safe-area-context", () => ({
|
|
@@ -8,45 +8,36 @@ const mockPreviousValue = null;
|
|
|
8
8
|
|
|
9
9
|
jest.mock("@applicaster/zapp-react-native-utils/reactHooks/connection", () => {
|
|
10
10
|
return {
|
|
11
|
-
...jest.requireActual(
|
|
12
|
-
"@applicaster/zapp-react-native-utils/reactHooks/connection"
|
|
13
|
-
),
|
|
14
11
|
useConnectionInfo: jest.fn(() => mockConnectionStatus),
|
|
15
12
|
};
|
|
16
13
|
});
|
|
17
14
|
|
|
18
15
|
jest.mock("@applicaster/zapp-react-native-utils/reactHooks/utils", () => {
|
|
19
16
|
return {
|
|
20
|
-
...jest.requireActual(
|
|
21
|
-
"@applicaster/zapp-react-native-utils/reactHooks/utils"
|
|
22
|
-
),
|
|
23
17
|
usePrevious: jest.fn(() => mockPreviousValue),
|
|
24
18
|
};
|
|
25
19
|
});
|
|
26
20
|
|
|
27
|
-
const mock_storeObj = {
|
|
28
|
-
plugins: [
|
|
29
|
-
{
|
|
30
|
-
name: "offline experience",
|
|
31
|
-
identifier: "offline-experience",
|
|
32
|
-
type: "general",
|
|
33
|
-
module: {
|
|
34
|
-
useOfflineExperienceConfiguration: () => ({
|
|
35
|
-
configurationFields: {},
|
|
36
|
-
localizations: {
|
|
37
|
-
offline_toast_message: "No internet connection",
|
|
38
|
-
online_toast_message: "You are back online",
|
|
39
|
-
},
|
|
40
|
-
}),
|
|
41
|
-
},
|
|
42
|
-
},
|
|
43
|
-
],
|
|
44
|
-
};
|
|
45
|
-
|
|
46
21
|
jest.mock("@applicaster/zapp-react-native-redux/hooks", () => ({
|
|
47
22
|
...jest.requireActual("@applicaster/zapp-react-native-redux/hooks"),
|
|
48
|
-
|
|
49
|
-
|
|
23
|
+
usePickFromState: () => ({
|
|
24
|
+
plugins: [
|
|
25
|
+
{
|
|
26
|
+
name: "offline experience",
|
|
27
|
+
identifier: "offline-experience",
|
|
28
|
+
type: "general",
|
|
29
|
+
module: {
|
|
30
|
+
useOfflineExperienceConfiguration: () => ({
|
|
31
|
+
configurationFields: {},
|
|
32
|
+
localizations: {
|
|
33
|
+
offline_toast_message: "No internet connection",
|
|
34
|
+
online_toast_message: "You are back online",
|
|
35
|
+
},
|
|
36
|
+
}),
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
}),
|
|
50
41
|
}));
|
|
51
42
|
|
|
52
43
|
jest.mock("react-native-safe-area-context", () => ({
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
|
|
18
18
|
import { TVEventHandlerComponent } from "@applicaster/zapp-react-native-tvos-ui-components/Components/TVEventHandlerComponent";
|
|
19
19
|
import { usePrevious } from "@applicaster/zapp-react-native-utils/reactHooks/utils";
|
|
20
|
-
|
|
20
|
+
import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
|
|
21
21
|
import {
|
|
22
22
|
useBackHandler,
|
|
23
23
|
useNavigation,
|
|
@@ -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";
|
|
@@ -60,8 +59,6 @@ import {
|
|
|
60
59
|
PlayerNativeCommandTypes,
|
|
61
60
|
PlayerNativeSendCommand,
|
|
62
61
|
} from "@applicaster/zapp-react-native-utils/appUtils/playerManager/playerNativeCommand";
|
|
63
|
-
import { useAppData } from "@applicaster/zapp-react-native-redux";
|
|
64
|
-
import { useRestrictMobilePlayback } from "./useRestrictMobilePlayback";
|
|
65
62
|
|
|
66
63
|
type Props = {
|
|
67
64
|
Player: React.ComponentType<any>;
|
|
@@ -111,7 +108,7 @@ const withBorderHack = () => {
|
|
|
111
108
|
/* @HACK: see GH#7269 */
|
|
112
109
|
return {
|
|
113
110
|
borderWidth: 1,
|
|
114
|
-
borderColor: "
|
|
111
|
+
borderColor: "black",
|
|
115
112
|
};
|
|
116
113
|
}
|
|
117
114
|
|
|
@@ -240,7 +237,7 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
240
237
|
const [isLoadingNextVideo, setIsLoadingNextVideo] = React.useState(false);
|
|
241
238
|
|
|
242
239
|
const navigator = useNavigation();
|
|
243
|
-
const {
|
|
240
|
+
const { appData } = usePickFromState(["appData"]);
|
|
244
241
|
const prevItemId = usePrevious(item?.id);
|
|
245
242
|
const screenData = useTargetScreenData(item);
|
|
246
243
|
const { setVisible: showNavBar } = useSetNavbarState();
|
|
@@ -265,21 +262,7 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
265
262
|
|
|
266
263
|
showNavBar(true);
|
|
267
264
|
navigator.goBack();
|
|
268
|
-
}, [isModal, state.playerId, showNavBar
|
|
269
|
-
|
|
270
|
-
const pluginConfiguration = React.useMemo(() => {
|
|
271
|
-
return (
|
|
272
|
-
playerManager.getPluginConfiguration() ||
|
|
273
|
-
R.prop("__plugin_configuration", Player)
|
|
274
|
-
);
|
|
275
|
-
}, [playerManager.isRegistered()]);
|
|
276
|
-
|
|
277
|
-
const { isRestricted } = useRestrictMobilePlayback({
|
|
278
|
-
player,
|
|
279
|
-
entry: item,
|
|
280
|
-
pluginConfiguration,
|
|
281
|
-
close,
|
|
282
|
-
});
|
|
265
|
+
}, [isModal, navigator.goBack, state.playerId, showNavBar]);
|
|
283
266
|
|
|
284
267
|
const playEntry = (entry) => navigator.replaceTop(entry, { mode });
|
|
285
268
|
|
|
@@ -347,12 +330,6 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
347
330
|
playerContainerLogger.error(errorObj);
|
|
348
331
|
|
|
349
332
|
setState({ error: errorObj });
|
|
350
|
-
|
|
351
|
-
if (!isTvOS) {
|
|
352
|
-
setTimeout(() => {
|
|
353
|
-
close();
|
|
354
|
-
}, 800);
|
|
355
|
-
}
|
|
356
333
|
},
|
|
357
334
|
[close]
|
|
358
335
|
);
|
|
@@ -471,6 +448,13 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
471
448
|
}
|
|
472
449
|
}, []);
|
|
473
450
|
|
|
451
|
+
const pluginConfiguration = React.useMemo(() => {
|
|
452
|
+
return (
|
|
453
|
+
playerManager.getPluginConfiguration() ||
|
|
454
|
+
R.prop("__plugin_configuration", Player)
|
|
455
|
+
);
|
|
456
|
+
}, [playerManager.isRegistered()]);
|
|
457
|
+
|
|
474
458
|
const disableMiniPlayer = React.useMemo(() => {
|
|
475
459
|
return pluginConfiguration?.disable_mini_player_when_inline;
|
|
476
460
|
}, [pluginConfiguration]);
|
|
@@ -670,7 +654,7 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
670
654
|
<PlayerFocusableWrapperView
|
|
671
655
|
nextFocusDown={context.bottomFocusableId}
|
|
672
656
|
>
|
|
673
|
-
{
|
|
657
|
+
{Player ? (
|
|
674
658
|
<Player
|
|
675
659
|
source={{
|
|
676
660
|
uri,
|
|
@@ -685,7 +669,7 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
685
669
|
fullscreen={mode === VideoModalMode.FULLSCREEN}
|
|
686
670
|
inline={inline}
|
|
687
671
|
isModal={isModal}
|
|
688
|
-
isTabletPortrait={isTabletPortrait}
|
|
672
|
+
isTabletPortrait={appData.isTabletPortrait}
|
|
689
673
|
muted={false}
|
|
690
674
|
playableItem={item}
|
|
691
675
|
playerEvent={playerEvent}
|
|
@@ -701,10 +685,8 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
701
685
|
>
|
|
702
686
|
{renderApplePlayer(applePlayerProps)}
|
|
703
687
|
</Player>
|
|
704
|
-
)}
|
|
688
|
+
) : null}
|
|
705
689
|
</PlayerFocusableWrapperView>
|
|
706
|
-
|
|
707
|
-
{state.error ? <ErrorDisplay error={state.error} /> : null}
|
|
708
690
|
</View>
|
|
709
691
|
{/* Components container */}
|
|
710
692
|
{isInlineTV && context.showComponentsContainer ? (
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Text } from "react-native";
|
|
3
|
+
import { render } from "@testing-library/react-native";
|
|
4
|
+
import { PreloaderWrapper } from "..";
|
|
5
|
+
|
|
6
|
+
describe("PreloaderWrapper", () => {
|
|
7
|
+
it("renders children when preloader is hidden", () => {
|
|
8
|
+
const { getByText } = render(
|
|
9
|
+
<PreloaderWrapper showPreloader={false}>
|
|
10
|
+
<Text>content</Text>
|
|
11
|
+
</PreloaderWrapper>
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
expect(getByText("content")).toBeDefined();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it("renders null when preloader is shown", () => {
|
|
18
|
+
const { queryByText } = render(
|
|
19
|
+
<PreloaderWrapper showPreloader>
|
|
20
|
+
<Text>content</Text>
|
|
21
|
+
</PreloaderWrapper>
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
expect(queryByText("content")).toBeNull();
|
|
25
|
+
});
|
|
26
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
type PreloaderWrapperProps = {
|
|
4
|
+
showPreloader?: boolean;
|
|
5
|
+
children?: React.ReactNode;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export const PreloaderWrapper: React.FC<PreloaderWrapperProps> = ({
|
|
9
|
+
showPreloader = false,
|
|
10
|
+
children,
|
|
11
|
+
}) => {
|
|
12
|
+
return !showPreloader ? children : null;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export default PreloaderWrapper;
|
|
@@ -281,7 +281,6 @@ function ComponentsMapComponent(props: Props) {
|
|
|
281
281
|
>
|
|
282
282
|
<ViewportTracker>
|
|
283
283
|
<FlatList
|
|
284
|
-
testID="components-map-flat-list"
|
|
285
284
|
ref={(ref) => {
|
|
286
285
|
flatListRef.current = ref;
|
|
287
286
|
}}
|
|
@@ -313,10 +312,10 @@ function ComponentsMapComponent(props: Props) {
|
|
|
313
312
|
onScrollEndDrag={_onScrollEndDrag}
|
|
314
313
|
scrollEventThrottle={16}
|
|
315
314
|
{...scrollViewExtraProps}
|
|
315
|
+
/* When wrapped in a parent ScrollView (e.g. tabs),
|
|
316
|
+
this FlatList doesn't scroll so onEndReached can fire repeatedly;
|
|
317
|
+
skip it here and let the parent ScrollView emit scroll-end instead. */
|
|
316
318
|
onEndReached={
|
|
317
|
-
/* When wrapped in a parent ScrollView (e.g. tabs),
|
|
318
|
-
this FlatList doesn't scroll so onEndReached can fire repeatedly;
|
|
319
|
-
skip it here and let the parent ScrollView emit scroll-end instead. */
|
|
320
319
|
isScreenWrappedInContainer
|
|
321
320
|
? undefined
|
|
322
321
|
: () => {
|