@24i/bigscreen-sdk 1.0.2-alpha.2074 → 1.0.2-alpha.2089

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 (41) hide show
  1. package/package.json +2 -2
  2. package/packages/developer-tools/src/TechnicalInfo/styles/TechnicalInfo.scss +1 -0
  3. package/packages/developer-tools/src/TechnicalInfo/utils/emeSupport.ts +6 -2
  4. package/packages/driver-tizen/src/DeviceTizen.ts +3 -1
  5. package/packages/driver-vidaa/src/DeviceVidaa.ts +7 -1
  6. package/packages/driver-vidaa/src/__mocks__/vidaa.ts +1 -0
  7. package/packages/driver-vidaa/src/constants.ts +8 -0
  8. package/packages/driver-vidaa/src/types.ts +8 -0
  9. package/packages/focus/src/Layout/Matrix.tsx +1 -2
  10. package/packages/grid/src/Base/Base.tsx +25 -6
  11. package/packages/grid/src/Base/MouseNavigation/MouseNavigation.tsx +82 -0
  12. package/packages/grid/src/Base/MouseNavigation/MouseNavigationFallback.ts +4 -0
  13. package/packages/grid/src/Base/MouseNavigation/index.tizen.tv.ts +1 -0
  14. package/packages/grid/src/Base/MouseNavigation/index.ts +1 -0
  15. package/packages/grid/src/Base/MouseNavigation/index.webos.tv.ts +1 -0
  16. package/packages/grid/src/Base/MouseNavigation/index.webtv.ts +1 -0
  17. package/packages/grid/src/Base/interface.ts +47 -0
  18. package/packages/grid/src/UnifiedGridController/UnifiedGridController.ts +6 -1
  19. package/packages/i18n/src/middlewares/i18next/Plurals/Plurals.ts +2 -2
  20. package/packages/keyboard/src/WhitelabelKeyboard/Keyboard.tsx +6 -2
  21. package/packages/list/src/Base/Base.tsx +4 -2
  22. package/packages/list/src/Base/MouseNavigation/MouseNavigation.tsx +33 -9
  23. package/packages/list/src/EdgeOffsetList/EdgeOffsetList.tsx +3 -1
  24. package/packages/list/src/types.ts +6 -0
  25. package/packages/menu/src/MenuAndContentContainer/MenuAndContentContainer.tsx +31 -16
  26. package/packages/menu/src/MenuAndContentContainer/interface.ts +0 -8
  27. package/packages/menu/src/WhitelabelMenu/SideMenu.scss +1 -1
  28. package/packages/menu/src/WhitelabelMenu/SideMenu.tsx +1 -1
  29. package/packages/menu/src/WhitelabelMenu/_animated.scss +1 -1
  30. package/packages/menu/src/WhitelabelMenu/rtl.scss +1 -1
  31. package/packages/modal-service/src/ModalService.tsx +3 -1
  32. package/packages/mouse-navigation/src/MouseNavigation.tsx +18 -0
  33. package/packages/player-ui/src/PlayerUI.tsx +1 -5
  34. package/packages/types-bigscreen-jsx/index.d.ts +1 -1
  35. package/packages/utils/src/counter.ts +3 -1
  36. package/packages/utils/src/xhr/xhrSendRetry.ts +2 -2
  37. package/packages/volume-control/src/__mocks__/VolumeControlUIMock.tsx +6 -2
  38. package/packages/grid/src/Base/Base.mouse.tsx +0 -24
  39. package/packages/grid/src/Base/index.tizen.tv.ts +0 -1
  40. package/packages/grid/src/Base/index.webos.tv.ts +0 -1
  41. package/packages/grid/src/Base/index.webtv.ts +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@24i/bigscreen-sdk",
3
- "version": "1.0.2-alpha.2074",
3
+ "version": "1.0.2-alpha.2089",
4
4
  "description": "SmartApps BIGscreen SDK monorepo",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -38,7 +38,7 @@
38
38
  "homepage": "https://github.com/24i/smartapps-bigscreen-sdk#readme",
39
39
  "dependencies": {
40
40
  "@24i/player-base": "6.10.0",
41
- "@24i/smartapps-datalayer": "2.3.2",
41
+ "@24i/smartapps-datalayer": "2.3.3",
42
42
  "@sentry/browser": "^7.8.0",
43
43
  "@types/prop-types": "^15.7.5",
44
44
  "@types/scheduler": "^0.16.1",
@@ -140,6 +140,7 @@
140
140
  display: inline-block;
141
141
  vertical-align: top;
142
142
  width: $value-width;
143
+ word-break: break-word;
143
144
  }
144
145
  }
145
146
  }
@@ -30,8 +30,12 @@ function isKeySystemSupported(keySystem: string, config: MediaKeySystemConfigura
30
30
  return new Promise((resolve) => {
31
31
  try {
32
32
  window.navigator.requestMediaKeySystemAccess(keySystem, config)
33
- .then(() => { resolve(true); })
34
- .catch(() => { resolve(false); });
33
+ .then(() => {
34
+ resolve(true);
35
+ })
36
+ .catch(() => {
37
+ resolve(false);
38
+ });
35
39
  } catch (e) {
36
40
  resolve(false);
37
41
  }
@@ -252,7 +252,9 @@ export class DeviceTizen extends DeviceBase {
252
252
  this.screenSaverStatus = status;
253
253
  resolve();
254
254
  },
255
- () => { resolve(); },
255
+ () => {
256
+ resolve();
257
+ },
256
258
  );
257
259
  });
