@24i/bigscreen-sdk 1.0.15 → 1.0.16-alpha.2315

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@24i/bigscreen-sdk",
3
- "version": "1.0.15",
3
+ "version": "1.0.16-alpha.2315",
4
4
  "description": "SmartApps BIGscreen SDK monorepo",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -19,7 +19,7 @@
19
19
  "typecheck:cached": "npm run typecheck -- --incremental",
20
20
  "test": "npm run jest -- --no-cache",
21
21
  "test:cached": "npm run jest",
22
- "coverage": "npm run jest -- --runInBand --coverage && coveralls < coverage/lcov.info",
22
+ "coverage": "npm run jest -- --runInBand --coverage",
23
23
  "branchlint": "branchlint",
24
24
  "generate-changelog": "smartapps-bigscreen-changelog-generator",
25
25
  "deploy-docs": "cd website && npm run build && vercel ./build/prd-nxg-bigscreen --token=$VERCEL_TOKEN_24I --local-config=./vercel.json --scope=24i -f -c --prod",
@@ -74,6 +74,7 @@
74
74
  "jest": "^29.3.1",
75
75
  "jest-canvas-mock": "^2.4.0",
76
76
  "jest-environment-jsdom": "^29.0.3",
77
+ "jest-sonar": "^0.2.15",
77
78
  "minimist": "^1.2.8",
78
79
  "patch-package": "^6.5.0",
79
80
  "sass": "^1.60.0",
