@applicaster/zapp-react-native-utils 12.0.5-rc.5 → 13.0.0-alpha.1035032144

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.
Files changed (101) hide show
  1. package/actionsExecutor/ActionExecutor.ts +16 -9
  2. package/actionsExecutor/ActionExecutorContext.tsx +74 -9
  3. package/alertUtils/alert.ts +148 -0
  4. package/alertUtils/index.ts +1 -148
  5. package/analyticsUtils/AnalyticPlayerListener.ts +18 -1
  6. package/analyticsUtils/__tests__/__snapshots__/analyticsManagerNoModule.test.js.snap +9 -9
  7. package/analyticsUtils/helpers/hooks.ts +1 -1
  8. package/appUtils/HooksManager/{Hook.js → Hook.ts} +35 -23
  9. package/appUtils/HooksManager/__tests__/__snapshots__/hook.test.js.snap +10 -8
  10. package/appUtils/HooksManager/__tests__/__snapshots__/hooksManager.test.js.snap +693 -0
  11. package/appUtils/HooksManager/__tests__/hook.test.js +196 -184
  12. package/appUtils/HooksManager/__tests__/hooksManager.test.js +96 -99
  13. package/appUtils/HooksManager/{constants.js → constants.ts} +1 -1
  14. package/appUtils/HooksManager/{index.js → index.ts} +121 -112
  15. package/appUtils/HooksManager/types.ts +119 -0
  16. package/appUtils/RiverFocusManager/index.js +17 -12
  17. package/appUtils/accessibilityManager/index.ts +1 -1
  18. package/appUtils/contextKeysManager/contextResolver.ts +77 -0
  19. package/appUtils/focusManager/__tests__/__snapshots__/focusManager.test.js.snap +6 -6
  20. package/appUtils/focusManager/treeDataStructure/Tree/index.js +2 -3
  21. package/appUtils/focusManager/treeDataStructure/Utils/index.js +1 -3
  22. package/appUtils/{index.js → index.ts} +1 -1
  23. package/appUtils/keyCodes/__tests__/__snapshots__/keyCodes.test.js.snap +2 -2
  24. package/appUtils/keyCodes/__tests__/keyCodes.test.js +4 -4
  25. package/appUtils/keyCodes/{index.js → index.ts} +2 -0
  26. package/appUtils/keyCodes/keys/index.ts +3 -0
  27. package/appUtils/keyCodes/{keys.android.js → keys/keyEventMapper.ts} +0 -19
  28. package/appUtils/keyCodes/keys/keys.android.ts +18 -0
  29. package/appUtils/keyCodes/keys/keys.ios.ts +25 -0
  30. package/appUtils/keyCodes/keys/keys.ts +15 -0
  31. package/appUtils/keyCodes/{keysByPlatform.js → keys/keysByPlatform.ts} +4 -0
  32. package/appUtils/keyCodes/keysByPlatform.ts +8 -0
  33. package/appUtils/keyInputHandler/KeyInputHandler.ts +68 -0
  34. package/appUtils/orientationHelper.ts +1 -1
  35. package/appUtils/platform/platformUtils.ts +6 -14
  36. package/appUtils/playerManager/player.ts +17 -5
  37. package/appUtils/playerManager/playerNative.ts +3 -2
  38. package/appUtils/playerManager/usePlayerControllerSetup.tsx +3 -3
  39. package/arrayUtils/__tests__/__snapshots__/arrayUtils.test.ts.snap +4 -4
  40. package/domUtils/{cookieManager.js → cookieManager.ts} +1 -2
  41. package/functionUtils/__tests__/__snapshots__/functionUtils.test.js.snap +4 -4
  42. package/functionUtils/index.ts +15 -11
  43. package/logger/const.ts +9 -67
  44. package/manifestUtils/__tests__/createConfig.test.js +16 -16
  45. package/modalState/index.ts +1 -5
  46. package/navigationUtils/__tests__/__snapshots__/navigationUtils.test.js.snap +6 -6
  47. package/navigationUtils/__tests__/itemTypes.test.js +2 -2
  48. package/navigationUtils/__tests__/navigationUtils.test.js +2 -2
  49. package/navigationUtils/index.ts +14 -5
  50. package/package.json +3 -2
  51. package/reactHooks/autoscrolling/__tests__/useTrackCurrentAutoScrollingElement.test.ts +1 -1
  52. package/reactHooks/autoscrolling/__tests__/useTrackedView.test.tsx +1 -1
  53. package/reactHooks/cell-click/__tests__/index.test.js +10 -2
  54. package/reactHooks/cell-click/index.ts +7 -1
  55. package/reactHooks/feed/__tests__/useBuildPipesUrl.test.tsx +4 -4
  56. package/reactHooks/feed/__tests__/useFeedLoader.test.tsx +10 -11
  57. package/reactHooks/feed/usePipesCacheReset.ts +5 -5
  58. package/reactHooks/flatList/__tests__/index.test.tsx +30 -21
  59. package/reactHooks/layout/__tests__/index.test.tsx +10 -10
  60. package/reactHooks/layout/useDimensions/helpers/__tests__/getInitialDimensions.native.test.js +14 -28
  61. package/reactHooks/layout/useDimensions/useDimensions.ts +8 -0
  62. package/reactHooks/navigation/__tests__/index.test.tsx +0 -4
  63. package/reactHooks/navigation/index.ts +29 -218
  64. package/reactHooks/navigation/useGetBottomTabBarHeight.ts +12 -0
  65. package/reactHooks/navigation/useGetNavBarTopBorderWidth.ts +14 -0
  66. package/reactHooks/navigation/useGetTabBarHeight.ts +12 -0
  67. package/reactHooks/navigation/useIsScreenActive.ts +17 -0
  68. package/reactHooks/navigation/useNavigationPluginData.ts +15 -0
  69. package/reactHooks/navigation/useNavigationType.ts +15 -0
  70. package/reactHooks/navigation/usePathname.ts +4 -0
  71. package/reactHooks/navigation/useRoute.ts +100 -0
  72. package/reactHooks/navigation/useUniqueRouteSuffix.ts +41 -0
  73. package/reactHooks/player/TVSeekControlller/ISeekController.ts +32 -0
  74. package/reactHooks/player/TVSeekControlller/LongPressSeekController.ts +71 -0
  75. package/reactHooks/player/TVSeekControlller/TVSeekController.ts +258 -0
  76. package/reactHooks/player/TVSeekControlller/TapSeekController.ts +53 -0
  77. package/reactHooks/player/__tests__/{useAutoSeek.test.tsx → useAutoSeek._test.tsx} +2 -3
  78. package/reactHooks/player/const.ts +0 -4
  79. package/reactHooks/player/index.ts +0 -6
  80. package/reactHooks/state/useStateFromSubscribe.ts +23 -0
  81. package/reactUtils/__tests__/reactUtils.test.js +10 -28
  82. package/reactUtils/createContext/__tests__/__snapshots__/helpers.test.js.snap +19 -19
  83. package/reactUtils/createContext/__tests__/__snapshots__/index.test.js.snap +2 -2
  84. package/reactUtils/createContext/__tests__/__snapshots__/provider.test.js.snap +3 -3
  85. package/reactUtils/createContext/__tests__/helpers.test.js +8 -8
  86. package/reactUtils/index.ts +0 -14
  87. package/screenState/index.ts +24 -10
  88. package/theme/__mocks__/index.ts +4 -0
  89. package/time/Timer.ts +1 -1
  90. package/types.ts +1 -0
  91. package/appUtils/keyCodes/keys.ios.js +0 -46
  92. package/reactHooks/player/useAutoSeek.tsx +0 -87
  93. package/reactHooks/player/useSeek.tsx +0 -66
  94. package/reactHooks/player/useTapSeek.tsx +0 -58
  95. /package/appUtils/HooksManager/{logger.js → logger.ts} +0 -0
  96. /package/appUtils/{directionHelper.js → directionHelper.ts} +0 -0
  97. /package/appUtils/keyCodes/{androidTVKeys.js → androidTVKeys.ts} +0 -0
  98. /package/appUtils/keyCodes/{keys.web.js → keys/keys.web.ts} +0 -0
  99. /package/appUtils/{localizationsHelper.js → localizationsHelper.ts} +0 -0
  100. /package/domUtils/{logger.js → logger.ts} +0 -0
  101. /package/reactHooks/player/__tests__/{useTapSeek.test.ts → useTapSeek._test.ts} +0 -0
