@applicaster/zapp-react-native-utils 15.0.0-alpha.3564377339 → 15.0.0-alpha.3642255793
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/adsUtils/__tests__/createVMAP.test.ts +419 -0
- package/analyticsUtils/analyticsMapper.ts +10 -2
- package/appDataUtils/__tests__/urlScheme.test.ts +678 -0
- package/appUtils/HooksManager/__tests__/__snapshots__/hooksManager.test.js.snap +0 -188
- package/appUtils/HooksManager/__tests__/hooksManager.test.js +16 -2
- package/appUtils/RiverFocusManager/{index.js → index.ts} +25 -18
- package/appUtils/contextKeysManager/__tests__/getKeys/failure.test.ts +7 -2
- package/appUtils/contextKeysManager/__tests__/getKeys/success.test.ts +48 -0
- package/appUtils/contextKeysManager/contextResolver.ts +51 -22
- package/appUtils/contextKeysManager/index.ts +65 -10
- package/appUtils/focusManager/__tests__/__snapshots__/focusManager.test.js.snap +3 -0
- package/appUtils/focusManager/index.ios.ts +37 -4
- package/appUtils/focusManagerAux/utils/index.ios.ts +122 -0
- package/appUtils/focusManagerAux/utils/utils.ios.ts +150 -11
- package/cloudEventsUtils/__tests__/index.test.ts +529 -0
- package/cloudEventsUtils/index.ts +65 -1
- package/configurationUtils/__tests__/imageSrcFromMediaItem.test.ts +38 -0
- package/configurationUtils/index.ts +17 -11
- package/dateUtils/__tests__/dayjs.test.ts +330 -0
- package/enumUtils/__tests__/getEnumKeyByEnumValue.test.ts +207 -0
- package/errorUtils/__tests__/GeneralError.test.ts +97 -0
- package/errorUtils/__tests__/HttpStatusCode.test.ts +344 -0
- package/errorUtils/__tests__/MissingPluginError.test.ts +113 -0
- package/errorUtils/__tests__/NetworkError.test.ts +202 -0
- package/errorUtils/__tests__/getParsedResponse.test.ts +188 -0
- package/errorUtils/__tests__/invariant.test.ts +112 -0
- package/headersUtils/__tests__/headersUtils.test.js +11 -1
- package/headersUtils/index.ts +2 -1
- package/manifestUtils/defaultManifestConfigurations/player.js +50 -10
- package/navigationUtils/index.ts +15 -5
- package/numberUtils/__tests__/toNumber.test.ts +12 -0
- package/numberUtils/__tests__/toPositiveNumber.test.ts +165 -0
- package/numberUtils/index.ts +19 -1
- package/package.json +4 -4
- package/reactHooks/app/__tests__/useAppState.test.ts +1 -1
- package/reactHooks/autoscrolling/__tests__/useTrackCurrentAutoScrollingElement.test.ts +1 -1
- package/reactHooks/autoscrolling/__tests__/useTrackedView.test.tsx +1 -2
- package/reactHooks/cell-click/__tests__/index.test.js +1 -3
- package/reactHooks/configuration/__tests__/index.test.tsx +1 -1
- package/reactHooks/connection/__tests__/index.test.js +1 -1
- package/reactHooks/feed/__tests__/useBatchLoading.test.tsx +32 -23
- package/reactHooks/feed/__tests__/useBuildPipesUrl.test.tsx +19 -19
- package/reactHooks/feed/__tests__/useEntryScreenId.test.tsx +1 -1
- package/reactHooks/feed/__tests__/useFeedLoader.test.tsx +42 -30
- package/reactHooks/feed/__tests__/useFeedRefresh.test.tsx +1 -1
- package/reactHooks/feed/__tests__/useInflatedUrl.test.tsx +1 -1
- package/reactHooks/hookModal/hooks/useHookModalScreenData.ts +12 -8
- package/reactHooks/layout/__tests__/index.test.tsx +1 -1
- package/reactHooks/layout/__tests__/useLayoutVersion.test.tsx +1 -1
- package/reactHooks/navigation/__tests__/index.test.tsx +40 -9
- package/reactHooks/navigation/index.ts +19 -4
- package/reactHooks/navigation/useRoute.ts +3 -1
- package/reactHooks/player/__tests__/useAutoSeek._test.tsx +1 -1
- package/reactHooks/player/__tests__/useTapSeek._test.ts +1 -1
- package/reactHooks/resolvers/__tests__/useCellResolver.test.tsx +1 -1
- package/reactHooks/resolvers/__tests__/useComponentResolver.test.tsx +1 -1
- package/reactHooks/screen/__tests__/useCurrentScreenData.test.tsx +2 -2
- package/reactHooks/screen/__tests__/useScreenBackgroundColor.test.tsx +1 -1
- package/reactHooks/screen/__tests__/useScreenData.test.tsx +1 -1
- package/reactHooks/screen/__tests__/useTargetScreenData.test.tsx +2 -2
- package/reactHooks/state/useRefWithInitialValue.ts +10 -0
- package/reactHooks/utils/__tests__/index.test.js +1 -1
- package/screenState/__tests__/index.test.ts +1 -1
- package/searchUtils/const.ts +7 -0
- package/searchUtils/index.ts +3 -0
- package/services/storageServiceSync.web.ts +1 -1
- package/stringUtils/index.ts +1 -1
- package/testUtils/index.tsx +1 -1
- package/utils/__tests__/mergeRight.test.ts +48 -0
- package/utils/index.ts +3 -0
- package/utils/mergeRight.ts +5 -0
|
@@ -4,7 +4,11 @@ import * as R from "ramda";
|
|
|
4
4
|
import {
|
|
5
5
|
isCurrentFocusOn,
|
|
6
6
|
isChildOf as isChildOfUtils,
|
|
7
|
-
|
|
7
|
+
isPartOfMenu,
|
|
8
|
+
isPartOfContent,
|
|
9
|
+
isPartOfTabsScreenContent,
|
|
10
|
+
} from "../focusManagerAux/utils/index.ios";
|
|
11
|
+
|
|
8
12
|
import { Tree } from "./treeDataStructure/Tree";
|
|
9
13
|
import { findFocusableNode } from "./treeDataStructure/Utils";
|
|
10
14
|
import { subscriber } from "../../functionUtils";
|
|
@@ -194,9 +198,9 @@ export const focusManager = (function () {
|
|
|
194
198
|
registerItem(id, component);
|
|
195
199
|
}
|
|
196
200
|
|
|
197
|
-
const
|
|
201
|
+
const groupId = component?.props?.groupId;
|
|
198
202
|
|
|
199
|
-
emitRegistered({ id,
|
|
203
|
+
emitRegistered({ id, groupId, isGroup });
|
|
200
204
|
}
|
|
201
205
|
|
|
202
206
|
function unregister(id, { group = false } = {}) {
|
|
@@ -279,7 +283,9 @@ export const focusManager = (function () {
|
|
|
279
283
|
function setFocus(
|
|
280
284
|
id: string,
|
|
281
285
|
direction?: FocusManager.IOS.Direction,
|
|
282
|
-
options?: Partial<{
|
|
286
|
+
options?: Partial<{
|
|
287
|
+
groupFocusedChanged: boolean;
|
|
288
|
+
}>,
|
|
283
289
|
callback?: any
|
|
284
290
|
) {
|
|
285
291
|
blur(direction);
|
|
@@ -418,6 +424,30 @@ export const focusManager = (function () {
|
|
|
418
424
|
return id && isCurrentFocusOn(id, currentFocusNode);
|
|
419
425
|
}
|
|
420
426
|
|
|
427
|
+
function isFocusOnMenu(): boolean {
|
|
428
|
+
const currentFocusable = getCurrentFocus();
|
|
429
|
+
|
|
430
|
+
return isPartOfMenu(focusableTree, currentFocusable?.props?.id);
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
function isFocusOnContent(): boolean {
|
|
434
|
+
const currentFocusable = getCurrentFocus();
|
|
435
|
+
|
|
436
|
+
return isPartOfContent(focusableTree, currentFocusable?.props?.id);
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
function isFocusOnTabsScreenContent(
|
|
440
|
+
screenPickerContentContainerId: string
|
|
441
|
+
): boolean {
|
|
442
|
+
const currentFocusable = getCurrentFocus();
|
|
443
|
+
|
|
444
|
+
return isPartOfTabsScreenContent(
|
|
445
|
+
focusableTree,
|
|
446
|
+
screenPickerContentContainerId,
|
|
447
|
+
currentFocusable?.props?.id
|
|
448
|
+
);
|
|
449
|
+
}
|
|
450
|
+
|
|
421
451
|
function isChildOf(childId, parentId): boolean {
|
|
422
452
|
return isChildOfUtils(focusableTree, childId, parentId);
|
|
423
453
|
}
|
|
@@ -444,6 +474,9 @@ export const focusManager = (function () {
|
|
|
444
474
|
isGroupItemFocused,
|
|
445
475
|
getPreferredFocusChild,
|
|
446
476
|
isFocusOn,
|
|
477
|
+
isFocusOnMenu,
|
|
478
|
+
isFocusOnContent,
|
|
479
|
+
isFocusOnTabsScreenContent,
|
|
447
480
|
isChildOf,
|
|
448
481
|
};
|
|
449
482
|
})();
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { isNil, startsWith } from "@applicaster/zapp-react-native-utils/utils";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
QUICK_BRICK_CONTENT,
|
|
5
|
+
QUICK_BRICK_NAVBAR,
|
|
6
|
+
} from "@applicaster/quick-brick-core/const";
|
|
7
|
+
|
|
8
|
+
const isNavBar = (node) => startsWith(QUICK_BRICK_NAVBAR, node?.id);
|
|
9
|
+
const isContent = (node) => startsWith(QUICK_BRICK_CONTENT, node?.id);
|
|
10
|
+
const isRoot = (node) => node?.id === "root";
|
|
11
|
+
|
|
12
|
+
export const isPartOfTabsScreenContent = (
|
|
13
|
+
focusableTree,
|
|
14
|
+
screenPickerContentContainerId,
|
|
15
|
+
id
|
|
16
|
+
) => {
|
|
17
|
+
const node = focusableTree.findInTree(id);
|
|
18
|
+
|
|
19
|
+
if (isNil(node)) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (isRoot(node)) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (isNavBar(node)) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (isContent(node)) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (node?.id === screenPickerContentContainerId) {
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return isPartOfTabsScreenContent(
|
|
40
|
+
focusableTree,
|
|
41
|
+
screenPickerContentContainerId,
|
|
42
|
+
node.parent?.id
|
|
43
|
+
);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export const isPartOfMenu = (focusableTree, id): boolean => {
|
|
47
|
+
const node = focusableTree.findInTree(id);
|
|
48
|
+
|
|
49
|
+
if (isNil(node)) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (isRoot(node)) {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (isNavBar(node)) {
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (isContent(node)) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return isPartOfMenu(focusableTree, node.parent?.id);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export const isPartOfContent = (focusableTree, id) => {
|
|
69
|
+
const node = focusableTree.findInTree(id);
|
|
70
|
+
|
|
71
|
+
if (isNil(node)) {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (isRoot(node)) {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (isNavBar(node)) {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (isContent(node)) {
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return isPartOfContent(focusableTree, node.parent?.id);
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export const isCurrentFocusOn = (id, node) => {
|
|
91
|
+
if (!node) {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (isRoot(node)) {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (node?.id === id) {
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return isCurrentFocusOn(id, node.parent);
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
export const isChildOf = (focusableTree, childId, parentId) => {
|
|
107
|
+
if (isNil(childId) || isNil(parentId)) {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const childNode = focusableTree.findInTree(childId);
|
|
112
|
+
|
|
113
|
+
if (isNil(childNode)) {
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (childNode.parent?.id === parentId) {
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return isChildOf(focusableTree, childNode.parent?.id, parentId);
|
|
122
|
+
};
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { ReplaySubject, Subject } from "rxjs";
|
|
2
|
-
import { filter, switchMap, take } from "rxjs/operators";
|
|
2
|
+
import { filter, switchMap, take, withLatestFrom, map } from "rxjs/operators";
|
|
3
|
+
|
|
3
4
|
import { BUTTON_PREFIX } from "@applicaster/zapp-react-native-ui-components/Components/MasterCell/DefaultComponents/tv/TvActionButtons/const";
|
|
4
5
|
import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils/focusManager/index.ios";
|
|
6
|
+
import { isPartOfMenu, isPartOfContent } from "./index.ios";
|
|
5
7
|
|
|
6
8
|
type FocusableID = string;
|
|
7
9
|
type RegistrationEvent = {
|
|
@@ -11,13 +13,23 @@ type RegistrationEvent = {
|
|
|
11
13
|
|
|
12
14
|
let focusableViewRegistrationSubject$ = new Subject<{
|
|
13
15
|
id: FocusableID;
|
|
14
|
-
|
|
16
|
+
groupId: FocusableID;
|
|
15
17
|
}>();
|
|
16
18
|
|
|
17
19
|
let focusableGroupRegistrationSubject$ = new ReplaySubject<{
|
|
18
20
|
id: FocusableID;
|
|
19
21
|
}>();
|
|
20
22
|
|
|
23
|
+
let focusableNativeViewRegistrationSubject$ = new Subject<{
|
|
24
|
+
id: FocusableID;
|
|
25
|
+
groupId: FocusableID;
|
|
26
|
+
}>();
|
|
27
|
+
|
|
28
|
+
let focusableNativeGroupRegistrationSubject$ = new ReplaySubject<{
|
|
29
|
+
id: FocusableID;
|
|
30
|
+
groupId: FocusableID;
|
|
31
|
+
}>();
|
|
32
|
+
|
|
21
33
|
const isFocusableButton = (id: Option<FocusableID>): boolean =>
|
|
22
34
|
id && id.includes?.(BUTTON_PREFIX);
|
|
23
35
|
|
|
@@ -41,35 +53,90 @@ export const resetFocusableRegistration = () => {
|
|
|
41
53
|
focusableGroupRegistrationSubject$.complete();
|
|
42
54
|
}
|
|
43
55
|
|
|
56
|
+
if (!focusableNativeViewRegistrationSubject$.closed) {
|
|
57
|
+
focusableNativeViewRegistrationSubject$.complete();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (!focusableNativeGroupRegistrationSubject$.closed) {
|
|
61
|
+
focusableNativeGroupRegistrationSubject$.complete();
|
|
62
|
+
}
|
|
63
|
+
|
|
44
64
|
focusableViewRegistrationSubject$ = new Subject<{
|
|
45
65
|
id: FocusableID;
|
|
46
|
-
|
|
66
|
+
groupId: FocusableID;
|
|
47
67
|
}>();
|
|
48
68
|
|
|
49
69
|
focusableGroupRegistrationSubject$ = new ReplaySubject<{
|
|
50
70
|
id: FocusableID;
|
|
51
71
|
}>();
|
|
72
|
+
|
|
73
|
+
focusableNativeViewRegistrationSubject$ = new Subject<{
|
|
74
|
+
id: FocusableID;
|
|
75
|
+
groupId: FocusableID;
|
|
76
|
+
}>();
|
|
77
|
+
|
|
78
|
+
focusableNativeGroupRegistrationSubject$ = new ReplaySubject<{
|
|
79
|
+
id: FocusableID;
|
|
80
|
+
groupId: FocusableID;
|
|
81
|
+
}>();
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const focusableNativeViewRegistration = ({ focusableView, focusableGroup }) => {
|
|
85
|
+
return focusableNativeViewRegistrationSubject$.pipe(
|
|
86
|
+
filter(
|
|
87
|
+
(focusableNativeView) => focusableNativeView.id === focusableView.id
|
|
88
|
+
),
|
|
89
|
+
take(1),
|
|
90
|
+
switchMap((focusableNativeView) =>
|
|
91
|
+
// start waiting registration of its parent FocusableNativeGroup
|
|
92
|
+
focusableNativeGroupRegistrationSubject$.pipe(
|
|
93
|
+
filter(
|
|
94
|
+
(focusableNativeGroup) =>
|
|
95
|
+
focusableNativeGroup.id === focusableNativeView.groupId
|
|
96
|
+
),
|
|
97
|
+
take(1),
|
|
98
|
+
map((focusableNativeGroup) => ({
|
|
99
|
+
focusableNativeGroup,
|
|
100
|
+
focusableNativeView,
|
|
101
|
+
focusableView,
|
|
102
|
+
focusableGroup,
|
|
103
|
+
}))
|
|
104
|
+
)
|
|
105
|
+
)
|
|
106
|
+
);
|
|
52
107
|
};
|
|
53
108
|
|
|
54
109
|
export const firstFocusableViewRegistrationFactory = () =>
|
|
55
110
|
focusableViewRegistrationSubject$.pipe(
|
|
56
111
|
take(1), // we care about only first FocusableView registration
|
|
57
|
-
switchMap((
|
|
58
|
-
// start waiting registration of its parent
|
|
112
|
+
switchMap((focusableView) =>
|
|
113
|
+
// start waiting registration of its parent FocusableGroup
|
|
59
114
|
focusableGroupRegistrationSubject$.pipe(
|
|
60
|
-
filter((
|
|
115
|
+
filter((focusableGroup) => focusableGroup.id === focusableView.groupId),
|
|
116
|
+
take(1),
|
|
117
|
+
map((focusableGroup) => ({
|
|
118
|
+
focusableView,
|
|
119
|
+
focusableGroup,
|
|
120
|
+
}))
|
|
61
121
|
)
|
|
62
122
|
),
|
|
63
|
-
|
|
123
|
+
// start waiting registration for FocusableNativeView and its parent FocusableNativeGroup
|
|
124
|
+
switchMap(({ focusableView, focusableGroup }) =>
|
|
125
|
+
focusableNativeViewRegistration({
|
|
126
|
+
focusableView,
|
|
127
|
+
focusableGroup,
|
|
128
|
+
})
|
|
129
|
+
)
|
|
64
130
|
);
|
|
65
131
|
|
|
132
|
+
// registration on RN level(into RN focusManager)
|
|
66
133
|
export const emitRegistered = ({
|
|
67
134
|
id,
|
|
68
|
-
|
|
135
|
+
groupId,
|
|
69
136
|
isGroup,
|
|
70
137
|
}: {
|
|
71
138
|
id: Option<FocusableID>;
|
|
72
|
-
|
|
139
|
+
groupId: Option<FocusableID>;
|
|
73
140
|
isGroup: boolean;
|
|
74
141
|
}): void => {
|
|
75
142
|
if (isFocusableButton(id)) {
|
|
@@ -80,13 +147,85 @@ export const emitRegistered = ({
|
|
|
80
147
|
focusableGroupRegistrationSubject$.next({ id });
|
|
81
148
|
}
|
|
82
149
|
|
|
83
|
-
if (!isGroup && id &&
|
|
84
|
-
focusableViewRegistrationSubject$.next({ id,
|
|
150
|
+
if (!isGroup && id && groupId) {
|
|
151
|
+
focusableViewRegistrationSubject$.next({ id, groupId });
|
|
85
152
|
}
|
|
86
153
|
};
|
|
87
154
|
|
|
155
|
+
// unregistration on RN level(into RN focusManager)
|
|
88
156
|
export const emitUnregistered = (id: Option<FocusableID>): void => {
|
|
89
157
|
if (isFocusableButton(id)) {
|
|
90
158
|
registeredSubject$.next({ id, registered: false });
|
|
91
159
|
}
|
|
92
160
|
};
|
|
161
|
+
|
|
162
|
+
// registration focusableNativeView and focusableNativeGroup
|
|
163
|
+
export const emitNativeRegistered = ({
|
|
164
|
+
id,
|
|
165
|
+
groupId,
|
|
166
|
+
isGroup,
|
|
167
|
+
}: {
|
|
168
|
+
id: Option<FocusableID>;
|
|
169
|
+
groupId: Option<FocusableID>;
|
|
170
|
+
isGroup: boolean;
|
|
171
|
+
}): void => {
|
|
172
|
+
if (!isGroup && id && groupId) {
|
|
173
|
+
focusableNativeViewRegistrationSubject$.next({ id, groupId });
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (isGroup && id && groupId) {
|
|
177
|
+
focusableNativeGroupRegistrationSubject$.next({ id, groupId });
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
// /////
|
|
182
|
+
|
|
183
|
+
const focusedSubject$ = new Subject<FocusableID>();
|
|
184
|
+
|
|
185
|
+
const focused$ = focusedSubject$.asObservable();
|
|
186
|
+
|
|
187
|
+
export const emitFocused = (id: FocusableID): void => {
|
|
188
|
+
focusedSubject$.next(id);
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
export const topMenuItemFocused$ = focused$.pipe(
|
|
192
|
+
filter((id) => id && isPartOfMenu(focusManager.focusableTree, id))
|
|
193
|
+
);
|
|
194
|
+
|
|
195
|
+
export const contentFocused$ = focused$.pipe(
|
|
196
|
+
filter((id) => {
|
|
197
|
+
const isContent = isPartOfContent(focusManager.focusableTree, id);
|
|
198
|
+
|
|
199
|
+
return id && isContent;
|
|
200
|
+
})
|
|
201
|
+
);
|
|
202
|
+
|
|
203
|
+
const createFocusableRegistry = () => {
|
|
204
|
+
const subject$ = new ReplaySubject<FocusableID | undefined>(1);
|
|
205
|
+
|
|
206
|
+
return {
|
|
207
|
+
observable$: subject$.asObservable(),
|
|
208
|
+
register: (id: FocusableID) => {
|
|
209
|
+
// save focusable_id on registration
|
|
210
|
+
subject$.next(id);
|
|
211
|
+
},
|
|
212
|
+
unregister: () => {
|
|
213
|
+
// reset focusable_id on unregistration
|
|
214
|
+
subject$.next(undefined);
|
|
215
|
+
},
|
|
216
|
+
};
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
/// HOME_TOP_MENU_ITEM
|
|
220
|
+
export const HomeTopMenuItemRegistry = createFocusableRegistry();
|
|
221
|
+
|
|
222
|
+
export const homeTopMenuItemFocused$ = topMenuItemFocused$.pipe(
|
|
223
|
+
withLatestFrom(HomeTopMenuItemRegistry.observable$),
|
|
224
|
+
filter(([id, homeId]) => id === homeId)
|
|
225
|
+
);
|
|
226
|
+
|
|
227
|
+
/// SCREEN_PICKER
|
|
228
|
+
export const ScreenPickerContentContainerRegistry = createFocusableRegistry();
|
|
229
|
+
|
|
230
|
+
/// SEARCH_INPUT
|
|
231
|
+
export const SearchInputRegistry = createFocusableRegistry();
|