@applicaster/zapp-react-native-utils 12.0.0-alpha.4576271826 → 12.0.0-alpha.4620237415
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/accessibilityManager/index.ts +1 -12
- package/appUtils/platform/platformUtils.ts +35 -2
- package/appUtils/playerManager/playerFactory.ts +1 -1
- package/appUtils/playerManager/playerHooks/usePlayerCurrentTime.tsx +57 -0
- package/appUtils/playerManager/usePlayerControllerSetup.tsx +2 -2
- package/arrayUtils/index.ts +11 -0
- package/focusManager/FocusManager.ts +20 -5
- package/focusManager/__tests__/FocusManager.test.ts +0 -1
- package/functionUtils/index.ts +38 -0
- package/manifestUtils/defaultManifestConfigurations/player.js +121 -0
- package/manifestUtils/keys.js +2 -1
- package/navigationUtils/index.ts +1 -1
- package/numberUtils/__tests__/toPositiveNumberWithDefault.test.ts +66 -0
- package/numberUtils/__tests__/toPositiveNumberWithDefaultZero.test.ts +66 -0
- package/numberUtils/index.ts +20 -0
- package/package.json +2 -2
- package/playerUtils/configurationGenerator.ts +120 -0
- package/reactHooks/cell-click/index.ts +17 -3
- package/reactHooks/feed/__tests__/useBatchLoading.test.tsx +69 -6
- package/reactHooks/feed/useBatchLoading.ts +52 -28
- package/reactHooks/layout/useDimensions/__tests__/useDimensions.test.ts +134 -0
- package/reactHooks/navigation/index.ts +1 -1
- package/reactHooks/player/useAutoSeek.tsx +9 -7
- package/reactHooks/useConfiguration.ts +2 -2
- package/testUtils/index.tsx +42 -9
|
@@ -85,18 +85,7 @@ export class AccessibilityManager {
|
|
|
85
85
|
textToRead = localizedMessage;
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
|
|
89
|
-
logger.debug({
|
|
90
|
-
message: `Reading text: ${textToRead}`,
|
|
91
|
-
data: {
|
|
92
|
-
textToRead,
|
|
93
|
-
text,
|
|
94
|
-
keyOfLocalizedText,
|
|
95
|
-
},
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
this.ttsManager.readText(textToRead);
|
|
99
|
-
}
|
|
88
|
+
this.ttsManager && this.ttsManager.readText(textToRead);
|
|
100
89
|
|
|
101
90
|
this.announcements$.next({
|
|
102
91
|
message: textToRead,
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { BehaviorSubject } from "rxjs";
|
|
2
2
|
|
|
3
3
|
import { sessionStorage } from "@applicaster/zapp-react-native-bridge/ZappStorage/SessionStorage";
|
|
4
|
+
import {
|
|
5
|
+
isLgPlatform,
|
|
6
|
+
isSamsungPlatform,
|
|
7
|
+
} from "@applicaster/zapp-react-dom-app/App/Loader/utils/platform";
|
|
4
8
|
|
|
5
9
|
import { PLATFORM_KEYS, PLATFORMS } from "./const";
|
|
6
10
|
import { createLogger, utilsLogger } from "../../logger";
|
|
@@ -25,8 +29,7 @@ const { log_debug } = createLogger({
|
|
|
25
29
|
parent: utilsLogger,
|
|
26
30
|
});
|
|
27
31
|
|
|
28
|
-
export const getUserAgent = () =>
|
|
29
|
-
window?.navigator?.userAgent || global?.navigator?.userAgent;
|
|
32
|
+
export const getUserAgent = () => window?.navigator?.userAgent;
|
|
30
33
|
|
|
31
34
|
/** VIZIO UTILS */
|
|
32
35
|
|
|
@@ -39,6 +42,8 @@ export const getUserAgent = () =>
|
|
|
39
42
|
export const isVizioPlatform = () => {
|
|
40
43
|
const userAgent = getUserAgent();
|
|
41
44
|
|
|
45
|
+
if (!userAgent) return false;
|
|
46
|
+
|
|
42
47
|
const isVizioAgent =
|
|
43
48
|
userAgent.includes(PLATFORMS.vizio) ||
|
|
44
49
|
userAgent.includes(PLATFORMS.smartcast) ||
|
|
@@ -178,6 +183,34 @@ export class TTSManager {
|
|
|
178
183
|
}
|
|
179
184
|
|
|
180
185
|
readText(text: string) {
|
|
186
|
+
if (isSamsungPlatform() && window.speechSynthesis) {
|
|
187
|
+
const utterance = new SpeechSynthesisUtterance(text);
|
|
188
|
+
window.speechSynthesis.speak(utterance);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (isLgPlatform() && window.webOS?.service) {
|
|
192
|
+
try {
|
|
193
|
+
window.webOS.service.request("luna://com.webos.service.tts", {
|
|
194
|
+
method: "speak",
|
|
195
|
+
onFailure(error: any) {
|
|
196
|
+
log_debug("There was a failure setting up webOS TTS service", {
|
|
197
|
+
error,
|
|
198
|
+
});
|
|
199
|
+
},
|
|
200
|
+
onSuccess(response: any) {
|
|
201
|
+
log_debug("webOS TTS service is configured successfully", {
|
|
202
|
+
response,
|
|
203
|
+
});
|
|
204
|
+
},
|
|
205
|
+
parameters: {
|
|
206
|
+
text,
|
|
207
|
+
},
|
|
208
|
+
});
|
|
209
|
+
} catch (error) {
|
|
210
|
+
log_debug("webOS TTS service error", { error });
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
181
214
|
if (!window.VIZIO?.Chromevox) return;
|
|
182
215
|
|
|
183
216
|
window.VIZIO.Chromevox.play(text);
|
|
@@ -46,7 +46,7 @@ export const playerFactory = (
|
|
|
46
46
|
|
|
47
47
|
// TODO: Fix type:
|
|
48
48
|
const playerProtocol: PlayerConstructor =
|
|
49
|
-
playerPlugin?.module?.playerProtocol(config?.screenConfig);
|
|
49
|
+
playerPlugin?.module?.playerProtocol(config?.screenConfig, config?.entry);
|
|
50
50
|
|
|
51
51
|
const playerView = (playerProtocol as any)?.Component || null;
|
|
52
52
|
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { useState, useEffect, useCallback } from "react";
|
|
2
|
+
import { Player } from "../player";
|
|
3
|
+
import { usePlayer } from "../usePlayer";
|
|
4
|
+
import { useThrottle } from "../../../functionUtils";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
*
|
|
8
|
+
* @param listenerId - A unique identifier for the listener.
|
|
9
|
+
* @param playerId - (Optional) The ID of the player to observe.
|
|
10
|
+
* @returns The current playback time in seconds.
|
|
11
|
+
*/
|
|
12
|
+
export const usePlayerCurrentTime = (
|
|
13
|
+
listenerId: string,
|
|
14
|
+
playerId?: string
|
|
15
|
+
): number | null => {
|
|
16
|
+
const [currentTime, setCurrentTime] = useState<number | null>(null);
|
|
17
|
+
const player: Player = usePlayer(playerId);
|
|
18
|
+
|
|
19
|
+
const updateCurrentTime = useCallback(() => {
|
|
20
|
+
if (player) {
|
|
21
|
+
const newCurrentTime = player.getContentPosition();
|
|
22
|
+
|
|
23
|
+
setCurrentTime((prevTime) =>
|
|
24
|
+
prevTime !== newCurrentTime ? newCurrentTime : prevTime
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
}, [player]);
|
|
28
|
+
|
|
29
|
+
const { throttledFunction: throttledUpdate, cancel } = useThrottle(
|
|
30
|
+
updateCurrentTime,
|
|
31
|
+
1000
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
if (player) {
|
|
36
|
+
throttledUpdate();
|
|
37
|
+
|
|
38
|
+
const listeners = {
|
|
39
|
+
onVideoProgress: throttledUpdate,
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const id = `${listenerId}_player_current_time`;
|
|
43
|
+
|
|
44
|
+
player.addListener({
|
|
45
|
+
id: id,
|
|
46
|
+
listener: listeners,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
return () => {
|
|
50
|
+
player.removeListener(id);
|
|
51
|
+
cancel();
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
}, [player, listenerId, throttledUpdate, cancel]);
|
|
55
|
+
|
|
56
|
+
return currentTime;
|
|
57
|
+
};
|
|
@@ -50,7 +50,7 @@ export const usePlayerControllerSetup = ({
|
|
|
50
50
|
});
|
|
51
51
|
|
|
52
52
|
setPlayerController(newPlayerController);
|
|
53
|
-
}, [playerId, entry?.id
|
|
53
|
+
}, [playerId, entry?.id]);
|
|
54
54
|
|
|
55
55
|
React.useEffect(() => {
|
|
56
56
|
if (!playerController) {
|
|
@@ -58,7 +58,7 @@ export const usePlayerControllerSetup = ({
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
if (!playerManager) {
|
|
61
|
-
return
|
|
61
|
+
return;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
if (playerManager.isPlayerRegistered(playerId)) {
|
package/arrayUtils/index.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/* eslint-disable unused-imports/no-unused-vars */
|
|
2
2
|
import * as R from "ramda";
|
|
3
|
+
import { invariant } from "@applicaster/zapp-react-native-utils/errorUtils";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* shifts an array by the given offset. a negative offset will take items
|
|
@@ -100,3 +101,13 @@ export const makeListOf = (value: unknown, size: number): number[] => {
|
|
|
100
101
|
export function isFilledArray(value: unknown): boolean {
|
|
101
102
|
return R.is(Array, value) && R.length(value) > 0;
|
|
102
103
|
}
|
|
104
|
+
|
|
105
|
+
// get random item from the list
|
|
106
|
+
export const sample = (xs: unknown[]): unknown => {
|
|
107
|
+
invariant(R.is(Array, xs), `input value is not a array: ${xs}`);
|
|
108
|
+
invariant(isFilledArray(xs), `input array is empty: ${xs}`);
|
|
109
|
+
|
|
110
|
+
const index = Math.floor(Math.random() * xs.length);
|
|
111
|
+
|
|
112
|
+
return xs[index];
|
|
113
|
+
};
|
|
@@ -18,6 +18,7 @@ class FocusManager {
|
|
|
18
18
|
private static instance: FocusManager;
|
|
19
19
|
|
|
20
20
|
private _focusedId: string | null = null;
|
|
21
|
+
private _prevFocusedId: string | null = null;
|
|
21
22
|
public previousNavigationDirection: FocusManager.Android.NavDir = null;
|
|
22
23
|
|
|
23
24
|
/**
|
|
@@ -47,10 +48,22 @@ class FocusManager {
|
|
|
47
48
|
return focusedRef?.current;
|
|
48
49
|
}
|
|
49
50
|
|
|
51
|
+
get prevFocused() {
|
|
52
|
+
const focusedRef = this.prevFocusedId
|
|
53
|
+
? FocusManager.findFocusable(this.prevFocusedId)
|
|
54
|
+
: { current: null };
|
|
55
|
+
|
|
56
|
+
return focusedRef?.current;
|
|
57
|
+
}
|
|
58
|
+
|
|
50
59
|
get focusedId() {
|
|
51
60
|
return FocusManager.instance._focusedId;
|
|
52
61
|
}
|
|
53
62
|
|
|
63
|
+
get prevFocusedId() {
|
|
64
|
+
return FocusManager.instance._prevFocusedId;
|
|
65
|
+
}
|
|
66
|
+
|
|
54
67
|
public static getInstance(): FocusManager {
|
|
55
68
|
if (!FocusManager.instance) {
|
|
56
69
|
FocusManager.instance = new FocusManager();
|
|
@@ -151,9 +164,8 @@ class FocusManager {
|
|
|
151
164
|
}
|
|
152
165
|
|
|
153
166
|
private setFocusLocal(nextFocus: FocusManager.TouchableReactRef) {
|
|
167
|
+
FocusManager.instance._prevFocusedId = FocusManager.instance._focusedId;
|
|
154
168
|
FocusManager.instance._focusedId = nextFocus?.current?.props?.id ?? null;
|
|
155
|
-
|
|
156
|
-
this.eventHandler?.invokeHandler?.(FOCUS_EVENTS.FOCUS, nextFocus);
|
|
157
169
|
}
|
|
158
170
|
|
|
159
171
|
private setPreviousNavigationDirection(
|
|
@@ -217,8 +229,11 @@ class FocusManager {
|
|
|
217
229
|
|
|
218
230
|
FocusManager.instance.setFocus(nextNextFocus, options);
|
|
219
231
|
} else {
|
|
220
|
-
FocusManager.instance.blurPrevious(options);
|
|
221
232
|
FocusManager.instance.setFocusLocal(nextFocus);
|
|
233
|
+
|
|
234
|
+
FocusManager.instance.blurPrevious(options);
|
|
235
|
+
this.eventHandler?.invokeHandler?.(FOCUS_EVENTS.FOCUS, nextFocus);
|
|
236
|
+
|
|
222
237
|
FocusManager.instance.setPreviousNavigationDirection(options ?? null);
|
|
223
238
|
|
|
224
239
|
nextFocus?.current?.onFocus?.(nextFocus.current, options ?? {});
|
|
@@ -227,8 +242,8 @@ class FocusManager {
|
|
|
227
242
|
|
|
228
243
|
blurPrevious(options?: FocusManager.Android.CallbackOptions) {
|
|
229
244
|
if (options) {
|
|
230
|
-
FocusManager.instance.
|
|
231
|
-
FocusManager.instance.
|
|
245
|
+
FocusManager.instance.prevFocused?.onBlur?.(
|
|
246
|
+
FocusManager.instance.prevFocused,
|
|
232
247
|
options
|
|
233
248
|
);
|
|
234
249
|
}
|
|
@@ -156,7 +156,6 @@ describe("FocusManager", () => {
|
|
|
156
156
|
child1.current.onBlur.mockClear();
|
|
157
157
|
focusManager.setFocus(child1.current.props.id);
|
|
158
158
|
focusManager.blurPrevious({ direction: "down" });
|
|
159
|
-
expect(child1.current.onBlur).toBeCalled();
|
|
160
159
|
});
|
|
161
160
|
|
|
162
161
|
it("focusManager - focus shouldn't change if nextFocus has blockFocus", () => {
|
package/functionUtils/index.ts
CHANGED
|
@@ -1,4 +1,42 @@
|
|
|
1
1
|
import * as R from "ramda";
|
|
2
|
+
import { useRef } from "react";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
* @param callback - The function to throttle.
|
|
7
|
+
* @param delay - The delay in milliseconds.
|
|
8
|
+
* @returns A throttled version of the callback.
|
|
9
|
+
*/
|
|
10
|
+
export const useThrottle = (callback: () => void, delay: number) => {
|
|
11
|
+
const lastCallRef = useRef<number>(0);
|
|
12
|
+
const timeoutRef = useRef<any | null>(null);
|
|
13
|
+
|
|
14
|
+
const throttledFunction = () => {
|
|
15
|
+
const now = Date.now();
|
|
16
|
+
|
|
17
|
+
if (now - lastCallRef.current >= delay) {
|
|
18
|
+
callback();
|
|
19
|
+
lastCallRef.current = now;
|
|
20
|
+
} else if (!timeoutRef.current) {
|
|
21
|
+
const remainingTime = delay - (now - lastCallRef.current);
|
|
22
|
+
|
|
23
|
+
timeoutRef.current = setTimeout(() => {
|
|
24
|
+
callback();
|
|
25
|
+
lastCallRef.current = Date.now();
|
|
26
|
+
timeoutRef.current = null;
|
|
27
|
+
}, remainingTime);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const cancel = () => {
|
|
32
|
+
if (timeoutRef.current) {
|
|
33
|
+
clearTimeout(timeoutRef.current);
|
|
34
|
+
timeoutRef.current = null;
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
return { throttledFunction, cancel };
|
|
39
|
+
};
|
|
2
40
|
|
|
3
41
|
/**
|
|
4
42
|
* standard debounce function.
|
|
@@ -18,6 +18,7 @@ function getDevice(platform) {
|
|
|
18
18
|
case "lg_tv":
|
|
19
19
|
case "samsung_tv":
|
|
20
20
|
case "web":
|
|
21
|
+
case "vizio":
|
|
21
22
|
return "tv";
|
|
22
23
|
}
|
|
23
24
|
}
|
|
@@ -1795,6 +1796,30 @@ function getPlayerConfiguration({ platform }) {
|
|
|
1795
1796
|
key: "menu_header_samsung_letter_spacing",
|
|
1796
1797
|
initial_value: 0,
|
|
1797
1798
|
},
|
|
1799
|
+
{
|
|
1800
|
+
type: "vizio_font_selector",
|
|
1801
|
+
label: "Vizio Font Family",
|
|
1802
|
+
key: "menu_header_vizio_font_family",
|
|
1803
|
+
initial_value: "SmsungOneUI-Bold",
|
|
1804
|
+
},
|
|
1805
|
+
{
|
|
1806
|
+
type: "number_input",
|
|
1807
|
+
label: "Vizio Font Size",
|
|
1808
|
+
key: "menu_header_vizio_font_size",
|
|
1809
|
+
initial_value: 30,
|
|
1810
|
+
},
|
|
1811
|
+
{
|
|
1812
|
+
type: "number_input",
|
|
1813
|
+
label: "Vizio Line Height",
|
|
1814
|
+
key: "menu_header_vizio_line_height",
|
|
1815
|
+
initial_value: 60,
|
|
1816
|
+
},
|
|
1817
|
+
{
|
|
1818
|
+
type: "number_input",
|
|
1819
|
+
label: "Vizio Letter Spacing",
|
|
1820
|
+
key: "menu_header_vizio_letter_spacing",
|
|
1821
|
+
initial_value: 0,
|
|
1822
|
+
},
|
|
1798
1823
|
]
|
|
1799
1824
|
),
|
|
1800
1825
|
// Captions Menu - Item Text Label
|
|
@@ -1874,6 +1899,30 @@ function getPlayerConfiguration({ platform }) {
|
|
|
1874
1899
|
key: "menu_item_samsung_letter_spacing",
|
|
1875
1900
|
initial_value: 0,
|
|
1876
1901
|
},
|
|
1902
|
+
{
|
|
1903
|
+
type: "vizio_font_selector",
|
|
1904
|
+
label: "Vizio Font Family",
|
|
1905
|
+
key: "menu_item_vizio_font_family",
|
|
1906
|
+
initial_value: "SmsungOneUI-Bold",
|
|
1907
|
+
},
|
|
1908
|
+
{
|
|
1909
|
+
type: "number_input",
|
|
1910
|
+
label: "Vizio Font Size",
|
|
1911
|
+
key: "menu_item_vizio_font_size",
|
|
1912
|
+
initial_value: 25,
|
|
1913
|
+
},
|
|
1914
|
+
{
|
|
1915
|
+
type: "number_input",
|
|
1916
|
+
label: "Vizio Line Height",
|
|
1917
|
+
key: "menu_item_vizio_line_height",
|
|
1918
|
+
initial_value: 40,
|
|
1919
|
+
},
|
|
1920
|
+
{
|
|
1921
|
+
type: "number_input",
|
|
1922
|
+
label: "Vizio Letter Spacing",
|
|
1923
|
+
key: "menu_item_vizio_letter_spacing",
|
|
1924
|
+
initial_value: 0,
|
|
1925
|
+
},
|
|
1877
1926
|
]
|
|
1878
1927
|
),
|
|
1879
1928
|
// Captions Menu - Item Border
|
|
@@ -2017,6 +2066,18 @@ function getPlayerConfiguration({ platform }) {
|
|
|
2017
2066
|
key: "samsung_tv_video_player_title_font_size",
|
|
2018
2067
|
initial_value: 64,
|
|
2019
2068
|
},
|
|
2069
|
+
{
|
|
2070
|
+
type: "vizio_font_selector",
|
|
2071
|
+
label: "Vizio Font Family",
|
|
2072
|
+
key: "vizio_video_player_title_font_family",
|
|
2073
|
+
initial_value: "Ubuntu-Bold",
|
|
2074
|
+
},
|
|
2075
|
+
{
|
|
2076
|
+
type: "number_input",
|
|
2077
|
+
label: "Vizio Font Size",
|
|
2078
|
+
key: "vizio_video_player_title_font_size",
|
|
2079
|
+
initial_value: 64,
|
|
2080
|
+
},
|
|
2020
2081
|
{
|
|
2021
2082
|
type: "tvos_font_selector",
|
|
2022
2083
|
label: "tvOS Font Family",
|
|
@@ -2090,6 +2151,18 @@ function getPlayerConfiguration({ platform }) {
|
|
|
2090
2151
|
key: "samsung_tv_video_player_summary_font_size",
|
|
2091
2152
|
initial_value: 30,
|
|
2092
2153
|
},
|
|
2154
|
+
{
|
|
2155
|
+
type: "vizio_font_selector",
|
|
2156
|
+
label: "Vizio Font Family",
|
|
2157
|
+
key: "vizio_video_player_summary_font_family",
|
|
2158
|
+
initial_value: "Ubuntu-Bold",
|
|
2159
|
+
},
|
|
2160
|
+
{
|
|
2161
|
+
type: "number_input",
|
|
2162
|
+
label: "Vizio Font Size",
|
|
2163
|
+
key: "vizio_video_player_summary_font_size",
|
|
2164
|
+
initial_value: 30,
|
|
2165
|
+
},
|
|
2093
2166
|
{
|
|
2094
2167
|
type: "tvos_font_selector",
|
|
2095
2168
|
label: "tvOS Font Family",
|
|
@@ -2157,6 +2230,18 @@ function getPlayerConfiguration({ platform }) {
|
|
|
2157
2230
|
key: "samsung_tv_audio_player_title_font_size",
|
|
2158
2231
|
initial_value: 38,
|
|
2159
2232
|
},
|
|
2233
|
+
{
|
|
2234
|
+
type: "vizio_font_selector",
|
|
2235
|
+
label: "Vizio Font Family",
|
|
2236
|
+
key: "vizio_tv_audio_player_title_font_family",
|
|
2237
|
+
initial_value: "Ubuntu-Bold",
|
|
2238
|
+
},
|
|
2239
|
+
{
|
|
2240
|
+
type: "number_input",
|
|
2241
|
+
label: "Vizio Font Size",
|
|
2242
|
+
key: "vizio_audio_player_title_font_size",
|
|
2243
|
+
initial_value: 38,
|
|
2244
|
+
},
|
|
2160
2245
|
{
|
|
2161
2246
|
type: "tvos_font_selector",
|
|
2162
2247
|
label: "tvOS Font Family",
|
|
@@ -2212,6 +2297,18 @@ function getPlayerConfiguration({ platform }) {
|
|
|
2212
2297
|
key: "samsung_tv_audio_player_summary_font_size",
|
|
2213
2298
|
initial_value: 20,
|
|
2214
2299
|
},
|
|
2300
|
+
{
|
|
2301
|
+
type: "vizio_font_selector",
|
|
2302
|
+
label: "Vizio Font Family",
|
|
2303
|
+
key: "vizio_audio_player_summary_font_family",
|
|
2304
|
+
initial_value: "Ubuntu-Bold",
|
|
2305
|
+
},
|
|
2306
|
+
{
|
|
2307
|
+
type: "number_input",
|
|
2308
|
+
label: "Vizio Font Size",
|
|
2309
|
+
key: "vizio_audio_player_summary_font_size",
|
|
2310
|
+
initial_value: 20,
|
|
2311
|
+
},
|
|
2215
2312
|
{
|
|
2216
2313
|
type: "tvos_font_selector",
|
|
2217
2314
|
label: "tvOS Font Family",
|
|
@@ -2267,6 +2364,18 @@ function getPlayerConfiguration({ platform }) {
|
|
|
2267
2364
|
key: "samsung_tv_player_time_font_size",
|
|
2268
2365
|
initial_value: 20,
|
|
2269
2366
|
},
|
|
2367
|
+
{
|
|
2368
|
+
type: "vizio_font_selector",
|
|
2369
|
+
label: "Vizio Font Family",
|
|
2370
|
+
key: "vizio_player_time_font_family",
|
|
2371
|
+
initial_value: "Ubuntu-Bold",
|
|
2372
|
+
},
|
|
2373
|
+
{
|
|
2374
|
+
type: "number_input",
|
|
2375
|
+
label: "Vizio Font Size",
|
|
2376
|
+
key: "vizio_player_time_font_size",
|
|
2377
|
+
initial_value: 20,
|
|
2378
|
+
},
|
|
2270
2379
|
{
|
|
2271
2380
|
type: "android_font_selector",
|
|
2272
2381
|
label: "Android TV Font Family",
|
|
@@ -2322,6 +2431,18 @@ function getPlayerConfiguration({ platform }) {
|
|
|
2322
2431
|
key: "samsung_tv_audio_player_run_time_font_size",
|
|
2323
2432
|
initial_value: 20,
|
|
2324
2433
|
},
|
|
2434
|
+
{
|
|
2435
|
+
type: "vizio_font_selector",
|
|
2436
|
+
label: "Vizio Font Family",
|
|
2437
|
+
key: "vizio_audio_player_run_time_font_family",
|
|
2438
|
+
initial_value: "Ubuntu-Bold",
|
|
2439
|
+
},
|
|
2440
|
+
{
|
|
2441
|
+
type: "number_input",
|
|
2442
|
+
label: "Vizio Font Size",
|
|
2443
|
+
key: "vizio_audio_player_run_time_font_size",
|
|
2444
|
+
initial_value: 20,
|
|
2445
|
+
},
|
|
2325
2446
|
{
|
|
2326
2447
|
type: "tvos_font_selector",
|
|
2327
2448
|
label: "tvOS Font Family",
|
package/manifestUtils/keys.js
CHANGED
|
@@ -17,10 +17,11 @@ const ZAPPIFEST_FIELDS = {
|
|
|
17
17
|
lg: "lg_tv_font_selector",
|
|
18
18
|
samsung: "samsung_font_selector",
|
|
19
19
|
roku: "roku_font_selector",
|
|
20
|
+
vizio: "vizio_font_selector",
|
|
20
21
|
},
|
|
21
22
|
};
|
|
22
23
|
|
|
23
|
-
const TV_PLATFORMS = ["tvOS", "android", "LG", "samsung", "roku"];
|
|
24
|
+
const TV_PLATFORMS = ["tvOS", "android", "LG", "samsung", "roku", "vizio"];
|
|
24
25
|
|
|
25
26
|
const FontPropsForTVPlatform = (platform) => ({
|
|
26
27
|
[`${R.toLower(platform)}FontFamily`]: {
|
package/navigationUtils/index.ts
CHANGED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { toPositiveNumberWithDefault } from "..";
|
|
2
|
+
|
|
3
|
+
describe("toNumber", () => {
|
|
4
|
+
const DEFAULT = 5;
|
|
5
|
+
|
|
6
|
+
it("return number if input is positive number", () => {
|
|
7
|
+
const inputs = [0, 1, 2, 100, 200.12, Infinity];
|
|
8
|
+
expect.assertions(inputs.length);
|
|
9
|
+
|
|
10
|
+
inputs.forEach((input) => {
|
|
11
|
+
const output = toPositiveNumberWithDefault(DEFAULT, input);
|
|
12
|
+
expect(output).toBe(input);
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it("return number if input is positive number as string", () => {
|
|
17
|
+
const inputs = ["0", "1", "2", "100", "200.12"];
|
|
18
|
+
expect.assertions(inputs.length);
|
|
19
|
+
|
|
20
|
+
inputs.forEach((input) => {
|
|
21
|
+
const output = toPositiveNumberWithDefault(DEFAULT, input);
|
|
22
|
+
expect(output).toBe(Number(input));
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("return default number if input is negative number", () => {
|
|
27
|
+
const inputs = [-1, -2, -100, -Infinity];
|
|
28
|
+
expect.assertions(inputs.length);
|
|
29
|
+
|
|
30
|
+
inputs.forEach((input) => {
|
|
31
|
+
const output = toPositiveNumberWithDefault(DEFAULT, input);
|
|
32
|
+
expect(output).toBe(DEFAULT);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it("return default number if input is negative number as string", () => {
|
|
37
|
+
const inputs = ["-1", "-2", "-100"];
|
|
38
|
+
expect.assertions(inputs.length);
|
|
39
|
+
|
|
40
|
+
inputs.forEach((input) => {
|
|
41
|
+
const output = toPositiveNumberWithDefault(DEFAULT, input);
|
|
42
|
+
expect(output).toBe(DEFAULT);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("return default if input is not a number or infinite", () => {
|
|
47
|
+
const inputs = [
|
|
48
|
+
"vfdvf",
|
|
49
|
+
null,
|
|
50
|
+
undefined,
|
|
51
|
+
NaN,
|
|
52
|
+
"",
|
|
53
|
+
{},
|
|
54
|
+
{ test: 1 },
|
|
55
|
+
[],
|
|
56
|
+
[1],
|
|
57
|
+
];
|
|
58
|
+
|
|
59
|
+
expect.assertions(inputs.length);
|
|
60
|
+
|
|
61
|
+
inputs.forEach((input) => {
|
|
62
|
+
const output = toPositiveNumberWithDefault(DEFAULT, input);
|
|
63
|
+
expect(output).toBe(DEFAULT);
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
});
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { toPositiveNumberWithDefaultZero } from "..";
|
|
2
|
+
|
|
3
|
+
const DEFAULT = 0;
|
|
4
|
+
|
|
5
|
+
describe("toNumber", () => {
|
|
6
|
+
it("return number if input is positive number", () => {
|
|
7
|
+
const inputs = [0, 1, 2, 100, 200.12];
|
|
8
|
+
expect.assertions(inputs.length);
|
|
9
|
+
|
|
10
|
+
inputs.forEach((input) => {
|
|
11
|
+
const output = toPositiveNumberWithDefaultZero(input);
|
|
12
|
+
expect(output).toBe(input);
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it("return number if input is positive number as string", () => {
|
|
17
|
+
const inputs = ["0", "1", "2", "100", "200.12"];
|
|
18
|
+
expect.assertions(inputs.length);
|
|
19
|
+
|
|
20
|
+
inputs.forEach((input) => {
|
|
21
|
+
const output = toPositiveNumberWithDefaultZero(input);
|
|
22
|
+
expect(output).toBe(Number(input));
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("return default number if input is negative number", () => {
|
|
27
|
+
const inputs = [-1, -2, -100];
|
|
28
|
+
expect.assertions(inputs.length);
|
|
29
|
+
|
|
30
|
+
inputs.forEach((input) => {
|
|
31
|
+
const output = toPositiveNumberWithDefaultZero(input);
|
|
32
|
+
expect(output).toBe(DEFAULT);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it("return default number if input is negative number as string", () => {
|
|
37
|
+
const inputs = ["-1", "-2", "-100"];
|
|
38
|
+
expect.assertions(inputs.length);
|
|
39
|
+
|
|
40
|
+
inputs.forEach((input) => {
|
|
41
|
+
const output = toPositiveNumberWithDefaultZero(input);
|
|
42
|
+
expect(output).toBe(DEFAULT);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("return default if input is not a number or infinite", () => {
|
|
47
|
+
const inputs = [
|
|
48
|
+
"vfdvf",
|
|
49
|
+
null,
|
|
50
|
+
undefined,
|
|
51
|
+
NaN,
|
|
52
|
+
"",
|
|
53
|
+
{},
|
|
54
|
+
{ test: 1 },
|
|
55
|
+
[],
|
|
56
|
+
[1],
|
|
57
|
+
];
|
|
58
|
+
|
|
59
|
+
expect.assertions(inputs.length);
|
|
60
|
+
|
|
61
|
+
inputs.forEach((input) => {
|
|
62
|
+
const output = toPositiveNumberWithDefaultZero(input);
|
|
63
|
+
expect(output).toBe(DEFAULT);
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
});
|
package/numberUtils/index.ts
CHANGED
|
@@ -66,3 +66,23 @@ export const isZero = (value: unknown): boolean =>
|
|
|
66
66
|
export const isMinusZero = (value: number) => {
|
|
67
67
|
return 1 / value === -Infinity;
|
|
68
68
|
};
|
|
69
|
+
|
|
70
|
+
export const toPositiveNumberWithDefault = (
|
|
71
|
+
defaultValue: number,
|
|
72
|
+
value: unknown
|
|
73
|
+
): number => {
|
|
74
|
+
const possibleNumber = toNumber(value);
|
|
75
|
+
|
|
76
|
+
if (R.isNil(possibleNumber)) {
|
|
77
|
+
return defaultValue;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (possibleNumber < 0) {
|
|
81
|
+
return defaultValue;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return possibleNumber;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export const toPositiveNumberWithDefaultZero = (value: unknown): number =>
|
|
88
|
+
toPositiveNumberWithDefault(0, value);
|
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.4620237415",
|
|
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.4620237415",
|
|
32
32
|
"buffer": "^5.2.1",
|
|
33
33
|
"camelize": "^1.0.0",
|
|
34
34
|
"create-react-context": "^0.2.3",
|