@@ -0,0 +1,119 @@
1
+ import { SubscriberObj } from "../../functionUtils";
2
+ import { HOOKS_EVENTS } from "./constants";
3
+
4
+ export interface HookConfiguration {}
5
+
6
+ /* existing Hook Plugn props: sample */
7
+
8
+ /*
9
+ interface _HookModulePlugin {
10
+ Component:
11
+ | React.FC<HookPluginProps>
12
+ | React.Component<HookPluginProps, any>
13
+ | React.ReactNode;
14
+ ModalContainer?: React.FC<ModalProps> | React.Component<ModalProps, any>;
15
+ skipHook?: (payload: ZappRiver | ZappEntry) => boolean;
16
+ presentFullScreen: boolean;
17
+ showNavBar?: boolean;
18
+ isFlowBlocker: (() => boolean) | boolean; // narrow this
19
+ hasPlayerHook?: boolean;
20
+ name: string;
21
+ runInBackground?: (
22
+ item: HookPluginProps["payload"],
23
+ callback: hookCallback,
24
+ hookPlugin: HookScreenData,
25
+ presentUI: (payload?: HookPluginProps["payload"]) => void
26
+ ) => any;
27
+ }
28
+ */
29
+
30
+ //* Derived from usage */
31
+ export interface HookModule {
32
+ ModalContainer?: React.ComponentType<any>;
33
+ Component: React.ComponentType<any>;
34
+ presentFullScreen: boolean;
35
+ run?: (
36
+ arg0: unknown,
37
+ callback: () => void,
38
+ configuration: HookConfiguration
39
+ ) => void; // not sure about optional parameter
40
+ hasPlayerHook?: boolean;
41
+ configuration?: HookConfiguration;
42
+ isFlowBlocker: () => boolean;
43
+ skipHook?: (payload?: ZappRiver | ZappEntry) => boolean;
44
+ runInBackground?: (
45
+ arg0: unknown,
46
+ callback: () => void,
47
+ hookPlugin: Hook,
48
+ presentUI: (payload?: HookPluginProps["payload"]) => void
49
+ ) => void;
50
+ name: string;
51
+ showNavBar?: boolean; // unsure
52
+ }
53
+
54
+ export type HookManagerArgs = {
55
+ rivers: Record<string, ZappRiver>;
56
+ plugins: ZappPlugin[];
57
+ targetScreen: ZappRiver;
58
+ startUpHooksData?: {
59
+ startUpHooks?: unknown[] | "in_process";
60
+ setStartUpHooks?: (arg0: string) => void;
61
+ };
62
+ };
63
+
64
+ export interface HookManager {
65
+ subscriber: SubscriberObj;
66
+ presentScreenHook: (
67
+ hook: Hook,
68
+ payload: unknown,
69
+ callback: (...any) => void
70
+ ) => void;
71
+ executeHook: (
72
+ hook: Hook,
73
+ payload: unknown,
74
+ callback: (...any) => void
75
+ ) => void;
76
+ handleHooks: (payload: unknown) => void;
77
+ runInBackground: (
78
+ hook: Hook,
79
+ payload: unknown,
80
+ callback: (...any) => void,
81
+ presentUI: (payload?: HookPluginProps["payload"]) => void
82
+ ) => void;
83
+ }
84
+
85
+ export type HookIniObj = {
86
+ hook: HookModule & {
87
+ module: HookModule;
88
+ general: unknown;
89
+ screen_id?: string;
90
+ identifier?: string;
91
+ weight?: number | string;
92
+ };
93
+ hooks: Hook<any>[];
94
+ manager: HookManager;
95
+ };
96
+
97
+ export interface Hook<T extends HookModule = HookModule> {
98
+ manager: HookManager;
99
+ lastHook: boolean;
100
+ state: number;
101
+ module: T;
102
+ screen_id: string;
103
+ identifier: string;
104
+ configuration: T["configuration"];
105
+ setStateAndNotify(
106
+ event: (typeof HOOKS_EVENTS)[keyof typeof HOOKS_EVENTS],
107
+ opts: {
108
+ error?: typeof Error;
109
+ route?: string;
110
+ hookPlugin: Hook<T>;
111
+ payload: unknown;
112
+ }
113
+ );
114
+ general?: {
115
+ transition_type: (typeof HOOKS_EVENTS)[keyof typeof HOOKS_EVENTS];
116
+ allow_screen_plugin_presentation: boolean;
117
+ is_flow_blocker: boolean;
118
+ };
119
+ }
@@ -26,7 +26,7 @@ export const riverFocusManager = (function () {
26
26
  /**
27
27
  * Retrieve screen focus data by id
28
28
  *
29
- * @param {String} screenFocusableGroupId Id that was used to save screen data.
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 {String} screenId Unique Id of the screen from layout.json
40
- * @param {boolean} isInsideContainer If this screen a screen picker child
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 {String} screenFocusableGroupId Top group id that was saved as screenn
64
- * @param {String} screenFocusedOnItem focusable item to focus
65
- * @param {object} history navigator history object
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
- * @param {String} screenId Unique Id of the screen from layout.json
120
- * @param {boolean} isInsideContainer If this screen a screen picker child
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 R.isNil(isInsideContainer)
125
- ? `RiverFocusableGroup-${screenId}`
126
- : `RiverFocusableGroup-${screenId}-isInsideContainer`;
129
+ return `RiverFocusableGroup-${screenId}${
130
+ R.isNil(isInsideContainer) ? "" : "-isInsideContainer"
131
+ }`;
127
132
  }
128
133
 
129
134
  return {
@@ -6,7 +6,7 @@ import { AccessibilityRole } from "react-native";
6
6
 
7
7
  export class AccessibilityManager {
8
8
  private static _instance: AccessibilityManager | null = null;
9
- private headingTimeout: ReturnType<typeof setTimeout> | null = null;
9
+ private headingTimeout: NodeJS.Timeout | null = null;
10
10
  private WORDS_PER_MINUTE = 160;
11
11
  private MINIMUM_PAUSE = 500;
12
12
  private state$ = new BehaviorSubject<AccessibilityState>({
@@ -0,0 +1,77 @@
1
+ import { createLogger } from "../../logger";
2
+ import { ContextKeysManager } from "./index";
3
+ import * as R from "ramda";
4
+
5
+ const { log_error } = createLogger({
6
+ subsystem: "contextResolver",
7
+ category: "General",
8
+ });
9
+
10
+ interface IResolver {
11
+ resolve: (string) => Promise<string | number | object>;
12
+ }
13
+
14
+ export class EntryResolver implements IResolver {
15
+ entry: ZappEntry;
16
+
17
+ constructor(entry: ZappEntry) {
18
+ this.entry = entry;
19
+ }
20
+
21
+ async resolve(key: string) {
22
+ if (!key || key.length === 0) {
23
+ return this.entry;
24
+ }
25
+
26
+ return R.view(R.lensPath(key.split(".")), this.entry);
27
+ }
28
+ }
29
+
30
+ export class ContextResolver implements IResolver {
31
+ resolve = async (compositeKey: string) =>
32
+ ContextKeysManager.instance.getKey(compositeKey);
33
+ }
34
+
35
+ export const resolveObjectValues = async (
36
+ data: Record<string, any>,
37
+ resolvers: Record<string, IResolver> = null
38
+ ) => {
39
+ const entries = Object.entries(data);
40
+
41
+ const exResolvers = { ctx: new ContextResolver(), ...resolvers };
42
+
43
+ const resolvedEntries = await Promise.all(
44
+ entries.map(async ([key, value]) => {
45
+ if (typeof value !== "string") {
46
+ return [key, value];
47
+ }
48
+
49
+ if (!value.startsWith("@")) {
50
+ return [key, value];
51
+ }
52
+
53
+ const regex = /@{([^/]+)\/([^}]*)}/;
54
+
55
+ const match = (value as string).match(regex);
56
+
57
+ if (match) {
58
+ const contextResolverName = match[1];
59
+ const compositeKey = match[2];
60
+
61
+ const resolver = exResolvers[contextResolverName] || exResolvers.ctx;
62
+ const resolvedValue = await resolver.resolve(compositeKey);
63
+
64
+ return [key, resolvedValue];
65
+ }
66
+
67
+ log_error("resolveObjectValues: invalid context string", {
68
+ key,
69
+ value,
70
+ });
71
+
72
+ return [key, null];
73
+ })
74
+ );
75
+
76
+ return Object.fromEntries(resolvedEntries);
77
+ };
@@ -1,14 +1,14 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
3
  exports[`focusManager should be defined 1`] = `
4
- Object {
4
+ {
5
5
  "blur": [Function],
6
6
  "disableFocus": [Function],
7
7
  "enableFocus": [Function],
8
8
  "focusableTree": Tree {
9
9
  "loadingCounter": 0,
10
- "root": Object {
11
- "children": Array [],
10
+ "root": {
11
+ "children": [],
12
12
  "component": null,
13
13
  "id": "root",
14
14
  "lastFocusedItem": null,
@@ -39,12 +39,12 @@ Object {
39
39
  `;
40
40
 
41
41
  exports[`focusManagerIOS should be defined 1`] = `
42
- Object {
42
+ {
43
43
  "focus": [Function],
44
44
  "focusableTree": Tree {
45
45
  "loadingCounter": 0,
46
- "root": Object {
47
- "children": Array [],
46
+ "root": {
47
+ "children": [],
48
48
  "component": null,
49
49
  "id": "root",
50
50
  "lastFocusedItem": null,
@@ -59,7 +59,7 @@ export class Tree {
59
59
  /**
60
60
  * Update node with provided data from newNode
61
61
  * @private
62
- * @param {Object} node to update
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(findChildNode);
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 { accessibilityManager } from "./accessibilityManager";
12
+ export { AccessibilityManager } from "./accessibilityManager";
13
13
 
14
14
  export function deprecationMessage(fn, replacement) {
15
15
  if (__DEV__ && process.env.NODE_ENV !== "test") {
@@ -1,11 +1,11 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
3
  exports[`keyCodes keyCode returns an object for a given key event 1`] = `
4
- Object {
4
+ {
5
5
  "direction": [Function],
6
6
  "matches": [Function],
7
7
  "matchesAny": [Function],
8
- "value": Object {
8
+ "value": {
9
9
  "code": "Enter",
10
10
  "keyCode": 13,
11
11
  },
@@ -1,4 +1,4 @@
1
- const { Platform } = require("react-native");
1
+ import { Platform } from "react-native";
2
2
 
3
3
  Platform.OS = "web";
4
4
 
@@ -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
  });
@@ -6,6 +6,8 @@ import * as R from "ramda";
6
6
  import { directionHelper } from "../directionHelper";
7
7
  import { KEYS, ARROW_KEYS } from "./keys";
8
8
 
9
+ export { KEYS, ARROW_KEYS, keyEventMapper } from "./keys";
10
+
9
11
  /**
10
12
  * @typedef KeyCode
11
13
  * @property {Object} value of the Key
@@ -0,0 +1,3 @@
1
+ export * from "./keys";
2
+
3
+ export { keyEventMapper } from "./keyEventMapper";
@@ -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,8 @@
1
+ export {
2
+ lg_tv,
3
+ samsung_tv,
4
+ web,
5
+ tvos,
6
+ android_tv,
7
+ vizio,
8
+ } from "./keys/keysByPlatform";
@@ -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
+ }
@@ -2,7 +2,7 @@
2
2
  import * as ReactNative from "react-native";
3
3
  import { isTV, platformSelect } from "../reactUtils";
4
4
  import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
5
- import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
5
+ import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks/device/useIsTablet";
6
6
 
7
7
  import {
8
8
  QUICK_BRICK_EVENTS,
@@ -11,20 +11,6 @@ import { createLogger, utilsLogger } from "../../logger";
11
11
  import { getPlatform } from "../../reactUtils";
12
12
  import { appStore } from "@applicaster/zapp-react-native-redux/AppStore";
13
13
 
14
- declare global {
15
- interface Window {
16
- VIZIO?: {
17
- exitApplication: () => void;
18
- Chromevox: {
19
- play: (text: string) => void;
20
- };
21
- setClosedCaptionHandler: (
22
- callback: (isCCEnabled: boolean) => void
23
- ) => void;
24
- };
25
- }
26
- }
27
-
28
14
  const { log_debug } = createLogger({
29
15
  category: "General",
30
16
  subsystem: "PlatformUtils",
@@ -91,6 +77,12 @@ export class ClosedCaptioningManager {
91
77
 
92
78
  private constructor() {
93
79
  this.initialize();
80
+
81
+ window["vizioDebug"] = {
82
+ setCCEnabled: (isCCEnabled: boolean) => {
83
+ this.ccState$.next(isCCEnabled);
84
+ },
85
+ };
94
86
  }
95
87
 
96
88
  static getInstance(): ClosedCaptioningManager {