@applicaster/zapp-react-dom-app 12.0.0-alpha.4220424021 → 12.0.0-alpha.4241289980

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.
@@ -33,9 +33,13 @@ import {
33
33
  import { PlayerContentContext } from "@applicaster/zapp-react-dom-ui-components/Contexts";
34
34
 
35
35
  import { withNavigator } from "@applicaster/zapp-react-native-ui-components/Decorators/Navigator";
36
- import { LONG_KEY_PRESS_TIMEOUT } from "@applicaster/quick-brick-core/const";
37
36
  import { getXray } from "@applicaster/zapp-react-native-utils/logger";
38
- import { confirmationDialogStore } from "@applicaster/zapp-react-native-ui-components/Contexts/ConfirmDialogState";
37
+
38
+ import {
39
+ confirmationDialogStore,
40
+ ConfirmationDialogState,
41
+ } from "@applicaster/zapp-react-native-ui-components/Contexts/ConfirmDialogState";
42
+
39
43
  import {
40
44
  isLgPlatform,
41
45
  isSamsungPlatform,
@@ -43,6 +47,7 @@ import {
43
47
  } from "@applicaster/zapp-react-native-utils/reactUtils";
44
48
 
45
49
  import { OnScreenKeyboard } from "@applicaster/zapp-react-dom-ui-components/Components/OnScreenKeyboard";
50
+ import { KeyboardLongPressManager } from "@applicaster/zapp-react-dom-ui-components/Utils/KeyboardLongPressManager";
46
51
 
47
52
  const { withXray } = getXray();
48
53
  const globalAny: any = global;
@@ -65,9 +70,14 @@ type Props = {
65
70
  onRewindPressOut: () => void;
66
71
  onForwardPressOut: () => void;
67
72
  };
73
+ confirmDialog: typeof confirmationDialogStore;
68
74
  };
69
75
 
70
- type State = { isKeyboardVisible: boolean; keyboardInput: string };
76
+ interface State {
77
+ isKeyboardVisible: boolean;
78
+ keyboardInput: string;
79
+ activeInputRef: HTMLInputElement | null;
80
+ }
71
81
 
72
82
  type KeyCode = { code: string; keyCode: number | string };
73
83
 
@@ -80,24 +90,24 @@ class InteractionManagerClass extends React.Component<Props, State> {
80
90
  onMouseMoveListener: (event: MouseEvent) => void;
81
91
  onScrollListener: (event: MouseEvent) => void;
82
92
 
83
- longKeyPressTimeout: any | null;
84
- longPressActive: boolean;
85
- timeout: any | null;
86
- sequenceTimeout: NodeJS.Timeout | null; // timeoutID
87
- userSequence: number[] = [];
88
- confirmDialog: any;
89
- isDismissing = false;
93
+ private longPressDetector: KeyboardLongPressManager;
94
+ private longPressActive: boolean = false;
95
+ private timeout: any | null = null;
96
+ private sequenceTimeout: NodeJS.Timeout | null;
97
+ private userSequence: number[] = [];
98
+ private isDismissing = false;
99
+ private confirmDialog: ConfirmationDialogState =
100
+ confirmationDialogStore.getState();
101
+
102
+ state: State = {
103
+ isKeyboardVisible: false,
104
+ keyboardInput: "",
105
+ activeInputRef: null,
106
+ };
90
107
 
91
108
  constructor(props) {
92
109
  super(props);
93
110
 
94
- this.onKeyDownListener = this.onKeyDown.bind(this);
95
-
96
- this.state = {
97
- isKeyboardVisible: false,
98
- keyboardInput: "",
99
- };
100
-
101
111
  this.onMouseMoveListener = debounce({
102
112
  fn: this.onMouseMove,
103
113
  context: this,
@@ -114,9 +124,7 @@ class InteractionManagerClass extends React.Component<Props, State> {
114
124
  context: this,
115
125
  });
116
126
 
117
- this.longKeyPressTimeout = null;
118
- this.longPressActive = false;
119
- this.confirmDialog = confirmationDialogStore.getState();
127
+ this.onKeyDownListener = this.onKeyDown.bind(this);
120
128
  this.resetHudTimeout = this.resetHudTimeout.bind(this);
121
129
  this.cursorVisibilityChange = this.cursorVisibilityChange.bind(this);
122
130
  this.onKeyDown = this.onKeyDown.bind(this);
@@ -132,9 +140,18 @@ class InteractionManagerClass extends React.Component<Props, State> {
132
140
  this.handleInputBlur = this.handleInputBlur.bind(this);
133
141
  this.handleKeyboardInput = this.handleKeyboardInput.bind(this);
134
142
  this.handleKeyboardDismiss = this.handleKeyboardDismiss.bind(this);
143
+ this.onKeyDownListener = this.onKeyDown.bind(this);
144
+ this.onKeyUp = this.onKeyUp.bind(this);
145
+ this.onMouseMoveListener = this.onMouseMove.bind(this);
146
+ this.onScrollListener = this.onScroll.bind(this);
147
+ this.onMouseDownListener = this.onMouseDown.bind(this);
148
+ this.onKeyboardStateChange = this.onKeyboardStateChange.bind(this);
149
+ this.onConfirmDialogOpen = this.onConfirmDialogOpen.bind(this);
150
+ this.onConfirmDialogClose = this.onConfirmDialogClose.bind(this);
135
151
 
136
152
  this.confirmDialog.setConfirmAction(this.performExit);
137
153
  this.confirmDialog.setCancelAction(this.onConfirmDialogClose);
154
+ this.longPressDetector = new KeyboardLongPressManager();
138
155
  }
139
156
 
140
157
  componentDidMount() {
@@ -161,6 +178,13 @@ class InteractionManagerClass extends React.Component<Props, State> {
161
178
  this.cursorVisibilityChange,
162
179
  false
163
180
  );
181
+
182
+ window.addEventListener("onLongPress", this.handleLongPress.bind(this));
183
+
184
+ window.addEventListener(
185
+ "onLongPressRelease",
186
+ this.handleLongPressRelease.bind(this)
187
+ );
164
188
  }
165
189
 
166
190
  componentWillUnmount() {
@@ -182,6 +206,13 @@ class InteractionManagerClass extends React.Component<Props, State> {
182
206
  }
183
207
 
184
208
  this.isDismissing = false;
209
+ this.longPressDetector.cleanup();
210
+ window.removeEventListener("onLongPress", this.handleLongPress);
211
+
212
+ window.removeEventListener(
213
+ "onLongPressRelease",
214
+ this.handleLongPressRelease
215
+ );
185
216
  }
186
217
 
187
218
  performExit() {
@@ -303,155 +334,13 @@ class InteractionManagerClass extends React.Component<Props, State> {
303
334
  }
304
335
  }
305
336
 
306
- clearLongPressTimeout() {
307
- if (this.longKeyPressTimeout) {
308
- clearTimeout(this.longKeyPressTimeout);
309
- this.longKeyPressTimeout = null;
310
- }
311
- }
312
-
313
- /**
314
- * If the keySupportsLongPress this method is called on longpress of key
315
- * Register your longpress handlers here, and make sure to add it to list of supported keys
316
- */
317
- onLongPress(event) {
318
- this.longPressActive = true;
319
- // Legacy way of determining whether controls are being displayed
320
- // Or if the player is in a playback state.
321
- const { displayState } = this.props;
322
- const playerState = displayState === DISPLAY_STATES.PLAYER;
323
- const hudState = displayState === DISPLAY_STATES.HUD;
324
- const playbackState = playerState || hudState;
325
-
326
- switch (event.code) {
327
- case KEYS.Back.code:
328
- // If you longpress the back button we probably want to exit
329
- this.platformBack();
330
-
331
- break;
332
-
333
- case KEYS.Enter.code:
334
- focusManager.longPress();
335
-
336
- break;
337
-
338
- case KEYS.Forward.code:
339
- playbackState && this.props.seekMethods.onForwardLongPress();
340
-
341
- break;
342
-
343
- case KEYS.Rewind.code:
344
- playbackState && this.props.seekMethods.onRewindLongPress();
345
-
346
- break;
347
-
348
- default:
349
- break;
350
- }
351
- }
352
-
353
- /**
354
- * If the keySupportsLongPress this method is called on keyup of a longpress key
355
- * If you need to handle the release or keyup of a longpress key register the handler here
356
- */
357
- onLongPressRelease(event) {
358
- this.longPressActive = false;
337
+ cancelHudTimeout() {
359
338
  this.resetHudTimeout();
360
-
361
- focusManager.pressOut();
362
-
363
- switch (event.code) {
364
- case KEYS.Forward.code:
365
- this.props.seekMethods.onForwardPressOut();
366
-
367
- break;
368
-
369
- case KEYS.Rewind.code:
370
- this.props.seekMethods.onForwardPressOut();
371
-
372
- break;
373
-
374
- default:
375
- break;
376
- }
377
- }
378
-
379
- /**
380
- * Resets the sequence of keys we captured.
381
- * Clear ensures that we don't interpret regular interactions
382
- * as a sequence used to unlock certain features
383
- */
384
- resetSequenceTimeout() {
385
- const SEQUENCE_ENTRY_TIME = 1900;
386
-
387
- if (this.sequenceTimeout) {
388
- // Start timer over
389
- clearTimeout(this.sequenceTimeout);
390
- }
391
-
392
- this.sequenceTimeout = setTimeout(() => {
393
- // User needs to complete sequence before SEQUENCE_ENTRY_TIME
394
- // or we set userSequence, and prev sequenceTimeout to empty values
395
- this.sequenceTimeout = null;
396
- this.userSequence = [];
397
- }, SEQUENCE_ENTRY_TIME);
398
- }
399
-
400
- /**
401
- * If a certain sequence of keys are pressed we enable special menus or settings
402
- * Each supported sequence can be stored as a constant
403
- */
404
- checkSequence(key) {
405
- const SINK_SEQUENCE = [
406
- KEYS.ArrowUp.keyCode,
407
- KEYS.ArrowUp.keyCode,
408
- KEYS.ArrowDown.keyCode,
409
- KEYS.ArrowDown.keyCode,
410
- KEYS.ArrowLeft.keyCode,
411
- KEYS.ArrowRight.keyCode,
412
- KEYS.ArrowLeft.keyCode,
413
- KEYS.ArrowRight.keyCode,
414
- ];
415
-
416
- this.resetSequenceTimeout();
417
- this.userSequence.push(key);
418
-
419
- // Remember [1,2,3] !== [1,2,3] in js, so string comparison is better
420
- const shouldAddSink =
421
- this.userSequence.toString() === SINK_SEQUENCE.toString();
422
-
423
- if (shouldAddSink) {
424
- this.props.xray.addRemoteSink({});
425
- }
426
- }
427
-
428
- /**
429
- * Determines whether the key supports or handles longpress
430
- * At the moment the only keys that support are the ones defined in
431
- * supportedEvents array. This logic just prevents us from registering timeouts for every key
432
- */
433
- keySupportsLongPress(event): boolean {
434
- const supportedEvents = [KEYS.Back, KEYS.Enter, KEYS.Rewind, KEYS.Forward];
435
-
436
- const eventMatcher = R.compose(R.prop("matches"), keyCode)(event);
437
-
438
- const supportsLongPress = R.compose(
439
- R.any(R.equals(true)),
440
- R.map(eventMatcher)
441
- )(supportedEvents);
442
-
443
- return supportsLongPress;
444
339
  }
445
340
 
446
341
  onKeyUp(event: KeyboardEvent) {
447
- // If this is a supported longpress key we need to clear the timeout and handle release of key
448
- // This logic is handled by onLongPressRelease
449
342
  if (this.keySupportsLongPress(event)) {
450
- if (this.longPressActive) {
451
- this.onLongPressRelease(event);
452
- } else {
453
- this.clearLongPressTimeout();
454
- }
343
+ this.longPressDetector.endKeyPressMonitoring(event.code);
455
344
  }
456
345
  }
457
346
 
@@ -461,23 +350,24 @@ class InteractionManagerClass extends React.Component<Props, State> {
461
350
 
462
351
  const { isDialogVisible } = confirmationDialogStore.getState();
463
352
 
464
- // If this is a supported longpress key we need to set the timeout and handle the longpress
465
- if (this.keySupportsLongPress(event)) {
466
- this.longKeyPressTimeout = setTimeout(() => {
467
- this.onLongPress(event);
468
- }, LONG_KEY_PRESS_TIMEOUT);
469
- }
470
-
471
353
  if (isKeyboardVisible && shouldUseOnScreenKeyboard()) {
472
354
  if (keyCode(event).matchesAny("Escape", "Back")) {
473
- event.preventDefault();
474
- event.stopPropagation();
475
355
  this.handleKeyboardDismiss();
476
-
477
- return;
478
356
  }
357
+
358
+ event.preventDefault();
359
+ event.stopPropagation();
360
+
361
+ return;
479
362
  }
480
363
 
364
+ if (this.keySupportsLongPress(event)) {
365
+ this.longPressDetector.monitorKeyPress(event.code, event);
366
+ }
367
+
368
+ // None of the logic below should be executed for repeated keys
369
+ if (event.repeat) return;
370
+
481
371
  /**
482
372
  When the player is displayed, we listen to Native Play / Pause / Stop
483
373
  buttons. Any other key press will display the transport controls
@@ -694,16 +584,18 @@ class InteractionManagerClass extends React.Component<Props, State> {
694
584
 
695
585
  handleInputFocus = (event: FocusEvent) => {
696
586
  if (!shouldUseOnScreenKeyboard()) return;
697
- const target = event.target as HTMLElement;
587
+ const target = event.target as HTMLInputElement;
698
588
 
699
- if (this.isDismissing) {
700
- return;
701
- }
589
+ if (this.isDismissing) return;
702
590
 
703
- if (target.tagName === "INPUT" || target.tagName === "TEXTAREA") {
591
+ if (
592
+ (target.tagName === "INPUT" && target.type === "text") ||
593
+ target.tagName === "TEXTAREA"
594
+ ) {
704
595
  this.setState({
705
596
  isKeyboardVisible: true,
706
- keyboardInput: (target as HTMLInputElement).value || "",
597
+ keyboardInput: target.value || "",
598
+ activeInputRef: target,
707
599
  });
708
600
  }
709
601
  };
@@ -733,6 +625,7 @@ class InteractionManagerClass extends React.Component<Props, State> {
733
625
  {
734
626
  isKeyboardVisible: false,
735
627
  keyboardInput: "",
628
+ activeInputRef: null,
736
629
  },
737
630
  () => {
738
631
  this.isDismissing = false;
@@ -740,15 +633,116 @@ class InteractionManagerClass extends React.Component<Props, State> {
740
633
  );
741
634
  };
742
635
 
743
- handleKeyboardInput(value: string) {
636
+ handleKeyboardInput = (value: string) => {
637
+ const { activeInputRef } = this.state;
638
+
639
+ if (activeInputRef) {
640
+ // Update the input's value
641
+ activeInputRef.value = value;
642
+
643
+ // Dispatch keyboard update event
644
+ const keyboardEvent = new CustomEvent("keyboardUpdate", {
645
+ detail: { value },
646
+ });
647
+
648
+ document.dispatchEvent(keyboardEvent);
649
+ }
650
+
744
651
  this.setState({ keyboardInput: value });
652
+ };
653
+
654
+ // TODO: use RemoteSequenceHandler class
655
+ private checkSequence(key: number) {
656
+ const SINK_SEQUENCE = [
657
+ KEYS.ArrowUp.keyCode,
658
+ KEYS.ArrowUp.keyCode,
659
+ KEYS.ArrowDown.keyCode,
660
+ KEYS.ArrowDown.keyCode,
661
+ KEYS.ArrowLeft.keyCode,
662
+ KEYS.ArrowRight.keyCode,
663
+ KEYS.ArrowLeft.keyCode,
664
+ KEYS.ArrowRight.keyCode,
665
+ ];
666
+
667
+ this.resetSequenceTimeout();
668
+ this.userSequence.push(key);
669
+
670
+ const shouldAddSink =
671
+ this.userSequence.toString() === SINK_SEQUENCE.toString();
672
+
673
+ if (shouldAddSink) {
674
+ this.props.xray.addRemoteSink({});
675
+ }
676
+ }
677
+
678
+ private resetSequenceTimeout() {
679
+ const SEQUENCE_ENTRY_TIME = 1900;
680
+
681
+ if (this.sequenceTimeout) {
682
+ clearTimeout(this.sequenceTimeout);
683
+ }
684
+
685
+ this.sequenceTimeout = setTimeout(() => {
686
+ this.sequenceTimeout = null;
687
+ this.userSequence = [];
688
+ }, SEQUENCE_ENTRY_TIME);
689
+ }
690
+
691
+ private handleLongPress = (event: CustomEvent) => {
692
+ const { keyCode } = event.detail;
693
+ const { displayState } = this.props;
694
+ const playerState = displayState === DISPLAY_STATES.PLAYER;
695
+ const hudState = displayState === DISPLAY_STATES.HUD;
696
+ const playbackState = playerState || hudState;
697
+ this.longPressActive = true;
698
+ this.cancelHudTimeout();
699
+
700
+ switch (keyCode) {
701
+ case KEYS.Forward.code:
702
+ playbackState && this.props.seekMethods.onForwardLongPress();
703
+ break;
704
+
705
+ case KEYS.Rewind.code:
706
+ playbackState && this.props.seekMethods.onRewindLongPress();
707
+ break;
708
+
709
+ case KEYS.Enter.code:
710
+ focusManager.longPress();
711
+ break;
712
+ }
713
+ };
714
+
715
+ private handleLongPressRelease = (event: CustomEvent) => {
716
+ const { keyCode } = event.detail;
717
+ this.longPressActive = false;
718
+ this.resetHudTimeout();
719
+
720
+ switch (keyCode) {
721
+ case KEYS.Forward.code:
722
+ this.props.seekMethods.onForwardPressOut();
723
+ break;
724
+
725
+ case KEYS.Rewind.code:
726
+ this.props.seekMethods.onRewindPressOut();
727
+ break;
728
+
729
+ case KEYS.Enter.code:
730
+ focusManager.pressOut();
731
+ break;
732
+ }
733
+ };
734
+
735
+ private keySupportsLongPress(event: KeyboardEvent): boolean {
736
+ return [KEYS.Forward.code, KEYS.Rewind.code, KEYS.Enter.code].includes(
737
+ event.code
738
+ );
745
739
  }
746
740
 
747
741
  render() {
748
742
  return (
749
743
  (shouldUseOnScreenKeyboard() && this.state.isKeyboardVisible && (
750
744
  <OnScreenKeyboard
751
- initialValue={this.state.keyboardInput}
745
+ value={this.state.keyboardInput}
752
746
  onInput={this.handleKeyboardInput}
753
747
  onDismiss={this.handleKeyboardDismiss}
754
748
  />
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/zapp-react-dom-app",
3
- "version": "12.0.0-alpha.4220424021",
3
+ "version": "12.0.0-alpha.4241289980",
4
4
  "description": "Zapp App Component for Applicaster's Quick Brick React Native App",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -22,18 +22,18 @@
22
22
  },
23
23
  "homepage": "https://github.com/applicaster/zapp-react-dom-app#readme",
24
24
  "dependencies": {
25
- "@applicaster/zapp-react-dom-ui-components": "12.0.0-alpha.4220424021",
26
- "@applicaster/zapp-react-native-bridge": "12.0.0-alpha.4220424021",
27
- "@applicaster/zapp-react-native-redux": "12.0.0-alpha.4220424021",
28
- "@applicaster/zapp-react-native-ui-components": "12.0.0-alpha.4220424021",
29
- "@applicaster/zapp-react-native-utils": "12.0.0-alpha.4220424021",
25
+ "@applicaster/zapp-react-dom-ui-components": "12.0.0-alpha.4241289980",
26
+ "@applicaster/zapp-react-native-bridge": "12.0.0-alpha.4241289980",
27
+ "@applicaster/zapp-react-native-redux": "12.0.0-alpha.4241289980",
28
+ "@applicaster/zapp-react-native-ui-components": "12.0.0-alpha.4241289980",
29
+ "@applicaster/zapp-react-native-utils": "12.0.0-alpha.4241289980",
30
30
  "abortcontroller-polyfill": "^1.7.5",
31
31
  "history": "^4.7.2",
32
32
  "react-router-dom": "^5.1.2",
33
33
  "typeface-montserrat": "^0.0.54",
34
- "video.js": "8.21.0",
35
- "videojs-contrib-eme": "^5.5.1",
36
- "videojs-contrib-quality-levels": "^4.1.0"
34
+ "video.js": "7.14.3",
35
+ "videojs-contrib-eme": "^3.8.1",
36
+ "videojs-contrib-quality-levels": "3.0.0"
37
37
  },
38
38
  "peerDependencies": {
39
39
  "core-js": "3.29.1",