258
260
  }
@@ -4,6 +4,7 @@ import {
4
4
  ScreenSaverStatus,
5
5
  VolumeRange,
6
6
  } from '@24i/bigscreen-sdk/driver-base';
7
+ import { NetworkConnectionTypeMap } from './constants';
7
8
  import { getPlatformInfo } from './formatUserAgent';
8
9
  import { HisenseVidaaApi } from './types';
9
10
  import { getKeyMap } from './keymap';
@@ -118,7 +119,12 @@ export class DeviceVidaa extends DeviceBase {
118
119
  }
119
120
 
120
121
  async getConnectionType(): Promise<ConnectionType> {
121
- // not supported on Hisense VIDAA platform
122
+ try {
123
+ const netType = window.Hisense_GetNetType();
124
+ return NetworkConnectionTypeMap[netType] || 'unknown';
125
+ } catch (e) {
126
+ console.error('[DeviceVidaa] Failed getConnectionType', e);
127
+ }
122
128
  return 'unknown';
123
129
  }
124
130
 
@@ -6,6 +6,7 @@ export const mockHisenseVidaaApi: HisenseVidaaApi = {
6
6
  Hisense_GetFirmWareVersion: () => 'V0000.01.00Q.L0301',
7
7
  Hisense_Get4KSupportState: () => true,
8
8
  Hisense_GetDeviceID: () => '861003009000001000000641123456789012',
9
+ Hisense_GetNetType: () => 'wireless',
9
10
  };
10
11
 
11
12
  // Key constants are set to random number values
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Mapping connection type from Hisense VIDAA to SDK connection type.
3
+ */
4
+ export const NetworkConnectionTypeMap = {
5
+ wired: 'cable',
6
+ wireless: 'wifi',
7
+ OFF: 'none',
8
+ } as const;
@@ -1,3 +1,5 @@
1
+ export type HisenseNetType = 'OFF' | 'wired' | 'wireless';
2
+
1
3
  export interface HisenseVidaaApi {
2
4
  /**
3
5
  * This interface will retrieve Hisense Unique ID for the device.
@@ -27,6 +29,12 @@ export interface HisenseVidaaApi {
27
29
  * @return a string that represents the TV model name.
28
30
  */
29
31
  Hisense_GetModelName: () => string,
32
+ /**
33
+ * This interface retrieves the network type of the device.
34
+ * @return a string that represents the network type for the device.
35
+ * The one from "OFF", "wired", "wireless".
36
+ */
37
+ Hisense_GetNetType: () => HisenseNetType,
30
38
  }
31
39
 
