@applicaster/zapp-react-native-utils 12.0.0-alpha.4337072244 → 12.0.0-alpha.4342066143
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/analyticsPlugins.ts +25 -0
- package/appUtils/focusManager/__tests__/__snapshots__/focusManager.test.js.snap +3 -3
- package/appUtils/focusManager/__tests__/focusManager.test.js +24 -4
- package/appUtils/focusManager/__tests__/index.test.ts +3 -3
- package/appUtils/focusManager/index.ts +56 -141
- package/appUtils/focusManager/treeDataStructure/Utils/index.js +43 -73
- package/appUtils/playerManager/usePlayerControllerSetup.tsx +6 -1
- package/arrayUtils/index.ts +0 -5
- package/numberUtils/__tests__/isLikeNumber.test.ts +0 -18
- package/numberUtils/index.ts +18 -5
- package/package.json +2 -2
- package/reactHooks/cell-click/__tests__/index.test.js +7 -10
- package/reactHooks/cell-click/index.ts +12 -12
- package/reactHooks/feed/__tests__/useBuildPipesUrl.test.tsx +70 -30
- package/reactHooks/feed/useBuildPipesUrl.ts +10 -7
- package/reactHooks/navigation/__tests__/index.test.tsx +11 -8
- package/reactHooks/navigation/index.ts +21 -80
- package/reactHooks/screen/__tests__/useCurrentScreenData.test.tsx +23 -21
- package/reactHooks/screen/index.ts +0 -2
- package/reactHooks/screen/useScreenContext.ts +3 -3
- package/appUtils/focusManager/utils/index.ts +0 -94
- package/arrayUtils/__tests__/isFilledArray.test.ts +0 -63
- package/reactHooks/screen/useScreenBackgroundColor.ts +0 -23
|
@@ -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
|
+
};
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
exports[`focusManager should be defined 1`] = `
|
|
4
4
|
Object {
|
|
5
5
|
"blur": [Function],
|
|
6
|
+
"disableAutomaticFocus": [Function],
|
|
6
7
|
"disableFocus": [Function],
|
|
8
|
+
"enableAutomaticFocus": [Function],
|
|
7
9
|
"enableFocus": [Function],
|
|
8
10
|
"focusableTree": Tree {
|
|
9
11
|
"loadingCounter": 0,
|
|
@@ -28,13 +30,11 @@ Object {
|
|
|
28
30
|
"on": [Function],
|
|
29
31
|
"press": [Function],
|
|
30
32
|
"pressOut": [Function],
|
|
31
|
-
"recoverFocus": [Function],
|
|
32
33
|
"register": [Function],
|
|
33
34
|
"removeHandler": [Function],
|
|
34
35
|
"setFocus": [Function],
|
|
35
|
-
"setFocusOnContent": [Function],
|
|
36
|
-
"setFocusOnMenu": [Function],
|
|
37
36
|
"setInitialFocus": [Function],
|
|
37
|
+
"setupInitialFocus": [Function],
|
|
38
38
|
"unregister": [Function],
|
|
39
39
|
}
|
|
40
40
|
`;
|
|
@@ -14,8 +14,10 @@ describe("focusManager", () => {
|
|
|
14
14
|
expect(focusManager).toMatchSnapshot();
|
|
15
15
|
});
|
|
16
16
|
|
|
17
|
-
it("
|
|
17
|
+
it("enableAutomaticFocus should not block setting focus", () => {
|
|
18
18
|
const mockSetFocus = jest.fn();
|
|
19
|
+
focusManager.setupInitialFocus("1", true);
|
|
20
|
+
focusManager.enableAutomaticFocus();
|
|
19
21
|
|
|
20
22
|
focusManager.register({
|
|
21
23
|
id: "1",
|
|
@@ -29,13 +31,31 @@ describe("focusManager", () => {
|
|
|
29
31
|
},
|
|
30
32
|
});
|
|
31
33
|
|
|
32
|
-
const { success } = focusManager.setInitialFocus();
|
|
33
|
-
|
|
34
|
-
expect(success).toBe(true);
|
|
35
34
|
expect(mockSetFocus).toBeCalledTimes(1);
|
|
36
35
|
expect(mockSetFocus).toBeCalledWith(null);
|
|
37
36
|
});
|
|
38
37
|
|
|
38
|
+
it("enableAutomaticFocus should block setting focus", () => {
|
|
39
|
+
const mockSetFocus = jest.fn();
|
|
40
|
+
focusManager.setupInitialFocus("1", true);
|
|
41
|
+
focusManager.disableAutomaticFocus();
|
|
42
|
+
|
|
43
|
+
focusManager.register({
|
|
44
|
+
id: "1",
|
|
45
|
+
component: {
|
|
46
|
+
setFocus: mockSetFocus,
|
|
47
|
+
willReceiveFocus: function () {},
|
|
48
|
+
isMounted: function () {
|
|
49
|
+
return true;
|
|
50
|
+
},
|
|
51
|
+
props: { groupId: "121" },
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
expect(mockSetFocus).toBeCalledTimes(0);
|
|
56
|
+
expect(mockSetFocus).not.toBeCalledWith(null);
|
|
57
|
+
});
|
|
58
|
+
|
|
39
59
|
describe("register", () => {});
|
|
40
60
|
describe("unregister", () => {});
|
|
41
61
|
describe("find", () => {});
|
|
@@ -18,6 +18,7 @@ describe("focusManager", () => {
|
|
|
18
18
|
"on",
|
|
19
19
|
"invokeHandler",
|
|
20
20
|
"removeHandler",
|
|
21
|
+
"setupInitialFocus",
|
|
21
22
|
"longPress",
|
|
22
23
|
"pressOut",
|
|
23
24
|
"enableFocus",
|
|
@@ -26,11 +27,10 @@ describe("focusManager", () => {
|
|
|
26
27
|
"isFocusDisabled",
|
|
27
28
|
"getCurrentFocusNode",
|
|
28
29
|
"focusableTree",
|
|
30
|
+
"disableAutomaticFocus",
|
|
31
|
+
"enableAutomaticFocus",
|
|
29
32
|
"getGroupRootById",
|
|
30
33
|
"isGroupItemFocused",
|
|
31
|
-
"setFocusOnMenu",
|
|
32
|
-
"setFocusOnContent",
|
|
33
|
-
"recoverFocus",
|
|
34
34
|
];
|
|
35
35
|
|
|
36
36
|
expectedMethods.forEach((method) => {
|
|
@@ -1,24 +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
|
-
import {
|
|
9
|
-
findFocusableNode,
|
|
10
|
-
findPriorityItem,
|
|
11
|
-
isTransitionHappening,
|
|
12
|
-
} from "./treeDataStructure/Utils";
|
|
3
|
+
import { findFocusableNode, findPriorityItem } from "./treeDataStructure/Utils";
|
|
13
4
|
import { subscriber } from "../../functionUtils";
|
|
14
5
|
import * as FOCUS_EVENTS from "./events";
|
|
15
6
|
import { coreLogger } from "../../logger";
|
|
16
|
-
import {
|
|
17
|
-
waitForActiveScreen,
|
|
18
|
-
waitForContent,
|
|
19
|
-
getContentNode,
|
|
20
|
-
getNavbarNode,
|
|
21
|
-
} from "./utils";
|
|
22
7
|
|
|
23
8
|
const logger = coreLogger.addSubsystem("focusManager");
|
|
24
9
|
|
|
@@ -59,9 +44,21 @@ export const focusManager = (function () {
|
|
|
59
44
|
// focusable node which currently holds the focus
|
|
60
45
|
let currentFocusNode = null;
|
|
61
46
|
let lastFocusedId = null;
|
|
47
|
+
let initialFocusOnContent = null;
|
|
62
48
|
let focusDisabled = false;
|
|
49
|
+
let focusAutoEnabled = true;
|
|
63
50
|
const eventHandler = subscriber();
|
|
64
51
|
|
|
52
|
+
function disableAutomaticFocus() {
|
|
53
|
+
logger.log({ message: "disableAutomaticFocus" });
|
|
54
|
+
focusAutoEnabled = false;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function enableAutomaticFocus() {
|
|
58
|
+
logger.log({ message: "focusManager: enableAutomaticFocus" });
|
|
59
|
+
focusAutoEnabled = true;
|
|
60
|
+
}
|
|
61
|
+
|
|
65
62
|
function enableFocus() {
|
|
66
63
|
focusDisabled = false;
|
|
67
64
|
}
|
|
@@ -96,7 +93,7 @@ export const focusManager = (function () {
|
|
|
96
93
|
!currentFocusable.isGroup &&
|
|
97
94
|
currentFocusable.isMounted()
|
|
98
95
|
) {
|
|
99
|
-
currentFocusable.blur(direction);
|
|
96
|
+
currentFocusable.blur(currentFocusable, direction);
|
|
100
97
|
currentFocusable.hasLostFocus(getCurrentFocus(), direction);
|
|
101
98
|
}
|
|
102
99
|
}
|
|
@@ -229,52 +226,32 @@ export const focusManager = (function () {
|
|
|
229
226
|
|
|
230
227
|
logger.log({ message: "setInitialFocus", data: { preferredFocus } });
|
|
231
228
|
|
|
232
|
-
if (
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
currentFocusedId === nextFocusedId
|
|
246
|
-
) {
|
|
247
|
-
// we are going to move focus to the same node(already focused) -> nothing to do
|
|
248
|
-
return { success: true };
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
if (focusableItem?.isGroup) {
|
|
252
|
-
// focusCandidate is a FocusableGroup, we are not able to land focus on group(only on Focusable)
|
|
253
|
-
return { success: false };
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
if (
|
|
257
|
-
focusableItem &&
|
|
258
|
-
!focusableItem.isGroup &&
|
|
259
|
-
isFocusEnabled(focusableItem)
|
|
260
|
-
) {
|
|
261
|
-
blur();
|
|
262
|
-
|
|
263
|
-
logger.log({
|
|
264
|
-
message: "setInitialFocus – currentFocusNode",
|
|
265
|
-
data: {
|
|
266
|
-
focusableItem,
|
|
267
|
-
},
|
|
268
|
-
});
|
|
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
|
+
}
|
|
269
242
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
243
|
+
logger.log({
|
|
244
|
+
message: "setInitialFocus – currentFocusNode",
|
|
245
|
+
data: {
|
|
246
|
+
focusableItem,
|
|
247
|
+
},
|
|
248
|
+
});
|
|
273
249
|
|
|
274
|
-
|
|
250
|
+
currentFocusNode = focusCandidate;
|
|
251
|
+
focusableItem.willReceiveFocus(focusableItem, null);
|
|
252
|
+
focusableItem && setFocus(focusCandidate.id, null);
|
|
253
|
+
}
|
|
275
254
|
}
|
|
276
|
-
|
|
277
|
-
return { success: false };
|
|
278
255
|
}
|
|
279
256
|
|
|
280
257
|
function treeLoaded(val, node) {
|
|
@@ -284,8 +261,17 @@ export const focusManager = (function () {
|
|
|
284
261
|
val,
|
|
285
262
|
node,
|
|
286
263
|
currentFocusNode,
|
|
264
|
+
initialFocusOnContent,
|
|
287
265
|
},
|
|
288
266
|
});
|
|
267
|
+
|
|
268
|
+
if ((val && !currentFocusNode) || initialFocusOnContent) {
|
|
269
|
+
logger.log({ message: `focusAutoEnabled ${focusAutoEnabled}` });
|
|
270
|
+
|
|
271
|
+
if (focusAutoEnabled) {
|
|
272
|
+
setInitialFocus(initialFocusOnContent ? node : undefined);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
289
275
|
}
|
|
290
276
|
|
|
291
277
|
/**
|
|
@@ -416,79 +402,11 @@ export const focusManager = (function () {
|
|
|
416
402
|
group ? unregisterGroup(id) : unregisterItem(id);
|
|
417
403
|
}
|
|
418
404
|
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
const selectedMenuItemId = R.find(
|
|
426
|
-
(child) => child.component.props.selected,
|
|
427
|
-
navbar.children
|
|
428
|
-
)?.id;
|
|
429
|
-
|
|
430
|
-
if (selectedMenuItemId) {
|
|
431
|
-
// set focus on selected menu item
|
|
432
|
-
setFocus(selectedMenuItemId);
|
|
433
|
-
|
|
434
|
-
return;
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
const firstMenuItemId = R.path(["children", 0, "id"], navbar);
|
|
438
|
-
|
|
439
|
-
if (firstMenuItemId) {
|
|
440
|
-
// set focus on first menu item
|
|
441
|
-
setFocus(firstMenuItemId);
|
|
442
|
-
}
|
|
443
|
-
} catch (error) {
|
|
444
|
-
logger.log({
|
|
445
|
-
message: "setFocusOnMenu – failed to put focus on top-menu",
|
|
446
|
-
data: {
|
|
447
|
-
currentRoute,
|
|
448
|
-
error,
|
|
449
|
-
},
|
|
450
|
-
});
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
async function setFocusOnContent(currentRoute: string) {
|
|
455
|
-
// we need to put focus on content here
|
|
456
|
-
// For doing it we have to wait registration of first focusable node into focusableTree
|
|
457
|
-
// we wait until content node starts having children
|
|
458
|
-
try {
|
|
459
|
-
await waitForActiveScreen(currentRoute, focusableTree);
|
|
460
|
-
await waitForContent(focusableTree);
|
|
461
|
-
|
|
462
|
-
const content = getContentNode(focusableTree);
|
|
463
|
-
|
|
464
|
-
const { success } = setInitialFocus(content);
|
|
465
|
-
|
|
466
|
-
if (!success) {
|
|
467
|
-
// we've failed to put initial focus on content, re-run "setFocusOnContent" again as a fallback
|
|
468
|
-
throw Error(
|
|
469
|
-
"we've failed to put initial focus on content, re-run 'setFocusOnContent' again as a fallback"
|
|
470
|
-
);
|
|
471
|
-
}
|
|
472
|
-
} catch (error) {
|
|
473
|
-
setFocusOnContent(currentRoute);
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
function isTransitionInProgress() {
|
|
478
|
-
const routes = R.pathOr([], ["root", "children"], focusableTree);
|
|
479
|
-
|
|
480
|
-
if (routes.length <= 1) {
|
|
481
|
-
// there is only one or zero routes
|
|
482
|
-
return false;
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
return isTransitionHappening(currentFocusNode, R.last(routes));
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
function recoverFocus() {
|
|
489
|
-
if (isTransitionInProgress()) {
|
|
490
|
-
// We've failed to set focused node on the new screen => run focus recovery
|
|
491
|
-
setInitialFocus();
|
|
405
|
+
function setupInitialFocus(id: string, focusOnContent?: boolean) {
|
|
406
|
+
if (focusOnContent) {
|
|
407
|
+
initialFocusOnContent = focusOnContent;
|
|
408
|
+
} else {
|
|
409
|
+
setFocus(id);
|
|
492
410
|
}
|
|
493
411
|
}
|
|
494
412
|
|
|
@@ -498,11 +416,6 @@ export const focusManager = (function () {
|
|
|
498
416
|
* @param {Object} direction of the scroll
|
|
499
417
|
*/
|
|
500
418
|
function moveFocus(direction) {
|
|
501
|
-
if (isTransitionInProgress()) {
|
|
502
|
-
// We are opening new screen. We need to ignore movement of focus.
|
|
503
|
-
return false;
|
|
504
|
-
}
|
|
505
|
-
|
|
506
419
|
if (focusDisabled) return false;
|
|
507
420
|
|
|
508
421
|
if (currentFocusNode) {
|
|
@@ -531,6 +444,8 @@ export const focusManager = (function () {
|
|
|
531
444
|
} else {
|
|
532
445
|
currentFocusNode.component.failedLostFocus(currentFocusNode, direction);
|
|
533
446
|
}
|
|
447
|
+
} else {
|
|
448
|
+
setInitialFocus();
|
|
534
449
|
}
|
|
535
450
|
}
|
|
536
451
|
|
|
@@ -590,6 +505,7 @@ export const focusManager = (function () {
|
|
|
590
505
|
on,
|
|
591
506
|
invokeHandler,
|
|
592
507
|
removeHandler,
|
|
508
|
+
setupInitialFocus,
|
|
593
509
|
longPress,
|
|
594
510
|
pressOut,
|
|
595
511
|
enableFocus,
|
|
@@ -598,10 +514,9 @@ export const focusManager = (function () {
|
|
|
598
514
|
isFocusDisabled,
|
|
599
515
|
getCurrentFocusNode,
|
|
600
516
|
focusableTree,
|
|
517
|
+
disableAutomaticFocus,
|
|
518
|
+
enableAutomaticFocus,
|
|
601
519
|
getGroupRootById,
|
|
602
520
|
isGroupItemFocused,
|
|
603
|
-
setFocusOnMenu,
|
|
604
|
-
setFocusOnContent,
|
|
605
|
-
recoverFocus,
|
|
606
521
|
};
|
|
607
522
|
})();
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as R from "ramda";
|
|
2
2
|
import { isNilOrEmpty } from "@applicaster/zapp-react-native-utils/reactUtils/helpers";
|
|
3
|
-
import { isZero } from "@applicaster/zapp-react-native-utils/numberUtils";
|
|
4
3
|
|
|
5
4
|
import { rejectItemByPath } from "../../../../objectUtils";
|
|
6
5
|
import {
|
|
@@ -144,47 +143,7 @@ const hasChildren = (target) =>
|
|
|
144
143
|
|
|
145
144
|
const hasComponent = (target) => !!target?.component;
|
|
146
145
|
|
|
147
|
-
const hasComponentAndChildren = allPass([hasComponent, hasChildren]);
|
|
148
|
-
|
|
149
|
-
const positiveOrZero = (value) => value > 0 || isZero(value);
|
|
150
|
-
|
|
151
|
-
const excludeFromFocusSearching = pathOr(false, [
|
|
152
|
-
"component",
|
|
153
|
-
"props",
|
|
154
|
-
"excludeFromFocusSearching",
|
|
155
|
-
]);
|
|
156
|
-
|
|
157
|
-
const isNavBar = (target) => startsWith("navbar", target?.id);
|
|
158
|
-
|
|
159
|
-
const ignoreMenuIfMultipleTargets = (nodes) => {
|
|
160
|
-
if (nodes.length > 1 && nodes.map((n) => n?.target?.id).includes("navbar")) {
|
|
161
|
-
return nodes.filter((n) => !isNavBar(n?.target));
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
return nodes;
|
|
165
|
-
};
|
|
166
|
-
|
|
167
|
-
const toDistance = ({ target, direction, comparisonRect }) => {
|
|
168
|
-
const componentRect = target.component?.getRect();
|
|
169
|
-
|
|
170
|
-
const orientationDistance = measureDistance(
|
|
171
|
-
direction,
|
|
172
|
-
comparisonRect,
|
|
173
|
-
componentRect
|
|
174
|
-
);
|
|
175
|
-
|
|
176
|
-
if (orientationDistance === -1) {
|
|
177
|
-
// ignores offscreen targets when moving up/down
|
|
178
|
-
return null;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
const euclidDistance = measureEuclidianDistanceToCenter(
|
|
182
|
-
comparisonRect,
|
|
183
|
-
componentRect
|
|
184
|
-
);
|
|
185
|
-
|
|
186
|
-
return orientationDistance > 0 ? euclidDistance : orientationDistance;
|
|
187
|
-
};
|
|
146
|
+
const hasComponentAndChildren = R.allPass([hasComponent, hasChildren]);
|
|
188
147
|
|
|
189
148
|
/**
|
|
190
149
|
* Get target in shortest distance in specified direction
|
|
@@ -214,18 +173,52 @@ export function getTargetInDirection(
|
|
|
214
173
|
|
|
215
174
|
const distances = targets
|
|
216
175
|
.filter(hasComponentAndChildren)
|
|
217
|
-
.
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
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
|
+
}
|
|
189
|
+
|
|
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);
|
|
223
208
|
|
|
224
209
|
const match = distances
|
|
225
210
|
.sort((a, b) => a.distance - b.distance) // sorts the distances
|
|
226
211
|
.filter(ignoreMenuIfMultipleTargets)[0]; // filters out multiple targets if necessary // gets the first element
|
|
227
212
|
|
|
228
|
-
return match
|
|
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;
|
|
229
222
|
}
|
|
230
223
|
|
|
231
224
|
/**
|
|
@@ -316,26 +309,3 @@ export function hasPriorityInDirection(direction, component) {
|
|
|
316
309
|
|
|
317
310
|
return (prioritiseFocusOn & mappedDirection) > 0;
|
|
318
311
|
}
|
|
319
|
-
|
|
320
|
-
export const getNodeBeforeRoot = (node) => {
|
|
321
|
-
if (isNil(node)) {
|
|
322
|
-
return undefined;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
if (isNil(node.parent)) {
|
|
326
|
-
return undefined;
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
if (node.parent.id === "root") {
|
|
330
|
-
return node;
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
return getNodeBeforeRoot(node.parent);
|
|
334
|
-
};
|
|
335
|
-
|
|
336
|
-
export const isTransitionHappening = (currentNode, nextNode) => {
|
|
337
|
-
const routeForCurrentNode = getNodeBeforeRoot(currentNode);
|
|
338
|
-
const routeForNextNode = getNodeBeforeRoot(nextNode);
|
|
339
|
-
|
|
340
|
-
return routeForCurrentNode?.id !== routeForNextNode?.id;
|
|
341
|
-
};
|
|
@@ -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,
|
package/arrayUtils/index.ts
CHANGED
|
@@ -95,8 +95,3 @@ export const makeListOfIndexes = (size: number): number[] =>
|
|
|
95
95
|
export const makeListOf = (value: unknown, size: number): number[] => {
|
|
96
96
|
return Array(size).fill(value);
|
|
97
97
|
};
|
|
98
|
-
|
|
99
|
-
/** Checks if a value is a non-empty array */
|
|
100
|
-
export function isFilledArray(value: unknown): boolean {
|
|
101
|
-
return R.is(Array, value) && R.length(value) > 0;
|
|
102
|
-
}
|
|
@@ -7,24 +7,12 @@ describe("isLikeNumber", () => {
|
|
|
7
7
|
expect(isLikeNumber(value)).toBe(true);
|
|
8
8
|
});
|
|
9
9
|
|
|
10
|
-
it("value is a number", () => {
|
|
11
|
-
const value = 123.45;
|
|
12
|
-
|
|
13
|
-
expect(isLikeNumber(value)).toBe(true);
|
|
14
|
-
});
|
|
15
|
-
|
|
16
10
|
it("value is a string as number", () => {
|
|
17
11
|
const value = "123";
|
|
18
12
|
|
|
19
13
|
expect(isLikeNumber(value)).toBe(true);
|
|
20
14
|
});
|
|
21
15
|
|
|
22
|
-
it("value is a string as number", () => {
|
|
23
|
-
const value = "123.45";
|
|
24
|
-
|
|
25
|
-
expect(isLikeNumber(value)).toBe(true);
|
|
26
|
-
});
|
|
27
|
-
|
|
28
16
|
it("value is empty string", () => {
|
|
29
17
|
const value = "";
|
|
30
18
|
|
|
@@ -66,10 +54,4 @@ describe("isLikeNumber", () => {
|
|
|
66
54
|
|
|
67
55
|
expect(isLikeNumber(value)).toBe(false);
|
|
68
56
|
});
|
|
69
|
-
|
|
70
|
-
it("NaN is not a number", () => {
|
|
71
|
-
const value = NaN;
|
|
72
|
-
|
|
73
|
-
expect(isLikeNumber(value)).toBe(false);
|
|
74
|
-
});
|
|
75
57
|
});
|
package/numberUtils/index.ts
CHANGED
|
@@ -50,14 +50,27 @@ export const toFiniteNumberWithDefault = (
|
|
|
50
50
|
return possibleNumber;
|
|
51
51
|
};
|
|
52
52
|
|
|
53
|
-
export const isLikeNumber = (value:
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
if (R.isNil(possibleNumber)) {
|
|
53
|
+
export const isLikeNumber = (value: any): boolean => {
|
|
54
|
+
if (R.isEmpty(value)) {
|
|
57
55
|
return false;
|
|
58
56
|
}
|
|
59
57
|
|
|
60
|
-
|
|
58
|
+
if (R.is(Number, value)) {
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (R.is(String, value)) {
|
|
63
|
+
const onlyDigit = value
|
|
64
|
+
.split("")
|
|
65
|
+
.filter((char) =>
|
|
66
|
+
["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"].includes(char)
|
|
67
|
+
)
|
|
68
|
+
.join("");
|
|
69
|
+
|
|
70
|
+
return value === onlyDigit;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return false;
|
|
61
74
|
};
|
|
62
75
|
|
|
63
76
|
export const isZero = (value: unknown): boolean =>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applicaster/zapp-react-native-utils",
|
|
3
|
-
"version": "12.0.0-alpha.
|
|
3
|
+
"version": "12.0.0-alpha.4342066143",
|
|
4
4
|
"description": "Applicaster Zapp React Native utilities package",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
},
|
|
29
29
|
"homepage": "https://github.com/applicaster/quickbrick#readme",
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@applicaster/applicaster-types": "12.0.0-alpha.
|
|
31
|
+
"@applicaster/applicaster-types": "12.0.0-alpha.4342066143",
|
|
32
32
|
"buffer": "^5.2.1",
|
|
33
33
|
"camelize": "^1.0.0",
|
|
34
34
|
"create-react-context": "^0.2.3",
|