@applicaster/zapp-react-native-utils 13.0.0-alpha.1692038547 → 13.0.0-alpha.1724095599
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/README.md +0 -10
- package/appUtils/contextKeysManager/index.ts +2 -2
- package/appUtils/contextKeysManager/utils/index.ts +2 -1
- package/appUtils/platform/platformUtils.ts +6 -0
- package/equalUtils/__tests__/isEqual/combination.test.ts +263 -0
- package/equalUtils/index.ts +49 -30
- package/focusManager/FocusManager.ts +14 -28
- package/focusManager/index.ts +41 -4
- package/manifestUtils/sharedConfiguration/screenPicker/__tests__/utils.test.js +304 -0
- package/manifestUtils/sharedConfiguration/screenPicker/stylesFields.js +875 -0
- package/manifestUtils/sharedConfiguration/screenPicker/utils.js +130 -0
- package/package.json +4 -6
- package/reactHooks/navigation/__mocks__/useNavigation.ts +3 -0
- package/reactHooks/navigation/index.ts +7 -19
- package/reactHooks/navigation/useProfilerLogging.ts +15 -0
- package/reactUtils/__tests__/__snapshots__/reactUtilsHelpers.test.js.snap +16 -4
- package/reactUtils/__tests__/reactUtils.test.js +1 -19
- package/reactUtils/__tests__/reactUtilsHelpers.test.js +72 -71
- package/reactUtils/createContext/__tests__/__snapshots__/helpers.test.js.snap +6 -72
- package/reactUtils/createContext/__tests__/__snapshots__/provider.test.js.snap +3 -28
- package/reactUtils/createContext/__tests__/__snapshots__/withConsumer.test.js.snap +3 -4
- package/reactUtils/createContext/__tests__/__snapshots__/withProvider.test.js.snap +7 -3
- package/reactUtils/createContext/__tests__/helpers.test.js +107 -121
- package/reactUtils/createContext/__tests__/{index.test.js → index.test.ts} +2 -2
- package/reactUtils/createContext/__tests__/provider.test.js +4 -6
- package/reactUtils/createContext/__tests__/withConsumer.test.js +12 -12
- package/reactUtils/createContext/__tests__/withProvider.test.js +4 -4
- package/reactUtils/createContext/helpers.ts +6 -1
- package/reactUtils/createContext/index.ts +11 -25
- package/reactUtils/index.ts +0 -11
- package/testUtils/index.tsx +0 -10
- package/reactUtils/createContext/__tests__/index-no-react.test.js +0 -27
- /package/reactUtils/createContext/__tests__/__snapshots__/{index.test.js.snap → index.test.ts.snap} +0 -0
package/README.md
CHANGED
|
@@ -376,16 +376,6 @@ useEffect(() => {
|
|
|
376
376
|
}, []);
|
|
377
377
|
```
|
|
378
378
|
|
|
379
|
-
### testUtils
|
|
380
|
-
|
|
381
|
-
`@applicaster/zapp-react-native-utils/testUtils`
|
|
382
|
-
|
|
383
|
-
- `testIDEquals: (testId: any) => boolean | { width: number, height: number }` - Function to be used in tandem with enzyme findWhere
|
|
384
|
-
|
|
385
|
-
```javascript
|
|
386
|
-
wrapper.findWhere(testIDEquals("text"));
|
|
387
|
-
```
|
|
388
|
-
|
|
389
379
|
### appUtils - contextKeysManager
|
|
390
380
|
|
|
391
381
|
`@applicaster/zapp-react-native-utils/appUtils/contextKeyManager`
|
|
@@ -16,12 +16,12 @@ import {
|
|
|
16
16
|
|
|
17
17
|
export { StorageLevel };
|
|
18
18
|
|
|
19
|
-
type KeyNameObj = {
|
|
19
|
+
export type KeyNameObj = {
|
|
20
20
|
namespace: string;
|
|
21
21
|
key: string;
|
|
22
22
|
};
|
|
23
23
|
|
|
24
|
-
type KeyName = string | KeyNameObj;
|
|
24
|
+
export type KeyName = string | KeyNameObj;
|
|
25
25
|
|
|
26
26
|
type ParsedKeyAndNamespace = {
|
|
27
27
|
namespace?: string;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import * as R from "ramda";
|
|
2
2
|
import { DEFAULT_NAMESPACE } from "../consts";
|
|
3
|
+
import { KeyName, KeyNameObj } from "../index";
|
|
3
4
|
|
|
4
5
|
const lastDotRegex = /\.([^.]+)$/;
|
|
5
6
|
const splitByLastDot = R.compose(R.init, R.split(lastDotRegex));
|
|
6
7
|
|
|
7
|
-
export function getNamespaceAndKey(namespacedKey) {
|
|
8
|
+
export function getNamespaceAndKey(namespacedKey: KeyName): KeyNameObj {
|
|
8
9
|
if (typeof namespacedKey !== "string") return namespacedKey;
|
|
9
10
|
|
|
10
11
|
const namespacedKeyProps = namespacedKey.includes(".")
|
|
@@ -77,6 +77,12 @@ export class ClosedCaptioningManager {
|
|
|
77
77
|
|
|
78
78
|
private constructor() {
|
|
79
79
|
this.initialize();
|
|
80
|
+
|
|
81
|
+
window["vizioDebug"] = {
|
|
82
|
+
setCCEnabled: (isCCEnabled: boolean) => {
|
|
83
|
+
this.ccState$.next(isCCEnabled);
|
|
84
|
+
},
|
|
85
|
+
};
|
|
80
86
|
}
|
|
81
87
|
|
|
82
88
|
static getInstance(): ClosedCaptioningManager {
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import { isEqual } from "../..";
|
|
2
|
+
|
|
3
|
+
const array = [1, 2, 3];
|
|
4
|
+
const sameProp = "sameProp";
|
|
5
|
+
|
|
6
|
+
describe("isEqual - comprehensive tests", () => {
|
|
7
|
+
describe("all conditions together", () => {
|
|
8
|
+
it("all conditions checked and not equal", () => {
|
|
9
|
+
const prev = {
|
|
10
|
+
byValueProp: { a: 1, b: 2 },
|
|
11
|
+
byRefProp: array,
|
|
12
|
+
byComparatorProp: "test",
|
|
13
|
+
extraProp1: 123,
|
|
14
|
+
extraProp2: sameProp,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const next = {
|
|
18
|
+
byValueProp: { a: 1, b: 2 },
|
|
19
|
+
byRefProp: array,
|
|
20
|
+
byComparatorProp: "different",
|
|
21
|
+
extraProp1: 456,
|
|
22
|
+
extraProp2: sameProp,
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const customComparator = jest.fn().mockReturnValue(true);
|
|
26
|
+
|
|
27
|
+
const result = isEqual({
|
|
28
|
+
byValue: ["byValueProp"],
|
|
29
|
+
byReference: ["byRefProp"],
|
|
30
|
+
byComparator: {
|
|
31
|
+
comparator: customComparator,
|
|
32
|
+
keys: ["byComparatorProp"],
|
|
33
|
+
},
|
|
34
|
+
compareRemainingKeysBySameValue: true,
|
|
35
|
+
})(prev, next);
|
|
36
|
+
|
|
37
|
+
expect(result).toBe(false);
|
|
38
|
+
|
|
39
|
+
expect(customComparator).toHaveBeenCalledWith(
|
|
40
|
+
prev.byComparatorProp,
|
|
41
|
+
next.byComparatorProp
|
|
42
|
+
);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it("all conditions pass with exact remaining keys check", () => {
|
|
46
|
+
const prev = {
|
|
47
|
+
byValueProp: { a: 1, b: 2 },
|
|
48
|
+
byRefProp: array,
|
|
49
|
+
byComparatorProp: "test",
|
|
50
|
+
extraProp: sameProp,
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const next = {
|
|
54
|
+
byValueProp: { a: 1, b: 2 },
|
|
55
|
+
byRefProp: array,
|
|
56
|
+
byComparatorProp: "test",
|
|
57
|
+
extraProp: sameProp,
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const customComparator = jest.fn().mockReturnValue(true);
|
|
61
|
+
|
|
62
|
+
const result = isEqual({
|
|
63
|
+
byValue: ["byValueProp"],
|
|
64
|
+
byReference: ["byRefProp"],
|
|
65
|
+
byComparator: {
|
|
66
|
+
comparator: customComparator,
|
|
67
|
+
keys: ["byComparatorProp"],
|
|
68
|
+
},
|
|
69
|
+
compareRemainingKeysBySameValue: true,
|
|
70
|
+
})(prev, next);
|
|
71
|
+
|
|
72
|
+
expect(result).toBe(true);
|
|
73
|
+
|
|
74
|
+
expect(customComparator).toHaveBeenCalledWith(
|
|
75
|
+
prev.byComparatorProp,
|
|
76
|
+
next.byComparatorProp
|
|
77
|
+
);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it("byReference check fails first (early return)", () => {
|
|
81
|
+
const prev = {
|
|
82
|
+
byValueProp: { a: 1, b: 2 },
|
|
83
|
+
byRefProp: array,
|
|
84
|
+
byComparatorProp: sameProp,
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const next = {
|
|
88
|
+
byValueProp: { a: 1, b: 2 },
|
|
89
|
+
byRefProp: [1, 2, 3],
|
|
90
|
+
byComparatorProp: sameProp,
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const customComparator = jest.fn().mockReturnValue(true);
|
|
94
|
+
|
|
95
|
+
const result = isEqual({
|
|
96
|
+
byValue: ["byValueProp"],
|
|
97
|
+
byReference: ["byRefProp"],
|
|
98
|
+
byComparator: {
|
|
99
|
+
comparator: customComparator,
|
|
100
|
+
keys: ["byComparatorProp"],
|
|
101
|
+
},
|
|
102
|
+
})(prev, next);
|
|
103
|
+
|
|
104
|
+
expect(result).toBe(false);
|
|
105
|
+
expect(customComparator).not.toHaveBeenCalled();
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it("byValue check fails after byReference passes", () => {
|
|
109
|
+
const prev = {
|
|
110
|
+
byValueProp: { a: 1, b: 2 },
|
|
111
|
+
byRefProp: array,
|
|
112
|
+
byComparatorProp: sameProp,
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
const next = {
|
|
116
|
+
byValueProp: { a: 1, b: 3 },
|
|
117
|
+
byRefProp: array,
|
|
118
|
+
byComparatorProp: sameProp,
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
const customComparator = jest.fn().mockReturnValue(true);
|
|
122
|
+
|
|
123
|
+
const result = isEqual({
|
|
124
|
+
byValue: ["byValueProp"],
|
|
125
|
+
byReference: ["byRefProp"],
|
|
126
|
+
byComparator: {
|
|
127
|
+
comparator: customComparator,
|
|
128
|
+
keys: ["byComparatorProp"],
|
|
129
|
+
},
|
|
130
|
+
})(prev, next);
|
|
131
|
+
|
|
132
|
+
expect(result).toBe(false);
|
|
133
|
+
expect(customComparator).not.toHaveBeenCalled();
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it("byComparator check fails after other checks pass", () => {
|
|
137
|
+
const prev = {
|
|
138
|
+
byValueProp: { a: 1, b: 2 },
|
|
139
|
+
byRefProp: array,
|
|
140
|
+
byComparatorProp: "test",
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
const next = {
|
|
144
|
+
byValueProp: { a: 1, b: 2 },
|
|
145
|
+
byRefProp: array,
|
|
146
|
+
byComparatorProp: "different",
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
const customComparator = jest.fn().mockReturnValue(false);
|
|
150
|
+
|
|
151
|
+
const result = isEqual({
|
|
152
|
+
byValue: ["byValueProp"],
|
|
153
|
+
byReference: ["byRefProp"],
|
|
154
|
+
byComparator: {
|
|
155
|
+
comparator: customComparator,
|
|
156
|
+
keys: ["byComparatorProp"],
|
|
157
|
+
},
|
|
158
|
+
})(prev, next);
|
|
159
|
+
|
|
160
|
+
expect(result).toBe(false);
|
|
161
|
+
|
|
162
|
+
expect(customComparator).toHaveBeenCalledWith(
|
|
163
|
+
prev.byComparatorProp,
|
|
164
|
+
next.byComparatorProp
|
|
165
|
+
);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it("remaining keys comparison fails", () => {
|
|
169
|
+
const sharedArray = [1, 2, 3];
|
|
170
|
+
|
|
171
|
+
const prev = {
|
|
172
|
+
byValueProp: { a: 1, b: 2 },
|
|
173
|
+
byRefProp: sharedArray,
|
|
174
|
+
byComparatorProp: "test",
|
|
175
|
+
extraProp: "original",
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
const next = {
|
|
179
|
+
byValueProp: { a: 1, b: 2 },
|
|
180
|
+
byRefProp: sharedArray,
|
|
181
|
+
byComparatorProp: "different",
|
|
182
|
+
extraProp: "changed",
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
const customComparator = jest.fn().mockReturnValue(true);
|
|
186
|
+
|
|
187
|
+
const result = isEqual({
|
|
188
|
+
byValue: ["byValueProp"],
|
|
189
|
+
byReference: ["byRefProp"],
|
|
190
|
+
byComparator: {
|
|
191
|
+
comparator: customComparator,
|
|
192
|
+
keys: ["byComparatorProp"],
|
|
193
|
+
},
|
|
194
|
+
compareRemainingKeysBySameValue: true,
|
|
195
|
+
})(prev, next);
|
|
196
|
+
|
|
197
|
+
expect(result).toBe(false);
|
|
198
|
+
expect(customComparator).toHaveBeenCalled();
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
it("with debug flag", () => {
|
|
202
|
+
const consoleSpy = jest.spyOn(console, "log").mockImplementation();
|
|
203
|
+
|
|
204
|
+
const prev = {
|
|
205
|
+
byValueProp: { a: 1, b: 2 },
|
|
206
|
+
byRefProp: array,
|
|
207
|
+
byComparatorProp: "test",
|
|
208
|
+
extraProp: sameProp,
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
const next = {
|
|
212
|
+
byValueProp: { a: 1, b: 2 },
|
|
213
|
+
byRefProp: array,
|
|
214
|
+
byComparatorProp: "different",
|
|
215
|
+
extraProp: sameProp,
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
const customComparator = jest.fn().mockReturnValue(true);
|
|
219
|
+
|
|
220
|
+
const result = isEqual({
|
|
221
|
+
byValue: ["byValueProp"],
|
|
222
|
+
byReference: ["byRefProp"],
|
|
223
|
+
byComparator: {
|
|
224
|
+
comparator: customComparator,
|
|
225
|
+
keys: ["byComparatorProp"],
|
|
226
|
+
},
|
|
227
|
+
compareRemainingKeysBySameValue: true,
|
|
228
|
+
debug: true,
|
|
229
|
+
})(prev, next);
|
|
230
|
+
|
|
231
|
+
expect(result).toBe(true);
|
|
232
|
+
expect(consoleSpy).toHaveBeenCalled();
|
|
233
|
+
|
|
234
|
+
consoleSpy.mockRestore();
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
it("handles missing properties", () => {
|
|
238
|
+
const prev = {
|
|
239
|
+
byValueProp: { a: 1, b: 2 },
|
|
240
|
+
byRefProp: [1, 2, 3],
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
const next = {
|
|
244
|
+
byValueProp: { a: 1, b: 2 },
|
|
245
|
+
byComparatorProp: "test",
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
const customComparator = jest.fn().mockReturnValue(true);
|
|
249
|
+
|
|
250
|
+
const result = isEqual({
|
|
251
|
+
byValue: ["byValueProp"],
|
|
252
|
+
byReference: ["byRefProp"],
|
|
253
|
+
byComparator: {
|
|
254
|
+
comparator: customComparator,
|
|
255
|
+
keys: ["byComparatorProp"],
|
|
256
|
+
},
|
|
257
|
+
})(prev, next);
|
|
258
|
+
|
|
259
|
+
expect(result).toBe(false);
|
|
260
|
+
expect(customComparator).not.toHaveBeenCalled();
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
});
|
package/equalUtils/index.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/* eslint no-console: off */
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import { equals } from "ramda";
|
|
4
|
+
|
|
5
|
+
const alwaysTrue = () => true;
|
|
4
6
|
|
|
5
7
|
export const isParentFocusEqual = (
|
|
6
8
|
prevParentFocus: ParentFocus,
|
|
@@ -18,7 +20,7 @@ export const isEqual =
|
|
|
18
20
|
({
|
|
19
21
|
byValue = [],
|
|
20
22
|
byReference = [],
|
|
21
|
-
byComparator = { comparator:
|
|
23
|
+
byComparator = { comparator: alwaysTrue, keys: [] },
|
|
22
24
|
debug = false,
|
|
23
25
|
compareRemainingKeysBySameValue = false,
|
|
24
26
|
}: {
|
|
@@ -29,42 +31,59 @@ export const isEqual =
|
|
|
29
31
|
compareRemainingKeysBySameValue?: boolean;
|
|
30
32
|
}) =>
|
|
31
33
|
(prev, next) => {
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
for (const key of byReference) {
|
|
35
|
+
if (prev[key] !== next[key]) {
|
|
36
|
+
if (debug) console.log({ isEqualByReference: false });
|
|
35
37
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
39
41
|
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
(key) => byComparator.comparator(prev[key], next[key]),
|
|
44
|
-
byComparator.keys
|
|
45
|
-
);
|
|
42
|
+
for (const key of byValue) {
|
|
43
|
+
if (!equals(prev[key], next[key])) {
|
|
44
|
+
if (debug) console.log({ isEqualByValue: false });
|
|
46
45
|
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
for (const key of byComparator.keys) {
|
|
51
|
+
if (!byComparator.comparator(prev[key], next[key])) {
|
|
52
|
+
if (debug) console.log({ isEqualByComparator: false });
|
|
53
|
+
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
49
56
|
}
|
|
50
57
|
|
|
51
58
|
if (compareRemainingKeysBySameValue) {
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
59
|
+
const allKeys = new Set([...Object.keys(prev), ...Object.keys(next)]);
|
|
60
|
+
|
|
61
|
+
const declaredKeys = new Set([
|
|
62
|
+
...byValue,
|
|
63
|
+
...byReference,
|
|
64
|
+
...byComparator.keys,
|
|
65
|
+
]);
|
|
56
66
|
|
|
57
|
-
const
|
|
58
|
-
Object.is(prev[key], next[key])
|
|
59
|
-
|
|
67
|
+
for (const key of Array.from(allKeys)) {
|
|
68
|
+
if (!declaredKeys.has(key) && !Object.is(prev[key], next[key])) {
|
|
69
|
+
if (debug) console.log({ isRestKeysEqualAllBySameValue: false });
|
|
60
70
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// if we made it here, everything matched
|
|
77
|
+
if (debug) {
|
|
78
|
+
console.log({
|
|
79
|
+
isEqualByValue: true,
|
|
80
|
+
isEqualByReference: true,
|
|
81
|
+
isEqualByComparator: true,
|
|
82
|
+
isRestKeysEqualAllBySameValue: compareRemainingKeysBySameValue
|
|
83
|
+
? true
|
|
84
|
+
: undefined,
|
|
85
|
+
});
|
|
67
86
|
}
|
|
68
87
|
|
|
69
|
-
return
|
|
88
|
+
return true;
|
|
70
89
|
};
|
|
@@ -227,14 +227,7 @@ class FocusManager {
|
|
|
227
227
|
|
|
228
228
|
const nextNextFocus = FocusManager.getNextFocusable(direction, nextFocus);
|
|
229
229
|
|
|
230
|
-
|
|
231
|
-
const nextNextFocusForParent =
|
|
232
|
-
FocusManager.instance.getNextFocusableForParent(direction, nextFocus);
|
|
233
|
-
|
|
234
|
-
FocusManager.instance.setFocus(nextNextFocusForParent, options);
|
|
235
|
-
} else {
|
|
236
|
-
FocusManager.instance.setFocus(nextNextFocus, options);
|
|
237
|
-
}
|
|
230
|
+
FocusManager.instance.setFocus(nextNextFocus, options);
|
|
238
231
|
} else {
|
|
239
232
|
FocusManager.instance.setFocusLocal(nextFocus);
|
|
240
233
|
|
|
@@ -257,7 +250,17 @@ class FocusManager {
|
|
|
257
250
|
}
|
|
258
251
|
|
|
259
252
|
onDisableFocusChange = (id) => {
|
|
260
|
-
|
|
253
|
+
const isFocused = FocusManager.instance.isFocused(id);
|
|
254
|
+
|
|
255
|
+
const isDescendantFocused = (() => {
|
|
256
|
+
try {
|
|
257
|
+
return FocusManager.instance.isAnyDescendantFocused(id);
|
|
258
|
+
} catch (_e) {
|
|
259
|
+
return false;
|
|
260
|
+
}
|
|
261
|
+
})();
|
|
262
|
+
|
|
263
|
+
if (isFocused || isDescendantFocused) {
|
|
261
264
|
// Move focus to next one
|
|
262
265
|
const nextFocus = FocusManager.instance.focused?.props
|
|
263
266
|
?.nextFocusDown as string;
|
|
@@ -314,26 +317,9 @@ class FocusManager {
|
|
|
314
317
|
return FocusManager.getNextFocusable(direction);
|
|
315
318
|
}
|
|
316
319
|
|
|
317
|
-
getNextFocusableForParent(
|
|
318
|
-
direction,
|
|
319
|
-
focusable?: FocusManager.TouchableReactRef
|
|
320
|
-
) {
|
|
321
|
-
const focusableId = focusable
|
|
322
|
-
? getFocusableId(focusable)
|
|
323
|
-
: FocusManager.instance.focusedId;
|
|
324
|
-
|
|
320
|
+
getNextFocusableForParent(direction) {
|
|
325
321
|
const focusDirection = toFocusDirection(direction);
|
|
326
|
-
const parentNode = this.tree.findParent(
|
|
327
|
-
|
|
328
|
-
const parentNodeParent = this.tree.findParent(parentNode?.id);
|
|
329
|
-
|
|
330
|
-
const hasNextFocusable = this.tree.find(
|
|
331
|
-
parentNode?.component?.current?.props[focusDirection]
|
|
332
|
-
);
|
|
333
|
-
|
|
334
|
-
if (!hasNextFocusable) {
|
|
335
|
-
return parentNodeParent?.component?.current?.props[focusDirection];
|
|
336
|
-
}
|
|
322
|
+
const parentNode = this.tree.findParent(FocusManager.instance.focusedId);
|
|
337
323
|
|
|
338
324
|
return parentNode?.component?.current?.props[focusDirection];
|
|
339
325
|
}
|
package/focusManager/index.ts
CHANGED
|
@@ -8,6 +8,8 @@ import { isNilOrEmpty } from "../reactUtils/helpers";
|
|
|
8
8
|
import { isAndroidTVPlatform } from "../reactUtils";
|
|
9
9
|
import { noop } from "../functionUtils";
|
|
10
10
|
|
|
11
|
+
const EMPTY_GROUP_COMPONENT = "empty_group_component";
|
|
12
|
+
|
|
11
13
|
export function useFocusManager() {
|
|
12
14
|
return focusManager;
|
|
13
15
|
}
|
|
@@ -74,6 +76,14 @@ export function useFocusEffect(onFocus, focusWatcher) {
|
|
|
74
76
|
}, focusWatcher);
|
|
75
77
|
}
|
|
76
78
|
|
|
79
|
+
export function shouldShowEmptyGroup(component) {
|
|
80
|
+
return (
|
|
81
|
+
component?.ui_components?.filter(
|
|
82
|
+
({ component_type }) => component_type === EMPTY_GROUP_COMPONENT
|
|
83
|
+
)?.length > 0
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
77
87
|
export const isFocusable = (component: ZappEntry | ZappUIComponent | any) =>
|
|
78
88
|
R.tryCatch(
|
|
79
89
|
R.compose(
|
|
@@ -101,15 +111,42 @@ export const useIsFocusable = (props: Props): void => {
|
|
|
101
111
|
component.rules.hide_component_if_data_is_empty
|
|
102
112
|
);
|
|
103
113
|
|
|
114
|
+
const isLoadingData = !!zappPipesData?.loading;
|
|
115
|
+
|
|
104
116
|
const hasNoData =
|
|
105
117
|
isNilOrEmpty(zappPipesData?.data) ||
|
|
106
118
|
isNilOrEmpty(zappPipesData?.data?.entry);
|
|
107
119
|
|
|
120
|
+
const hasDataError = !!zappPipesData?.error;
|
|
121
|
+
|
|
122
|
+
const hasEmptyGroup = shouldShowEmptyGroup(component);
|
|
123
|
+
|
|
124
|
+
const isGallery = component?.component_type === "gallery-qb";
|
|
125
|
+
|
|
126
|
+
const isHiddenDueToEmptyData =
|
|
127
|
+
!isLoadingData && hasNoData && hideIfDataEmpty && !hasEmptyGroup;
|
|
128
|
+
|
|
129
|
+
const defaultFocusableLogic =
|
|
130
|
+
componentCellsFocusable && (!hasNoData || !hideIfDataEmpty);
|
|
131
|
+
|
|
108
132
|
React.useEffect(() => {
|
|
109
133
|
if (isAndroidTVPlatform()) {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
)
|
|
134
|
+
let isFocusableNew = false;
|
|
135
|
+
|
|
136
|
+
if (isGallery) {
|
|
137
|
+
isFocusableNew = true;
|
|
138
|
+
} else if (isFocusable(component)) {
|
|
139
|
+
isFocusableNew = defaultFocusableLogic;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
setIsFocusable(isFocusableNew);
|
|
113
143
|
}
|
|
114
|
-
}, [
|
|
144
|
+
}, [
|
|
145
|
+
defaultFocusableLogic,
|
|
146
|
+
isHiddenDueToEmptyData,
|
|
147
|
+
isGallery,
|
|
148
|
+
setIsFocusable,
|
|
149
|
+
hasDataError,
|
|
150
|
+
hasEmptyGroup,
|
|
151
|
+
]);
|
|
115
152
|
};
|