@applicaster/zapp-react-native-utils 12.0.2-rc.0 → 13.0.0-alpha.1552112220
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/analyticsUtils/AnalyticPlayerListener.ts +18 -1
- package/appUtils/HooksManager/{Hook.js → Hook.ts} +35 -23
- package/appUtils/HooksManager/__tests__/__snapshots__/hook.test.js.snap +4 -2
- 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} +121 -112
- package/appUtils/HooksManager/types.ts +116 -0
- package/appUtils/RiverFocusManager/index.js +17 -12
- package/appUtils/focusManager/treeDataStructure/Tree/index.js +2 -3
- package/appUtils/focusManager/treeDataStructure/Utils/index.js +1 -3
- package/appUtils/{index.js → index.ts} +1 -1
- package/appUtils/keyCodes/__tests__/keyCodes.test.js +3 -3
- package/appUtils/keyCodes/{index.js → index.ts} +2 -0
- 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 -0
- package/appUtils/keyCodes/keysByPlatform.ts +8 -0
- package/appUtils/keyInputHandler/KeyInputHandler.ts +68 -0
- package/appUtils/platform/platformUtils.ts +0 -14
- package/appUtils/playerManager/index.ts +6 -2
- package/appUtils/playerManager/player.ts +17 -5
- package/appUtils/playerManager/playerNative.ts +2 -1
- package/appUtils/playerManager/usePlayerControllerSetup.tsx +3 -3
- package/domUtils/{cookieManager.js → cookieManager.ts} +1 -2
- package/functionUtils/index.ts +15 -11
- package/modalState/index.ts +1 -5
- package/navigationUtils/index.ts +14 -5
- package/package.json +2 -2
- package/reactHooks/navigation/index.ts +7 -4
- package/reactHooks/player/TVSeekControlller/ISeekController.ts +32 -0
- package/reactHooks/player/TVSeekControlller/LongPressSeekController.ts +71 -0
- package/reactHooks/player/TVSeekControlller/TVSeekController.ts +258 -0
- package/reactHooks/player/TVSeekControlller/TapSeekController.ts +53 -0
- package/reactHooks/player/const.ts +0 -4
- package/reactHooks/player/index.ts +0 -6
- package/reactUtils/index.ts +0 -14
- package/appUtils/keyCodes/keys.ios.js +0 -46
- package/reactHooks/player/__tests__/useAutoSeek.test.tsx +0 -116
- package/reactHooks/player/__tests__/useTapSeek.test.ts +0 -94
- package/reactHooks/player/useAutoSeek.tsx +0 -87
- package/reactHooks/player/useSeek.tsx +0 -66
- package/reactHooks/player/useTapSeek.tsx +0 -58
- /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
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { SubscriberObj } from "../../functionUtils";
|
|
2
|
+
import { HOOKS_EVENTS } from "./constants";
|
|
3
|
+
|
|
4
|
+
export interface HookConfiguration {}
|
|
5
|
+
|
|
6
|
+
/* existing Hook Plugn props: sample */
|
|
7
|
+
interface _HookModulePlugin {
|
|
8
|
+
Component:
|
|
9
|
+
| React.FC<HookPluginProps>
|
|
10
|
+
| React.Component<HookPluginProps, any>
|
|
11
|
+
| React.ReactNode;
|
|
12
|
+
ModalContainer?: React.FC<ModalProps> | React.Component<ModalProps, any>;
|
|
13
|
+
skipHook?: (payload: ZappRiver | ZappEntry) => boolean;
|
|
14
|
+
presentFullScreen: boolean;
|
|
15
|
+
showNavBar?: boolean;
|
|
16
|
+
isFlowBlocker: (() => boolean) | boolean; // narrow this
|
|
17
|
+
hasPlayerHook?: boolean;
|
|
18
|
+
name: string;
|
|
19
|
+
runInBackground?: (
|
|
20
|
+
item: HookPluginProps["payload"],
|
|
21
|
+
callback: hookCallback,
|
|
22
|
+
hookPlugin: HookScreenData,
|
|
23
|
+
presentUI: (payload?: HookPluginProps["payload"]) => void
|
|
24
|
+
) => any;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
//* Derived from usage */
|
|
28
|
+
export interface HookModule {
|
|
29
|
+
ModalContainer?: React.ComponentType<any>;
|
|
30
|
+
Component: React.ComponentType<any>;
|
|
31
|
+
presentFullScreen: boolean;
|
|
32
|
+
run?: (
|
|
33
|
+
arg0: unknown,
|
|
34
|
+
callback: () => void,
|
|
35
|
+
configuration: HookConfiguration
|
|
36
|
+
) => void; // not sure about optional parameter
|
|
37
|
+
hasPlayerHook?: boolean;
|
|
38
|
+
configuration?: HookConfiguration;
|
|
39
|
+
isFlowBlocker: () => boolean;
|
|
40
|
+
skipHook?: (payload?: ZappRiver | ZappEntry) => boolean;
|
|
41
|
+
runInBackground?: (
|
|
42
|
+
arg0: unknown,
|
|
43
|
+
callback: () => void,
|
|
44
|
+
hookPlugin: Hook,
|
|
45
|
+
presentUI: (payload?: HookPluginProps["payload"]) => void
|
|
46
|
+
) => void;
|
|
47
|
+
name: string;
|
|
48
|
+
showNavBar?: boolean; // unsure
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export type HookManagerArgs = {
|
|
52
|
+
rivers: Record<string, ZappRiver>;
|
|
53
|
+
plugins: ZappPlugin[];
|
|
54
|
+
targetScreen: ZappRiver;
|
|
55
|
+
startUpHooksData?: {
|
|
56
|
+
startUpHooks?: unknown[] | "in_process";
|
|
57
|
+
setStartUpHooks?: (arg0: string) => void;
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export interface HookManager {
|
|
62
|
+
subscriber: SubscriberObj;
|
|
63
|
+
presentScreenHook: (
|
|
64
|
+
hook: Hook,
|
|
65
|
+
payload: unknown,
|
|
66
|
+
callback: (...any) => void
|
|
67
|
+
) => void;
|
|
68
|
+
executeHook: (
|
|
69
|
+
hook: Hook,
|
|
70
|
+
payload: unknown,
|
|
71
|
+
callback: (...any) => void
|
|
72
|
+
) => void;
|
|
73
|
+
handleHooks: (payload: unknown) => void;
|
|
74
|
+
runInBackground: (
|
|
75
|
+
hook: Hook,
|
|
76
|
+
payload: unknown,
|
|
77
|
+
callback: (...any) => void,
|
|
78
|
+
presentUI: (payload?: HookPluginProps["payload"]) => void
|
|
79
|
+
) => void;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export type HookIniObj = {
|
|
83
|
+
hook: HookModule & {
|
|
84
|
+
module: HookModule;
|
|
85
|
+
general: unknown;
|
|
86
|
+
screen_id?: string;
|
|
87
|
+
identifier?: string;
|
|
88
|
+
weight?: number | string;
|
|
89
|
+
};
|
|
90
|
+
hooks: Hook<any>[];
|
|
91
|
+
manager: HookManager;
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
export interface Hook<T extends HookModule = HookModule> {
|
|
95
|
+
manager: HookManager;
|
|
96
|
+
lastHook: boolean;
|
|
97
|
+
state: number;
|
|
98
|
+
module: T;
|
|
99
|
+
screen_id: string;
|
|
100
|
+
identifier: string;
|
|
101
|
+
configuration: T["configuration"];
|
|
102
|
+
setStateAndNotify(
|
|
103
|
+
event: typeof HOOKS_EVENTS[keyof typeof HOOKS_EVENTS],
|
|
104
|
+
opts: {
|
|
105
|
+
error?: typeof Error;
|
|
106
|
+
route?: string;
|
|
107
|
+
hookPlugin: Hook<T>;
|
|
108
|
+
payload: unknown;
|
|
109
|
+
}
|
|
110
|
+
);
|
|
111
|
+
general?: {
|
|
112
|
+
transition_type: typeof HOOKS_EVENTS[keyof typeof HOOKS_EVENTS];
|
|
113
|
+
allow_screen_plugin_presentation: boolean;
|
|
114
|
+
is_flow_blocker: boolean;
|
|
115
|
+
};
|
|
116
|
+
}
|
|
@@ -26,7 +26,7 @@ export const riverFocusManager = (function () {
|
|
|
26
26
|
/**
|
|
27
27
|
* Retrieve screen focus data by id
|
|
28
28
|
*
|
|
29
|
-
* @param {
|
|
29
|
+
* @param {{screenFocusableGroupId: string}} screenFocusableGroupId Unique Id of the screen from layout.json
|
|
30
30
|
*
|
|
31
31
|
*/
|
|
32
32
|
function screenFocusableData({ screenFocusableGroupId }) {
|
|
@@ -36,8 +36,9 @@ export const riverFocusManager = (function () {
|
|
|
36
36
|
/**
|
|
37
37
|
* Clear screen data for specific screen
|
|
38
38
|
*
|
|
39
|
-
* @param {
|
|
40
|
-
*
|
|
39
|
+
* @param {{ screenId: string, isInsideContainer: boolean }}
|
|
40
|
+
* screenId Unique Id of the screen from layout.json
|
|
41
|
+
* isInsideContainer If this screen a screen picker child
|
|
41
42
|
*
|
|
42
43
|
*/
|
|
43
44
|
function clearScreenData({ screenId, isInsideContainer }) {
|
|
@@ -60,9 +61,13 @@ export const riverFocusManager = (function () {
|
|
|
60
61
|
/**
|
|
61
62
|
* Focus on selected items
|
|
62
63
|
*
|
|
63
|
-
* @param {
|
|
64
|
-
*
|
|
65
|
-
*
|
|
64
|
+
* @param {{
|
|
65
|
+
* screenFocusableGroupId: string,
|
|
66
|
+
* screenFocusedOnItem: () => void,
|
|
67
|
+
* previousAction: QuickBrickNavigationActionType,
|
|
68
|
+
* isDeepLink: boolean }} object contains data for focus
|
|
69
|
+
* - `screenFocusedOnItem` focusable item to focus
|
|
70
|
+
* - `previousActionhistory` navigator history object
|
|
66
71
|
*
|
|
67
72
|
*/
|
|
68
73
|
function focusOnSelectedItem({
|
|
@@ -115,15 +120,15 @@ export const riverFocusManager = (function () {
|
|
|
115
120
|
|
|
116
121
|
/**
|
|
117
122
|
* Create unique key that will be used for save focused group data inside specific screen
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
*
|
|
123
|
+
* @param {{ screenId: string, isInsideContainer: boolean }}
|
|
124
|
+
* screenId Unique Id of the screen from layout.json
|
|
125
|
+
* isInsideContainer If this screen a screen picker child
|
|
121
126
|
*
|
|
122
127
|
*/
|
|
123
128
|
function screenFocusableGroupId({ screenId, isInsideContainer }) {
|
|
124
|
-
return
|
|
125
|
-
?
|
|
126
|
-
|
|
129
|
+
return `RiverFocusableGroup-${screenId}${
|
|
130
|
+
R.isNil(isInsideContainer) ? "" : "-isInsideContainer"
|
|
131
|
+
}`;
|
|
127
132
|
}
|
|
128
133
|
|
|
129
134
|
return {
|
|
@@ -59,7 +59,7 @@ export class Tree {
|
|
|
59
59
|
/**
|
|
60
60
|
* Update node with provided data from newNode
|
|
61
61
|
* @private
|
|
62
|
-
* @param {Object}
|
|
62
|
+
* @param {Object} currentNode to update
|
|
63
63
|
* @param {Object} newNode node to take data from
|
|
64
64
|
*/
|
|
65
65
|
updateNode(currentNode, newNode) {
|
|
@@ -175,7 +175,6 @@ export class Tree {
|
|
|
175
175
|
* @private
|
|
176
176
|
* @param {Object} node to check
|
|
177
177
|
* @returns True if node has defined groupID
|
|
178
|
-
* @returns False if node has NOT defined groupID
|
|
179
178
|
*/
|
|
180
179
|
hasGroupID(node) {
|
|
181
180
|
return node.component && node.component.props.groupId;
|
|
@@ -191,7 +190,7 @@ export class Tree {
|
|
|
191
190
|
const findChildNode = this.findInTree(node.component.props.groupId);
|
|
192
191
|
|
|
193
192
|
if (findChildNode) {
|
|
194
|
-
this.root.children.pop(
|
|
193
|
+
this.root.children.pop();
|
|
195
194
|
node.children.push(findChildNode);
|
|
196
195
|
}
|
|
197
196
|
}
|
|
@@ -191,7 +191,6 @@ const toDistance = ({ target, direction, comparisonRect }) => {
|
|
|
191
191
|
* Get target in shortest distance in specified direction
|
|
192
192
|
* @private
|
|
193
193
|
* @param {Object} direction of the navigation, which led to this focus change
|
|
194
|
-
* @param {Object} excludedNode node which should be excluded from target group
|
|
195
194
|
* @param {Array} targetNodes array of input target nodes
|
|
196
195
|
* @param {Object} comparisonRect rectangle to compare sides in direction.
|
|
197
196
|
* @returns {Object} target in direction.
|
|
@@ -300,8 +299,7 @@ export function findFocusableNode(direction, currentFocusNode) {
|
|
|
300
299
|
* @public
|
|
301
300
|
* @param {Object} direction of the navigation, which led to this focus change
|
|
302
301
|
* @param {Object} component - object to check props.prioritiseFocusOn
|
|
303
|
-
* @returns {Boolean} TRUE if object has priority in direction.
|
|
304
|
-
* @returns {Boolean} FALSE if object has NO priority in direction.
|
|
302
|
+
* @returns {Boolean} TRUE if object has priority in direction. FALSE if object has NO priority in direction.
|
|
305
303
|
*/
|
|
306
304
|
export function hasPriorityInDirection(direction, component) {
|
|
307
305
|
const { prioritiseFocusOn = 0 } = component.props;
|
|
@@ -9,7 +9,7 @@ export { KEYS, ARROW_KEYS } from "./keyCodes/keys";
|
|
|
9
9
|
|
|
10
10
|
export { playerManager } from "./playerManager";
|
|
11
11
|
|
|
12
|
-
export {
|
|
12
|
+
export { AccessibilityManager } from "./accessibilityManager";
|
|
13
13
|
|
|
14
14
|
export function deprecationMessage(fn, replacement) {
|
|
15
15
|
if (__DEV__ && process.env.NODE_ENV !== "test") {
|
|
@@ -13,7 +13,7 @@ const globalTizen = {
|
|
|
13
13
|
describe("keyCodes", () => {
|
|
14
14
|
describe("keyCode", () => {
|
|
15
15
|
const { keyCode } = require("..");
|
|
16
|
-
const { KEYS } = require("../keys.web");
|
|
16
|
+
const { KEYS } = require("../keys/keys.web");
|
|
17
17
|
|
|
18
18
|
it("returns an object for a given key event", () => {
|
|
19
19
|
expect(keyCode(KEYS.Enter)).toMatchSnapshot();
|
|
@@ -63,7 +63,7 @@ describe("keyCodes", () => {
|
|
|
63
63
|
it("uses the proper keyCode for the environment", () => {
|
|
64
64
|
Platform.OS = "samsung_tv";
|
|
65
65
|
const { keyCode } = require("../");
|
|
66
|
-
const { KEYS } = require("../keys.web");
|
|
66
|
+
const { KEYS } = require("../keys/keys.web");
|
|
67
67
|
|
|
68
68
|
expect(globalTizen.tvinputdevice.registerKeyBatch).toHaveBeenCalledWith([
|
|
69
69
|
"MediaPlay",
|
|
@@ -97,7 +97,7 @@ describe("keyCodes", () => {
|
|
|
97
97
|
it("uses the proper keyCode for the environment", () => {
|
|
98
98
|
Platform.OS = "lg_tv";
|
|
99
99
|
const { keyCode } = require("..");
|
|
100
|
-
const { KEYS } = require("../keys.web");
|
|
100
|
+
const { KEYS } = require("../keys/keys.web");
|
|
101
101
|
// Back is reserved on LG
|
|
102
102
|
expect(keyCode({ keyCode: 417 }).matches(KEYS.Forward)).toBeTruthy();
|
|
103
103
|
});
|
|
@@ -1,22 +1,3 @@
|
|
|
1
|
-
export const KEYS = {
|
|
2
|
-
Enter: { code: "Enter", keyCode: 13 },
|
|
3
|
-
EnterKeyboard: { code: "EnterKeyboard", keyCode: 66 },
|
|
4
|
-
Back: { code: "Back", keyCode: 8 },
|
|
5
|
-
Space: { code: "Space", keyCode: 32 },
|
|
6
|
-
m: { code: "m", keyCode: 77 },
|
|
7
|
-
ArrowLeft: { code: "ArrowLeft", keyCode: 37 },
|
|
8
|
-
ArrowUp: { code: "ArrowUp", keyCode: 38 },
|
|
9
|
-
ArrowRight: { code: "ArrowRight", keyCode: 39 },
|
|
10
|
-
ArrowDown: { code: "ArrowDown", keyCode: 40 },
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export const ARROW_KEYS = [
|
|
14
|
-
KEYS.ArrowUp,
|
|
15
|
-
KEYS.ArrowLeft,
|
|
16
|
-
KEYS.ArrowDown,
|
|
17
|
-
KEYS.ArrowRight,
|
|
18
|
-
];
|
|
19
|
-
|
|
20
1
|
export function keyEventMapper(keyCode) {
|
|
21
2
|
switch (keyCode) {
|
|
22
3
|
case 19: // ArrowUp
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export const KEYS = {
|
|
2
|
+
Enter: { code: "Enter", keyCode: 13 },
|
|
3
|
+
EnterKeyboard: { code: "EnterKeyboard", keyCode: 66 },
|
|
4
|
+
Back: { code: "Back", keyCode: 8 },
|
|
5
|
+
Space: { code: "Space", keyCode: 32 },
|
|
6
|
+
m: { code: "m", keyCode: 77 },
|
|
7
|
+
ArrowLeft: { code: "ArrowLeft", keyCode: 37 },
|
|
8
|
+
ArrowUp: { code: "ArrowUp", keyCode: 38 },
|
|
9
|
+
ArrowRight: { code: "ArrowRight", keyCode: 39 },
|
|
10
|
+
ArrowDown: { code: "ArrowDown", keyCode: 40 },
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const ARROW_KEYS = [
|
|
14
|
+
KEYS.ArrowUp,
|
|
15
|
+
KEYS.ArrowLeft,
|
|
16
|
+
KEYS.ArrowDown,
|
|
17
|
+
KEYS.ArrowRight,
|
|
18
|
+
];
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export const KEYS = {
|
|
2
|
+
Enter: { code: "Enter", keyCode: 13 },
|
|
3
|
+
Space: { code: "Space", keyCode: 32 },
|
|
4
|
+
m: { code: "m", keyCode: 77 },
|
|
5
|
+
ArrowLeft: { code: "ArrowLeft", keyCode: 37 },
|
|
6
|
+
ArrowUp: { code: "ArrowUp", keyCode: 38 },
|
|
7
|
+
ArrowRight: { code: "ArrowRight", keyCode: 39 },
|
|
8
|
+
ArrowDown: { code: "ArrowDown", keyCode: 40 },
|
|
9
|
+
Back: { code: "Backspace", keyCode: 8 },
|
|
10
|
+
Play: { code: "PlayPause", keyCode: 179 },
|
|
11
|
+
Pause: { code: "Pause", keyCode: 179 },
|
|
12
|
+
Forward: { code: "Forward", keyCode: 176 },
|
|
13
|
+
Rewind: { code: "Rewind", keyCode: 177 },
|
|
14
|
+
VolumeUp: { code: "VolumeUp", keyCode: 175 },
|
|
15
|
+
VolumeDown: { code: "VolumeDown", keyCode: 174 },
|
|
16
|
+
ToggleMute: { code: "VolumeMute", keyCode: 173 },
|
|
17
|
+
Stop: { code: "Q", keyCode: 81 },
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const ARROW_KEYS = [
|
|
21
|
+
KEYS.ArrowUp,
|
|
22
|
+
KEYS.ArrowLeft,
|
|
23
|
+
KEYS.ArrowDown,
|
|
24
|
+
KEYS.ArrowRight,
|
|
25
|
+
];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// dummy file to make sure the folder structure is created
|
|
2
|
+
export const KEYS: Record<string, { code: string; keyCode: number }> = {
|
|
3
|
+
ArrowLeft: { code: "ArrowLeft", keyCode: -1 },
|
|
4
|
+
ArrowUp: { code: "ArrowUp", keyCode: -1 },
|
|
5
|
+
ArrowRight: { code: "ArrowRight", keyCode: -1 },
|
|
6
|
+
ArrowDown: { code: "ArrowDown", keyCode: -1 },
|
|
7
|
+
Back: { code: "Back", keyCode: -1 },
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export const ARROW_KEYS = [
|
|
11
|
+
KEYS.ArrowUp,
|
|
12
|
+
KEYS.ArrowLeft,
|
|
13
|
+
KEYS.ArrowDown,
|
|
14
|
+
KEYS.ArrowRight,
|
|
15
|
+
];
|
|
@@ -77,6 +77,10 @@ const web = {
|
|
|
77
77
|
Exit: { code: "Exit", keyCode: null },
|
|
78
78
|
Escape: { code: "Escape", keyCode: 27 },
|
|
79
79
|
EscapeDevice: { code: "Escape", keyCode: 27 },
|
|
80
|
+
// For Debugging
|
|
81
|
+
Z: { code: "KeyZ", keyCode: 90 }, // Hardware Backward Button
|
|
82
|
+
X: { code: "KeyX", keyCode: 88 }, // Hardware Enter Button
|
|
83
|
+
C: { code: "KeyC", keyCode: 67 }, // Hardware Forward Button
|
|
80
84
|
};
|
|
81
85
|
|
|
82
86
|
const android_tv = {
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
export type SeekKeyHandlerListener = {
|
|
2
|
+
onRewindPress: () => boolean;
|
|
3
|
+
onForwardPress: () => boolean;
|
|
4
|
+
onRewindPressOut: () => void;
|
|
5
|
+
onForwardPressOut: () => void;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export class KeyInputHandler {
|
|
9
|
+
private static instance: KeyInputHandler;
|
|
10
|
+
|
|
11
|
+
public static getInstance() {
|
|
12
|
+
if (!KeyInputHandler.instance) {
|
|
13
|
+
KeyInputHandler.instance = new KeyInputHandler();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return KeyInputHandler.instance;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
constructor() {
|
|
20
|
+
this.listeners = [];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
private listeners: SeekKeyHandlerListener[] = [];
|
|
24
|
+
|
|
25
|
+
addListener = (listener: SeekKeyHandlerListener) => {
|
|
26
|
+
this.listeners.splice(0, 0, listener);
|
|
27
|
+
|
|
28
|
+
return () => this.removeListener(listener);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
removeListener = (listener: SeekKeyHandlerListener) => {
|
|
32
|
+
this.listeners = this.listeners.filter((l) => l !== listener);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
onRewindPress = () => {
|
|
36
|
+
for (const element of this.listeners) {
|
|
37
|
+
if (element.onRewindPress()) {
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
onForwardPress = () => {
|
|
44
|
+
for (const element of this.listeners) {
|
|
45
|
+
if (element.onForwardPress()) {
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
// TODO: Event should be send to listeners who handled down event
|
|
52
|
+
onRewindPressOut = () => {
|
|
53
|
+
this.listeners.forEach((listener) => listener.onRewindPressOut());
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
onForwardPressOut = () => {
|
|
57
|
+
this.listeners.forEach((listener) => listener.onForwardPressOut());
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
getSeekMethods = () => {
|
|
61
|
+
return {
|
|
62
|
+
onForwardPress: this.onForwardPress,
|
|
63
|
+
onRewindPress: this.onRewindPress,
|
|
64
|
+
onForwardPressOut: this.onForwardPressOut,
|
|
65
|
+
onRewindPressOut: this.onRewindPressOut,
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
}
|
|
@@ -9,20 +9,6 @@ import {
|
|
|
9
9
|
import { PLATFORM_KEYS, PLATFORMS } from "./const";
|
|
10
10
|
import { createLogger, utilsLogger } from "../../logger";
|
|
11
11
|
|
|
12
|
-
declare global {
|
|
13
|
-
interface Window {
|
|
14
|
-
VIZIO?: {
|
|
15
|
-
exitApplication: () => void;
|
|
16
|
-
Chromevox: {
|
|
17
|
-
play: (text: string) => void;
|
|
18
|
-
};
|
|
19
|
-
setClosedCaptionHandler: (
|
|
20
|
-
callback: (isCCEnabled: boolean) => void
|
|
21
|
-
) => void;
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
12
|
const { log_debug } = createLogger({
|
|
27
13
|
category: "General",
|
|
28
14
|
subsystem: "PlatformUtils",
|
|
@@ -169,8 +169,12 @@ export class PlayerManager {
|
|
|
169
169
|
this.addPlayer(id, playerController);
|
|
170
170
|
|
|
171
171
|
if (playerController.playerRole === PlayerRole.Primary) {
|
|
172
|
-
if (
|
|
173
|
-
RNPlayerManager
|
|
172
|
+
if (RNPlayerManager) {
|
|
173
|
+
Object.keys(RNPlayerManager).forEach((pluginId) => {
|
|
174
|
+
if (pluginId !== playerController.playerPluginId) {
|
|
175
|
+
RNPlayerManager[pluginId]?.stopBackgroundPlayback?.();
|
|
176
|
+
}
|
|
177
|
+
});
|
|
174
178
|
}
|
|
175
179
|
|
|
176
180
|
playerController.addListener({
|
|
@@ -5,6 +5,7 @@ import { createLogger, utilsLogger } from "../../logger";
|
|
|
5
5
|
import { getBoolFromConfigValue } from "../../configurationUtils";
|
|
6
6
|
import { PlayerRole, SharedPlayerCallBacksKeys } from "./conts";
|
|
7
7
|
import { OverlaysObserver } from "./OverlayObserver/OverlaysObserver";
|
|
8
|
+
import { TVSeekController } from "../../reactHooks/player/TVSeekControlller/TVSeekController";
|
|
8
9
|
|
|
9
10
|
const logger = createLogger({
|
|
10
11
|
category: "PlayerController",
|
|
@@ -49,6 +50,8 @@ export class Player {
|
|
|
49
50
|
[key: string]: QuickBrickPlayer.SharedPlayerCallBacks;
|
|
50
51
|
} = {};
|
|
51
52
|
|
|
53
|
+
public seekController?: TVSeekController | null;
|
|
54
|
+
|
|
52
55
|
get entry(): ZappEntry | null {
|
|
53
56
|
return this._entry;
|
|
54
57
|
}
|
|
@@ -59,6 +62,8 @@ export class Player {
|
|
|
59
62
|
}
|
|
60
63
|
|
|
61
64
|
constructor(props) {
|
|
65
|
+
this.seekController = null;
|
|
66
|
+
|
|
62
67
|
this.playerState = {
|
|
63
68
|
// We want isLive null by default to be able not to show controls if we do not know type
|
|
64
69
|
isLive: null,
|
|
@@ -91,6 +96,8 @@ export class Player {
|
|
|
91
96
|
this.onVideoProgress = this.onVideoProgress.bind(this);
|
|
92
97
|
this.onVideoLoad = this.onVideoLoad.bind(this);
|
|
93
98
|
this.isFullScreenSupported = this.isFullScreenSupported.bind(this);
|
|
99
|
+
this.onPlayerSeekComplete = this.onPlayerSeekComplete.bind(this);
|
|
100
|
+
|
|
94
101
|
this.entryObservable = null;
|
|
95
102
|
}
|
|
96
103
|
|
|
@@ -321,7 +328,7 @@ export class Player {
|
|
|
321
328
|
* You should use dispatchPlayerEvent at PlayerContainer or call playerManager.invokeHandler directly
|
|
322
329
|
* This allows you to use one method for everything.
|
|
323
330
|
*/
|
|
324
|
-
|
|
331
|
+
onPlayerSeekStart = (event: QuickBrickPlayer.OnSeekStartEvent) => {
|
|
325
332
|
const { isLive, seekableDuration, currentTime, duration, seekTime } = event;
|
|
326
333
|
|
|
327
334
|
this.setPlaybackState({ currentTime, duration, seekableDuration, isLive });
|
|
@@ -336,10 +343,11 @@ export class Player {
|
|
|
336
343
|
});
|
|
337
344
|
};
|
|
338
345
|
|
|
339
|
-
|
|
346
|
+
onPlayerSeekComplete = (event: QuickBrickPlayer.OnSeekCompleteEvent) => {
|
|
340
347
|
const { isLive, seekableDuration, currentTime, duration } = event;
|
|
341
348
|
|
|
342
349
|
this.setPlaybackState({ currentTime, duration, seekableDuration, isLive });
|
|
350
|
+
|
|
343
351
|
this.playerState.seekPosition = null;
|
|
344
352
|
|
|
345
353
|
if (!isLive) {
|
|
@@ -620,14 +628,18 @@ export class Player {
|
|
|
620
628
|
selectTrack = (_track) => {};
|
|
621
629
|
|
|
622
630
|
protected notifyPlayHeadPositionUpdate = () => {
|
|
631
|
+
const currentTime = this.getPosition();
|
|
632
|
+
|
|
623
633
|
const event = {
|
|
624
|
-
currentTime
|
|
634
|
+
currentTime,
|
|
625
635
|
duration: this.getDuration(),
|
|
626
636
|
item: this.getEntry(),
|
|
627
637
|
seekableDuration: this.playerState.seekableDuration,
|
|
628
638
|
isLive: this.isLive(),
|
|
629
639
|
};
|
|
630
640
|
|
|
641
|
+
this.seekController?.onVideoProgress(currentTime);
|
|
642
|
+
|
|
631
643
|
this.invokeListenersUpdate({
|
|
632
644
|
callbackName: SharedPlayerCallBacksKeys.OnVideoProgress,
|
|
633
645
|
event,
|
|
@@ -653,8 +665,8 @@ export class Player {
|
|
|
653
665
|
};
|
|
654
666
|
|
|
655
667
|
public getListener = (): QuickBrickPlayer.SharedPlayerCallBacks => ({
|
|
656
|
-
onPlayerSeekStart: this.
|
|
657
|
-
onPlayerSeekComplete: this.
|
|
668
|
+
onPlayerSeekStart: this.onPlayerSeekStart,
|
|
669
|
+
onPlayerSeekComplete: this.onPlayerSeekComplete,
|
|
658
670
|
onVideoEnd: this.onVideoEnd,
|
|
659
671
|
onError: this.onError,
|
|
660
672
|
onVideoError: this.onVideoError,
|
|
@@ -222,9 +222,10 @@ export class PlayerNative extends Player {
|
|
|
222
222
|
|
|
223
223
|
onVideoLoad = (event) => {
|
|
224
224
|
if (this.startPosition) {
|
|
225
|
-
super.onVideoLoad({ ...event, ignoreContinueWatching: true });
|
|
226
225
|
this.seekTo(this.startPosition);
|
|
227
226
|
this.startPosition = null;
|
|
227
|
+
|
|
228
|
+
super.onVideoLoad({ ...event, ignoreContinueWatching: true });
|
|
228
229
|
} else {
|
|
229
230
|
super.onVideoLoad(event);
|
|
230
231
|
}
|
|
@@ -39,7 +39,7 @@ export const usePlayerControllerSetup = ({
|
|
|
39
39
|
? { supports_native_controls: true, ...config }
|
|
40
40
|
: config;
|
|
41
41
|
|
|
42
|
-
const
|
|
42
|
+
const combinedProps = {
|
|
43
43
|
player: ref,
|
|
44
44
|
listener: props as any,
|
|
45
45
|
config: newConfig,
|
|
@@ -47,9 +47,9 @@ export const usePlayerControllerSetup = ({
|
|
|
47
47
|
entry,
|
|
48
48
|
playerPluginId: pluginId,
|
|
49
49
|
playerRole: PlayerRole.Primary,
|
|
50
|
-
}
|
|
50
|
+
};
|
|
51
51
|
|
|
52
|
-
setPlayerController(
|
|
52
|
+
setPlayerController(new ControllerType(combinedProps));
|
|
53
53
|
}, [playerId, entry?.id]);
|
|
54
54
|
|
|
55
55
|
React.useEffect(() => {
|
|
@@ -2,7 +2,6 @@ import { domUtilsLogger } from "./logger";
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Gets an object of cookies and sets them on the DOM.
|
|
5
|
-
* @param {Object} cookies selected data key for label.
|
|
6
5
|
*/
|
|
7
6
|
export function setCookies(cookies): void {
|
|
8
7
|
const cookieKeys = Object.keys(cookies);
|
|
@@ -25,7 +24,7 @@ export function setCookies(cookies): void {
|
|
|
25
24
|
/**
|
|
26
25
|
* Gets cookies set on DOM
|
|
27
26
|
*/
|
|
28
|
-
export function getCookies():
|
|
27
|
+
export function getCookies(): typeof document.cookie {
|
|
29
28
|
try {
|
|
30
29
|
if (document) {
|
|
31
30
|
return document.cookie;
|