@applicaster/zapp-react-native-utils 13.0.0-alpha.2635505531 → 13.0.0-alpha.2685746452
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/actionsExecutor/ActionExecutor.ts +16 -9
- package/actionsExecutor/ActionExecutorContext.tsx +74 -9
- package/alertUtils/alert.ts +148 -0
- package/alertUtils/index.ts +1 -148
- package/analyticsUtils/AnalyticPlayerListener.ts +18 -1
- package/analyticsUtils/__tests__/__snapshots__/analyticsManagerNoModule.test.js.snap +9 -9
- package/analyticsUtils/currentScreenProperities.ts +6 -4
- package/analyticsUtils/helpers/hooks.ts +1 -1
- package/appUtils/HooksManager/{Hook.js → Hook.ts} +35 -23
- package/appUtils/HooksManager/__tests__/__snapshots__/hook.test.js.snap +10 -8
- package/appUtils/HooksManager/__tests__/__snapshots__/hooksManager.test.js.snap +693 -0
- package/appUtils/HooksManager/__tests__/hook.test.js +196 -184
- package/appUtils/HooksManager/__tests__/hooksManager.test.js +96 -99
- package/appUtils/HooksManager/{constants.js → constants.ts} +1 -1
- package/appUtils/HooksManager/{index.js → index.ts} +122 -113
- package/appUtils/HooksManager/types.ts +119 -0
- package/appUtils/RiverFocusManager/index.js +17 -12
- package/appUtils/accessibilityManager/index.ts +42 -1
- package/appUtils/contextKeysManager/contextResolver.ts +77 -0
- package/appUtils/contextKeysManager/index.ts +2 -2
- package/appUtils/contextKeysManager/utils/index.ts +2 -1
- package/appUtils/focusManager/__tests__/__snapshots__/focusManager.test.js.snap +7 -6
- package/appUtils/focusManager/index.ts +100 -74
- package/appUtils/focusManager/treeDataStructure/Tree/index.js +25 -3
- package/appUtils/focusManager/treeDataStructure/Utils/index.js +1 -3
- package/appUtils/focusManager/utils/enums.ts +4 -0
- package/appUtils/focusManagerAux/utils/index.ts +4 -3
- package/appUtils/{index.js → index.ts} +1 -1
- package/appUtils/keyCodes/__tests__/__snapshots__/keyCodes.test.js.snap +2 -2
- package/appUtils/keyCodes/__tests__/keyCodes.test.js +4 -4
- package/appUtils/keyCodes/{index.js → index.ts} +13 -7
- package/appUtils/keyCodes/keys/index.ts +3 -0
- package/appUtils/keyCodes/{keys.android.js → keys/keyEventMapper.ts} +0 -19
- package/appUtils/keyCodes/keys/keys.android.ts +18 -0
- package/appUtils/keyCodes/keys/keys.ios.ts +25 -0
- package/appUtils/keyCodes/keys/keys.ts +15 -0
- package/appUtils/keyCodes/{keysByPlatform.js → keys/keysByPlatform.ts} +4 -3
- package/appUtils/keyCodes/keysByPlatform.ts +8 -0
- package/appUtils/keyInputHandler/KeyInputHandler.ts +68 -0
- package/appUtils/orientationHelper.ts +11 -13
- package/appUtils/platform/const.ts +14 -0
- package/appUtils/platform/platformUtils.ts +47 -18
- package/appUtils/playerManager/index.ts +7 -3
- package/appUtils/playerManager/player.ts +38 -22
- package/appUtils/playerManager/playerNative.ts +19 -4
- package/appUtils/playerManager/usePlayerControllerSetup.tsx +1 -15
- package/arrayUtils/__tests__/__snapshots__/arrayUtils.test.ts.snap +4 -4
- package/dateUtils/index.ts +2 -0
- package/domUtils/{cookieManager.js → cookieManager.ts} +1 -2
- package/equalUtils/__tests__/isEqual/combination.test.ts +263 -0
- package/equalUtils/index.ts +49 -30
- package/focusManager/FocusManager.ts +11 -1
- package/focusManager/index.ts +49 -4
- package/functionUtils/__tests__/__snapshots__/functionUtils.test.js.snap +4 -4
- package/functionUtils/index.ts +36 -19
- package/idleUtils/__tests__/withTimeout$.test.ts +37 -0
- package/idleUtils/index.ts +1 -1
- package/idleUtils/withTimeout.ts +15 -2
- package/logger/const.ts +9 -67
- package/manifestUtils/__tests__/createConfig.test.js +16 -16
- package/manifestUtils/defaultManifestConfigurations/player.js +8 -0
- package/manifestUtils/fonts/index.js +5 -6
- 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/modalState/index.ts +1 -5
- package/navigationUtils/__tests__/__snapshots__/navigationUtils.test.js.snap +6 -6
- package/navigationUtils/__tests__/itemTypes.test.js +2 -2
- package/navigationUtils/__tests__/navigationUtils.test.js +2 -2
- package/navigationUtils/index.ts +17 -8
- package/numberUtils/index.ts +7 -5
- package/package.json +5 -10
- package/playerUtils/configurationGenerator.ts +8 -0
- package/reactHooks/autoscrolling/__tests__/useTrackCurrentAutoScrollingElement.test.ts +1 -1
- package/reactHooks/autoscrolling/__tests__/useTrackedView.test.tsx +6 -8
- package/reactHooks/autoscrolling/useTrackedView.ts +12 -1
- package/reactHooks/cell-click/__tests__/index.test.js +10 -2
- package/reactHooks/cell-click/index.ts +7 -1
- package/reactHooks/feed/__tests__/useBuildPipesUrl.test.tsx +4 -4
- package/reactHooks/feed/__tests__/useFeedLoader.test.tsx +10 -11
- package/reactHooks/feed/useFeedLoader.tsx +1 -1
- package/reactHooks/feed/usePipesCacheReset.ts +5 -5
- package/reactHooks/flatList/__tests__/index.test.tsx +30 -21
- package/reactHooks/layout/__tests__/index.test.tsx +10 -10
- package/reactHooks/layout/useDimensions/helpers/__tests__/getInitialDimensions.native.test.js +14 -28
- package/reactHooks/layout/useDimensions/helpers/__tests__/getInitialDimensions.test.js +1 -1
- package/reactHooks/layout/useDimensions/useDimensions.ts +8 -0
- package/reactHooks/navigation/__mocks__/useNavigation.ts +3 -0
- package/reactHooks/navigation/__tests__/index.test.tsx +6 -21
- package/reactHooks/navigation/index.ts +41 -240
- package/reactHooks/navigation/useGetBottomTabBarHeight.ts +12 -0
- package/reactHooks/navigation/useGetNavBarTopBorderWidth.ts +14 -0
- package/reactHooks/navigation/useGetTabBarHeight.ts +10 -0
- package/reactHooks/navigation/useIsScreenActive.ts +17 -0
- package/reactHooks/navigation/useNavigationPluginData.ts +15 -0
- package/reactHooks/navigation/useNavigationType.ts +15 -0
- package/reactHooks/navigation/usePathname.ts +4 -0
- package/reactHooks/navigation/useProfilerLogging.ts +15 -0
- package/reactHooks/navigation/useRoute.ts +100 -0
- package/reactHooks/navigation/useUniqueRouteSuffix.ts +41 -0
- package/reactHooks/player/TVSeekControlller/ISeekController.ts +28 -3
- package/reactHooks/player/TVSeekControlller/LongPressSeekController.ts +43 -96
- package/reactHooks/player/TVSeekControlller/TVSeekController.ts +203 -97
- package/reactHooks/player/TVSeekControlller/TapSeekController.ts +35 -55
- package/reactHooks/player/__tests__/{useAutoSeek.test.tsx → useAutoSeek._test.tsx} +2 -10
- package/reactHooks/player/const.ts +1 -5
- package/reactHooks/player/index.ts +0 -6
- package/reactHooks/state/useRefWithInitialValue.ts +14 -0
- package/reactHooks/state/useStateFromSubscribe.ts +23 -0
- package/reactHooks/usePluginConfiguration.ts +1 -1
- package/reactHooks/useSubscriberFor.ts +4 -3
- package/reactUtils/__tests__/__snapshots__/reactUtilsHelpers.test.js.snap +16 -4
- package/reactUtils/__tests__/reactUtils.test.js +1 -37
- package/reactUtils/__tests__/reactUtilsHelpers.test.js +72 -71
- package/reactUtils/createContext/__tests__/__snapshots__/helpers.test.js.snap +13 -79
- package/reactUtils/createContext/__tests__/__snapshots__/{index.test.js.snap → index.test.ts.snap} +2 -2
- 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 -25
- package/screenState/index.ts +24 -10
- package/services/js2native.ts +673 -0
- package/testUtils/index.tsx +0 -10
- package/theme/__mocks__/index.ts +4 -0
- package/theme/index.ts +1 -1
- package/time/BackgroundTimer.ts +55 -0
- package/time/Timer.ts +9 -6
- package/types.ts +1 -0
- package/utils/README.md +34 -0
- package/utils/clone.ts +56 -0
- package/utils/flatten.ts +3 -0
- package/utils/index.ts +7 -0
- package/utils/splitEvery.ts +27 -0
- package/utils/times.ts +2 -0
- package/zappFrameworkUtils/presentPluginOneTime.ts +2 -3
- package/appUtils/keyCodes/keys.ios.js +0 -46
- package/appUtils/playerManager/DelayedSeekPlayerWrapper.tsx +0 -180
- package/reactHooks/player/useAutoSeek.tsx +0 -106
- package/reactHooks/player/useSeek.tsx +0 -17
- package/reactHooks/player/useTapSeek.tsx +0 -85
- package/reactUtils/createContext/__tests__/index-no-react.test.js +0 -27
- /package/appUtils/HooksManager/{logger.js → logger.ts} +0 -0
- /package/appUtils/{directionHelper.js → directionHelper.ts} +0 -0
- /package/appUtils/keyCodes/{androidTVKeys.js → androidTVKeys.ts} +0 -0
- /package/appUtils/keyCodes/{keys.web.js → keys/keys.web.ts} +0 -0
- /package/appUtils/{localizationsHelper.js → localizationsHelper.ts} +0 -0
- /package/domUtils/{logger.js → logger.ts} +0 -0
- /package/reactHooks/player/__tests__/{useTapSeek.test.ts → useTapSeek._test.ts} +0 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { DeviceEventEmitter, NativeModules } from "react-native";
|
|
2
|
+
import { platformSelect } from "../reactUtils";
|
|
3
|
+
|
|
4
|
+
const { BackgroundTimer: RNBackgroundTimer } = NativeModules;
|
|
5
|
+
|
|
6
|
+
class BackgroundTimer {
|
|
7
|
+
private uniqueId: number;
|
|
8
|
+
private readonly callbacks: Record<number, () => void>;
|
|
9
|
+
|
|
10
|
+
constructor() {
|
|
11
|
+
this.uniqueId = 0;
|
|
12
|
+
this.callbacks = {};
|
|
13
|
+
|
|
14
|
+
const EventEmitter = platformSelect({
|
|
15
|
+
android: DeviceEventEmitter,
|
|
16
|
+
ios: undefined,
|
|
17
|
+
default: undefined,
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
EventEmitter?.addListener("BackgroundTimer.timer.fired", (id: number) => {
|
|
21
|
+
if (this.callbacks[id]) {
|
|
22
|
+
const callback = this.callbacks[id];
|
|
23
|
+
delete this.callbacks[id];
|
|
24
|
+
callback();
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
setTimeout(callback, timeout): number | NodeJS.Timeout {
|
|
30
|
+
if (!RNBackgroundTimer) {
|
|
31
|
+
return global.setTimeout(callback, timeout);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
this.uniqueId += 1;
|
|
35
|
+
const timeoutId = this.uniqueId;
|
|
36
|
+
|
|
37
|
+
this.callbacks[timeoutId] = callback;
|
|
38
|
+
RNBackgroundTimer.setTimeout(timeoutId, timeout);
|
|
39
|
+
|
|
40
|
+
return timeoutId;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
clearTimeout(timeoutId: number | NodeJS.Timeout): void {
|
|
44
|
+
if (!RNBackgroundTimer) {
|
|
45
|
+
return global.clearTimeout(timeoutId as NodeJS.Timeout);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (this.callbacks[timeoutId as number]) {
|
|
49
|
+
delete this.callbacks[timeoutId as number];
|
|
50
|
+
RNBackgroundTimer.clearTimeout(timeoutId);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export default new BackgroundTimer();
|
package/time/Timer.ts
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
|
+
import BackgroundTimer from "./BackgroundTimer";
|
|
2
|
+
|
|
1
3
|
export class Timer {
|
|
2
4
|
private startTime: number;
|
|
3
|
-
private
|
|
4
|
-
private timeoutId: NodeJS.Timeout | null;
|
|
5
|
+
private timeoutId: number | NodeJS.Timeout | null;
|
|
5
6
|
|
|
6
|
-
constructor(
|
|
7
|
-
|
|
7
|
+
constructor(
|
|
8
|
+
private callback: () => void,
|
|
9
|
+
private remaining: number = null
|
|
10
|
+
) {
|
|
8
11
|
this.timeoutId = null;
|
|
9
12
|
}
|
|
10
13
|
|
|
11
14
|
start(): void {
|
|
12
15
|
this.startTime = Date.now();
|
|
13
|
-
this.timeoutId = setTimeout(this.callback, this.remaining);
|
|
16
|
+
this.timeoutId = BackgroundTimer.setTimeout(this.callback, this.remaining);
|
|
14
17
|
|
|
15
18
|
this.remaining = 0;
|
|
16
19
|
}
|
|
@@ -26,6 +29,6 @@ export class Timer {
|
|
|
26
29
|
}
|
|
27
30
|
|
|
28
31
|
clear(): void {
|
|
29
|
-
clearTimeout(this.timeoutId);
|
|
32
|
+
BackgroundTimer.clearTimeout(this.timeoutId);
|
|
30
33
|
}
|
|
31
34
|
}
|
package/types.ts
CHANGED
package/utils/README.md
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
### ramda replacement utils
|
|
2
|
+
|
|
3
|
+
See contribution guide below
|
|
4
|
+
|
|
5
|
+
## Reference
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### _.flatten
|
|
9
|
+
R.times => flatten.ts
|
|
10
|
+
|
|
11
|
+
### _.times
|
|
12
|
+
R.times => times.ts
|
|
13
|
+
|
|
14
|
+
### _.drop
|
|
15
|
+
R.drop(N,array) => array.slice(N)
|
|
16
|
+
|
|
17
|
+
### _.clone
|
|
18
|
+
R.clone => clone.ts
|
|
19
|
+
|
|
20
|
+
### _.splitEvery
|
|
21
|
+
R.splitEvery => splitEvery.ts
|
|
22
|
+
|
|
23
|
+
### _.length
|
|
24
|
+
R.length(data) => data?.length ?? 0
|
|
25
|
+
|
|
26
|
+
## Contribution
|
|
27
|
+
|
|
28
|
+
To add new helper function
|
|
29
|
+
|
|
30
|
+
1. Search for replacement ( you can reuse lodash, preferable pure JS solution), arguments should match with Ramda definition
|
|
31
|
+
2. Add new file, update exports in index file
|
|
32
|
+
3. If replacement is simple enough that doesn't need a function - add snippet to this README
|
|
33
|
+
4. Make sure README is updated and contains reference for newly added function
|
|
34
|
+
5. Write unit test to test input/output. You can use AI's help.
|
package/utils/clone.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates a deep copy of the value which may contain (nested) `Array`s and `Object`s,
|
|
3
|
+
* `Number`s, `String`s, `Boolean`s and `Date`s. `Function`s are assigned by reference
|
|
4
|
+
* rather than copied. Dispatches to a `clone` method if present.
|
|
5
|
+
*
|
|
6
|
+
* @param {*} value - The value to clone
|
|
7
|
+
* @return {*} A deep copy of the provided value
|
|
8
|
+
*/
|
|
9
|
+
export const clone = (value) => {
|
|
10
|
+
// Handle null or undefined
|
|
11
|
+
if (value == null) {
|
|
12
|
+
return value;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Check if value has a custom clone method
|
|
16
|
+
if (typeof value.clone === "function") {
|
|
17
|
+
return value.clone();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Handle primitive types (they're immutable so no need to clone)
|
|
21
|
+
if (typeof value !== "object") {
|
|
22
|
+
return value;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Handle Date objects
|
|
26
|
+
if (value instanceof Date) {
|
|
27
|
+
return new Date(value.getTime());
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Handle RegExp objects
|
|
31
|
+
if (value instanceof RegExp) {
|
|
32
|
+
return new RegExp(value.source, value.flags);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Handle Array objects
|
|
36
|
+
if (Array.isArray(value)) {
|
|
37
|
+
return value.map((item) => clone(item));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Handle Object literals
|
|
41
|
+
if (Object.prototype.toString.call(value) === "[object Object]") {
|
|
42
|
+
const result = {};
|
|
43
|
+
const keys = Object.keys(value);
|
|
44
|
+
|
|
45
|
+
for (let i = 0; i < keys.length; i++) {
|
|
46
|
+
const key = keys[i];
|
|
47
|
+
result[key] = clone(value[key]);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return result;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// For other types like Maps, Sets, etc., we would need additional handling
|
|
54
|
+
// For simplicity, we'll return the original value for unsupported types
|
|
55
|
+
return value;
|
|
56
|
+
};
|
package/utils/flatten.ts
ADDED
package/utils/index.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export function splitEvery(size, collection) {
|
|
2
|
+
if (size <= 0) {
|
|
3
|
+
throw new Error("First argument to splitEvery must be a positive integer");
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
const result = [];
|
|
7
|
+
|
|
8
|
+
// Handle string input
|
|
9
|
+
if (typeof collection === "string") {
|
|
10
|
+
for (let i = 0; i < collection.length; i += size) {
|
|
11
|
+
result.push(collection.slice(i, i + size));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return result;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Handle array input
|
|
18
|
+
if (Array.isArray(collection)) {
|
|
19
|
+
for (let i = 0; i < collection.length; i += size) {
|
|
20
|
+
result.push(collection.slice(i, i + size));
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return result;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return result;
|
|
27
|
+
}
|
package/utils/times.ts
ADDED
|
@@ -92,9 +92,8 @@ export const PresentHookPluginOneTime = (
|
|
|
92
92
|
const presentOneTimeVersionName =
|
|
93
93
|
await getLatestWatchedVersionNumberFromStorage(storageKey, namespace);
|
|
94
94
|
|
|
95
|
-
const applicationVersionName =
|
|
96
|
-
versionNameKey
|
|
97
|
-
);
|
|
95
|
+
const applicationVersionName =
|
|
96
|
+
await sessionStorage.getItem(versionNameKey);
|
|
98
97
|
|
|
99
98
|
if (!presentOneTimeVersionName || !applicationVersionName) {
|
|
100
99
|
log_info(
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
/* global tizen */
|
|
2
|
-
const isTizen = typeof tizen !== "undefined";
|
|
3
|
-
|
|
4
|
-
export const KEYS = {
|
|
5
|
-
Enter: { code: "Enter", keyCode: 13 },
|
|
6
|
-
Space: { code: "Space", keyCode: 32 },
|
|
7
|
-
m: { code: "m", keyCode: 77 },
|
|
8
|
-
ArrowLeft: { code: "ArrowLeft", keyCode: 37 },
|
|
9
|
-
ArrowUp: { code: "ArrowUp", keyCode: 38 },
|
|
10
|
-
ArrowRight: { code: "ArrowRight", keyCode: 39 },
|
|
11
|
-
ArrowDown: { code: "ArrowDown", keyCode: 40 },
|
|
12
|
-
Back: isTizen
|
|
13
|
-
? { code: "Back", keyCode: 10009 }
|
|
14
|
-
: { code: "Backspace", keyCode: 8 },
|
|
15
|
-
Play: isTizen
|
|
16
|
-
? { code: "MediaPlay", keyCode: 10252 }
|
|
17
|
-
: { code: "PlayPause", keyCode: 179 },
|
|
18
|
-
Pause: isTizen
|
|
19
|
-
? { code: "MediaPause", keyCode: 19 }
|
|
20
|
-
: { code: "Pause", keyCode: 179 },
|
|
21
|
-
Forward: isTizen
|
|
22
|
-
? { code: "MediaFastForward", keyCode: 417 }
|
|
23
|
-
: { code: "Forward", keyCode: 176 },
|
|
24
|
-
Rewind: isTizen
|
|
25
|
-
? { code: "MediaRewind", keyCode: 412 }
|
|
26
|
-
: { code: "Rewind", keyCode: 177 },
|
|
27
|
-
VolumeUp: isTizen
|
|
28
|
-
? { code: "VolumeUp", keyCode: 447 }
|
|
29
|
-
: { code: "VolumeUp", keyCode: 175 },
|
|
30
|
-
VolumeDown: isTizen
|
|
31
|
-
? { code: "VolumeDown", keyCode: 448 }
|
|
32
|
-
: { code: "VolumeDown", keyCode: 174 },
|
|
33
|
-
ToggleMute: isTizen
|
|
34
|
-
? { code: "VolumeMute", keyCode: 449 }
|
|
35
|
-
: { code: "VolumeMute", keyCode: 173 },
|
|
36
|
-
Stop: isTizen
|
|
37
|
-
? { code: "MediaStop", keyCode: 413 }
|
|
38
|
-
: { code: "Q", keyCode: 81 },
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
export const ARROW_KEYS = [
|
|
42
|
-
KEYS.ArrowUp,
|
|
43
|
-
KEYS.ArrowLeft,
|
|
44
|
-
KEYS.ArrowDown,
|
|
45
|
-
KEYS.ArrowRight,
|
|
46
|
-
];
|
|
@@ -1,180 +0,0 @@
|
|
|
1
|
-
import { Player } from "./player";
|
|
2
|
-
import { BehaviorSubject } from "rxjs";
|
|
3
|
-
|
|
4
|
-
export class DelayedSeekPlayerWrapper extends Player {
|
|
5
|
-
private wrappedPlayer: Player;
|
|
6
|
-
private delayedSeekPosition: number;
|
|
7
|
-
private wasPlaying: boolean;
|
|
8
|
-
|
|
9
|
-
constructor(props, player: Player) {
|
|
10
|
-
super(props);
|
|
11
|
-
this.wrappedPlayer = player;
|
|
12
|
-
this.delayedSeekPosition = null;
|
|
13
|
-
|
|
14
|
-
this.wrappedPlayer.addListener({
|
|
15
|
-
id: "Master-Wrapper-Listener",
|
|
16
|
-
listener: this,
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
this.onPlayerSeekComplete = this.onPlayerSeekComplete.bind(this);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
getOverlayObservable = () => {
|
|
23
|
-
return this.wrappedPlayer.getOverlayObservable();
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
getEntryObservable = (): BehaviorSubject<ZappEntry | null> => {
|
|
27
|
-
return this.wrappedPlayer.getEntryObservable();
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
getEntry = (): ZappEntry | null => this.wrappedPlayer.getEntry();
|
|
31
|
-
|
|
32
|
-
getListener = (): QuickBrickPlayer.SharedPlayerCallBacks => {
|
|
33
|
-
return this.wrappedPlayer.getListener();
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
togglePlayPause = () => {
|
|
37
|
-
this.wrappedPlayer.togglePlayPause();
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
selectTrack = (_track) => this.wrappedPlayer.selectTrack(_track);
|
|
41
|
-
|
|
42
|
-
// Implement all default methods by delegating them to wrapped player
|
|
43
|
-
public seekTo = (position: number) => {
|
|
44
|
-
this.wrappedPlayer.seekTo(position);
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
public isPlaying = () => {
|
|
48
|
-
return this.wrappedPlayer.isPlaying();
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
public isPaused = () => {
|
|
52
|
-
return this.wrappedPlayer.isPaused();
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
public play = () => {
|
|
56
|
-
this.wrappedPlayer.play();
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
public pause = () => {
|
|
60
|
-
this.wrappedPlayer.pause();
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
getState = () => {
|
|
64
|
-
const currentState = this.wrappedPlayer.getState();
|
|
65
|
-
|
|
66
|
-
if (this.delayedSeekPosition === null) {
|
|
67
|
-
return currentState;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return {
|
|
71
|
-
...currentState,
|
|
72
|
-
contentPosition: this.delayedSeekPosition,
|
|
73
|
-
isPaused: false,
|
|
74
|
-
seekPosition: this.delayedSeekPosition,
|
|
75
|
-
};
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
forward = (deltaTime: number) => {
|
|
79
|
-
if (this.delayedSeekPosition !== null) {
|
|
80
|
-
this.delayedSeekPosition += deltaTime;
|
|
81
|
-
this.playerState.seekPosition = this.delayedSeekPosition;
|
|
82
|
-
|
|
83
|
-
this.onVideoProgress({
|
|
84
|
-
currentTime: this.playerState.seekPosition,
|
|
85
|
-
duration: this.getDuration(),
|
|
86
|
-
seekableDuration: this.playerState.seekableDuration,
|
|
87
|
-
isLive: this.playerState.isLive,
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
// this.scheduleResumePlayback(DELAYED_SEEK_DELAY, this.delayedSeekPosition);
|
|
91
|
-
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
if (this.playerState.seekPosition == null) {
|
|
96
|
-
this.playerState.seekPosition = this.playerState.contentPosition;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
this.playerState.seekPosition += deltaTime;
|
|
100
|
-
|
|
101
|
-
this.wrappedPlayer.forward(deltaTime);
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
rewind = (deltaTime: number) => {
|
|
105
|
-
if (this.delayedSeekPosition !== null) {
|
|
106
|
-
this.delayedSeekPosition -= deltaTime;
|
|
107
|
-
|
|
108
|
-
if (this.delayedSeekPosition < 0) {
|
|
109
|
-
this.delayedSeekPosition = 0;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
this.playerState.seekPosition = this.delayedSeekPosition;
|
|
113
|
-
|
|
114
|
-
this.onVideoProgress({
|
|
115
|
-
currentTime: this.playerState.seekPosition,
|
|
116
|
-
duration: this.getDuration(),
|
|
117
|
-
seekableDuration: this.playerState.seekableDuration,
|
|
118
|
-
isLive: this.playerState.isLive,
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
// this.scheduleResumePlayback(DELAYED_SEEK_DELAY, this.delayedSeekPosition);
|
|
122
|
-
|
|
123
|
-
return;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
if (this.playerState.seekPosition == null) {
|
|
127
|
-
this.playerState.seekPosition = this.playerState.contentPosition;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
this.playerState.seekPosition -= deltaTime;
|
|
131
|
-
this.wrappedPlayer.rewind(deltaTime);
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
public getConfig = () => this.wrappedPlayer.getConfig();
|
|
135
|
-
|
|
136
|
-
// TODO: replace with enum of supported orientations
|
|
137
|
-
isFullScreenSupported(): boolean {
|
|
138
|
-
return this.wrappedPlayer.isFullScreenSupported();
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
public supportsNativeControls = (): boolean =>
|
|
142
|
-
this.wrappedPlayer.supportsNativeControls();
|
|
143
|
-
|
|
144
|
-
public supportNativeCast = (): boolean =>
|
|
145
|
-
this.wrappedPlayer.supportNativeCast();
|
|
146
|
-
|
|
147
|
-
public isInDelayedSeek = () => this.delayedSeekPosition !== null;
|
|
148
|
-
|
|
149
|
-
public enterDelayedSeek() {
|
|
150
|
-
if (this.delayedSeekPosition !== null) {
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
if (this.playerState.seekPosition === null) {
|
|
155
|
-
this.playerState.seekPosition = this.playerState.contentPosition;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
this.delayedSeekPosition = this.playerState.seekPosition;
|
|
159
|
-
|
|
160
|
-
if (!this.isPaused()) {
|
|
161
|
-
this.wasPlaying = true;
|
|
162
|
-
this.wrappedPlayer.pause();
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
public exitDelayedSeek() {
|
|
167
|
-
if (this.delayedSeekPosition === null) {
|
|
168
|
-
return;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
this.wrappedPlayer.seekTo(this.delayedSeekPosition);
|
|
172
|
-
|
|
173
|
-
if (this.wasPlaying) {
|
|
174
|
-
this.wasPlaying = false;
|
|
175
|
-
this.wrappedPlayer.play();
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
this.delayedSeekPosition = null;
|
|
179
|
-
}
|
|
180
|
-
}
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import React, { useEffect, useState } from "react";
|
|
2
|
-
import { usePrevious } from "@applicaster/zapp-react-native-utils/reactHooks/utils";
|
|
3
|
-
import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils/playerManager";
|
|
4
|
-
import {
|
|
5
|
-
MAX_SEEK_TIME,
|
|
6
|
-
ON_HOLD_INTERVAL,
|
|
7
|
-
SEEK_TYPE,
|
|
8
|
-
SKIP_TIME_BASE,
|
|
9
|
-
} from "./const";
|
|
10
|
-
import { noop } from "../../functionUtils";
|
|
11
|
-
|
|
12
|
-
export const useAutoSeek = (resetHUDTimer = noop) => {
|
|
13
|
-
const [isRunning, setIsRunning] = useState<boolean>(false);
|
|
14
|
-
const [direction, setDirection] = useState<Nullable<SEEK_TYPE>>(null);
|
|
15
|
-
const [multiplier, setMultiplier] = useState(1);
|
|
16
|
-
|
|
17
|
-
const intervalTimer = React.useRef(null);
|
|
18
|
-
const prevRunning = usePrevious(isRunning);
|
|
19
|
-
|
|
20
|
-
const setIntervalTimer = (cb) => {
|
|
21
|
-
if (intervalTimer.current) {
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
intervalTimer.current = setInterval(() => {
|
|
26
|
-
intervalTimer.current = null;
|
|
27
|
-
cb();
|
|
28
|
-
}, ON_HOLD_INTERVAL);
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
const clearIntervalTimer = () => {
|
|
32
|
-
clearInterval(intervalTimer.current);
|
|
33
|
-
intervalTimer.current = null;
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
const resetState = () => {
|
|
37
|
-
setIsRunning(false);
|
|
38
|
-
setDirection(null);
|
|
39
|
-
setMultiplier(1);
|
|
40
|
-
clearIntervalTimer();
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
useEffect(() => {
|
|
44
|
-
const player = playerManager.getInstanceController();
|
|
45
|
-
if (!player) return;
|
|
46
|
-
|
|
47
|
-
if (isRunning) {
|
|
48
|
-
player?.enterDelayedSeek();
|
|
49
|
-
} else if (!isRunning) {
|
|
50
|
-
player.exitDelayedSeek();
|
|
51
|
-
}
|
|
52
|
-
}, [isRunning]);
|
|
53
|
-
|
|
54
|
-
useEffect(() => {
|
|
55
|
-
if (!isRunning) {
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
const player = playerManager.getInstanceController();
|
|
60
|
-
|
|
61
|
-
if (!player) return;
|
|
62
|
-
|
|
63
|
-
if (direction) {
|
|
64
|
-
player[direction](Math.min(MAX_SEEK_TIME, SKIP_TIME_BASE * multiplier));
|
|
65
|
-
resetHUDTimer();
|
|
66
|
-
}
|
|
67
|
-
}, [multiplier, direction, isRunning]);
|
|
68
|
-
|
|
69
|
-
useEffect(() => {
|
|
70
|
-
if (isRunning && isRunning !== prevRunning) {
|
|
71
|
-
setIntervalTimer(() => {
|
|
72
|
-
setMultiplier((prev) => {
|
|
73
|
-
return prev + 1;
|
|
74
|
-
});
|
|
75
|
-
});
|
|
76
|
-
} else if (!isRunning && isRunning !== prevRunning) {
|
|
77
|
-
resetState();
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
return () => {
|
|
81
|
-
clearIntervalTimer();
|
|
82
|
-
};
|
|
83
|
-
}, [isRunning, direction]);
|
|
84
|
-
|
|
85
|
-
const autoSeekStop = React.useCallback(() => {
|
|
86
|
-
resetState();
|
|
87
|
-
}, []);
|
|
88
|
-
|
|
89
|
-
const autoSeekStart = React.useCallback(
|
|
90
|
-
(eventType: SEEK_TYPE) => {
|
|
91
|
-
// Check if there is another session running
|
|
92
|
-
if (isRunning) {
|
|
93
|
-
autoSeekStop();
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
setDirection(eventType);
|
|
97
|
-
setIsRunning(true);
|
|
98
|
-
},
|
|
99
|
-
[isRunning, autoSeekStop]
|
|
100
|
-
);
|
|
101
|
-
|
|
102
|
-
return React.useMemo(
|
|
103
|
-
() => ({ autoSeekStart, autoSeekStop }),
|
|
104
|
-
[autoSeekStart, autoSeekStop]
|
|
105
|
-
);
|
|
106
|
-
};
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import React, { useMemo } from "react";
|
|
2
|
-
import { noop } from "../../functionUtils";
|
|
3
|
-
import { TVSeekController } from "./TVSeekControlller/TVSeekController";
|
|
4
|
-
|
|
5
|
-
export const useSeek = (resetHUDTimer = noop) => {
|
|
6
|
-
return useMemo(() => TVSeekController.getInstance().getSeekMethods(), []);
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
export const withUseSeek = (Component) =>
|
|
10
|
-
Object.assign(
|
|
11
|
-
(props) => {
|
|
12
|
-
const seekMethods = useSeek(props?.resetHUDTimer);
|
|
13
|
-
|
|
14
|
-
return <Component {...props} seekMethods={seekMethods} />;
|
|
15
|
-
},
|
|
16
|
-
{ displayName: "WithUseSeek" }
|
|
17
|
-
);
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import { useCallback, useRef, useState } from "react";
|
|
2
|
-
import * as R from "ramda";
|
|
3
|
-
import {
|
|
4
|
-
MAX_SEEK_TIME,
|
|
5
|
-
ON_PRESS_RESET_DURATION,
|
|
6
|
-
SEEK_TYPE,
|
|
7
|
-
SKIP_TIME_BASE,
|
|
8
|
-
} from "./const";
|
|
9
|
-
import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils";
|
|
10
|
-
|
|
11
|
-
type SeekType = SEEK_TYPE | null;
|
|
12
|
-
|
|
13
|
-
const getSkipTime = (multiplier) =>
|
|
14
|
-
R.min(MAX_SEEK_TIME, SKIP_TIME_BASE * multiplier);
|
|
15
|
-
|
|
16
|
-
export const useTapSeek = () => {
|
|
17
|
-
const [resumeTimer, setResumeTimer] = useState<NodeJS.Timeout>(null);
|
|
18
|
-
const onPressMultiplier = useRef(1);
|
|
19
|
-
const lastPressTime = useRef(0);
|
|
20
|
-
const currentOnPressEventType = useRef<SeekType>(null);
|
|
21
|
-
|
|
22
|
-
const resetMultiplier = useCallback(() => {
|
|
23
|
-
onPressMultiplier.current = 1;
|
|
24
|
-
}, []);
|
|
25
|
-
|
|
26
|
-
const handlePressEvent = useCallback(
|
|
27
|
-
(eventType) => {
|
|
28
|
-
const player = playerManager.getInstanceController();
|
|
29
|
-
if (!player) return;
|
|
30
|
-
|
|
31
|
-
const now = Date.now();
|
|
32
|
-
const timeSinceLastPress = now - lastPressTime.current;
|
|
33
|
-
const isSameEventType = eventType === currentOnPressEventType.current;
|
|
34
|
-
|
|
35
|
-
const isWithinResetDuration =
|
|
36
|
-
timeSinceLastPress <= ON_PRESS_RESET_DURATION;
|
|
37
|
-
|
|
38
|
-
const shouldIncreaseMultiplier = isSameEventType && isWithinResetDuration;
|
|
39
|
-
|
|
40
|
-
if (shouldIncreaseMultiplier) {
|
|
41
|
-
onPressMultiplier.current += 1;
|
|
42
|
-
} else {
|
|
43
|
-
resetMultiplier();
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const seekTime = getSkipTime(onPressMultiplier.current);
|
|
47
|
-
|
|
48
|
-
player[eventType](seekTime);
|
|
49
|
-
|
|
50
|
-
if (resumeTimer) {
|
|
51
|
-
clearTimeout(resumeTimer);
|
|
52
|
-
|
|
53
|
-
const timer = setTimeout(() => {
|
|
54
|
-
player.exitDelayedSeek();
|
|
55
|
-
setResumeTimer(null);
|
|
56
|
-
}, 2000);
|
|
57
|
-
|
|
58
|
-
setResumeTimer(timer);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const clicksBeforePause = 3;
|
|
62
|
-
|
|
63
|
-
// Only pause player if user starts to seek on large increments
|
|
64
|
-
if (onPressMultiplier.current > clicksBeforePause) {
|
|
65
|
-
if (!player.isPaused()) {
|
|
66
|
-
player.enterDelayedSeek();
|
|
67
|
-
|
|
68
|
-
const timer = setTimeout(() => {
|
|
69
|
-
player.exitDelayedSeek();
|
|
70
|
-
setResumeTimer(null);
|
|
71
|
-
}, 2000);
|
|
72
|
-
|
|
73
|
-
clearTimeout(resumeTimer);
|
|
74
|
-
setResumeTimer(timer);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
lastPressTime.current = now;
|
|
79
|
-
currentOnPressEventType.current = eventType;
|
|
80
|
-
},
|
|
81
|
-
[resetMultiplier, resumeTimer]
|
|
82
|
-
);
|
|
83
|
-
|
|
84
|
-
return handlePressEvent;
|
|
85
|
-
};
|