@applicaster/zapp-react-native-utils 12.0.0-alpha.5350212300 → 12.0.0-alpha.5400461972
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/analyticsUtils/AnalyticsEvents/index.ts +6 -0
- package/analyticsUtils/AnalyticsEvents/searchEvents.ts +21 -0
- package/analyticsUtils/analyticsPlugins.ts +25 -0
- package/analyticsUtils/events.ts +6 -0
- package/analyticsUtils/index.tsx +6 -0
- package/appUtils/focusManager/index.ts +25 -128
- package/appUtils/focusManager/treeDataStructure/Utils/index.js +42 -97
- package/appUtils/playerManager/usePlayerControllerSetup.tsx +6 -1
- package/cellUtils/__tests__/cellUtils.test.ts +9 -20
- package/cellUtils/index.ts +6 -12
- package/dateUtils/index.ts +11 -0
- package/headersUtils/index.ts +1 -0
- package/inflatedUrlUtils/index.ts +4 -4
- package/localizationUtils/__tests__/localizationUtils.test.ts +72 -53
- package/localizationUtils/index.ts +13 -22
- package/numberUtils/index.ts +4 -0
- package/package.json +2 -2
- package/reactHooks/cell-click/__tests__/index.test.js +5 -0
- package/reactHooks/cell-click/index.ts +2 -2
- package/reactHooks/feed/__tests__/useInflatedUrl.test.ts +18 -3
- package/reactHooks/feed/useInflatedUrl.ts +44 -15
- package/reactHooks/navigation/__tests__/index.test.tsx +11 -8
- package/reactHooks/navigation/index.ts +17 -80
- package/reactHooks/screen/useScreenContext.ts +3 -3
- package/reactUtils/helpers.tsx +1 -1
- package/types.ts +4 -0
- package/appUtils/focusManager/utils/index.ts +0 -65
|
@@ -7,6 +7,10 @@ import { sendHeaderClickEvent } from "./sendHeaderClickEvent";
|
|
|
7
7
|
import { sendHardwareBackButtonClickEvent } from "./sendHardwareBackButtonClickEvent";
|
|
8
8
|
import { sendDownloadsEvent } from "./sendDownloadsEvent";
|
|
9
9
|
import { sendScreenEvent } from "./sendScreenEvent";
|
|
10
|
+
import {
|
|
11
|
+
sendSearchCanceledEvent,
|
|
12
|
+
sendSearchExecutedEvent,
|
|
13
|
+
} from "./searchEvents";
|
|
10
14
|
|
|
11
15
|
export {
|
|
12
16
|
sendScreenEvent,
|
|
@@ -18,4 +22,6 @@ export {
|
|
|
18
22
|
sendHeaderClickEvent,
|
|
19
23
|
sendHardwareBackButtonClickEvent,
|
|
20
24
|
sendDownloadsEvent,
|
|
25
|
+
sendSearchCanceledEvent,
|
|
26
|
+
sendSearchExecutedEvent,
|
|
21
27
|
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { log_debug } from "../logger";
|
|
2
|
+
import { postAnalyticEvent } from "../manager";
|
|
3
|
+
import { ANALYTICS_CORE_EVENTS } from "../events";
|
|
4
|
+
|
|
5
|
+
export const sendSearchCanceledEvent = (analyticsProps) => {
|
|
6
|
+
const eventName = ANALYTICS_CORE_EVENTS.SEARCH_CANCELED;
|
|
7
|
+
postAnalyticEvent(eventName, analyticsProps);
|
|
8
|
+
|
|
9
|
+
log_debug(`sendSearchCanceledEvent: send event: ${eventName}`, {
|
|
10
|
+
analyticsProps,
|
|
11
|
+
});
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const sendSearchExecutedEvent = (analyticsProps) => {
|
|
15
|
+
const eventName = ANALYTICS_CORE_EVENTS.SEARCH_EXECUTED;
|
|
16
|
+
postAnalyticEvent(eventName, analyticsProps);
|
|
17
|
+
|
|
18
|
+
log_debug(`sendSearchExecutedEvent: send event: ${eventName}`, {
|
|
19
|
+
analyticsProps,
|
|
20
|
+
});
|
|
21
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as R from "ramda";
|
|
2
|
+
import { appStore } from "@applicaster/zapp-react-native-redux/AppStore";
|
|
3
|
+
|
|
4
|
+
export const getVideojsAnalyticPluginsConfig = async (entry: ZappEntry) => {
|
|
5
|
+
let videojsConfiguration = {};
|
|
6
|
+
|
|
7
|
+
const plugins = appStore.get("plugins");
|
|
8
|
+
const analyticPlugins = R.filter(R.propEq("type", "analytics"), plugins);
|
|
9
|
+
|
|
10
|
+
const configurations = await Promise.all(
|
|
11
|
+
analyticPlugins.map(async (plugin) => {
|
|
12
|
+
const { configuration, module } = plugin;
|
|
13
|
+
|
|
14
|
+
return module?.getPlayerConfiguration?.(configuration, entry);
|
|
15
|
+
})
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
configurations.forEach((analyticConfig) => {
|
|
19
|
+
if (typeof analyticConfig === "object" && analyticConfig !== null) {
|
|
20
|
+
videojsConfiguration = { ...videojsConfiguration, ...analyticConfig };
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
return videojsConfiguration;
|
|
25
|
+
};
|
package/analyticsUtils/events.ts
CHANGED
|
@@ -23,10 +23,16 @@ export const TAPPING_EVENTS = {
|
|
|
23
23
|
TAP_NAVBAR_BACK_BUTTON: "tap_navbar_back_button",
|
|
24
24
|
};
|
|
25
25
|
|
|
26
|
+
export const SEARCH_EVENTS = {
|
|
27
|
+
SEARCH_EXECUTED: "search_executed",
|
|
28
|
+
SEARCH_CANCELED: "search_canceled",
|
|
29
|
+
};
|
|
30
|
+
|
|
26
31
|
export const ANALYTICS_CORE_EVENTS = {
|
|
27
32
|
...LEGACY_EVENTS,
|
|
28
33
|
...SCREEN_VIEW_EVENTS,
|
|
29
34
|
...TAPPING_EVENTS,
|
|
35
|
+
...SEARCH_EVENTS,
|
|
30
36
|
};
|
|
31
37
|
|
|
32
38
|
export const WEBVIEW_EVENTS = {
|
package/analyticsUtils/index.tsx
CHANGED
|
@@ -18,6 +18,8 @@ import {
|
|
|
18
18
|
sendHardwareBackButtonClickEvent,
|
|
19
19
|
sendDownloadsEvent,
|
|
20
20
|
sendScreenEvent,
|
|
21
|
+
sendSearchCanceledEvent,
|
|
22
|
+
sendSearchExecutedEvent,
|
|
21
23
|
} from "./AnalyticsEvents";
|
|
22
24
|
|
|
23
25
|
import { postAnalyticEvent } from "./manager";
|
|
@@ -66,6 +68,8 @@ type AnalyticsFunctions = {
|
|
|
66
68
|
item: ZappEntry;
|
|
67
69
|
state: OfflineItemState;
|
|
68
70
|
}) => void;
|
|
71
|
+
sendSearchCanceledEvent: (props: AnalyticsDefaultProperties) => void;
|
|
72
|
+
sendSearchExecutedEvent: (props: AnalyticsDefaultProperties) => void;
|
|
69
73
|
};
|
|
70
74
|
|
|
71
75
|
type GetAnalyticsFunctions = (
|
|
@@ -102,6 +106,8 @@ export function getAnalyticsFunctions({
|
|
|
102
106
|
sendHardwareBackButtonClickEvent,
|
|
103
107
|
sendScreenEvent,
|
|
104
108
|
sendDownloadsEvent,
|
|
109
|
+
sendSearchCanceledEvent,
|
|
110
|
+
sendSearchExecutedEvent,
|
|
105
111
|
};
|
|
106
112
|
}
|
|
107
113
|
|
|
@@ -1,20 +1,9 @@
|
|
|
1
1
|
import * as R from "ramda";
|
|
2
|
-
import {
|
|
3
|
-
isNilOrEmpty,
|
|
4
|
-
isNotNil,
|
|
5
|
-
} from "@applicaster/zapp-react-native-utils/reactUtils/helpers";
|
|
6
|
-
|
|
7
2
|
import { Tree } from "./treeDataStructure/Tree";
|
|
8
3
|
import { findFocusableNode, findPriorityItem } from "./treeDataStructure/Utils";
|
|
9
4
|
import { subscriber } from "../../functionUtils";
|
|
10
5
|
import * as FOCUS_EVENTS from "./events";
|
|
11
6
|
import { coreLogger } from "../../logger";
|
|
12
|
-
import {
|
|
13
|
-
waitForActiveScreen,
|
|
14
|
-
waitForContent,
|
|
15
|
-
getContentNode,
|
|
16
|
-
getActiveScreen,
|
|
17
|
-
} from "./utils";
|
|
18
7
|
|
|
19
8
|
const logger = coreLogger.addSubsystem("focusManager");
|
|
20
9
|
|
|
@@ -57,7 +46,7 @@ export const focusManager = (function () {
|
|
|
57
46
|
let lastFocusedId = null;
|
|
58
47
|
let initialFocusOnContent = null;
|
|
59
48
|
let focusDisabled = false;
|
|
60
|
-
let focusAutoEnabled =
|
|
49
|
+
let focusAutoEnabled = true;
|
|
61
50
|
const eventHandler = subscriber();
|
|
62
51
|
|
|
63
52
|
function disableAutomaticFocus() {
|
|
@@ -104,7 +93,7 @@ export const focusManager = (function () {
|
|
|
104
93
|
!currentFocusable.isGroup &&
|
|
105
94
|
currentFocusable.isMounted()
|
|
106
95
|
) {
|
|
107
|
-
currentFocusable.blur(direction);
|
|
96
|
+
currentFocusable.blur(currentFocusable, direction);
|
|
108
97
|
currentFocusable.hasLostFocus(getCurrentFocus(), direction);
|
|
109
98
|
}
|
|
110
99
|
}
|
|
@@ -230,55 +219,38 @@ export const focusManager = (function () {
|
|
|
230
219
|
/**
|
|
231
220
|
* sets the initial focus when the screen loads, or when focus is lost
|
|
232
221
|
*/
|
|
233
|
-
function setInitialFocus(lastAddedParentNode?: any
|
|
222
|
+
function setInitialFocus(lastAddedParentNode?: any) {
|
|
234
223
|
const preferredFocus = findPriorityItem(
|
|
235
224
|
lastAddedParentNode?.children || focusableTree.root.children
|
|
236
225
|
);
|
|
237
226
|
|
|
238
227
|
logger.log({ message: "setInitialFocus", data: { preferredFocus } });
|
|
239
228
|
|
|
240
|
-
if (
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
return;
|
|
254
|
-
}
|
|
229
|
+
if (preferredFocus && preferredFocus.length > 0) {
|
|
230
|
+
const focusCandidate = preferredFocus[0];
|
|
231
|
+
const focusableItem = focusCandidate.component;
|
|
232
|
+
|
|
233
|
+
if (
|
|
234
|
+
focusableItem &&
|
|
235
|
+
!focusableItem.isGroup &&
|
|
236
|
+
isFocusEnabled(focusableItem)
|
|
237
|
+
) {
|
|
238
|
+
if (initialFocusOnContent) {
|
|
239
|
+
blur();
|
|
240
|
+
initialFocusOnContent = false;
|
|
241
|
+
}
|
|
255
242
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
243
|
+
logger.log({
|
|
244
|
+
message: "setInitialFocus – currentFocusNode",
|
|
245
|
+
data: {
|
|
246
|
+
focusableItem,
|
|
247
|
+
},
|
|
248
|
+
});
|
|
261
249
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
isFocusEnabled(focusableItem)
|
|
266
|
-
) {
|
|
267
|
-
if (initialFocusOnContent) {
|
|
268
|
-
blur();
|
|
269
|
-
initialFocusOnContent = false;
|
|
250
|
+
currentFocusNode = focusCandidate;
|
|
251
|
+
focusableItem.willReceiveFocus(focusableItem, null);
|
|
252
|
+
focusableItem && setFocus(focusCandidate.id, null);
|
|
270
253
|
}
|
|
271
|
-
|
|
272
|
-
logger.log({
|
|
273
|
-
message: "setInitialFocus – currentFocusNode",
|
|
274
|
-
data: {
|
|
275
|
-
focusableItem,
|
|
276
|
-
},
|
|
277
|
-
});
|
|
278
|
-
|
|
279
|
-
currentFocusNode = focusCandidate;
|
|
280
|
-
focusableItem.willReceiveFocus(focusableItem, null);
|
|
281
|
-
focusableItem && setFocus(focusCandidate.id, null);
|
|
282
254
|
}
|
|
283
255
|
}
|
|
284
256
|
|
|
@@ -351,8 +323,6 @@ export const focusManager = (function () {
|
|
|
351
323
|
* @returns {React.Component} the registered component
|
|
352
324
|
*/
|
|
353
325
|
function registerGroup(id, component) {
|
|
354
|
-
// console.log("debug_2", "FM registerGroup", { id, component });
|
|
355
|
-
|
|
356
326
|
focusableTree.addNode({ id, component });
|
|
357
327
|
|
|
358
328
|
return component;
|
|
@@ -368,8 +338,6 @@ export const focusManager = (function () {
|
|
|
368
338
|
* @returns {React.Component} the registered component
|
|
369
339
|
*/
|
|
370
340
|
function registerItem(id, component) {
|
|
371
|
-
// console.log("debug_2", "FM registerItem", { id, component });
|
|
372
|
-
|
|
373
341
|
focusableTree.addNode({ id, component });
|
|
374
342
|
|
|
375
343
|
if (!currentFocusNode && id === lastFocusedId && !id.includes("menu")) {
|
|
@@ -386,8 +354,6 @@ export const focusManager = (function () {
|
|
|
386
354
|
* @param {String} id of the group to unregister
|
|
387
355
|
*/
|
|
388
356
|
function unregisterGroup(id) {
|
|
389
|
-
// console.log("debug_2", "FM unregisterGroup", { id });
|
|
390
|
-
|
|
391
357
|
focusableTree.findAndRemoveNode(id);
|
|
392
358
|
}
|
|
393
359
|
|
|
@@ -399,8 +365,6 @@ export const focusManager = (function () {
|
|
|
399
365
|
* @param {String} id of the Focusable to unregister
|
|
400
366
|
*/
|
|
401
367
|
function unregisterItem(id) {
|
|
402
|
-
// console.log("debug_2", "FM unregisterItem", { id });
|
|
403
|
-
|
|
404
368
|
focusableTree.findAndRemoveNode(id);
|
|
405
369
|
|
|
406
370
|
if (currentFocusNode && currentFocusNode.id === id) {
|
|
@@ -439,8 +403,6 @@ export const focusManager = (function () {
|
|
|
439
403
|
}
|
|
440
404
|
|
|
441
405
|
function setupInitialFocus(id: string, focusOnContent?: boolean) {
|
|
442
|
-
console.log("debug_2", "FM - setupInitialFocus", { id, focusOnContent });
|
|
443
|
-
|
|
444
406
|
if (focusOnContent) {
|
|
445
407
|
initialFocusOnContent = focusOnContent;
|
|
446
408
|
} else {
|
|
@@ -448,62 +410,6 @@ export const focusManager = (function () {
|
|
|
448
410
|
}
|
|
449
411
|
}
|
|
450
412
|
|
|
451
|
-
async function setFocusOnMenu(currentRoute: string) {
|
|
452
|
-
console.log("debug_2", "FM - setFocusOnMenu", { currentRoute });
|
|
453
|
-
|
|
454
|
-
try {
|
|
455
|
-
await waitForActiveScreen(currentRoute, focusableTree);
|
|
456
|
-
|
|
457
|
-
const navbar = R.find(
|
|
458
|
-
(child) => R.startsWith("navbar", child.id),
|
|
459
|
-
getActiveScreen(focusableTree).children
|
|
460
|
-
);
|
|
461
|
-
|
|
462
|
-
const selectedMenuItemId = R.find(
|
|
463
|
-
(child) => child.component.props.selected,
|
|
464
|
-
navbar?.children || []
|
|
465
|
-
)?.id;
|
|
466
|
-
|
|
467
|
-
if (selectedMenuItemId) {
|
|
468
|
-
// set focus on selected menu item
|
|
469
|
-
setFocus(selectedMenuItemId);
|
|
470
|
-
return;
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
const firstMenuItemId = R.path(["children", 0, "id"], navbar);
|
|
474
|
-
|
|
475
|
-
if (firstMenuItemId) {
|
|
476
|
-
// set focus on first menu item
|
|
477
|
-
setFocus(firstMenuItemId);
|
|
478
|
-
}
|
|
479
|
-
} catch (error) {
|
|
480
|
-
// failed to put focus on top-menu => log it
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
async function setFocusOnContent(currentRoute: string) {
|
|
485
|
-
console.log("debug_2", "FM - setFocusOnContent", { currentRoute });
|
|
486
|
-
|
|
487
|
-
// we need to put focus on content here
|
|
488
|
-
// For doing it we have to wait registration of first focusable node into focusableTree
|
|
489
|
-
// this is the temporary hack with waiting until content node starts having children
|
|
490
|
-
try {
|
|
491
|
-
await waitForActiveScreen(currentRoute, focusableTree);
|
|
492
|
-
await waitForContent(focusableTree);
|
|
493
|
-
|
|
494
|
-
const content = getContentNode(focusableTree);
|
|
495
|
-
|
|
496
|
-
const fallback = () => {
|
|
497
|
-
throw Error("Failed to land focus on content");
|
|
498
|
-
};
|
|
499
|
-
|
|
500
|
-
setInitialFocus(content, fallback);
|
|
501
|
-
} catch (e) {
|
|
502
|
-
// we've failed to put initial focus on content, put focus on menu as a last chance
|
|
503
|
-
setFocusOnMenu(currentRoute);
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
|
|
507
413
|
/**
|
|
508
414
|
* moves the focus in a provided direction
|
|
509
415
|
* @public
|
|
@@ -516,13 +422,6 @@ export const focusManager = (function () {
|
|
|
516
422
|
currentFocusNode.component.willLoseFocus(currentFocusNode, direction);
|
|
517
423
|
const nextFocusable = findFocusableNode(direction, currentFocusNode);
|
|
518
424
|
|
|
519
|
-
// console.log("debug_2", "FM moveFocus", {
|
|
520
|
-
// direction: direction?.value,
|
|
521
|
-
// currentFocusNode,
|
|
522
|
-
// focusableTree,
|
|
523
|
-
// nextFocusable,
|
|
524
|
-
// });
|
|
525
|
-
|
|
526
425
|
if (nextFocusable?.component?.isMounted?.()) {
|
|
527
426
|
const nextRect = nextFocusable.component.getRect();
|
|
528
427
|
|
|
@@ -619,7 +518,5 @@ export const focusManager = (function () {
|
|
|
619
518
|
enableAutomaticFocus,
|
|
620
519
|
getGroupRootById,
|
|
621
520
|
isGroupItemFocused,
|
|
622
|
-
setFocusOnMenu,
|
|
623
|
-
setFocusOnContent,
|
|
624
521
|
};
|
|
625
522
|
})();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as R from "ramda";
|
|
2
2
|
import { isNilOrEmpty } from "@applicaster/zapp-react-native-utils/reactUtils/helpers";
|
|
3
3
|
|
|
4
4
|
import { rejectItemByPath } from "../../../../objectUtils";
|
|
@@ -143,49 +143,7 @@ const hasChildren = (target) =>
|
|
|
143
143
|
|
|
144
144
|
const hasComponent = (target) => !!target?.component;
|
|
145
145
|
|
|
146
|
-
const hasComponentAndChildren = allPass([hasComponent, hasChildren]);
|
|
147
|
-
|
|
148
|
-
const positiveOrZero = (value) => value >= 0;
|
|
149
|
-
|
|
150
|
-
const excludeFromFocusSearching = pathOr(false, [
|
|
151
|
-
"component",
|
|
152
|
-
"props",
|
|
153
|
-
"excludeFromFocusSearching",
|
|
154
|
-
]);
|
|
155
|
-
|
|
156
|
-
// const isAllScreens = all(excludeFromFocusSearching);
|
|
157
|
-
|
|
158
|
-
const isNavBar = (target) => startsWith("navbar", target?.id);
|
|
159
|
-
|
|
160
|
-
const ignoreMenuIfMultipleTargets = (nodes) => {
|
|
161
|
-
if (nodes.length > 1 && nodes.map((n) => n?.target?.id).includes("navbar")) {
|
|
162
|
-
return nodes.filter((n) => !isNavBar(n?.target));
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
return nodes;
|
|
166
|
-
};
|
|
167
|
-
|
|
168
|
-
const toDistance = ({ target, direction, comparisonRect }) => {
|
|
169
|
-
const componentRect = target.component?.getRect();
|
|
170
|
-
|
|
171
|
-
const orientationDistance = measureDistance(
|
|
172
|
-
direction,
|
|
173
|
-
comparisonRect,
|
|
174
|
-
componentRect
|
|
175
|
-
);
|
|
176
|
-
|
|
177
|
-
if (orientationDistance === -1) {
|
|
178
|
-
// ignores offscreen targets when moving up/down
|
|
179
|
-
return null;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
const euclidDistance = measureEuclidianDistanceToCenter(
|
|
183
|
-
comparisonRect,
|
|
184
|
-
componentRect
|
|
185
|
-
);
|
|
186
|
-
|
|
187
|
-
return orientationDistance > 0 ? euclidDistance : orientationDistance;
|
|
188
|
-
};
|
|
146
|
+
const hasComponentAndChildren = R.allPass([hasComponent, hasChildren]);
|
|
189
147
|
|
|
190
148
|
/**
|
|
191
149
|
* Get target in shortest distance in specified direction
|
|
@@ -215,32 +173,52 @@ export function getTargetInDirection(
|
|
|
215
173
|
|
|
216
174
|
const distances = targets
|
|
217
175
|
.filter(hasComponentAndChildren)
|
|
218
|
-
.
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
176
|
+
.map((target) => {
|
|
177
|
+
const componentRect = target.component?.getRect();
|
|
178
|
+
|
|
179
|
+
const distance = measureDistance(
|
|
180
|
+
direction,
|
|
181
|
+
comparisonRect,
|
|
182
|
+
componentRect
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
if (distance === -1) {
|
|
186
|
+
// ignores offscreen targets when moving up/down
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
224
189
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
190
|
+
const orientationDistance = measureDistance(
|
|
191
|
+
direction,
|
|
192
|
+
comparisonRect,
|
|
193
|
+
componentRect
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
const euclidDistance = measureEuclidianDistanceToCenter(
|
|
197
|
+
comparisonRect,
|
|
198
|
+
componentRect
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
return {
|
|
202
|
+
distance:
|
|
203
|
+
orientationDistance > 0 ? euclidDistance : orientationDistance,
|
|
204
|
+
target,
|
|
205
|
+
};
|
|
206
|
+
})
|
|
207
|
+
.filter((obj) => obj && obj.distance >= 0);
|
|
228
208
|
|
|
229
209
|
const match = distances
|
|
230
210
|
.sort((a, b) => a.distance - b.distance) // sorts the distances
|
|
231
211
|
.filter(ignoreMenuIfMultipleTargets)[0]; // filters out multiple targets if necessary // gets the first element
|
|
232
212
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
return match?.target;
|
|
213
|
+
return distances && distances.length > 0 ? match.target : null;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
function ignoreMenuIfMultipleTargets(nodes) {
|
|
217
|
+
if (nodes.length > 1 && nodes.map((n) => n?.target?.id).includes("navbar")) {
|
|
218
|
+
return nodes.filter((n) => n?.target?.id !== "navbar");
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return nodes;
|
|
244
222
|
}
|
|
245
223
|
|
|
246
224
|
/**
|
|
@@ -331,36 +309,3 @@ export function hasPriorityInDirection(direction, component) {
|
|
|
331
309
|
|
|
332
310
|
return (prioritiseFocusOn & mappedDirection) > 0;
|
|
333
311
|
}
|
|
334
|
-
|
|
335
|
-
export const getNodeBeforeRoot = (node) => {
|
|
336
|
-
if (isNil(node)) {
|
|
337
|
-
return undefined;
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
if (node.parent.id === "root") {
|
|
341
|
-
return node;
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
return getNodeBeforeRoot(node.parent);
|
|
345
|
-
};
|
|
346
|
-
|
|
347
|
-
export const isAllowedToMoveTo = (currentNode, nextNode) => {
|
|
348
|
-
const screenForCurrentNode = getNodeBeforeRoot(currentNode);
|
|
349
|
-
const screenForNextNode = getNodeBeforeRoot(nextNode);
|
|
350
|
-
|
|
351
|
-
return screenForCurrentNode.id === screenForNextNode.id;
|
|
352
|
-
|
|
353
|
-
// console.log("debug_2", "isAllowedToMoveTo", {
|
|
354
|
-
// nodeBeforeRoot,
|
|
355
|
-
// });
|
|
356
|
-
|
|
357
|
-
// if (nodeBeforeRoot?.id === "navbar") {
|
|
358
|
-
// return true;
|
|
359
|
-
// }
|
|
360
|
-
|
|
361
|
-
// if (nodeBeforeRoot?.component?.props?.isActive) {
|
|
362
|
-
// return true;
|
|
363
|
-
// }
|
|
364
|
-
|
|
365
|
-
// return false;
|
|
366
|
-
};
|
|
@@ -4,6 +4,7 @@ import { useEffect } from "react";
|
|
|
4
4
|
import { playerManager } from "./index";
|
|
5
5
|
import { useValidatePlayerConfig } from "../../playerUtils/useValidatePlayerConfig";
|
|
6
6
|
import { PlayerRole } from "./conts";
|
|
7
|
+
import { isAppleTV } from "@applicaster/zapp-react-native-ui-components/Helpers/Platform";
|
|
7
8
|
|
|
8
9
|
// TODO: Rename to ControllerType
|
|
9
10
|
export const usePlayerControllerSetup = ({
|
|
@@ -34,10 +35,14 @@ export const usePlayerControllerSetup = ({
|
|
|
34
35
|
useValidatePlayerConfig(config);
|
|
35
36
|
|
|
36
37
|
useEffect(() => {
|
|
38
|
+
const newConfig = isAppleTV()
|
|
39
|
+
? { supports_native_controls: true, ...config }
|
|
40
|
+
: config;
|
|
41
|
+
|
|
37
42
|
const newPlayerController = new ControllerType({
|
|
38
43
|
player: ref,
|
|
39
44
|
listener: props as any,
|
|
40
|
-
config,
|
|
45
|
+
config: newConfig,
|
|
41
46
|
playerId,
|
|
42
47
|
entry,
|
|
43
48
|
playerPluginId: pluginId,
|
|
@@ -24,7 +24,6 @@ import {
|
|
|
24
24
|
EMPTY,
|
|
25
25
|
FALLBACK,
|
|
26
26
|
TRANSFORM,
|
|
27
|
-
defaultColor,
|
|
28
27
|
} from "./fixtures";
|
|
29
28
|
|
|
30
29
|
describe("getKeyForLabel", () => {
|
|
@@ -395,9 +394,7 @@ describe("getColorFromData", () => {
|
|
|
395
394
|
it("should return value directly if valid color", () => {
|
|
396
395
|
const result = getColorFromData({
|
|
397
396
|
data: entry,
|
|
398
|
-
|
|
399
|
-
getValue: getValue(componentStyle),
|
|
400
|
-
defaultColor,
|
|
397
|
+
valueFromLayout: "#123456",
|
|
401
398
|
});
|
|
402
399
|
|
|
403
400
|
expect(result).toBe("#123456");
|
|
@@ -406,9 +403,7 @@ describe("getColorFromData", () => {
|
|
|
406
403
|
it("should return valid rgba color name", () => {
|
|
407
404
|
const result = getColorFromData({
|
|
408
405
|
data: entry,
|
|
409
|
-
|
|
410
|
-
getValue: getValue(componentStyle),
|
|
411
|
-
defaultColor,
|
|
406
|
+
valueFromLayout: "rgba(255, 255, 255, 0)",
|
|
412
407
|
});
|
|
413
408
|
|
|
414
409
|
expect(result).toBe("rgba(255, 255, 255, 0)");
|
|
@@ -417,33 +412,27 @@ describe("getColorFromData", () => {
|
|
|
417
412
|
it("should return path value if path value is set and is valid color", () => {
|
|
418
413
|
const result = getColorFromData({
|
|
419
414
|
data: entry,
|
|
420
|
-
|
|
421
|
-
getValue: getValue(componentStyle),
|
|
422
|
-
defaultColor,
|
|
415
|
+
valueFromLayout: "background_color",
|
|
423
416
|
});
|
|
424
417
|
|
|
425
418
|
expect(result).toBe("#123456");
|
|
426
419
|
});
|
|
427
420
|
|
|
428
|
-
it("should return
|
|
421
|
+
it("should return path value if path value is set, nested and is valid color", () => {
|
|
429
422
|
const result = getColorFromData({
|
|
430
423
|
data: entry,
|
|
431
|
-
|
|
432
|
-
getValue: getValue(componentStyle),
|
|
433
|
-
defaultColor,
|
|
424
|
+
valueFromLayout: "extensions.background_color",
|
|
434
425
|
});
|
|
435
426
|
|
|
436
|
-
expect(result).toBe(
|
|
427
|
+
expect(result).toBe("#123456");
|
|
437
428
|
});
|
|
438
429
|
|
|
439
|
-
it("should return
|
|
430
|
+
it("should return valueFromLayout if path does not exist", () => {
|
|
440
431
|
const result = getColorFromData({
|
|
441
432
|
data: entry,
|
|
442
|
-
|
|
443
|
-
getValue: getValue(componentStyle),
|
|
444
|
-
defaultColor,
|
|
433
|
+
valueFromLayout: "invalid_color",
|
|
445
434
|
});
|
|
446
435
|
|
|
447
|
-
expect(result).toBe(
|
|
436
|
+
expect(result).toBe("invalid_color");
|
|
448
437
|
});
|
|
449
438
|
});
|
package/cellUtils/index.ts
CHANGED
|
@@ -447,30 +447,24 @@ export const toResizeMode = (
|
|
|
447
447
|
|
|
448
448
|
type GetColorFromData = {
|
|
449
449
|
data: Record<string, any>;
|
|
450
|
-
|
|
451
|
-
getValue: Function;
|
|
452
|
-
defaultColor: string;
|
|
450
|
+
valueFromLayout: string;
|
|
453
451
|
};
|
|
454
452
|
|
|
455
453
|
export const getColorFromData = ({
|
|
456
454
|
data,
|
|
457
|
-
|
|
458
|
-
getValue,
|
|
459
|
-
defaultColor,
|
|
455
|
+
valueFromLayout,
|
|
460
456
|
}: GetColorFromData): string => {
|
|
461
|
-
const value = getValue(key);
|
|
462
|
-
|
|
463
457
|
// Temporary hack to fix color validation when alpha is floating point number
|
|
464
458
|
// https://github.com/dreamyguy/validate-color/issues/44
|
|
465
|
-
if (validateColor(
|
|
466
|
-
return
|
|
459
|
+
if (validateColor(valueFromLayout.replace(".00", ""))) {
|
|
460
|
+
return valueFromLayout;
|
|
467
461
|
}
|
|
468
462
|
|
|
469
|
-
const pathValue = R.path(
|
|
463
|
+
const pathValue = R.path(valueFromLayout.split("."), data);
|
|
470
464
|
|
|
471
465
|
if (pathValue && validateColor(pathValue)) {
|
|
472
466
|
return pathValue;
|
|
473
467
|
}
|
|
474
468
|
|
|
475
|
-
return
|
|
469
|
+
return valueFromLayout;
|
|
476
470
|
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import dayjs from "dayjs";
|
|
2
|
+
import utc from "dayjs/plugin/utc";
|
|
3
|
+
import timezone from "dayjs/plugin/timezone";
|
|
4
|
+
import isoWeek from "dayjs/plugin/isoWeek";
|
|
5
|
+
|
|
6
|
+
// Extend dayjs with plugins
|
|
7
|
+
dayjs.extend(utc);
|
|
8
|
+
dayjs.extend(timezone);
|
|
9
|
+
dayjs.extend(isoWeek);
|
|
10
|
+
|
|
11
|
+
export { dayjs };
|
package/headersUtils/index.ts
CHANGED
|
@@ -28,5 +28,6 @@ export const getAppDataHeaders = (screenId: string) => {
|
|
|
28
28
|
"x-applicaster-signed-device-info-token": appData.signedDeviceInfoToken,
|
|
29
29
|
"x-applicaster-device-make": appData.deviceMake,
|
|
30
30
|
"x-applicaster-device-model": appData.deviceModel,
|
|
31
|
+
"x-applicaster-uuid": appData?.uuid,
|
|
31
32
|
};
|
|
32
33
|
};
|