@applicaster/zapp-react-native-utils 13.0.0-alpha.4936752427 → 13.0.0-alpha.4958485095
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/appUtils/focusManager/__tests__/__snapshots__/focusManager.test.js.snap +1 -0
- package/appUtils/focusManager/index.ts +9 -0
- package/appUtils/platform/platformUtils.ts +30 -3
- package/arrayUtils/index.ts +1 -1
- package/componentsUtils/__tests__/isFirstComponentGallery.test.ts +33 -0
- package/componentsUtils/__tests__/isFirstComponentScreenPicker.test.ts +33 -0
- package/componentsUtils/__tests__/isGallery.test.ts +33 -0
- package/componentsUtils/__tests__/isScreenPicker.test.ts +33 -0
- package/componentsUtils/index.ts +17 -0
- package/equalUtils/index.ts +10 -3
- package/focusManager/FocusManager.ts +11 -1
- package/manifestUtils/__tests__/createConfig.test.js +0 -2
- package/package.json +2 -2
- package/reactHooks/layout/useDimensions/useDimensions.ts +8 -0
- package/reactHooks/navigation/useGetTabBarHeight.ts +1 -3
- package/reactHooks/state/useRefWithInitialValue.ts +14 -0
- package/reactHooks/state/useStateFromSubscribe.ts +23 -0
|
@@ -345,6 +345,14 @@ export const focusManager = (function () {
|
|
|
345
345
|
});
|
|
346
346
|
}
|
|
347
347
|
|
|
348
|
+
function pressIn() {
|
|
349
|
+
const currentFocusable = getCurrentFocus();
|
|
350
|
+
|
|
351
|
+
if (currentFocusable) {
|
|
352
|
+
currentFocusable.pressIn(null);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
348
356
|
/**
|
|
349
357
|
* calls the `press` method on the current focus component
|
|
350
358
|
* @public
|
|
@@ -552,6 +560,7 @@ export const focusManager = (function () {
|
|
|
552
560
|
invokeHandler,
|
|
553
561
|
removeHandler,
|
|
554
562
|
longPress,
|
|
563
|
+
pressIn,
|
|
555
564
|
pressOut,
|
|
556
565
|
enableFocus,
|
|
557
566
|
setInitialFocus,
|
|
@@ -77,13 +77,22 @@ 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 {
|
|
83
89
|
if (!ClosedCaptioningManager.ccManagerInstance) {
|
|
90
|
+
log_debug("ClosedCaptioningManager: Creating new instance");
|
|
84
91
|
ClosedCaptioningManager.ccManagerInstance = new ClosedCaptioningManager();
|
|
85
92
|
}
|
|
86
93
|
|
|
94
|
+
log_debug("ClosedCaptioningManager: Returning existing instance");
|
|
95
|
+
|
|
87
96
|
return ClosedCaptioningManager.ccManagerInstance;
|
|
88
97
|
}
|
|
89
98
|
|
|
@@ -92,23 +101,41 @@ export class ClosedCaptioningManager {
|
|
|
92
101
|
PLATFORM_KEYS.deviceClosedCaptioningEnabled
|
|
93
102
|
);
|
|
94
103
|
|
|
95
|
-
log_debug("Initializing closed captioning manager", { existingState });
|
|
96
|
-
|
|
97
104
|
if (existingState !== null) {
|
|
105
|
+
log_debug(
|
|
106
|
+
`ClosedCaptioningManager: Setting initial state to ${existingState}`
|
|
107
|
+
);
|
|
108
|
+
|
|
98
109
|
this.ccState$.next(existingState === "true" || existingState === true);
|
|
110
|
+
} else {
|
|
111
|
+
log_debug("ClosedCaptioningManager: No existing state found");
|
|
99
112
|
}
|
|
100
113
|
|
|
101
114
|
if (hasVizioAPIs()) {
|
|
115
|
+
log_debug("ClosedCaptioningManager: Setting closed captioning handler");
|
|
116
|
+
|
|
102
117
|
window.VIZIO!.setClosedCaptionHandler((isCCEnabled) => {
|
|
103
|
-
log_debug(
|
|
118
|
+
log_debug(
|
|
119
|
+
"ClosedCaptioningManager: There was a change in the CC state",
|
|
120
|
+
{ isCCEnabled }
|
|
121
|
+
);
|
|
104
122
|
|
|
105
123
|
sessionStorage.setItem(
|
|
106
124
|
PLATFORM_KEYS.deviceClosedCaptioningEnabled,
|
|
107
125
|
isCCEnabled
|
|
108
126
|
);
|
|
109
127
|
|
|
128
|
+
log_debug(
|
|
129
|
+
"ClosedCaptioningManager: Saved CC state to session storage",
|
|
130
|
+
{ isCCEnabled }
|
|
131
|
+
);
|
|
132
|
+
|
|
110
133
|
this.ccState$.next(isCCEnabled);
|
|
111
134
|
});
|
|
135
|
+
} else {
|
|
136
|
+
log_debug(
|
|
137
|
+
"ClosedCaptioningManager: Vizio APIs are not available, skipping setup"
|
|
138
|
+
);
|
|
112
139
|
}
|
|
113
140
|
}
|
|
114
141
|
|
package/arrayUtils/index.ts
CHANGED
|
@@ -93,7 +93,7 @@ export const isIndexInRange = (index: number, length: number): boolean => {
|
|
|
93
93
|
export const makeListOfIndexes = (size: number): number[] =>
|
|
94
94
|
Array.from({ length: size }, (_, index) => index);
|
|
95
95
|
|
|
96
|
-
export const makeListOf = (value:
|
|
96
|
+
export const makeListOf = <T>(value: T, size: number): T[] => {
|
|
97
97
|
return Array(size).fill(value);
|
|
98
98
|
};
|
|
99
99
|
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { isFirstComponentGallery } from "../index";
|
|
2
|
+
|
|
3
|
+
describe("isFirstComponentGallery", () => {
|
|
4
|
+
it("should return true if the first component is a gallery", () => {
|
|
5
|
+
const components = [
|
|
6
|
+
{ component_type: "gallery-qb" },
|
|
7
|
+
{ component_type: "other-component" },
|
|
8
|
+
];
|
|
9
|
+
|
|
10
|
+
expect(isFirstComponentGallery(components)).toBe(true);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it("should return false if the first component is not a gallery", () => {
|
|
14
|
+
const components = [
|
|
15
|
+
{ component_type: "other-component" },
|
|
16
|
+
{ component_type: "gallery-qb" },
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
expect(isFirstComponentGallery(components)).toBe(false);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it("should return false if the components array is empty", () => {
|
|
23
|
+
const components = [];
|
|
24
|
+
|
|
25
|
+
expect(isFirstComponentGallery(components)).toBe(false);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("should return false if the components array is undefined", () => {
|
|
29
|
+
const components = undefined;
|
|
30
|
+
|
|
31
|
+
expect(isFirstComponentGallery(components)).toBe(false);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { isFirstComponentScreenPicker } from "..";
|
|
2
|
+
|
|
3
|
+
describe("isFirstComponentScreenPicker", () => {
|
|
4
|
+
it("should return true if the first component screen-picker", () => {
|
|
5
|
+
const items = [{ component_type: "screen-picker-qb-tv" }];
|
|
6
|
+
expect(isFirstComponentScreenPicker(items)).toBe(true);
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
it("should return false if the first component type is not screen-picker", () => {
|
|
10
|
+
const items = [{ component_type: "other-component" }];
|
|
11
|
+
expect(isFirstComponentScreenPicker(items)).toBe(false);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it("should return false if the component type is undefined", () => {
|
|
15
|
+
const items = [{ component_type: undefined }];
|
|
16
|
+
expect(isFirstComponentScreenPicker(items)).toBe(false);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it("should return false if the item is null", () => {
|
|
20
|
+
const items = null;
|
|
21
|
+
expect(isFirstComponentScreenPicker(items)).toBe(false);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it("should return false if the item is undefined", () => {
|
|
25
|
+
const items = undefined;
|
|
26
|
+
expect(isFirstComponentScreenPicker(items)).toBe(false);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("should return false if the item is an empty object", () => {
|
|
30
|
+
const items = {};
|
|
31
|
+
expect(isFirstComponentScreenPicker(items)).toBe(false);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { isGallery } from "..";
|
|
2
|
+
|
|
3
|
+
describe("isGallery", () => {
|
|
4
|
+
it("should return true if the component type is 'gallery-qb'", () => {
|
|
5
|
+
const item = { component_type: "gallery-qb" };
|
|
6
|
+
expect(isGallery(item)).toBe(true);
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
it("should return false if the component type is not 'gallery-qb'", () => {
|
|
10
|
+
const item = { component_type: "other-component" };
|
|
11
|
+
expect(isGallery(item)).toBe(false);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it("should return false if the component type is undefined", () => {
|
|
15
|
+
const item = { component_type: undefined };
|
|
16
|
+
expect(isGallery(item)).toBe(false);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it("should return false if the item is null", () => {
|
|
20
|
+
const item = null;
|
|
21
|
+
expect(isGallery(item)).toBe(false);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it("should return false if the item is undefined", () => {
|
|
25
|
+
const item = undefined;
|
|
26
|
+
expect(isGallery(item)).toBe(false);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("should return false if the item is an empty object", () => {
|
|
30
|
+
const item = {};
|
|
31
|
+
expect(isGallery(item)).toBe(false);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { isScreenPicker } from "..";
|
|
2
|
+
|
|
3
|
+
describe("isScreenPicker", () => {
|
|
4
|
+
it("should return true if the component type is 'screen-picker-qb-tv'", () => {
|
|
5
|
+
const item = { component_type: "screen-picker-qb-tv" };
|
|
6
|
+
expect(isScreenPicker(item)).toBe(true);
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
it("should return false if the component type is not 'screen-picker-qb-tv'", () => {
|
|
10
|
+
const item = { component_type: "other-component" };
|
|
11
|
+
expect(isScreenPicker(item)).toBe(false);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it("should return false if the component type is undefined", () => {
|
|
15
|
+
const item = { component_type: undefined };
|
|
16
|
+
expect(isScreenPicker(item)).toBe(false);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it("should return false if the item is null", () => {
|
|
20
|
+
const item = null;
|
|
21
|
+
expect(isScreenPicker(item)).toBe(false);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it("should return false if the item is undefined", () => {
|
|
25
|
+
const item = undefined;
|
|
26
|
+
expect(isScreenPicker(item)).toBe(false);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("should return false if the item is an empty object", () => {
|
|
30
|
+
const item = {};
|
|
31
|
+
expect(isScreenPicker(item)).toBe(false);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export const isGallery = (item): boolean =>
|
|
2
|
+
item?.component_type === "gallery-qb";
|
|
3
|
+
|
|
4
|
+
export const isScreenPicker = (item): boolean =>
|
|
5
|
+
item?.component_type === "screen-picker-qb-tv";
|
|
6
|
+
|
|
7
|
+
export const isFirstComponentScreenPicker = (
|
|
8
|
+
components: ZappUIComponent[]
|
|
9
|
+
): boolean => {
|
|
10
|
+
return isScreenPicker(components?.[0]);
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const isFirstComponentGallery = (
|
|
14
|
+
components: ZappUIComponent[]
|
|
15
|
+
): boolean => {
|
|
16
|
+
return isGallery(components?.[0]);
|
|
17
|
+
};
|
package/equalUtils/index.ts
CHANGED
|
@@ -49,9 +49,16 @@ export const isEqual =
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
if (compareRemainingKeysBySameValue) {
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
const allKeys = new Set([...Object.keys(prev), ...Object.keys(next)]);
|
|
53
|
+
|
|
54
|
+
const declaredKeys = new Set([
|
|
55
|
+
...byValue,
|
|
56
|
+
...byReference,
|
|
57
|
+
...byComparator.keys,
|
|
58
|
+
]);
|
|
59
|
+
|
|
60
|
+
const undeclaredKeys = Array.from(allKeys).filter(
|
|
61
|
+
(key) => !declaredKeys.has(key)
|
|
55
62
|
);
|
|
56
63
|
|
|
57
64
|
const isRestKeysEqualAllBySameValue = undeclaredKeys.every((key) =>
|
|
@@ -250,7 +250,17 @@ class FocusManager {
|
|
|
250
250
|
}
|
|
251
251
|
|
|
252
252
|
onDisableFocusChange = (id) => {
|
|
253
|
-
|
|
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) {
|
|
254
264
|
// Move focus to next one
|
|
255
265
|
const nextFocus = FocusManager.instance.focused?.props
|
|
256
266
|
?.nextFocusDown as string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applicaster/zapp-react-native-utils",
|
|
3
|
-
"version": "13.0.0-alpha.
|
|
3
|
+
"version": "13.0.0-alpha.4958485095",
|
|
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": "13.0.0-alpha.
|
|
31
|
+
"@applicaster/applicaster-types": "13.0.0-alpha.4958485095",
|
|
32
32
|
"buffer": "^5.2.1",
|
|
33
33
|
"camelize": "^1.0.0",
|
|
34
34
|
"create-react-context": "^0.2.3",
|
|
@@ -52,6 +52,14 @@ export const useDimensions: UseDimensions = (
|
|
|
52
52
|
? { fullDimensions }
|
|
53
53
|
: { ...fullDimensions };
|
|
54
54
|
|
|
55
|
+
if (options.updateForInactiveScreens === undefined) {
|
|
56
|
+
options.updateForInactiveScreens = true;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (options.fullDimensions === undefined) {
|
|
60
|
+
options.fullDimensions = false;
|
|
61
|
+
}
|
|
62
|
+
|
|
55
63
|
const [dimensions, setDimensions] = useState(getInitialDimensions(context));
|
|
56
64
|
const deviceInfo = useRef(getDeviceInfo(dimensions, appData));
|
|
57
65
|
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
2
|
-
|
|
3
1
|
import { platformSelect } from "../../reactUtils";
|
|
4
2
|
|
|
5
3
|
const TAB_BAR_HEIGHT_IOS = 49;
|
|
@@ -7,6 +5,6 @@ const TAB_BAR_HEIGHT_ANDROID = 56;
|
|
|
7
5
|
|
|
8
6
|
export const useGetTabBarHeight = () =>
|
|
9
7
|
platformSelect({
|
|
10
|
-
ios: TAB_BAR_HEIGHT_IOS
|
|
8
|
+
ios: TAB_BAR_HEIGHT_IOS,
|
|
11
9
|
android: TAB_BAR_HEIGHT_ANDROID,
|
|
12
10
|
}) as number;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* returns a ref with an initial value that is lazily evaluated once
|
|
5
|
+
* */
|
|
6
|
+
export const useRefWithInitialValue = <T>(initialValueGetter: () => T) => {
|
|
7
|
+
const ref = React.useRef<T>(null);
|
|
8
|
+
|
|
9
|
+
if (ref.current === null) {
|
|
10
|
+
ref.current = initialValueGetter();
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
return ref;
|
|
14
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
import type { Subject } from "rxjs";
|
|
3
|
+
|
|
4
|
+
export const useStateFromSubscribe = <T, U>(
|
|
5
|
+
subject: Subject<T>,
|
|
6
|
+
onUpdate: (
|
|
7
|
+
observerValue: T,
|
|
8
|
+
next: React.Dispatch<React.SetStateAction<U>>
|
|
9
|
+
) => void,
|
|
10
|
+
initialValue: U
|
|
11
|
+
) => {
|
|
12
|
+
const [state, setState] = useState<U>(initialValue);
|
|
13
|
+
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
const subscription = subject.subscribe((observer) =>
|
|
16
|
+
onUpdate(observer, setState)
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
return () => subscription.unsubscribe();
|
|
20
|
+
}, [subject]);
|
|
21
|
+
|
|
22
|
+
return state;
|
|
23
|
+
};
|