@applicaster/zapp-react-dom-app 13.0.0-alpha.4004617449 → 13.0.0-alpha.4012243505

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.
@@ -31,7 +31,10 @@ import {
31
31
  import { PlayerContentContext } from "@applicaster/zapp-react-dom-ui-components/Contexts";
32
32
 
33
33
  import { withNavigator } from "@applicaster/zapp-react-native-ui-components/Decorators/Navigator";
34
- import { getXray } from "@applicaster/zapp-react-native-utils/logger";
34
+ import {
35
+ getXray,
36
+ createLogger,
37
+ } from "@applicaster/zapp-react-native-utils/logger";
35
38
 
36
39
  import {
37
40
  confirmationDialogStore,
@@ -51,6 +54,11 @@ import { KeyInputHandler } from "@applicaster/zapp-react-native-utils/appUtils/k
51
54
  const { withXray } = getXray();
52
55
  const globalAny: any = global;
53
56
 
57
+ const { log_debug, log_warning } = createLogger({
58
+ category: "InteractionManager",
59
+ subsystem: "zapp-react-dom-app",
60
+ });
61
+
54
62
  const shouldUseOnScreenKeyboard = () =>
55
63
  isVizioPlatform() || window.applicaster.useOnScreenKeyboard;
56
64
 
@@ -283,8 +291,7 @@ class InteractionManagerClass extends React.Component<Props, State> {
283
291
  this.handleWebOsBack();
284
292
  }
285
293
  } catch (e) {
286
- // eslint-disable-next-line no-console
287
- console.warn("Failed to execute platformBack", e);
294
+ log_warning("Failed to execute platformBack", e);
288
295
  }
289
296
  }
290
297
 
@@ -378,23 +385,103 @@ class InteractionManagerClass extends React.Component<Props, State> {
378
385
  }
379
386
  }
380
387
 
