@maestro_io/maestro-web-sdk 5.1.1 → 5.2.0

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 (162) hide show
  1. package/dist/1.maestro-web-sdk.esm.js +1 -1
  2. package/dist/1.maestro-web-sdk.esm.js.map +1 -1
  3. package/dist/10.maestro-web-sdk.esm.js +1 -1
  4. package/dist/10.maestro-web-sdk.esm.js.map +1 -1
  5. package/dist/11.maestro-web-sdk.esm.js +1 -1
  6. package/dist/11.maestro-web-sdk.esm.js.map +1 -1
  7. package/dist/12.maestro-web-sdk.esm.js +1 -1
  8. package/dist/12.maestro-web-sdk.esm.js.map +1 -1
  9. package/dist/13.maestro-web-sdk.esm.js +1 -1
  10. package/dist/13.maestro-web-sdk.esm.js.map +1 -1
  11. package/dist/14.maestro-web-sdk.esm.js +1 -1
  12. package/dist/14.maestro-web-sdk.esm.js.map +1 -1
  13. package/dist/15.maestro-web-sdk.esm.js +1 -1
  14. package/dist/15.maestro-web-sdk.esm.js.map +1 -1
  15. package/dist/16.maestro-web-sdk.esm.js +1 -1
  16. package/dist/16.maestro-web-sdk.esm.js.map +1 -1
  17. package/dist/17.maestro-web-sdk.esm.js +1 -1
  18. package/dist/17.maestro-web-sdk.esm.js.map +1 -1
  19. package/dist/18.maestro-web-sdk.esm.js +1 -1
  20. package/dist/18.maestro-web-sdk.esm.js.map +1 -1
  21. package/dist/19.maestro-web-sdk.esm.js +1 -1
  22. package/dist/19.maestro-web-sdk.esm.js.map +1 -1
  23. package/dist/2.maestro-web-sdk.esm.js +1 -1
  24. package/dist/20.maestro-web-sdk.esm.js +1 -1
  25. package/dist/20.maestro-web-sdk.esm.js.map +1 -1
  26. package/dist/21.maestro-web-sdk.esm.js +1 -1
  27. package/dist/21.maestro-web-sdk.esm.js.map +1 -1
  28. package/dist/22.maestro-web-sdk.esm.js +1 -1
  29. package/dist/22.maestro-web-sdk.esm.js.map +1 -1
  30. package/dist/23.maestro-web-sdk.esm.js +1 -1
  31. package/dist/23.maestro-web-sdk.esm.js.map +1 -1
  32. package/dist/24.maestro-web-sdk.esm.js +1 -1
  33. package/dist/24.maestro-web-sdk.esm.js.map +1 -1
  34. package/dist/25.maestro-web-sdk.esm.js +1 -1
  35. package/dist/25.maestro-web-sdk.esm.js.map +1 -1
  36. package/dist/26.maestro-web-sdk.esm.js +1 -1
  37. package/dist/26.maestro-web-sdk.esm.js.map +1 -1
  38. package/dist/27.maestro-web-sdk.esm.js +1 -1
  39. package/dist/27.maestro-web-sdk.esm.js.map +1 -1
  40. package/dist/28.maestro-web-sdk.esm.js +1 -1
  41. package/dist/28.maestro-web-sdk.esm.js.map +1 -1
  42. package/dist/29.maestro-web-sdk.esm.js +1 -1
  43. package/dist/29.maestro-web-sdk.esm.js.map +1 -1
  44. package/dist/3.maestro-web-sdk.esm.js +1 -1
  45. package/dist/3.maestro-web-sdk.esm.js.map +1 -1
  46. package/dist/30.maestro-web-sdk.esm.js +1 -1
  47. package/dist/30.maestro-web-sdk.esm.js.map +1 -1
  48. package/dist/31.maestro-web-sdk.esm.js +1 -1
  49. package/dist/31.maestro-web-sdk.esm.js.map +1 -1
  50. package/dist/32.maestro-web-sdk.esm.js +1 -1
  51. package/dist/32.maestro-web-sdk.esm.js.map +1 -1
  52. package/dist/33.maestro-web-sdk.esm.js +1 -1
  53. package/dist/33.maestro-web-sdk.esm.js.map +1 -1
  54. package/dist/34.maestro-web-sdk.esm.js +1 -1
  55. package/dist/34.maestro-web-sdk.esm.js.map +1 -1
  56. package/dist/35.maestro-web-sdk.esm.js +1 -1
  57. package/dist/35.maestro-web-sdk.esm.js.map +1 -1
  58. package/dist/36.maestro-web-sdk.esm.js +1 -1
  59. package/dist/36.maestro-web-sdk.esm.js.map +1 -1
  60. package/dist/37.maestro-web-sdk.esm.js +1 -1
  61. package/dist/37.maestro-web-sdk.esm.js.map +1 -1
  62. package/dist/38.maestro-web-sdk.esm.js +1 -1
  63. package/dist/38.maestro-web-sdk.esm.js.map +1 -1
  64. package/dist/39.maestro-web-sdk.esm.js +2 -0
  65. package/dist/39.maestro-web-sdk.esm.js.map +1 -0
  66. package/dist/4.maestro-web-sdk.esm.js +1 -1
  67. package/dist/4.maestro-web-sdk.esm.js.map +1 -1
  68. package/dist/40.maestro-web-sdk.esm.js +2 -0
  69. package/dist/40.maestro-web-sdk.esm.js.map +1 -0
  70. package/dist/5.maestro-web-sdk.esm.js +1 -1
  71. package/dist/5.maestro-web-sdk.esm.js.map +1 -1
  72. package/dist/6.maestro-web-sdk.esm.js +1 -1
  73. package/dist/6.maestro-web-sdk.esm.js.map +1 -1
  74. package/dist/7.maestro-web-sdk.esm.js +1 -1
  75. package/dist/7.maestro-web-sdk.esm.js.map +1 -1
  76. package/dist/8.maestro-web-sdk.esm.js +1 -1
  77. package/dist/8.maestro-web-sdk.esm.js.map +1 -1
  78. package/dist/9.maestro-web-sdk.esm.js +1 -1
  79. package/dist/9.maestro-web-sdk.esm.js.map +1 -1
  80. package/dist/index.d.ts +12 -2
  81. package/dist/maestro-web-sdk.esm.js +3 -3
  82. package/dist/maestro-web-sdk.esm.js.map +1 -1
  83. package/dist/maestro-web-sdk.umd.js +3 -3
  84. package/dist/maestro-web-sdk.umd.js.map +1 -1
  85. package/dist/package.json +1 -1
  86. package/dist/src/components/atoms/SvgIcon/AddIcon.d.ts +3 -0
  87. package/dist/src/components/atoms/SvgIcon/AddIcon.js +6 -0
  88. package/dist/src/components/atoms/SvgIcon/Icon.js +2 -0
  89. package/dist/src/components/core/PanelManager/PanelManager.js +5 -3
  90. package/dist/src/components/molecules/NetworkDialog/NetworkDialog.d.ts +11 -0
  91. package/dist/src/components/molecules/NetworkDialog/NetworkDialog.js +34 -0
  92. package/dist/src/components/molecules/NetworkDialog/index.d.ts +2 -0
  93. package/dist/src/components/molecules/NetworkDialog/index.js +2 -0
  94. package/dist/src/components/molecules/NetworkError/NetworkError.d.ts +104 -0
  95. package/dist/src/components/molecules/NetworkError/NetworkError.js +26 -0
  96. package/dist/src/components/molecules/NetworkError/index.d.ts +2 -0
  97. package/dist/src/components/molecules/NetworkError/index.js +2 -0
  98. package/dist/src/components/molecules/PanelNavButton/PanelNavButton.d.ts +1 -0
  99. package/dist/src/components/molecules/PanelNavButton/PanelNavButton.js +16 -7
  100. package/dist/src/components/organisms/PanelNavigation/PanelNavigation.d.ts +1 -0
  101. package/dist/src/components/organisms/PanelNavigation/PanelNavigation.js +11 -7
  102. package/dist/src/development/MaestroEventDelegate.js +1 -0
  103. package/dist/src/helpers/site.d.ts +1 -0
  104. package/dist/src/helpers/site.js +6 -0
  105. package/dist/src/helpers/siteConfig.d.ts +1 -0
  106. package/dist/src/helpers/siteConfig.js +5 -0
  107. package/dist/src/interfaces/IMaestroEventDelegate.d.ts +8 -1
  108. package/dist/src/models/IPanel.d.ts +1 -1
  109. package/dist/src/models/IPanel.js +1 -1
  110. package/dist/src/modules/espn/bets/view/BetsView.js +1 -1
  111. package/dist/src/modules/espn/components/TabLoadError/TabLoadError.d.ts +96 -0
  112. package/dist/src/modules/espn/components/TabLoadError/TabLoadError.js +14 -0
  113. package/dist/src/modules/espn/components/TabLoadError/index.d.ts +2 -0
  114. package/dist/src/modules/espn/components/TabLoadError/index.js +2 -0
  115. package/dist/src/modules/espn/fantasy/components/TournamentOverflowQR/TournamentOverflowQR.d.ts +5 -5
  116. package/dist/src/modules/espn/fantasy/components/TournamentOverflowQR/TournamentOverflowQR.js +7 -73
  117. package/dist/src/modules/espn/fantasy/services/FantasyService.js +1 -1
  118. package/dist/src/modules/espn/fantasy/view/FantasyItemView.js +1 -1
  119. package/dist/src/modules/espn/fantasy/view/FantasyView.js +1 -1
  120. package/dist/src/modules/espn/fantasy/view-model/FantasyViewModel.js +7 -0
  121. package/dist/src/modules/espn/key-plays/view/KeyPlayErrorStateView.js +1 -1
  122. package/dist/src/modules/espn/shop/view/ShopView.js +1 -1
  123. package/dist/src/modules/espn/stats/view/StatsView.js +1 -1
  124. package/dist/src/modules/fox/components/TabLoadError/TabLoadError.d.ts +96 -0
  125. package/dist/src/modules/fox/components/TabLoadError/TabLoadError.js +19 -0
  126. package/dist/src/modules/fox/components/TabLoadError/index.d.ts +2 -0
  127. package/dist/src/modules/fox/components/TabLoadError/index.js +2 -0
  128. package/dist/src/modules/fox/multi-view/interfaces/IMultiViewViewModel.d.ts +3 -0
  129. package/dist/src/modules/fox/multi-view/interfaces/IMultiViewViewModel.js +1 -0
  130. package/dist/src/modules/fox/multi-view/services/MultiViewService.d.ts +99 -0
  131. package/dist/src/modules/fox/multi-view/services/MultiViewService.js +94 -0
  132. package/dist/src/modules/fox/multi-view/types.d.ts +48 -0
  133. package/dist/src/modules/fox/multi-view/types.js +86 -0
  134. package/dist/src/modules/fox/multi-view/view/CuratedMultiview/CuratedMultiviews.d.ts +8 -0
  135. package/dist/src/modules/fox/multi-view/view/CuratedMultiview/CuratedMultiviews.js +91 -0
  136. package/dist/src/modules/fox/multi-view/view/CuratedMultiview/index.d.ts +2 -0
  137. package/dist/src/modules/fox/multi-view/view/CuratedMultiview/index.js +2 -0
  138. package/dist/src/modules/fox/multi-view/view/FoxMultiView.d.ts +1 -0
  139. package/dist/src/modules/fox/multi-view/view/FoxMultiView.js +62 -2
  140. package/dist/src/modules/fox/multi-view/view/components/CustomMultiviewStreamsCard/CustomMultiviewStreamsCard.d.ts +122 -0
  141. package/dist/src/modules/fox/multi-view/view/components/CustomMultiviewStreamsCard/CustomMultiviewStreamsCard.js +51 -0
  142. package/dist/src/modules/fox/multi-view/view/components/CustomMultiviewStreamsCard/index.d.ts +2 -0
  143. package/dist/src/modules/fox/multi-view/view/components/CustomMultiviewStreamsCard/index.js +2 -0
  144. package/dist/src/modules/fox/multi-view/view/components/LayoutSelector/LayoutSelector.d.ts +13 -0
  145. package/dist/src/modules/fox/multi-view/view/components/LayoutSelector/LayoutSelector.js +40 -0
  146. package/dist/src/modules/fox/multi-view/view/components/LayoutSelector/index.d.ts +2 -0
  147. package/dist/src/modules/fox/multi-view/view/components/LayoutSelector/index.js +2 -0
  148. package/dist/src/modules/fox/multi-view/view/components/curated-multiview-card/CuratedMultiviewCard.d.ts +101 -0
  149. package/dist/src/modules/fox/multi-view/view/components/curated-multiview-card/CuratedMultiviewCard.js +21 -0
  150. package/dist/src/modules/fox/multi-view/view/components/curated-multiview-card/index.d.ts +2 -0
  151. package/dist/src/modules/fox/multi-view/view/components/curated-multiview-card/index.js +2 -0
  152. package/dist/src/modules/fox/multi-view/view-model/MultiViewViewModel.d.ts +63 -0
  153. package/dist/src/modules/fox/multi-view/view-model/MultiViewViewModel.js +328 -0
  154. package/dist/src/modules/fox/multi-view/view-model/index.d.ts +1 -0
  155. package/dist/src/modules/fox/multi-view/view-model/index.js +1 -0
  156. package/dist/src/services/NetworkManager/NetworkManager.js +1 -1
  157. package/dist/src/services/NetworkManager/errors.d.ts +3 -1
  158. package/dist/src/services/NetworkManager/errors.js +15 -1
  159. package/dist/src/services/StaticService/StaticService.js +1 -0
  160. package/dist/src/view-models/MaestroEventViewModel.d.ts +2 -0
  161. package/dist/src/view-models/MaestroEventViewModel.js +17 -1
  162. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  /// <reference types="prop-types" />