@@ -29,9 +29,9 @@ export const mapPayload = (
29
29
  payload: AnyPayload,
30
30
  ) => {
31
31
  const pageParams = triggerName === 'scene_view' ? {
32
- _ee: payload.firstEvent ? 1 : 0,
33
- _fv: payload.firstVisit ? 1 : 0,
34
- _ss: payload.sessionStarted ? 1 : 0,
32
+ ...(payload.firstEvent && { _ee: 1 }),
33
+ ...(payload.firstVisit && { _fv: 1 }),
34
+ ...(payload.sessionStarted && { _ss: 1 }),
35
35
  } : {};
36
36
  const gtagPayload: Record<string, any> = {
37
37
  'ep.event_trigger': triggerName,
@@ -12,6 +12,7 @@ It provides common functionality for you.
12
12
  ## Props
13
13
  - `onPress` - called for onClick and onKeyDown
14
14
  - `ref` is forwarded to underlying `div`
15
+ - `blockRepeatedKeyDown` - interactable must suppress repeated onPress calls, until the key is released. This is because because keyDown event is repeatedly fired when user holds key on webTv and Adrodid Tv. This may lead to unpredictable behavior.
15
16
  - other `div` props
16
17
 
17
18
  ## Provided functionality
@@ -34,4 +35,4 @@ renders
34
35
  <div class="btn btn-primary" tabindex="0">
35
36
  Play video
36
37
  </div>
37
- ```
38
+ ```
@@ -3,21 +3,46 @@ import { isClickOrEnter } from '@24i/bigscreen-sdk/device';
3
3
  import { Props } from './interface';
4
4
 
5
5
  export const Interactable = forwardRef<Props>(
6
- ({ children, onPress, ...otherProps }, ref: Reference<HTMLDivElement> | null) => {
6
+ ({ children, onPress, blockRepeatedKeyDown, ...otherProps },
7
+ ref: Reference<HTMLDivElement> | null) => {
7
8
  const domRef = ref || createRef<HTMLDivElement>();
8
- const onPressProxy = (e: KeyboardEvent | MouseEvent) => {
9
- if (typeof onPress === 'function' && isClickOrEnter(e)) onPress(e);
9
+
10
+ let keyIsReleased = true;
11
+
12
+ const releaseKey = () => {
13
+ keyIsReleased = true;
14
+ window.removeEventListener('keyup', releaseKey);
15
+ };
16
+
17
+ const onClickProxy = (e: MouseEvent) => {
18
+ if (typeof onPress === 'function' && isClickOrEnter(e)) {
19
+ onPress(e);
20
+ }
10
21
  };
22
+
23
+ const onKeyDownProxy = (e: KeyboardEvent) => {
24
+ if (typeof onPress === 'function' && isClickOrEnter(e) && keyIsReleased) {
25
+ if (blockRepeatedKeyDown) {
26
+ keyIsReleased = false;
27
+ window.addEventListener('keyup', releaseKey);
28
+ onPress(e);
29
+ } else {
30
+ onPress(e);
31
+ }
32
+ }
33
+ };
34
+
11
35
  const onMouseEnter = () => {
12
36
  domRef.current!.focus({ preventScroll: true });
13
37
  };
38
+
14
39
  return (
15
40
  <div
16
41
  {...otherProps}
17
42
  ref={domRef}
18
43
  onMouseEnter={onMouseEnter}
19
- onClick={onPressProxy}
20
- onKeyDown={onPressProxy}
44
+ onClick={onClickProxy}
45
+ onKeyDown={onKeyDownProxy}
21
46
  tabIndex={0}
22
47
  >
23
48
  {children}
@@ -3,4 +3,5 @@ import { Children } from '@24i/bigscreen-sdk/jsx';
3
3
  export type Props = {
4
4
  children?: Children,
5
5
  onPress?: (event: KeyboardEvent | MouseEvent) => void,
6
+ blockRepeatedKeyDown?: boolean,
6
7
  } & Omit<React.HTMLAttributes<HTMLDivElement>, 'children'>;
@@ -1,5 +1,6 @@
1
1
  export { click } from './click';
2
2
  export { enter } from './enter';
3
3
  export { keydown } from './keydown';
4
+ export { keyup } from './keyup';
4
5
  export { shallow } from './shallow';
5
6
  export { MountedComponent } from './MountedComponent';
@@ -0,0 +1,27 @@
1
+ import { Reference, Component } from '../index';
2
+ import { unwrapReference } from '../utils';
3
+
4
+ type ToPress = Reference<HTMLElement> | HTMLElement | Window | Document | Component<any>;
5
+
6
+ interface Key {
7
+ keyCode: number,
8
+ code: string,
9
+ key?: string,
10
+ }
11
+
12
+ export const keyup = (toPress: ToPress, keyOrKeyCode: number | Key) => {
13
+ const element = unwrapReference<ToPress>(toPress);
14
+ let kbEventOptions: KeyboardEventInit;
15
+ if (typeof keyOrKeyCode === 'number') {
16
+ kbEventOptions = { keyCode: keyOrKeyCode };
17
+ } else {
18
+ const { keyCode, code, key } = keyOrKeyCode;
19
+ kbEventOptions = { keyCode, code, key };
20
+ }
21
+ const event = new KeyboardEvent('keyup', kbEventOptions);
22
+ if ((element as any).onKeyUp) {
23
+ (element as any).onKeyUp(event);
24
+ } else if ((element as any).dispatchEvent) {
25
+ (element as Element).dispatchEvent(event);
26
+ }
27
+ };
@@ -10,11 +10,15 @@ type Props = {
10
10
  isFocusable?: boolean;
11
11
  };
12
12
 
13
+ type RenderFunction = (ref:Reference) => JSX.Element;
14
+
13
15
  export class ModalService extends Component<Props> {
14
16
  private openState = false;
15
17
 
16
18
  private readonly rootRef = createRef<HTMLDivElement>();
17
19
 
20
+ private readonly modalQueue: RenderFunction[] = [];
21
+
18
22
  modalRef = createRef<any>();
19
23
 
20
24
  static defaultProps = {
@@ -40,7 +44,19 @@ export class ModalService extends Component<Props> {
40
44
  return this.modalRef;
41
45
  }
42
46
 
43
- open<T extends IModal>(render: (ref: Reference<T>) => JSX.Element) {
47
+ private enqueueModal(modal: RenderFunction) {
48
+ this.modalQueue.push(modal);
49
+ }
50
+
51
+ private dequeueModal() {
52
+ return this.modalQueue.shift();
53
+ }
54
+
55
+ open<T extends IModal>(render: (ref: Reference<T>) => JSX.Element, queueModal = false) {
56
+ if (queueModal && this.openState) {
57
+ this.enqueueModal(render);
58
+ return;
59
+ }
44
60
  const { isFocusable } = this.props;
45
61
  this.openState = true;
46
62
  this.clearMount(
@@ -60,6 +76,8 @@ export class ModalService extends Component<Props> {
60
76
  if (isFocusable) {
61
77
  focusCandidate();
62
78
  }
79
+ const modalFromQueue = this.dequeueModal();
80
+ if (modalFromQueue) this.open(modalFromQueue);
63
81
  }
64
82
 
65
83
  isOpen() {
@@ -58,6 +58,7 @@ export class PlayerInteractable extends Component<Props> {
58
58
  ref={this.div}
59
59
  className={`player-ui-button ${hidden ? DISPLAY_NONE : ''} ${className}`}
60
60
  onPress={this.onPress}
61
+ blockRepeatedKeyDown
61
62
  >
62
63
  {children}
63
64
  </Interactable>