32
40
  export type HisenseVidaaKeys = {
@@ -154,8 +154,7 @@ export class Matrix extends Component<Props> implements IFocusable {
154
154
  isDifferentReferenceFromCurrent(index: Index2D): boolean {
155
155
  const { current } = this.getRefAt(this.index);
156
156
  const { current: searched } = this.getRefAt(index);
157
- if (current !== searched && searched !== null) return true;
158
- return false;
157
+ return current !== searched && searched !== null;
159
158
  }
160
159
 
161
160
  isSameReferenceAsCurrent(index: Index2D): boolean {
@@ -1,13 +1,14 @@
1
1
  import { createRef, Component, Reference, DeclareProps } from '@24i/bigscreen-sdk/jsx';
2
2
  import { device } from '@24i/bigscreen-sdk/device';
3
- import { MouseNavigation } from '@24i/bigscreen-sdk/mouse-navigation';
4
3
  import { Scroller } from '@24i/bigscreen-sdk/scroller';
5
4
  import { stopEvent } from '@24i/bigscreen-sdk/utils/stopEvent';
6
5
  import { noop } from '@24i/bigscreen-sdk/utils/noop';
7
6
  import { forEach } from '@24i/bigscreen-sdk/perf-utils/array';
8
7
  import { createTimeout, createCounter, ICounter } from '@24i/bigscreen-sdk/utils';
8
+ import { MouseNavigation } from './MouseNavigation';
9
9
  import { FastFocusingOptimizer } from '../FastFocusingOptimizer/FastFocusingOptimizer';
10
10
  import { SharedProps, Item } from '../types';
11
+ import { MouseNavigation as IMouseNavigation } from './interface';
11
12
 
12
13
  export type Props<T extends Item<U>, U> = Omit<SharedProps<T, U>, 'scrollStep'> & {
13
14
  forward: () => boolean,
@@ -21,7 +22,6 @@ export type Props<T extends Item<U>, U> = Omit<SharedProps<T, U>, 'scrollStep'>
21
22
  adjustFocusFromTarget?: (itemRefIndex: number, groupRefIndex: number) => void,
22
23
  horizontal?: boolean,
23
24
  limit?: number,
24
- mrcuRef?: Reference<MouseNavigation>;
25
25
  shouldApplySlowdown?: () => boolean,
26
26
  };
27
27
 
@@ -55,6 +55,8 @@ export class GridBase<T extends Item<U>, U>
55
55
 
56
56
  scrollerDom = createRef<HTMLDivElement>();
57
57
 
58
+ mrcuRef = createRef<IMouseNavigation>();
59
+
58
60
  itemRefs: Reference<T>[] = [];
59
61
 
60
62
  groupRefs: Reference<HTMLDivElement>[] = [];
@@ -151,14 +153,13 @@ export class GridBase<T extends Item<U>, U>
151
153
  onWheel = (event: WheelEvent) => {
152
154
  const {
153
155
  forwardGroup, backwardGroup, shouldApplySlowdown,
154
- mrcuRef,
155
156
  } = this.props;
156
157
  let processed;
157
158
  if (event.deltaY > 0) processed = shouldApplySlowdown() || forwardGroup();
158
159
  else if (event.deltaY < 0) processed = shouldApplySlowdown() || backwardGroup();
159
160
  if (processed) {
160
161
  stopEvent(event);
161
- mrcuRef?.current?.handleArrowState();
162
+ this.mrcuRef.current?.handleArrowState();
162
163
  if (this.fastScrollingCounter) {
163
164
  this.fastScrollingCounter.add();
164
165
  this.fakeWheelStop();
@@ -434,7 +435,15 @@ export class GridBase<T extends Item<U>, U>
434
435
  }
435
436
 
436
437
  render() {
437
- const { horizontal, className } = this.props;
438
+ const {
439
+ horizontal,
440
+ className,
441
+ forwardGroup,
442
+ backwardGroup,
443
+ shouldShowMrcuForward,
444
+ shouldShowMrcuBackward,
445
+ } = this.props;
446
+
438
447
  return (
439
448
  <Scroller
440
449
  className={className}
@@ -443,7 +452,17 @@ export class GridBase<T extends Item<U>, U>
443
452
  onKeyDown={this.onKeyDown}
444
453
  horizontal={horizontal}
445
454
  >
446
- {this.renderData()}
455
+ <>{this.renderData()}</>
456
+ <MouseNavigation
457
+ // @ts-ignore - needed to convert fallback (false) to interface
458
+ ref={this.mrcuRef}
459
+ getMountingPoint={() => this.scroller.current!.wrapRef}
460
+ horizontal={horizontal}
461
+ forward={forwardGroup}
462
+ backward={backwardGroup}
463
+ shouldShowMrcuForward={shouldShowMrcuForward}
464
+ shouldShowMrcuBackward={shouldShowMrcuBackward}
465
+ />
447
466
  </Scroller>
448
467
  );
449
468
  }
@@ -0,0 +1,82 @@
1
+ import { Component, createRef, removeNode } from '@24i/bigscreen-sdk/jsx';
2
+ import { MouseNavigation as MouseNavigationBase } from '@24i/bigscreen-sdk/mouse-navigation';
3
+ import { device, DeviceEventMap } from '@24i/bigscreen-sdk/device';
4
+ import {
5
+ MouseNavigationProps as Props,
6
+ MouseNavigation as IMouseNavigation,
7
+ } from '../interface';
8
+
9
+ export class MouseNavigation extends Component<Props> implements IMouseNavigation {
10
+ private readonly wrapper = createRef<HTMLDivElement>();
11
+
12
+ private readonly mouseNavigationBase = createRef<MouseNavigationBase>();
13
+
14
+ private isMouseEnabled = true;
15
+
16
+ componentDidMount() {
17
+ this.handleWheelListener();
18
+ device.addEventListener('mouseactive', this.mouseListener);
19
+ }
20
+
21
+ componentWillUnmount() {
22
+ this.handleWheelListener();
23
+ device.removeEventListener('mouseactive', this.mouseListener);
24
+ }
25
+
26
+ handleWheelListener() {
27
+ if (this.isMouseEnabled && device.isMouseUsed()) {
28
+ this.renderArrows();
29
+ } else {
30
+ this.destroyArrows();
31
+ }
32
+ }
33
+
34
+ handleArrowState() {
35
+ this.mouseNavigationBase?.current?.handleArrowState();
36
+ }
37
+
38
+ mouseListener: DeviceEventMap['mouseactive'] = ({ isMouseActive }) => {
39
+ this.isMouseEnabled = isMouseActive;
40
+ this.handleWheelListener();
41
+ };
42
+
43
+ destroyArrows() {
44
+ if (!this.wrapper.current) return;
45
+ removeNode(this.wrapper);
46
+ }
47
+
48
+ renderArrows() {
49
+ const {
50
+ horizontal,
51
+ forward,
52
+ backward,
53
+ shouldShowMrcuForward,
54
+ shouldShowMrcuBackward,
55
+ getMountingPoint,
56
+ } = this.props;
57
+
58
+ const direction = horizontal ? 'horizontal' : 'vertical';
59
+
60
+ this.appendMount(
61
+ <div ref={this.wrapper} className="mouse-navigation">
62
+ <MouseNavigationBase
63
+ // @ts-ignore - needed to convert fallback (false) to interface
64
+ ref={this.mouseNavigationBase}
65
+ getMountingPoint={() => this.wrapper}
66
+ direction={direction}
67
+ forward={forward}
68
+ backward={backward}
69
+ shouldShowMrcuForward={shouldShowMrcuForward}
70
+ shouldShowMrcuBackward={shouldShowMrcuBackward}
71
+ >
72
+ {null as unknown as JSX.Element}
73
+ </MouseNavigationBase>
74
+ </div>,
75
+ getMountingPoint(),
76
+ );
77
+ }
78
+
79
+ render() {
80
+ return null;
81
+ }
82
+ }
@@ -0,0 +1,4 @@
1
+ import { MouseNavigationProps as Props } from '../interface';
2
+
3
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
4
+ export const MouseNavigation = (props: Props) => false as unknown as JSX.Element;
@@ -0,0 +1 @@
1
+ export { MouseNavigation } from './MouseNavigation';
@@ -0,0 +1 @@
1
+ export { MouseNavigation } from './MouseNavigationFallback';
@@ -0,0 +1 @@
1
+ export { MouseNavigation } from './MouseNavigation';
@@ -0,0 +1 @@
1
+ export { MouseNavigation } from './MouseNavigation';
@@ -0,0 +1,47 @@
1
+ import { Reference, Component } from '@24i/bigscreen-sdk/jsx';
2
+
3
+ export type MouseNavigationProps = {
4
+ /**
5
+ * Function to call on the press of the right arrow.
6
+ */
7
+ forward(): boolean,
8
+ /**
9
+ * Function to call on the press of the left arrow.
10
+ */
11
+ backward(): boolean,
12
+ /**
13
+ * Function to call on the press of the down arrow.
14
+ */
15
+ forwardGroup?(): boolean,
16
+ /**
17
+ * Function to call on the press of the up arrow.
18
+ */
19
+ backwardGroup?(): boolean,
20
+ /**
21
+ * Function which determines whether to show the forward arrow.
22
+ */
23
+ shouldShowMrcuForward?(): boolean,
24
+ /**
25
+ * Function which determines whether to show the backward arrow.
26
+ */
27
+ shouldShowMrcuBackward?(): boolean,
28
+ /**
29
+ * Returns a reference to the element where your `children` should be rendered.
30
+ */
31
+ getMountingPoint(): Reference<HTMLElement>;
32
+ /**
33
+ * Property determines whether navigation is horizontal.
34
+ */
35
+ horizontal?: boolean,
36
+ };
37
+
38
+ export interface MouseNavigation extends Component<MouseNavigationProps> {
39
+ /**
40
+ * Function to disable showing an arrow in the given direction.
41
+ */
42
+ handleArrowState(): void,
43
+ }
44
+
45
+ export interface MouseNavigationComponent {
46
+ new (props: MouseNavigationProps): MouseNavigation,
47
+ }
@@ -295,6 +295,8 @@ export class UnifiedGridController<T> implements IUnifiedGridController<T> {
295
295
  }
296
296
 
297
297
  focusToIndex(dataIndex: number, animate = false) {
298
+ const { grid } = this;
299
+ const base = grid.base.current!;
298
300
  const targetScrollIndex = this.itemIndexToScrollIndex(dataIndex);
299
301
  if (targetScrollIndex > this.scrollIndex) {
300
302
  this.adjustGroupsOffsetsForward(targetScrollIndex);
@@ -304,8 +306,9 @@ export class UnifiedGridController<T> implements IUnifiedGridController<T> {
304
306
  if (targetScrollIndex !== this.scrollIndex) {
305
307
  this.scroll(targetScrollIndex, animate);
306
308
  }
307
- this.grid.base.current!.index = dataIndex;
309
+ base.index = dataIndex;
308
310
  this.focusCurrentItem();
311
+ base.mrcuRef.current?.handleArrowState();
309
312
  }
310
313
 
311
314
  protected focusScrollWrap() {
@@ -521,6 +524,7 @@ export class UnifiedGridController<T> implements IUnifiedGridController<T> {
521
524
  forEach(this.groups, (group, index) => {
522
525
  this.updateItemsInGroup(group, index * itemsInGroup);
523
526
  });
527
+ base.mrcuRef.current?.handleArrowState();
524
528
  }
525
529
 
526
530
  prependData(data: T[]) {
@@ -546,5 +550,6 @@ export class UnifiedGridController<T> implements IUnifiedGridController<T> {
546
550
  this.scrollIndexToPixels(this.scrollIndex),
547
551
  );
548
552
  this.focusCurrentItem();
553
+ base.mrcuRef.current?.handleArrowState();
549
554
  }
550
555
  }
@@ -45,8 +45,8 @@ const isCountInInterval = (count: number, interval: string) => {
45
45
  if (numbers.length === 1 && parseInt(numbers[0], 10) === count) return true;
46
46
  const from = parseInt(numbers[0], 10);
47
47
  const to = numbers[1] === 'inf' ? Infinity : parseInt(numbers[1], 10);
48
- if (count >= from && count <= to) return true;
49
- return false;
48
+ return count >= from && count <= to;
49
+
50
50
  };
51
51
 
52
52
  const shouldUseInterval = (
@@ -145,7 +145,9 @@ export class Keyboard extends KeyboardBase<Layouts, Props> {
145
145
  <Interactable
146
146
  ref={this.keyRefs.space}
147
147
  className="key key-wide key-space"
148
- onPress={() => { this.onKey(' '); }}
148
+ onPress={() => {
149
+ this.onKey(' ');
150
+ }}
149
151
  >
150
152
  <div className="key-background">
151
153
  {texts.space}
@@ -208,7 +210,9 @@ export class Keyboard extends KeyboardBase<Layouts, Props> {
208
210
  <Interactable
209
211
  ref={this.keyRefs.space}
210
212
  className="key key-wide key-space"
211
- onPress={() => { this.onKey(' '); }}
213
+ onPress={() => {
214
+ this.onKey(' ');
215
+ }}
212
216
  >
213
217
  <div className="key-background">
214
218
  {texts.space}
@@ -49,6 +49,8 @@ export class ListBase<T extends Item<U>, U>
49
49
 
50
50
  mrcuRef = createRef<IMouseNavigation>();
51
51
 
52
+ // mrcuRef2: Reference<HTMLDivElement>;
53
+
52
54
  itemRefs: Reference<T>[] = [];
53
55
 
54
56
  index = 0;
@@ -344,7 +346,7 @@ export class ListBase<T extends Item<U>, U>
344
346
  }
345
347
 
346
348
  render() {
347
- const { horizontal, className } = this.props;
349
+ const { horizontal, className, mrcuMountingPoint } = this.props;
348
350
  return (
349
351
  <Scroller
350
352
  className={className}
@@ -357,7 +359,7 @@ export class ListBase<T extends Item<U>, U>
357
359
  <MouseNavigation
358
360
  // @ts-ignore - needed to convert fallback (false) to interface
359
361
  ref={this.mrcuRef}
360
- getMountingPoint={() => this.scroller.current!.wrapRef}
362
+ getMountingPoint={() => mrcuMountingPoint || this.scroller.current!.wrapRef}
361
363
  {...this.props}
362
364
  />
363
365
  </Scroller>
@@ -1,24 +1,48 @@
1
- import { Component, createRef } from '@24i/bigscreen-sdk/jsx';
1
+ import { Component, createRef, removeNode } from '@24i/bigscreen-sdk/jsx';
2
2
  import { MouseNavigation as MouseNavigationBase } from '@24i/bigscreen-sdk/mouse-navigation';
3
- import { device } from '@24i/bigscreen-sdk/device';
3
+ import { device, DeviceEventMap } from '@24i/bigscreen-sdk/device';
4
4
  import {
5
5
  MouseNavigationProps as Props,
6
6
  MouseNavigation as IMouseNavigation,
7
7
  } from '../interface';
8
8
 
9
9
  export class MouseNavigation extends Component<Props> implements IMouseNavigation {
10
- private readonly div = createRef<HTMLDivElement>();
10
+ private readonly wrapper = createRef<HTMLDivElement>();
11
11
 
12
- private readonly base = createRef<MouseNavigationBase>();
12
+ private readonly mouseNavigationBase = createRef<MouseNavigationBase>();
13
+
14
+ private isMouseEnabled = true;
13
15
 
14
16
  componentDidMount() {
15
- if (device.isMouseUsed()) {
17
+ this.handleWheelListener();
18
+ device.addEventListener('mouseactive', this.mouseListener);
19
+ }
20
+
21
+ componentWillUnmount() {
22
+ this.handleWheelListener();
23
+ device.removeEventListener('mouseactive', this.mouseListener);
24
+ }
25
+
26
+ handleWheelListener() {
27
+ if (this.isMouseEnabled && device.isMouseUsed()) {
16
28
  this.renderArrows();
29
+ } else {
30
+ this.destroyArrows();
17
31
  }
18
32
  }
19
33
 
20
34
  handleArrowState() {
21
- this.base?.current?.handleArrowState();
35
+ this.mouseNavigationBase?.current?.handleArrowState();
36
+ }
37
+
38
+ mouseListener: DeviceEventMap['mouseactive'] = ({ isMouseActive }) => {
39
+ this.isMouseEnabled = isMouseActive;
40
+ this.handleWheelListener();
41
+ };
42
+
43
+ destroyArrows() {
44
+ if (!this.wrapper.current) return;
45
+ removeNode(this.wrapper);
22
46
  }
23
47
 
24
48
  renderArrows() {
@@ -34,11 +58,11 @@ export class MouseNavigation extends Component<Props> implements IMouseNavigatio
34
58
  const direction = horizontal ? 'horizontal' : 'vertical';
35
59
 
36
60
  this.appendMount(
37
- <div ref={this.div} className="mouse-navigation">
61
+ <div ref={this.wrapper} className="mouse-navigation">
38
62
  <MouseNavigationBase
39
63
  // @ts-ignore - needed to convert fallback (false) to interface
40
- ref={this.base}
41
- getMountingPoint={() => this.div}
64
+ ref={this.mouseNavigationBase}
65
+ getMountingPoint={() => this.wrapper}
42
66
  direction={direction}
43
67
  forward={forward}
44
68
  backward={backward}
@@ -1,4 +1,4 @@
1
- import { Component, createRef, DeclareProps } from '@24i/bigscreen-sdk/jsx';
1
+ import { Component, createRef, DeclareProps, Reference } from '@24i/bigscreen-sdk/jsx';
2
2
  import { IFocusable } from '@24i/bigscreen-sdk/focus';
3
3
  import { noop } from '@24i/bigscreen-sdk/utils/noop';
4
4
  import { ListBase } from '../Base';
@@ -29,6 +29,8 @@ export class EdgeOffsetList<T extends Item<U>, U>
29
29
  */
30
30
  base = createRef<ListBase<T, U>>();
31
31
 
32
+ //mrcuRef = createRef<HTMLDivElement>();
33
+
32
34
  /**
33
35
  * Unified controller for leveraging common behaviour
34
36
  */
@@ -1,5 +1,6 @@
1
1
  import { Reference, Component } from '@24i/bigscreen-sdk/jsx';
2
2
  import { EasingType } from '@24i/bigscreen-sdk/animations';
3
+ import { HtmlAttributes } from 'csstype';
3
4
 
4
5
  export interface Item<T> extends Component<any> {
5
6
  focus: (options?: FocusOptions) => void,
@@ -66,6 +67,11 @@ export type BasicProps<T extends Item<U>, U> = {
66
67
  */
67
68
  fastFocusingOptimization?: boolean,
68
69
 
70
+ /**
71
+ * Returns a reference to the custom HTML div for the mrcu arrows.
72
+ */
73
+ mrcuMountingPoint?: Reference<HTMLDivElement>,
74
+
69
75
  /**
70
76
  * Function called every time before list performs one full scroll.
71
77
  * @param item Reference to item on current scroll
@@ -1,6 +1,7 @@
1
1
  import { Component, createRef } from '@24i/bigscreen-sdk/jsx';
2
2
  import { device } from '@24i/bigscreen-sdk/device';
3
3
  import { stopEvent } from '@24i/bigscreen-sdk/utils/stopEvent';
4
+ import { getDisplayToggler, DISPLAY_NONE } from '@24i/bigscreen-sdk/utils/displayToggler';
4
5
  import { service } from './service';
5
6
  import {
6
7
  Props,
@@ -25,6 +26,16 @@ export class MenuAndContentContainer<T extends string = string>
25
26
  */
26
27
  listensToMouse = false;
27
28
 
29
+ /**
30
+ * Element for triggering menu by mouse event.
31
+ */
32
+ mouseTriggerElement = createRef<HTMLDivElement>();
33
+
34
+ /**
35
+ * DisplayToggler for {@link mouseTriggerElement}.
36
+ */
37
+ mouseTriggerElementDisplayToggler = getDisplayToggler(this.mouseTriggerElement, true);
38
+
28
39
  /**
29
40
  * Adds event listeners:
30
41
  * - keydown to {@link Props.elementForEvents elementForEvents}
@@ -58,10 +69,12 @@ export class MenuAndContentContainer<T extends string = string>
58
69
  onVisibilityChange = (visible: boolean) => {
59
70
  if (visible) {
60
71
  this.menu.current!.focus();
72
+ if (this.listensToMouse) this.mouseTriggerElementDisplayToggler.hide();
61
73
  service.triggerEvent('visibilitychange', true);
62
74
  } else {
63
75
  const { router: { current: router } } = this.props;
64
76
  router!.focus();
77
+ if (this.listensToMouse) this.mouseTriggerElementDisplayToggler.show();
65
78
  service.triggerEvent('visibilitychange', false);
66
79
  }
67
80
  };
@@ -88,14 +101,10 @@ export class MenuAndContentContainer<T extends string = string>
88
101
  * @param event mouse event
89
102
  */
90
103
  onMouseMove = (event: MouseEvent) => {
91
- const { Menu } = this.props;
92
104
  const menu = this.menu.current!;
93
105
  if (this.isMenuAvailable() && !menu.isOpen()) {
94
- const { clientX, clientY } = event;
95
- if (Menu.shouldOpenMenuWithMouse({ clientX, clientY })) {
96
- menu.open();
97
- stopEvent(event);
98
- }
106
+ menu.open();
107
+ stopEvent(event);
99
108
  }
100
109
  };
101
110
 
@@ -127,8 +136,8 @@ export class MenuAndContentContainer<T extends string = string>
127
136
  addMouseListener() {
128
137
  if (!this.listensToMouse) {
129
138
  this.listensToMouse = true;
130
- const { elementForEvents } = this.props;
131
- elementForEvents.current!.addEventListener('mousemove', this.onMouseMove);
139
+ if (!this.menu.current!.isOpen()) this.mouseTriggerElementDisplayToggler.show();
140
+ this.mouseTriggerElement.current!.addEventListener('mousemove', this.onMouseMove);
132
141
  }
133
142
  }
134
143
 
@@ -138,8 +147,8 @@ export class MenuAndContentContainer<T extends string = string>
138
147
  removeMouseListener() {
139
148
  if (this.listensToMouse) {
140
149
  this.listensToMouse = false;
141
- const { elementForEvents } = this.props;
142
- elementForEvents.current!.removeEventListener('mousemove', this.onMouseMove);
150
+ if (!this.menu.current!.isOpen()) this.mouseTriggerElementDisplayToggler.hide();
151
+ this.mouseTriggerElement.current!.removeEventListener('mousemove', this.onMouseMove);
143
152
  }
144
153
  }
145
154
 
@@ -155,12 +164,18 @@ export class MenuAndContentContainer<T extends string = string>
155
164
  const { children, items, Menu } = this.props;
156
165
  return (
157
166
  <>
158
- <Menu
159
- ref={this.menu}
160
- items={items}
161
- onVisibilityChange={this.onVisibilityChange}
162
- contentContainer={this}
163
- />
167
+ <div className="menu-container">
168
+ <Menu
169
+ ref={this.menu}
170
+ items={items}
171
+ onVisibilityChange={this.onVisibilityChange}
172
+ contentContainer={this}
173
+ />
174
+ <div
175
+ ref={this.mouseTriggerElement}
176
+ className={`menu-mouse-trigger ${DISPLAY_NONE}`}
177
+ />
178
+ </div>
164
179
  {children}
165
180
  </>
166
181
  );
@@ -119,13 +119,6 @@ export interface Menu<
119
119
  updateItems(items: MenuItem<T>[]): void,
120
120
  }
121
121
 
122
- /**
123
- * Function for deciding whether to open menu based on mouse position.
124
- */
125
- type MouseMenuOpenResolver = (
126
- ({ clientX, clientY }: { clientX: number, clientY: number }) => boolean
127
- );
128
-
129
122
  /**
130
123
  * Function for deciding whether to open menu based on pressed key.
131
124
  */
@@ -145,7 +138,6 @@ type KeyboardMenuCloseResolver = (
145
138
  */
146
139
  export interface MenuComponent<T extends string = string, P extends MenuProps<T> = MenuProps<T>> {
147
140
  new (props: P): Menu<T, P>,
148
- shouldOpenMenuWithMouse: MouseMenuOpenResolver,
149
141
  shouldOpenMenu: KeyboardMenuOpenResolver,
150
142
  shouldCloseMenu: KeyboardMenuCloseResolver,
151
143
  }
@@ -1,4 +1,4 @@
1
- .menu-container {
1
+ .menu-container .side-menu {
2
2
  position: absolute;
3
3
  top: 0;
4
4
  left: 0;
@@ -220,7 +220,7 @@ export class SideMenu extends Component<Props> implements ISideMenu {
220
220
  render() {
221
221
  const { items } = this.props;
222
222
  return (
223
- <div ref={this.visualController.div} className={`menu-container ${DISPLAY_NONE}`}>
223
+ <div ref={this.visualController.div} className={`side-menu ${DISPLAY_NONE}`}>
224
224
  <div
225
225
  ref={this.visualController.overlay}
226
226
  className={`overlay ${animated ? DISPLAY_NONE : ''}`}
@@ -2,7 +2,7 @@
2
2
  @import '@24i/bigscreen-sdk/sass-utils/transition';
3
3
  @import '@24i/bigscreen-sdk/sass-utils/prefix-property';
4
4
 
5
- .menu-container {
5
+ .menu-container .side-menu {
6
6
  @include transform(translate3d(0, 0, 0));
7
7
  @include transition(prefix-property(transform), 300ms);
8
8
 
@@ -1,6 +1,6 @@
1
1
  @import '@24i/bigscreen-sdk/sass-utils/transform';
2
2
 
3
- [dir=rtl] .menu-container {
3
+ [dir=rtl] .menu-container .side-menu {
4
4
  left: auto;
5
5
  right: 0;
6
6
 
@@ -36,7 +36,9 @@ export class ModalService extends Component<Props> {
36
36
  }
37
37
  };
38
38
 
39
- getMountedComponent() { return this.modalRef; }
39
+ getMountedComponent() {
40
+ return this.modalRef;
41
+ }
40
42
 
41
43
  open<T extends IModal>(render: (ref: Reference<T>) => JSX.Element) {
42
44
  const { isFocusable } = this.props;
@@ -94,6 +94,22 @@ export class MouseNavigation extends Component<Props> {
94
94
  }
95
95
  };
96
96
 
97
+ onWheel = (event: WheelEvent) => {
98
+ const { forward, backward, direction } = this.props;
99
+ const { horizontal } = this.mapDirectionToProps(direction);
100
+ if (horizontal) return;
101
+ if (event.deltaY > 0) forward();
102
+ else if (event.deltaY < 0) backward();
103
+ };
104
+
105
+ addWheelListner() {
106
+ this.arrows.current?.domRef.current?.addEventListener('wheel', this.onWheel);
107
+ }
108
+
109
+ removeWheelListner() {
110
+ this.arrows.current?.domRef.current?.removeEventListener('wheel', this.onWheel);
111
+ }
112
+
97
113
  isActive() {
98
114
  return this.navigationState === 'active';
99
115
  }
@@ -112,6 +128,7 @@ export class MouseNavigation extends Component<Props> {
112
128
  getMountingPoint(),
113
129
  );
114
130
  this.handleArrowState();
131
+ this.addWheelListner();
115
132
  this.navigationState = 'active';
116
133
  };
117
134
 
@@ -129,6 +146,7 @@ export class MouseNavigation extends Component<Props> {
129
146
  destroyArrows() {
130
147
  if (this.navigationState === 'inactive') return;
131
148
  this.navigationState = 'inactive';
149
+ this.removeWheelListner();
132
150
  removeNode(this.arrows.current!.domRef);
133
151
  }
134
152
 
@@ -189,11 +189,7 @@ export class PlayerUI extends Component<Props>
189
189
  }
190
190
 
191
191
  canHideAutomatically() {
192
- return (
193
- this.isPlaying()
194
- && !this.seeking.isSeeking()
195
- && !this.isHidingDisabled
196
- );
192
+ return !this.isHidingDisabled;
197
193
  }
198
194
 
199
195
  isPlaying() {
@@ -1273,7 +1273,6 @@ declare namespace React {
1273
1273
  shiftKey: boolean;
1274
1274
  /** @deprecated */
1275
1275
  which: number;
1276
- target: EventTarget & T;
1277
1276
  }
1278
1277
 
1279
1278
  interface MouseEvent<T = Element, E = NativeMouseEvent> extends UIEvent<T, E> {
@@ -2144,6 +2143,7 @@ declare namespace React {
2144
2143
  name?: string | undefined;
2145
2144
  noValidate?: boolean | undefined;
2146
2145
  target?: string | undefined;
2146
+ rel?: string | undefined;
2147
2147
  }
2148
2148
 
2149
2149
  interface HtmlHTMLAttributes<T> extends HTMLAttributes<T> {
@@ -42,6 +42,8 @@ export const createCounter = ({ triggerAt, callback }: CounterProps): ICounter =
42
42
  getCurrentValue: () => counter,
43
43
  isTriggered: () => counter >= triggerAt,
44
44
  isEqual: (value: number = triggerAt) => counter === value,
45
- reset: () => { counter = 0; },
45
+ reset: () => {
46
+ counter = 0;
47
+ },
46
48
  };
47
49
  };
@@ -32,8 +32,8 @@ export type ShouldRetryParam = {
32
32
  function shouldRetryRequest(data: ShouldRetryParam) {
33
33
  const { error, response } = data;
34
34
  if (error) return true;
35
- if (!response || !response.ok) return true;
36
- return false;
35
+ return !response || !response.ok;
36
+
37
37
  }
38
38
 
39
39
  export const defaultRetryConfig = {
@@ -12,7 +12,11 @@ export class VolumeControlUIMock extends Component<{}> implements IVolumeControl
12
12
 
13
13
  hide = () => {};
14
14
 
15
- isVisible() { return true; }
15
+ isVisible() {
16
+ return true;
17
+ }
16
18
 
17
- render() { return <div className="volume-control-ui" />; }
19
+ render() {
20
+ return <div className="volume-control-ui" />;
21
+ }
18
22
  }
@@ -1,24 +0,0 @@
1
- import { createRef, forwardRef, Reference } from '@24i/bigscreen-sdk/jsx';
2
- import { MouseNavigation } from '@24i/bigscreen-sdk/mouse-navigation';
3
- import { GridBase as Base, Props as GridProps } from './Base';
4
- import { Item } from '../types';
5
-
6
- export const GridBase = forwardRef(<T extends Item<U>, U>(props: GridProps<T, U>,
7
- gridRef: Reference<Base<T, U>>,
8
- ) => {
9
- const direction = props.horizontal ? 'horizontal' : 'vertical';
10
- const mrcuRef = createRef<MouseNavigation>();
11
- return (
12
- <MouseNavigation
13
- ref={mrcuRef}
14
- getMountingPoint={() => gridRef.current!.scroller.current!.wrapRef}
15
- direction={direction}
16
- forward={props.mrcuForward || props.forwardGroup}
17
- backward={props.mrcuBackward || props.backwardGroup}
18
- shouldShowMrcuForward={props.shouldShowMrcuForward}
19
- shouldShowMrcuBackward={props.shouldShowMrcuBackward}
20
- >
21
- <Base {...props} ref={gridRef} mrcuRef={mrcuRef} />
22
- </MouseNavigation>
23
- );
24
- });
@@ -1 +0,0 @@
1
- export { GridBase } from './Base.mouse';
@@ -1 +0,0 @@
1
- export { GridBase } from './Base.mouse';
@@ -1 +0,0 @@
1
- export { GridBase } from './Base.mouse';