2
2
  import React from 'react';
3
3
  import { WithFocusableProps } from '@/external/spatial-navigation';
4
- import { Direction, Layout } from '@/external/spatial-navigation/utils';
4
+ import { Layout } from '@/external/spatial-navigation/utils';
5
5
  import './TournamentOverflowQR.styles.css';
6
6
  import { TournamentOverflowQRItem } from '../../types';
7
7
  type Props = {
@@ -17,7 +17,7 @@ declare const _default: {
17
17
  parentFocusKey: string;
18
18
  };
19
19
  setFocus: (focusKey: string) => void;
20
- navigateByDirection: (direction: Direction, details?: import("@/external/spatial-navigation/utils").Details) => void;
20
+ navigateByDirection: (direction: import("@/external/spatial-navigation/utils").Direction, details?: import("@/external/spatial-navigation/utils").Details) => void;
21
21
  stealFocus: () => void;
22
22
  onUpdateFocus: (focused: boolean) => void;
23
23
  onUpdateHasFocusedChild: (hasFocusedChild: boolean) => void;
@@ -25,7 +25,7 @@ declare const _default: {
25
25
  onClickPressHandler: (details: import("@/external/spatial-navigation/utils").Details) => void;
26
26
  onEnterReleaseHandler: () => void;
27
27
  onBackPressHandler: (details: import("@/external/spatial-navigation/utils").Details) => void;
28
- onArrowPressHandler: (direction: Direction, details: import("@/external/spatial-navigation/utils").Details) => boolean | void;
28
+ onArrowPressHandler: (direction: import("@/external/spatial-navigation/utils").Direction, details: import("@/external/spatial-navigation/utils").Details) => boolean | void;
29
29
  onBecameFocusedHandler: (layout: Layout, details: import("@/external/spatial-navigation/utils").Details) => void;
30
30
  onBecameBlurredHandler: (layout: Layout, details: import("@/external/spatial-navigation/utils").Details) => void;
31
31
  componentDidMount(): void;
@@ -58,7 +58,7 @@ declare const _default: {
58
58
  parentFocusKey: string;
59
59
  };
60
60
  setFocus: (focusKey: string) => void;
61
- navigateByDirection: (direction: Direction, details?: import("@/external/spatial-navigation/utils").Details) => void;
61
+ navigateByDirection: (direction: import("@/external/spatial-navigation/utils").Direction, details?: import("@/external/spatial-navigation/utils").Details) => void;
62
62
  stealFocus: () => void;
63
63
  onUpdateFocus: (focused: boolean) => void;
64
64
  onUpdateHasFocusedChild: (hasFocusedChild: boolean) => void;
@@ -66,7 +66,7 @@ declare const _default: {
66
66
  onClickPressHandler: (details: import("@/external/spatial-navigation/utils").Details) => void;
67
67
  onEnterReleaseHandler: () => void;
68
68
  onBackPressHandler: (details: import("@/external/spatial-navigation/utils").Details) => void;
69
- onArrowPressHandler: (direction: Direction, details: import("@/external/spatial-navigation/utils").Details) => boolean | void;
69
+ onArrowPressHandler: (direction: import("@/external/spatial-navigation/utils").Direction, details: import("@/external/spatial-navigation/utils").Details) => boolean | void;
70
70
  onBecameFocusedHandler: (layout: Layout, details: import("@/external/spatial-navigation/utils").Details) => void;
71
71
  onBecameBlurredHandler: (layout: Layout, details: import("@/external/spatial-navigation/utils").Details) => void;
72
72
  componentDidMount(): void;
@@ -2,93 +2,27 @@ import React from 'react';
2
2
  import { withFocusable, } from '@/external/spatial-navigation';
3
3
  import './TournamentOverflowQR.styles.css';
4
4
  import Image from '@/components/atoms/Image';
5
- import ActionButton from '@/components/molecules/ActionButton';
6
- import SDK from '@/index';
7
5
  const FocusableWrapper = withFocusable()((props) => {
8
- const { children, focused = false, expanded, backgroundImage } = props;
9
- return (React.createElement("div", { className: "tournament-overflow-qr focus-ring T02", "data-focused": focused, "data-expanded": expanded, "data-focuskey": props.focusKey || '', role: "button", tabIndex: 0, style: {
6
+ const { children, focused = false, backgroundImage } = props;
7
+ return (React.createElement("div", { className: "tournament-overflow-qr focus-ring T02", "data-focused": focused, "data-focuskey": props.focusKey || '', role: "button", tabIndex: 0, style: {
10
8
  backgroundImage: `url(${backgroundImage})`,
11
- } }, children(focused)));
9
+ } }, children));
12
10
  });
13
11
  class TournamentOverflowQR extends React.Component {
14
- constructor() {
15
- super(...arguments);
16
- Object.defineProperty(this, "state", {
17
- enumerable: true,
18
- configurable: true,
19
- writable: true,
20
- value: {
21
- expanded: false,
22
- }
23
- });
24
- Object.defineProperty(this, "onDismissPress", {
25
- enumerable: true,
26
- configurable: true,
27
- writable: true,
28
- value: () => {
29
- this.setState({ expanded: false }, () => {
30
- SDK.getMaestroEventViewModel().navigation.setFocus(this.focusKey);
31
- });
32
- }
33
- });
34
- }
35
12
  get focusKey() {
36
13
  return `tournament-overflow-qr-${this.props.item.id}`;
37
14
  }
38
- onEnterPress() {
39
- const newValue = !this.state.expanded;
40
- this.setState({
41
- expanded: newValue,
42
- }, () => {
43
- if (newValue) {
44
- SDK.getMaestroEventViewModel().navigation.setFocus(`${this.focusKey}`);
45
- }
46
- });
47
- this.props.onEnterPress();
48
- }
49
- onArrowPress(direction) {
50
- if (this.state.expanded && (direction === 'up' || direction === 'down')) {
51
- this.setState({
52
- expanded: false,
53
- }, () => {
54
- SDK.getMaestroEventViewModel().navigation.navigateByDirection(direction);
55
- });
56
- return false;
57
- }
58
- return true;
59
- }
60
- onBackPress() {
61
- if (this.state.expanded) {
62
- this.setState({
63
- expanded: false,
64
- });
65
- return false;
66
- }
67
- return true;
68
- }
69
- renderCollapsedView() {
70
- const { item } = this.props;
71
- return (React.createElement(React.Fragment, null,
72
- React.createElement("div", { className: "tournament-overflow-qr-content" },
73
- React.createElement("p", { className: "tournament-overflow-qr-title T30 FONT_BOLD_HEADLINE" }, item.title),
74
- React.createElement("p", { className: "tournament-overflow-qr-subtitle T10 FONT_BOLD" }, item.description)),
75
- React.createElement(Image, { src: item.logo, alt: "Tournament Logo", className: "tournament-overflow-qr-logo-image" })));
76
- }
77
- renderExpandedView(focused) {
15
+ renderExpandedView() {
78
16
  const { item } = this.props;
79
17
  return (React.createElement("div", { className: "tournament-overflow-qr-expanded" },
80
18
  React.createElement(Image, { src: item.logo, alt: "Tournament Logo", className: "tournament-overflow-qr-expanded-logo" }),
81
19
  React.createElement("p", { className: "tournament-overflow-qr-expanded-title T20 FONT_BOLD" }, item.title),
82
- React.createElement(Image, { src: item.qrCode, alt: "QR Code", width: 250, height: 250, className: "tournament-overflow-qr-expanded-qr" }),
83
- React.createElement("p", { className: "tournament-overflow-qr-expanded-instructions T04 FONT_BOLD_HEADLINE" }, item.description),
84
- React.createElement(ActionButton, { onEnterPress: this.onDismissPress, focusKey: `${this.focusKey}-dismiss`, "data-focused": focused }, "Dismiss")));
20
+ React.createElement(Image, { src: item.qrCode, alt: "QR Code", width: 300, height: 300, className: "tournament-overflow-qr-expanded-qr" }),
21
+ React.createElement("p", { className: "tournament-overflow-qr-expanded-instructions T20 FONT_BOLD" }, item.description)));
85
22
  }
86
23
  render() {
87
24
  const { item } = this.props;
88
- const { expanded } = this.state;
89
- return (React.createElement(FocusableWrapper, { ...this.props, focusKey: this.focusKey, onEnterPress: this.onEnterPress.bind(this), onArrowPress: this.onArrowPress.bind(this), onBackPress: this.onBackPress.bind(this), expanded: expanded, backgroundImage: item.background }, (focused) => expanded
90
- ? this.renderExpandedView(focused)
91
- : this.renderCollapsedView()));
25
+ return (React.createElement(FocusableWrapper, { ...this.props, focusKey: this.focusKey, backgroundImage: item.background }, this.renderExpandedView()));
92
26
  }
93
27
  }
94
28
  export default withFocusable()(TournamentOverflowQR);
@@ -115,7 +115,7 @@ class FantasyService {
115
115
  },
116
116
  params: {
117
117
  competitionId,
118
- view: 'ictv_challenges',
118
+ view: 'ictv_scoreboard',
119
119
  platform: 'fantasyictv_bbd',
120
120
  },
121
121
  });