381
- onKeyDown(event) {
388
+ /**
389
+ When pressing escape or the Native "Back" button:
390
+ if on the transport controls: we show the player
391
+ if on the player : we show the UI
392
+ if on the UI : we exit the app
393
+ note: backspace affects the keyboard input, so it behaves differently
394
+ */
395
+ onBackPress(event) {
382
396
  const { displayState, setDisplayState, navigator } = this.props;
397
+ const { isDialogVisible } = confirmationDialogStore.getState();
383
398
  const { isKeyboardVisible } = this.state;
384
399
 
385
- const { isDialogVisible } = confirmationDialogStore.getState();
400
+ log_debug("onBackPress", {
401
+ eventCode: event.code,
402
+ displayState,
403
+ isDialogVisible,
404
+ isKeyboardVisible,
405
+ });
386
406
 
387
407
  if (isKeyboardVisible && shouldUseOnScreenKeyboard()) {
388
- if (keyCode(event).matchesAny("Escape", "Back")) {
389
- this.handleKeyboardDismiss();
390
- }
391
-
408
+ this.handleKeyboardDismiss();
392
409
  event.preventDefault();
393
410
  event.stopPropagation();
394
411
 
395
412
  return;
396
413
  }
397
414
 
415
+ switch (displayState) {
416
+ case DISPLAY_STATES.DEFAULT:
417
+ case DISPLAY_STATES.PLAYER:
418
+ if (isDialogVisible) {
419
+ this.onConfirmDialogClose();
420
+ } else if (navigator.canGoBack()) {
421
+ navigator.goBack();
422
+ } else if (this.isHomeScreen()) {
423
+ this.platformBack();
424
+ } else if (navigator.currentRoute.includes("hook")) {
425
+ // If code reaches this block navigator cant go back, it is not home,
426
+ // and this is a login plugin that was pushed on top of the home
427
+ // Treat it like a home screen and run platformBack()
428
+ const entryData = navigator?.data?.entry;
429
+ const isHookInHomescreen = entryData?.payload?.home;
430
+
431
+ const isHookFlowBlocker =
432
+ typeof entryData?.hookPlugin?.module?.isFlowBlocker === "function"
433
+ ? entryData?.hookPlugin?.module?.isFlowBlocker()
434
+ : entryData?.hookPlugin?.module?.isFlowBlocker;
435
+
436
+ if (isHookInHomescreen && isHookFlowBlocker) {
437
+ this.platformBack();
438
+ } else {
439
+ navigator.goBack(false, true);
440
+ }
441
+ } else {
442
+ this.goToHome();
443
+ }
444
+
445
+ break;
446
+ case DISPLAY_STATES.HUD:
447
+ // IF transport controls are open, close them instead of closing player
448
+ setDisplayState(DISPLAY_STATES.PLAYER);
449
+ break;
450
+ default:
451
+ setDisplayState(DISPLAY_STATES.PLAYER);
452
+ break;
453
+ }
454
+ }
455
+
456
+ onBackspacePress(event) {
457
+ const isInputFocused =
458
+ document.activeElement instanceof HTMLInputElement ||
459
+ document.activeElement instanceof HTMLTextAreaElement;
460
+
461
+ // Don't handle backspace if input is focused
462
+ if (isInputFocused) {
463
+ return;
464
+ }
465
+
466
+ this.onBackPress(event);
467
+ }
468
+
469
+ onKeyDown(event) {
470
+ const { displayState, setDisplayState, navigator } = this.props;
471
+ const { isDialogVisible } = confirmationDialogStore.getState();
472
+
473
+ if (keyCode(event).matches("Backspace")) {
474
+ this.onBackspacePress(event);
475
+
476
+ return;
477
+ }
478
+
479
+ if (keyCode(event).matchesAny(KEYS.Back, KEYS.Escape, KEYS.EscapeDevice)) {
480
+ this.onBackPress(event);
481
+
482
+ return;
483
+ }
484
+
398
485
  if (this.keySupportsLongPress(event)) {
399
486
  this.longPressDetector.monitorKeyPress(event.code, event);
400
487
  }
@@ -460,55 +547,6 @@ class InteractionManagerClass extends React.Component<Props, State> {
460
547
  }
461
548
  }
462
549
 
463
- /**
464
- When pressing escape or the Native "Back" button:
465
- if on the transport controls: we show the player
466
- if on the player : we show the UI
467
- if on the UI : we exit the app
468
- note: backspace affects the keyboard input, so it not handled here
469
- */
470
- if (keyCode(event).matchesAny(KEYS.Back, KEYS.Escape, KEYS.EscapeDevice)) {
471
- switch (displayState) {
472
- case DISPLAY_STATES.DEFAULT:
473
- case DISPLAY_STATES.PLAYER:
474
- if (isDialogVisible) {
475
- this.onConfirmDialogClose();
476
- } else if (navigator.canGoBack()) {
477
- navigator.goBack();
478
- } else if (this.isHomeScreen()) {
479
- this.platformBack();
480
- } else if (navigator.currentRoute.includes("hook")) {
481
- // If code reaches this block navigator cant go back, it is not home,
482
- // and this is a login plugin that was pushed on top of the home
483
- // Treat it like a home screen and run platformBack()
484
- const entryData = navigator?.data?.entry;
485
- const isHookInHomescreen = entryData?.payload?.home;
486
-
487
- const isHookFlowBlocker =
488
- typeof entryData?.hookPlugin?.module?.isFlowBlocker === "function"
489
- ? entryData?.hookPlugin?.module?.isFlowBlocker()
490
- : entryData?.hookPlugin?.module?.isFlowBlocker;
491
-
492
- if (isHookInHomescreen && isHookFlowBlocker) {
493
- this.platformBack();
494
- } else {
495
- navigator.goBack(false, true);
496
- }
497
- } else {
498
- this.goToHome();
499
- }
500
-
501
- break;
502
- case DISPLAY_STATES.HUD:
503
- // IF transport controls are open, close them instead of closing player
504
- setDisplayState(DISPLAY_STATES.PLAYER);
505
- break;
506
- default:
507
- setDisplayState(DISPLAY_STATES.PLAYER);
508
- break;
509
- }
510
- }
511
-
512
550
  if (
513
551
  keyCode(event).matches(KEYS.Enter) ||
514
552
  (__DEV__ && keyCode(event).matches(KEYS.X))
@@ -533,10 +571,7 @@ class InteractionManagerClass extends React.Component<Props, State> {
533
571
  this.platformBack();
534
572
  }
535
573
 
536
- if (
537
- keyCode(event).matchesAny(...ARROW_KEYS) &&
538
- !this.state.isKeyboardVisible
539
- ) {
574
+ if (keyCode(event).matchesAny(...ARROW_KEYS)) {
540
575
  if (displayState === DISPLAY_STATES.PLAYER) {
541
576
  setDisplayState(DISPLAY_STATES.HUD);
542
577
  }
@@ -549,6 +584,12 @@ class InteractionManagerClass extends React.Component<Props, State> {
549
584
  focusManager.moveFocus(direction);
550
585
  }
551
586
 
587
+ if (!isDialogVisible) {
588
+ // run focus recovery on user interaction attempt
589
+ // probably we failed to set initial focus for some reason
590
+ focusManager.recoverFocus();
591
+ }
592
+
552
593
  if (
553
594
  displayState === DISPLAY_STATES.PLAYER ||
554
595
  displayState === DISPLAY_STATES.HUD
@@ -4,8 +4,6 @@ import { Background } from "@applicaster/zapp-react-dom-ui-components/Components
4
4
  import { ConfirmDialog } from "@applicaster/zapp-react-dom-ui-components/Components/ConfirmDialog";
5
5
  import { NavWrapper } from "@applicaster/zapp-react-dom-ui-components/Components/NavWrapper";
6
6
  import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
7
- import { getLocalizations } from "@applicaster/zapp-react-native-utils/localizationUtils";
8
- import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
9
7
 
10
8
  import LayoutComponent from "@applicaster/zapp-react-native-ui-components/Components/Layout";
11
9
 
@@ -16,16 +14,11 @@ type Props = {
16
14
  export function Layout({ children }: Props) {
17
15
  const { activeRiver } = useNavigation();
18
16
 
19
- const { remoteConfigurations } = usePickFromState(["remoteConfigurations"]);
20
-
21
- const localizations = getLocalizations(remoteConfigurations);
22
-
23
17
  const ComponentsExtraProps = React.useMemo(
24
18
  () => ({
25
19
  NavBar: { activeRiver },
26
- Background: { localizations },
27
20
  }),
28
- [activeRiver, localizations]
21
+ [activeRiver]
29
22
  );
30
23
 
31
24
  return (
@@ -3,11 +3,6 @@ import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils"
3
3
  import { QuickBrickCommunicationModule } from "../../Polyfills/QuickBrickCommunicationModule";
4
4
  import { loadLocaleImpl, getLanguageCode } from "./utils";
5
5
 
6
- type Locale = {
7
- language: string;
8
- country: string;
9
- };
10
-
11
6
  async function getBrowserLocale() {
12
7
  return navigator.language;
13
8
  }
@@ -19,7 +14,7 @@ async function getSamsungLocale() {
19
14
  }
20
15
 
21
16
  try {
22
- tizen.systeminfo.getPropertyValue("LOCALE", (locale: Locale) => {
17
+ tizen.systeminfo.getPropertyValue("LOCALE", (locale) => {
23
18
  resolve(locale.language);
24
19
  });
25
20
  } catch (e) {
@@ -31,31 +31,3 @@ exports[`storageObject when the requested storage exists getAllItems returns all
31
31
  "otherKey": "otherValue",
32
32
  }
33
33
  `;
34
-
35
- exports[`storageObject when the requested storage exists getItem gets properties from the storage 1`] = `"bar"`;
36
-
37
- exports[`storageObject when the requested storage exists getItem gets properties from the storage 2`] = `"bar"`;
38
-
39
- exports[`storageObject when the requested storage exists getItem gets properties from the storage 3`] = `"bar"`;
40
-
41
- exports[`storageObject when the requested storage exists getItem gets properties from the storage 4`] = `"bar"`;
42
-
43
- exports[`storageObject when the requested storage exists getItem gets properties from the storage with a namespace 1`] = `"baz"`;
44
-
45
- exports[`storageObject when the requested storage exists getItem gets properties from the storage with a namespace 2`] = `"baz"`;
46
-
47
- exports[`storageObject when the requested storage exists getItem rejects if the property cannot be retrieved 1`] = `[Error: Could not retrieve item applicaster.v2_::_fail_key]`;
48
-
49
- exports[`storageObject when the requested storage exists getItem rejects if the property cannot be retrieved 2`] = `[Error: Could not retrieve item applicaster.v2_::_fail_key]`;
50
-
51
- exports[`storageObject when the requested storage exists removeItem removes an item 1`] = `true`;
52
-
53
- exports[`storageObject when the requested storage exists removeItem removes an item 2`] = `true`;
54
-
55
- exports[`storageObject when the requested storage exists removeItem removes an item 3`] = `true`;
56
-
57
- exports[`storageObject when the requested storage exists removeItem removes an item 4`] = `true`;
58
-
59
- exports[`storageObject when the requested storage exists setItem will reject a promise if it the setting of the data fails 1`] = `[Error: Could not set item applicaster.v2_::_fail_key]`;
60
-
61
- exports[`storageObject when the requested storage exists setItem will reject a promise if it the setting of the data fails 2`] = `[Error: Could not set item applicaster.v2_::_fail_key]`;
@@ -4,7 +4,8 @@ import {
4
4
  applyNamespaceToKeyName,
5
5
  STORAGE_TYPES,
6
6
  DEFAULT_NAMESPACE,
7
- } from "../index";
7
+ } from "../";
8
+
8
9
  import { StorageMock } from "./StorageMocks";
9
10
 
10
11
  import * as functionUtils from "@applicaster/zapp-react-native-utils/functionUtils";
@@ -26,14 +27,7 @@ function clearStorage() {
26
27
  R.forEach((storage) => global.window[storage].clear(), STORAGE_TYPES);
27
28
  }
28
29
 
29
- async function testStorage(expectations) {
30
- await Promise.all(
31
- R.map((storage) => {
32
- const Storage = getStorageModule(storage);
33
- expectations(Storage);
34
- }, STORAGE_TYPES)
35
- );
36
- }
30
+ const storages = R.map((storage) => getStorageModule(storage), STORAGE_TYPES);
37
31
 
38
32
  describe("storageObject", () => {
39
33
  beforeEach(resetMocks);
@@ -48,143 +42,119 @@ describe("storageObject", () => {
48
42
 
49
43
  beforeEach(clearStorage);
50
44
 
51
- it("returns an object with 3 methods", () => {
52
- expect.assertions(6);
53
-
54
- testStorage((Storage) => {
55
- expect(Storage).toHaveProperty("setItem");
56
- expect(Storage).toHaveProperty("getItem");
57
- expect(Storage).toHaveProperty("getAllItems");
58
- });
45
+ it.each(storages)("returns an object with 3 methods", (storage) => {
46
+ expect(storage).toHaveProperty("setItem");
47
+ expect(storage).toHaveProperty("getItem");
48
+ expect(storage).toHaveProperty("getAllItems");
59
49
  });
60
50
 
61
51
  describe("setItem", () => {
62
52
  beforeEach(clearStorage);
63
53
 
64
- it("sets a property in the storage", async () => {
65
- expect.assertions(4);
54
+ it.each(storages)("sets a property in the storage", async (storage) => {
55
+ const result = await storage.setItem(key, value, null);
66
56
 
67
- await testStorage(async (Storage) => {
68
- const result = await Storage.setItem(key, value, null);
57
+ const keyWithDefaultNameSpace = applyNamespaceToKeyName(
58
+ key,
59
+ DEFAULT_NAMESPACE
60
+ );
69
61
 
70
- const keyWithDefaultNameSpace = applyNamespaceToKeyName(
71
- key,
72
- DEFAULT_NAMESPACE
73
- );
62
+ expect(result).toBe(true);
74
63
 
75
- expect(result).toBe(true);
76
- expect(Storage[keyWithDefaultNameSpace]).toEqual(value);
77
- });
64
+ expect(storage.getItem(keyWithDefaultNameSpace)).resolves.toEqual(
65
+ value
66
+ );
78
67
  });
79
68
 
80
- it("sets a property in the storage with a namespace", async () => {
81
- expect.assertions(4);
82
-
83
- await testStorage(async (Storage) => {
84
- const result = await Storage.setItem(key, namespaceValue, namespace);
69
+ it.each(storages)(
70
+ "sets a property in the storage with a namespace",
71
+ async (storage) => {
72
+ const result = await storage.setItem(key, namespaceValue, namespace);
85
73
 
86
74
  expect(result).toBe(true);
87
- expect(Storage[keyName]).toEqual(namespaceValue);
88
- });
89
- });
90
75
 
91
- it("will reject a promise if it the setting of the data fails", async () => {
92
- expect.assertions(2);
76
+ expect(storage.getItem(keyName)).resolves.toEqual(namespaceValue);
77
+ }
78
+ );
93
79
 
94
- await testStorage(async (Storage) => {
95
- await expect(
96
- Storage.setItem(failKey, value)
97
- ).rejects.toMatchSnapshot();
98
- });
99
- });
80
+ it.each(storages)(
81
+ "will reject a promise if it the setting of the data fails",
82
+ async (storage) => {
83
+ await expect(storage.setItem(failKey, value)).rejects.toThrow(
84
+ "Could not set item applicaster.v2_::_fail_key"
85
+ );
86
+ }
87
+ );
100
88
  });
101
89
 
102
90
  describe("getItem", () => {
103
91
  beforeEach(async () => {
104
92
  clearStorage();
105
93
 
106
- await testStorage(async (Storage) => {
94
+ storages.forEach((Storage) => {
107
95
  Storage.setItem(key, value, null);
108
96
  Storage.setItem(key, namespaceValue, namespace);
109
97
  });
110
98
  });
111
99
 
112
- it("gets properties from the storage", async () => {
113
- expect.assertions(8);
114
-
115
- await testStorage(async (Storage) => {
116
- await expect(Storage.getItem(key)).resolves.toEqual(value);
117
- await expect(Storage.getItem(key)).resolves.toMatchSnapshot();
118
- await expect(Storage.getItem(key, null)).resolves.toEqual(value);
119
- await expect(Storage.getItem(key, null)).resolves.toMatchSnapshot();
120
- });
100
+ it.each(storages)("gets properties from the storage", async (storage) => {
101
+ const result = await storage.getItem(key);
102
+ const resultWithNull = await storage.getItem(key, null);
103
+ expect(result).toEqual(value);
104
+ expect(resultWithNull).toEqual(value);
121
105
  });
122
106
 
123
- it("gets properties from the storage with a namespace", async () => {
124
- expect.assertions(4);
125
-
126
- await testStorage(async (Storage) => {
127
- await expect(Storage.getItem(key, namespace)).resolves.toEqual(
128
- namespaceValue
107
+ it.each(storages)(
108
+ "gets properties from the storage with a namespace",
109
+ (storage) => {
110
+ expect(storage.getItem(key, namespace)).resolves.toEqual(
111
+ "namespaceValue"
129
112
  );
113
+ }
114
+ );
130
115
 
131
- await expect(
132
- Storage.getItem(key, namespace)
133
- ).resolves.toMatchSnapshot();
134
- });
135
- });
136
-
137
- it("rejects if the property cannot be retrieved", async () => {
138
- expect.assertions(2);
139
-
140
- await testStorage(async (Storage) => {
141
- await expect(Storage.getItem(failKey)).rejects.toMatchSnapshot();
142
- });
143
- });
116
+ it.each(storages)(
117
+ "rejects if the property cannot be retrieved",
118
+ async (storage) => {
119
+ await expect(storage.getItem(failKey)).rejects.toThrow(
120
+ "Could not retrieve item applicaster.v2_::_fail_key"
121
+ );
122
+ }
123
+ );
144
124
  });
145
125
 
146
126
  describe("getAllItems", () => {
147
127
  beforeEach(async () => {
148
128
  clearStorage();
149
129
 
150
- await testStorage(async (Storage) => {
151
- await Storage.setItem(key, value);
152
- await Storage.setItem(key, namespaceValue, namespace);
153
- await Storage.setItem("otherKey", "otherValue");
154
- await Storage.setItem("otherKey", "otherValue", namespace);
130
+ storages.forEach((Storage) => {
131
+ Storage.setItem(key, value);
132
+ Storage.setItem(key, namespaceValue, namespace);
133
+ Storage.setItem("otherKey", "otherValue");
134
+ Storage.setItem("otherKey", "otherValue", namespace);
155
135
  });
156
136
  });
157
137
 
158
- it("returns all keys", async () => {
159
- expect.assertions(2);
160
-
161
- await testStorage(async (Storage) => {
162
- await expect(Storage.getAllItems()).resolves.toMatchSnapshot();
163
- });
138
+ it.each(storages)("returns all keys", async (Storage) => {
139
+ const res = await Storage.getAllItems();
140
+ expect(res).toMatchSnapshot();
164
141
  });
165
142
 
166
- it("returns all keys in the namespace if provided", async () => {
167
- expect.assertions(2);
168
-
169
- await testStorage(async (Storage) => {
143
+ it.each(storages)(
144
+ "returns all keys in the namespace if provided",
145
+ async (Storage) => {
170
146
  await expect(
171
147
  Storage.getAllItems(namespace)
172
148
  ).resolves.toMatchSnapshot();
173
- });
174
- });
149
+ }
150
+ );
175
151
  });
176
152
 
177
153
  describe("removeItem", () => {
178
- it("removes an item", async () => {
179
- expect.assertions(4);
180
-
181
- await testStorage(async (Storage) => {
182
- await expect(Storage.removeItem(key)).resolves.toMatchSnapshot();
154
+ it.each(storages)("removes an item", async (Storage) => {
155
+ await expect(Storage.removeItem(key)).resolves.toBeTruthy();
183
156
 
184
- await expect(
185
- Storage.removeItem(key, namespace)
186
- ).resolves.toMatchSnapshot();
187
- });
157
+ await expect(Storage.removeItem(key, namespace)).resolves.toBeTruthy();
188
158
  });
189
159
  });
190
160
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/zapp-react-dom-app",
3
- "version": "13.0.0-alpha.4004617449",
3
+ "version": "13.0.0-alpha.4012243505",
4
4
  "description": "Zapp App Component for Applicaster's Quick Brick React Native App",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -22,11 +22,11 @@
22
22
  },
23
23
  "homepage": "https://github.com/applicaster/zapp-react-dom-app#readme",
24
24
  "dependencies": {
25
- "@applicaster/zapp-react-dom-ui-components": "13.0.0-alpha.4004617449",
26
- "@applicaster/zapp-react-native-bridge": "13.0.0-alpha.4004617449",
27
- "@applicaster/zapp-react-native-redux": "13.0.0-alpha.4004617449",
28
- "@applicaster/zapp-react-native-ui-components": "13.0.0-alpha.4004617449",
29
- "@applicaster/zapp-react-native-utils": "13.0.0-alpha.4004617449",
25
+ "@applicaster/zapp-react-dom-ui-components": "13.0.0-alpha.4012243505",
26
+ "@applicaster/zapp-react-native-bridge": "13.0.0-alpha.4012243505",
27
+ "@applicaster/zapp-react-native-redux": "13.0.0-alpha.4012243505",
28
+ "@applicaster/zapp-react-native-ui-components": "13.0.0-alpha.4012243505",
29
+ "@applicaster/zapp-react-native-utils": "13.0.0-alpha.4012243505",
30
30
  "abortcontroller-polyfill": "^1.7.5",
31
31
  "react-router-dom": "^5.1.2",
32
32
  "typeface-montserrat": "^0.0.54",
@@ -37,15 +37,14 @@
37
37
  "peerDependencies": {
38
38
  "@applicaster/zapp-pipes-v2-client": "*",
39
39
  "@react-native-community/netinfo": "*",
40
- "@types/node": "*",
41
40
  "core-js": "3.29.1",
42
41
  "immer": "*",
43
- "react": "17.0.2",
44
- "react-dom": "17.0.2",
42
+ "react": "*",
43
+ "react-dom": "*",
45
44
  "react-native": "*",
46
45
  "react-native-safe-area-context": "*",
47
46
  "react-native-svg": "*",
48
- "react-native-web": "0.18.11",
47
+ "react-native-web": "*",
49
48
  "uglify-js": "*",
50
49
  "validate-color": "*",
51
50
  "zustand": "*"