@@ -37,7 +37,7 @@ const FantasyItemView = ({ item, onEnterPress: onEnterPressProp, }) => {
37
37
  case 'tournament-bracket-card':
38
38
  return (React.createElement(TournamentBracketCard, { key: item.id, item: item, onArrowPress: onArrowPress, onBecameFocused: onBecameFocused, onEnterPress: onEnterPress }));
39
39
  case 'tournament-overflow-qr':
40
- return (React.createElement(TournamentOverflowQR, { key: item.id, item: item, onEnterPress: onEnterPress, onBecameFocused: onBecameFocused }));
40
+ return (React.createElement(TournamentOverflowQR, { key: item.id, item: item, onArrowPress: onArrowPress, onEnterPress: onEnterPress, onBecameFocused: onBecameFocused }));
41
41
  default:
42
42
  console.warn('Unknown fantasy item type:', JSON.stringify(item));
43
43
  return null;
@@ -2,7 +2,7 @@ import React, { Component } from 'react';
2
2
  import './FantasyView.styles.css';
3
3
  import ScrollableContainer from '@/components/core/ScrollableContainer';
4
4
  import SDK from '@/index';
5
- import TabLoadErrorView from '@/components/molecules/TabLoadError';
5
+ import TabLoadErrorView from '../../components/TabLoadError';
6
6
  import { captureException } from '@/sentry';
7
7
  import FantasyItemView from './FantasyItemView';
8
8
  import FantasyHeaderView from './FantasyHeaderView';
@@ -154,8 +154,10 @@ export class FantasyViewModel {
154
154
  await this.fetchData();
155
155
  }
156
156
  async fetchData() {
157
+ this.isDataLoading.value = true;
157
158
  const isAuthenticated = await this.delegate.userIsAuthenticated();
158
159
  if (!isAuthenticated) {
160
+ this.isDataLoading.value = false;
159
161
  this.append({
160
162
  id: 'not-logged-in',
161
163
  type: 'notLoggedIn',
@@ -211,8 +213,11 @@ export class FantasyViewModel {
211
213
  this.itemToLeagueKey.clear();
212
214
  this._fantasyLeagues = [];
213
215
  this._tournamentChallenges = [];
216
+ this._promoItem = null;
214
217
  this._tcProcessingCount = 0;
215
218
  this.isLoadingTc.value = false;
219
+ this.fantasyItems.value = [];
220
+ this.hasEverSuccessfullyLoaded.value = false;
216
221
  }
217
222
  /**
218
223
  * Track panel view event
@@ -334,6 +339,7 @@ export class FantasyViewModel {
334
339
  // Mark successful load
335
340
  this.hasEverSuccessfullyLoaded.value = true;
336
341
  this.errorState.value = 'none';
342
+ this.isDataLoading.value = false;
337
343
  // Initial rebuild even if empty, to ensure state is clean
338
344
  this.rebuildFantasyItems();
339
345
  }
@@ -342,6 +348,7 @@ export class FantasyViewModel {
342
348
  context: 'FantasyViewModel.processFantasy',
343
349
  });
344
350
  console.error('[FANTASY] Error processing fantasy data:', error);
351
+ this.isDataLoading.value = false;
345
352
  if (!this.hasEverSuccessfullyLoaded.value) {
346
353
  this.errorState.value = 'tabLoadFailure';
347
354
  }
@@ -1,7 +1,7 @@
1
1
  import './KeyPlayErrorStateView.styles.css';
2
2
  import React from 'react';
3
3
  import SDK from '@/index';
4
- import TabLoadErrorView from '@/components/molecules/TabLoadError';
4
+ import TabLoadErrorView from '../../components/TabLoadError';
5
5
  import { useMaxHeightToBottom } from '@/hooks/useMaxHeightToBottom';
6
6
  const UnpopulatedEvent = () => {
7
7
  const maxHeightRef = useMaxHeightToBottom();
@@ -2,7 +2,7 @@ import React, { Component } from 'react';
2
2
  import './ShopView.styles.css';
3
3
  import ScrollableContainer from '@/components/core/ScrollableContainer';
4
4
  import SDK from '@/index';
5
- import TabLoadErrorView from '@/components/molecules/TabLoadError';
5
+ import TabLoadErrorView from '../../components/TabLoadError';
6
6
  import { isShopProduct, } from '../types';
7
7
  import ShopSection from './components/ShopSection';
8
8
  import ProductDetailView from './ProductDetailView';
@@ -3,7 +3,7 @@ import './StatsView.styles.css';
3
3
  import ScrollableContainer from '@/components/core/ScrollableContainer';
4
4
  import SDK from '@/index';
5
5
  import StatsItemView from './StatsItemView';
6
- import TabLoadErrorView from '@/components/molecules/TabLoadError';
6
+ import TabLoadErrorView from '../../components/TabLoadError';
7
7
  import { captureException } from '@/sentry';
8
8
  import { setupMaxHeightToBottom } from '@/hooks/useMaxHeightToBottom';
9
9
  const STICKY_HEADER_HEIGHT = 32; // Match KeyPlaysView
@@ -0,0 +1,96 @@
1
+ /// <reference types="prop-types" />
2
+ import { WithFocusableProps } from '@/external/spatial-navigation';
3
+ import React from 'react';
4
+ import './TabLoadError.styles.css';
5
+ declare const _default: {
6
+ new (props: (object & WithFocusableProps) | Readonly<object & WithFocusableProps>): {
7
+ state: import("../../../../external/spatial-navigation/withFocusable").WithFocusableState;
8
+ navigation: import("../../../../external/spatial-navigation/spatialNavigation").default;
9
+ getChildContext(): {
10
+ parentFocusKey: string;
11
+ };
12
+ setFocus: (focusKey: string) => void;
13
+ navigateByDirection: (direction: import("../../../../external/spatial-navigation/utils").Direction, details?: import("../../../../external/spatial-navigation/utils").Details) => void;
14
+ stealFocus: () => void;
15
+ onUpdateFocus: (focused: boolean) => void;
16
+ onUpdateHasFocusedChild: (hasFocusedChild: boolean) => void;
17
+ onEnterPressHandler: (details: import("../../../../external/spatial-navigation/utils").Details) => void;
18
+ onClickPressHandler: (details: import("../../../../external/spatial-navigation/utils").Details) => void;
19
+ onEnterReleaseHandler: () => void;
20
+ onBackPressHandler: (details: import("../../../../external/spatial-navigation/utils").Details) => void;
21
+ onArrowPressHandler: (direction: import("../../../../external/spatial-navigation/utils").Direction, details: import("../../../../external/spatial-navigation/utils").Details) => boolean | void;
22
+ onBecameFocusedHandler: (layout: import("../../../../external/spatial-navigation/utils").Layout, details: import("../../../../external/spatial-navigation/utils").Details) => void;
23
+ onBecameBlurredHandler: (layout: import("../../../../external/spatial-navigation/utils").Layout, details: import("../../../../external/spatial-navigation/utils").Details) => void;
24
+ componentDidMount(): void;
25
+ componentDidUpdate(): void;
26
+ componentWillUnmount(): void;
27
+ render(): React.ReactElement<object & WithFocusableProps, string | React.JSXElementConstructor<any>>;
28
+ context: any;
29
+ setState<K extends keyof import("../../../../external/spatial-navigation/withFocusable").WithFocusableState>(state: import("../../../../external/spatial-navigation/withFocusable").WithFocusableState | ((prevState: Readonly<import("../../../../external/spatial-navigation/withFocusable").WithFocusableState>, props: Readonly<object & WithFocusableProps>) => import("../../../../external/spatial-navigation/withFocusable").WithFocusableState | Pick<import("../../../../external/spatial-navigation/withFocusable").WithFocusableState, K> | null) | Pick<import("../../../../external/spatial-navigation/withFocusable").WithFocusableState, K> | null, callback?: (() => void) | undefined): void;
30
+ forceUpdate(callback?: (() => void) | undefined): void;
31
+ readonly props: Readonly<object & WithFocusableProps> & Readonly<{
32
+ children?: React.ReactNode;
33
+ }>;
34
+ refs: {
35
+ [key: string]: React.ReactInstance;
36
+ };
37
+ shouldComponentUpdate?(nextProps: Readonly<object & WithFocusableProps>, nextState: Readonly<import("../../../../external/spatial-navigation/withFocusable").WithFocusableState>, nextContext: any): boolean;
38
+ componentDidCatch?(error: Error, errorInfo: React.ErrorInfo): void;
39
+ getSnapshotBeforeUpdate?(prevProps: Readonly<object & WithFocusableProps>, prevState: Readonly<import("../../../../external/spatial-navigation/withFocusable").WithFocusableState>): any;
40
+ componentWillMount?(): void;
41
+ UNSAFE_componentWillMount?(): void;
42
+ componentWillReceiveProps?(nextProps: Readonly<object & WithFocusableProps>, nextContext: any): void;
43
+ UNSAFE_componentWillReceiveProps?(nextProps: Readonly<object & WithFocusableProps>, nextContext: any): void;
44
+ componentWillUpdate?(nextProps: Readonly<object & WithFocusableProps>, nextState: Readonly<import("../../../../external/spatial-navigation/withFocusable").WithFocusableState>, nextContext: any): void;
45
+ UNSAFE_componentWillUpdate?(nextProps: Readonly<object & WithFocusableProps>, nextState: Readonly<import("../../../../external/spatial-navigation/withFocusable").WithFocusableState>, nextContext: any): void;
46
+ };
47
+ new (props: object & WithFocusableProps, context: any): {
48
+ state: import("../../../../external/spatial-navigation/withFocusable").WithFocusableState;
49
+ navigation: import("../../../../external/spatial-navigation/spatialNavigation").default;
50
+ getChildContext(): {
51
+ parentFocusKey: string;
52
+ };
53
+ setFocus: (focusKey: string) => void;
54
+ navigateByDirection: (direction: import("../../../../external/spatial-navigation/utils").Direction, details?: import("../../../../external/spatial-navigation/utils").Details) => void;
55
+ stealFocus: () => void;
56
+ onUpdateFocus: (focused: boolean) => void;
57
+ onUpdateHasFocusedChild: (hasFocusedChild: boolean) => void;
58
+ onEnterPressHandler: (details: import("../../../../external/spatial-navigation/utils").Details) => void;
59
+ onClickPressHandler: (details: import("../../../../external/spatial-navigation/utils").Details) => void;
60
+ onEnterReleaseHandler: () => void;
61
+ onBackPressHandler: (details: import("../../../../external/spatial-navigation/utils").Details) => void;
62
+ onArrowPressHandler: (direction: import("../../../../external/spatial-navigation/utils").Direction, details: import("../../../../external/spatial-navigation/utils").Details) => boolean | void;
63
+ onBecameFocusedHandler: (layout: import("../../../../external/spatial-navigation/utils").Layout, details: import("../../../../external/spatial-navigation/utils").Details) => void;
64
+ onBecameBlurredHandler: (layout: import("../../../../external/spatial-navigation/utils").Layout, details: import("../../../../external/spatial-navigation/utils").Details) => void;
65
+ componentDidMount(): void;
66
+ componentDidUpdate(): void;
67
+ componentWillUnmount(): void;
68
+ render(): React.ReactElement<object & WithFocusableProps, string | React.JSXElementConstructor<any>>;
69
+ context: any;
70
+ setState<K extends keyof import("../../../../external/spatial-navigation/withFocusable").WithFocusableState>(state: import("../../../../external/spatial-navigation/withFocusable").WithFocusableState | ((prevState: Readonly<import("../../../../external/spatial-navigation/withFocusable").WithFocusableState>, props: Readonly<object & WithFocusableProps>) => import("../../../../external/spatial-navigation/withFocusable").WithFocusableState | Pick<import("../../../../external/spatial-navigation/withFocusable").WithFocusableState, K> | null) | Pick<import("../../../../external/spatial-navigation/withFocusable").WithFocusableState, K> | null, callback?: (() => void) | undefined): void;
71
+ forceUpdate(callback?: (() => void) | undefined): void;
72
+ readonly props: Readonly<object & WithFocusableProps> & Readonly<{
73
+ children?: React.ReactNode;
74
+ }>;
75
+ refs: {
76
+ [key: string]: React.ReactInstance;
77
+ };
78
+ shouldComponentUpdate?(nextProps: Readonly<object & WithFocusableProps>, nextState: Readonly<import("../../../../external/spatial-navigation/withFocusable").WithFocusableState>, nextContext: any): boolean;
79
+ componentDidCatch?(error: Error, errorInfo: React.ErrorInfo): void;
80
+ getSnapshotBeforeUpdate?(prevProps: Readonly<object & WithFocusableProps>, prevState: Readonly<import("../../../../external/spatial-navigation/withFocusable").WithFocusableState>): any;
81
+ componentWillMount?(): void;
82
+ UNSAFE_componentWillMount?(): void;
83
+ componentWillReceiveProps?(nextProps: Readonly<object & WithFocusableProps>, nextContext: any): void;
84
+ UNSAFE_componentWillReceiveProps?(nextProps: Readonly<object & WithFocusableProps>, nextContext: any): void;
85
+ componentWillUpdate?(nextProps: Readonly<object & WithFocusableProps>, nextState: Readonly<import("../../../../external/spatial-navigation/withFocusable").WithFocusableState>, nextContext: any): void;
86
+ UNSAFE_componentWillUpdate?(nextProps: Readonly<object & WithFocusableProps>, nextState: Readonly<import("../../../../external/spatial-navigation/withFocusable").WithFocusableState>, nextContext: any): void;
87
+ };
88
+ contextTypes: {
89
+ parentFocusKey: import("prop-types").Requireable<string>;
90
+ };
91
+ childContextTypes: {
92
+ parentFocusKey: import("prop-types").Requireable<string>;
93
+ };
94
+ contextType?: React.Context<any> | undefined;
95
+ };
96
+ export default _default;
@@ -0,0 +1,19 @@
1
+ import { withFocusable, } from '@/external/spatial-navigation';
2
+ import React from 'react';
3
+ import './TabLoadError.styles.css';
4
+ import ActionButton from '@/components/molecules/ActionButton';
5
+ const TabLoadErrorView = (props) => {
6
+ const { focused, onEnterPress } = props;
7
+ const setHeight = (element) => {
8
+ if (!element)
9
+ return;
10
+ const rect = element.getBoundingClientRect();
11
+ element.style.height = `${window.innerHeight - rect.top}px`;
12
+ };
13
+ return (React.createElement("div", { className: "tab-load-error", ref: setHeight },
14
+ React.createElement("h3", { className: "T70" }, "Oops! Something went wrong."),
15
+ React.createElement("p", { className: "T20" }, 'We are having trouble loading Multiview right now. Please try again'),
16
+ React.createElement("div", { className: "fox" },
17
+ React.createElement(ActionButton, { "data-focused": focused, onEnterPress: onEnterPress }, "Try Again"))));
18
+ };
19
+ export default withFocusable()(TabLoadErrorView);
@@ -0,0 +1,2 @@
1
+ import TabLoadErrorView from './TabLoadError';
2
+ export default TabLoadErrorView;
@@ -0,0 +1,2 @@
1
+ import TabLoadErrorView from './TabLoadError';
2
+ export default TabLoadErrorView;
@@ -0,0 +1,3 @@
1
+ export interface IMultiViewViewModel {
2
+ cleanup(): void;
3
+ }
@@ -0,0 +1,99 @@
1
+ import { HttpMethod } from '@/services/NetworkManager/NetworkManager';
2
+ import { MultiViewLayout } from '../types';
3
+ export type ProductAPIData = {
4
+ endpoint: string;
5
+ method: HttpMethod;
6
+ headers: Record<string, string>;
7
+ };
8
+ export type ProductAPIErrorPayload = {
9
+ code: number;
10
+ message: string;
11
+ success: false;
12
+ data?: unknown;
13
+ };
14
+ export type MultiViewListingRequest = {
15
+ layoutId: string;
16
+ listings: Array<{
17
+ listingId: string;
18
+ callsign: string;
19
+ }>;
20
+ };
21
+ export type MultiViewListingResponse = {
22
+ multiviewId?: string;
23
+ callbackSeconds?: number;
24
+ };
25
+ export interface CuratedMultiviewResponse {
26
+ status: boolean;
27
+ data?: {
28
+ items?: CuratedMultiviewItem[];
29
+ };
30
+ }
31
+ interface CuratedMultiviewItem {
32
+ entity_id?: string;
33
+ type?: string;
34
+ title?: string;
35
+ is_multiview?: boolean;
36
+ is_multiview_eligible?: boolean;
37
+ is_sportingevent?: boolean;
38
+ images?: {
39
+ still?: string;
40
+ };
41
+ multiview?: string[];
42
+ multiview_metadata?: CuratedMultiviewMetadata[];
43
+ }
44
+ interface CuratedMultiviewMetadata {
45
+ entity_id: string;
46
+ type: string;
47
+ is_sportingevent: boolean;
48
+ images: Record<string, unknown>;
49
+ left_team: Team;
50
+ right_team: Team;
51
+ }
52
+ interface Team {
53
+ abbreviation: string;
54
+ }
55
+ export declare const isProductAPIValid: (data: any) => data is ProductAPIData;
56
+ /**
57
+ * Service for handling multi-view API calls
58
+ */
59
+ declare class MultiViewService {
60
+ private networkManager;
61
+ private productAPI;
62
+ constructor();
63
+ /**
64
+ * Fetch available multi-view layouts
65
+ *
66
+ * @returns Promise resolving to layouts data
67
+ */
68
+ getLayouts(): Promise<MultiViewLayout[]> | null;
69
+ /**
70
+ * Set the product API configuration
71
+ *
72
+ * @param productAPI - The product API endpoint, method, and headers
73
+ */
74
+ setProductAPIData(productAPI: ProductAPIData): void;
75
+ /**
76
+ * Start polling curated multiviews using the product API configuration.
77
+ * Returns null if no product API has been set.
78
+ *
79
+ * @param interval - Polling interval in milliseconds
80
+ * @param onData - Callback invoked with the data on each successful poll
81
+ * @param onError - Optional callback invoked on error
82
+ * @returns Object with a stop function, or null if no productAPI is configured
83
+ */
84
+ pollCuratedMultiviews(interval: number, onData: (data: CuratedMultiviewResponse) => void, onError?: (error: Error) => void): {
85
+ stop: () => void;
86
+ } | null;
87
+ /**
88
+ * Request an existing or new custom multiview.
89
+ * If the multiview exists, the response will include a multiviewId.
90
+ * If the multiview needs to be created, the response will include
91
+ * callbackSeconds indicating when to retry.
92
+ *
93
+ * @param config - The layout ID and listings for the multiview
94
+ * @param headers - Request headers (e.g. x-access-token, Content-Type)
95
+ * @returns Promise resolving to the multiview listing response
96
+ */
97
+ getOrCreateCustomMultiview(config: MultiViewListingRequest, headers?: Record<string, string>): Promise<MultiViewListingResponse>;
98
+ }
99
+ export default MultiViewService;
@@ -0,0 +1,94 @@
1
+ import NetworkManager, { HttpMethod, } from '@/services/NetworkManager/NetworkManager';
2
+ const MULTIVIEW_BASE_URL = 'https://qa-mvlm.api.shared.digitalvideoplatform.com';
3
+ export const isProductAPIValid = (data) => {
4
+ if (!data || typeof data !== 'object')
5
+ return false;
6
+ return (typeof data.endpoint === 'string' &&
7
+ typeof data.method === 'string' &&
8
+ data.headers !== null &&
9
+ typeof data.headers === 'object' &&
10
+ !Array.isArray(data.headers));
11
+ };
12
+ /**
13
+ * Service for handling multi-view API calls
14
+ */
15
+ class MultiViewService {
16
+ constructor() {
17
+ Object.defineProperty(this, "networkManager", {
18
+ enumerable: true,
19
+ configurable: true,
20
+ writable: true,
21
+ value: void 0
22
+ });
23
+ Object.defineProperty(this, "productAPI", {
24
+ enumerable: true,
25
+ configurable: true,
26
+ writable: true,
27
+ value: null
28
+ });
29
+ this.networkManager = new NetworkManager();
30
+ }
31
+ /**
32
+ * Fetch available multi-view layouts
33
+ *
34
+ * @returns Promise resolving to layouts data
35
+ */
36
+ getLayouts() {
37
+ if (!this.productAPI) {
38
+ return null;
39
+ }
40
+ return this.networkManager.externalApiRequest({
41
+ endpoint: `${MULTIVIEW_BASE_URL}/mvlm/v1/layouts`,
42
+ headers: this.productAPI.headers,
43
+ });
44
+ }
45
+ /**
46
+ * Set the product API configuration
47
+ *
48
+ * @param productAPI - The product API endpoint, method, and headers
49
+ */
50
+ setProductAPIData(productAPI) {
51
+ this.productAPI = productAPI;
52
+ }
53
+ /**
54
+ * Start polling curated multiviews using the product API configuration.
55
+ * Returns null if no product API has been set.
56
+ *
57
+ * @param interval - Polling interval in milliseconds
58
+ * @param onData - Callback invoked with the data on each successful poll
59
+ * @param onError - Optional callback invoked on error
60
+ * @returns Object with a stop function, or null if no productAPI is configured
61
+ */
62
+ pollCuratedMultiviews(interval, onData, onError) {
63
+ if (!this.productAPI) {
64
+ return null;
65
+ }
66
+ return this.networkManager.pollExternalApiRequest({
67
+ endpoint: this.productAPI.endpoint,
68
+ interval,
69
+ method: this.productAPI.method,
70
+ headers: this.productAPI.headers,
71
+ onData,
72
+ onError,
73
+ });
74
+ }
75
+ /**
76
+ * Request an existing or new custom multiview.
77
+ * If the multiview exists, the response will include a multiviewId.
78
+ * If the multiview needs to be created, the response will include
79
+ * callbackSeconds indicating when to retry.
80
+ *
81
+ * @param config - The layout ID and listings for the multiview
82
+ * @param headers - Request headers (e.g. x-access-token, Content-Type)
83
+ * @returns Promise resolving to the multiview listing response
84
+ */
85
+ getOrCreateCustomMultiview(config, headers = {}) {
86
+ return this.networkManager.externalApiRequest({
87
+ endpoint: `${MULTIVIEW_BASE_URL}/mvlm/v1/mvlisting`,
88
+ method: HttpMethod.POST,
89
+ data: config,
90
+ headers,
91
+ });
92
+ }
93
+ }
94
+ export default MultiViewService;
@@ -0,0 +1,48 @@
1
+ /**
2
+ * @description Represents a single stream/camera listing available for multi-view
3
+ */
4
+ export interface CuratedMultiviewListing {
5
+ id: string;
6
+ description: string;
7
+ backgroundImage: string;
8
+ type: string;
9
+ }
10
+ /**
11
+ * @description Position data for a single window within a layout
12
+ */
13
+ export interface LayoutPosition {
14
+ w: number;
15
+ h: number;
16
+ x: number;
17
+ y: number;
18
+ }
19
+ /**
20
+ * @description Defines a multi-view layout configuration with positioned windows
21
+ */
22
+ export interface MultiViewLayout {
23
+ layoutId: string;
24
+ description: string;
25
+ positions: Record<string, LayoutPosition>;
26
+ name: string;
27
+ windowCount: number;
28
+ positionsOrder: string[];
29
+ }
30
+ /**
31
+ * @description Child listing with position for new multiview event payload (PRD: SDK to pass event to client)
32
+ */
33
+ export interface NewMultiviewChildListing {
34
+ listingId: string;
35
+ callsign: string;
36
+ position: LayoutPosition;
37
+ }
38
+ /**
39
+ * @description Payload for fox-multiview:new-multiview panel event when a curated multiview is selected
40
+ */
41
+ export interface NewMultiviewPayload {
42
+ multiviewID: string;
43
+ childListings: NewMultiviewChildListing[];
44
+ }
45
+ /**
46
+ * @description Available layouts organized by stream count
47
+ */
48
+ export declare const DEFAULT_LAYOUTS_BY_LISTINGS_QUANTITY: Record<number, MultiViewLayout>;