@maestro_io/maestro-web-sdk 3.3.0 → 4.0.0-beta.1
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/dist/f8820fca3a2a7957f753167da0884f9d.png +0 -0
- package/dist/maestro-web-sdk.esm.js +12 -12
- package/dist/maestro-web-sdk.esm.js.map +1 -1
- package/dist/maestro-web-sdk.umd.js +12 -12
- package/dist/maestro-web-sdk.umd.js.map +1 -1
- package/dist/package.json +91 -0
- package/dist/src/__mocks__/sentry.d.ts +4 -0
- package/dist/src/components/atoms/BaseButton/BaseButton.d.ts +1 -1
- package/dist/src/components/atoms/BaseButton/BaseButton.js +11 -0
- package/dist/src/components/atoms/BaseButton/index.js +2 -0
- package/dist/src/components/atoms/Image/index.d.ts +1 -1
- package/dist/src/components/atoms/Image/index.js +34 -0
- package/dist/src/components/atoms/Rive/index.d.ts +141 -11
- package/dist/src/components/atoms/Rive/index.js +53 -0
- package/dist/src/components/atoms/SvgIcon/BetGeneralIcon.d.ts +1 -2
- package/dist/src/components/atoms/SvgIcon/BetGeneralIcon.js +9 -0
- package/dist/src/components/atoms/SvgIcon/BetsIcon.d.ts +1 -1
- package/dist/src/components/atoms/SvgIcon/BetsIcon.js +11 -0
- package/dist/src/components/atoms/SvgIcon/BetsWarningIcon.d.ts +1 -1
- package/dist/src/components/atoms/SvgIcon/BetsWarningIcon.js +11 -0
- package/dist/src/components/atoms/SvgIcon/CheckmarkIcon.d.ts +1 -2
- package/dist/src/components/atoms/SvgIcon/CheckmarkIcon.js +6 -0
- package/dist/src/components/atoms/SvgIcon/CollapseIcon.d.ts +1 -2
- package/dist/src/components/atoms/SvgIcon/CollapseIcon.js +6 -0
- package/dist/src/components/atoms/SvgIcon/ExpandIcon.d.ts +1 -2
- package/dist/src/components/atoms/SvgIcon/ExpandIcon.js +6 -0
- package/dist/src/components/atoms/SvgIcon/FantasyIcon.d.ts +1 -1
- package/dist/src/components/atoms/SvgIcon/FantasyIcon.js +15 -0
- package/dist/src/components/atoms/SvgIcon/FlameIcon.d.ts +1 -1
- package/dist/src/components/atoms/SvgIcon/FlameIcon.js +11 -0
- package/dist/src/components/atoms/SvgIcon/Icon.d.ts +5 -5
- package/dist/src/components/atoms/SvgIcon/Icon.js +44 -0
- package/dist/src/components/atoms/SvgIcon/KeyPlaysIcon.d.ts +1 -1
- package/dist/src/components/atoms/SvgIcon/KeyPlaysIcon.js +10 -0
- package/dist/src/components/atoms/SvgIcon/MobilePhoneIcon.d.ts +1 -1
- package/dist/src/components/atoms/SvgIcon/MobilePhoneIcon.js +11 -0
- package/dist/src/components/atoms/SvgIcon/PlayIcon.d.ts +1 -1
- package/dist/src/components/atoms/SvgIcon/PlayIcon.js +8 -0
- package/dist/src/components/atoms/SvgIcon/ShopIcon.d.ts +1 -1
- package/dist/src/components/atoms/SvgIcon/ShopIcon.js +7 -0
- package/dist/src/components/atoms/SvgIcon/StatsIcon.d.ts +1 -1
- package/dist/src/components/atoms/SvgIcon/StatsIcon.js +12 -0
- package/dist/src/components/atoms/SvgIcon/TimesIcon.d.ts +1 -2
- package/dist/src/components/atoms/SvgIcon/TimesIcon.js +6 -0
- package/dist/src/components/atoms/SvgIcon/WarningIcon.d.ts +1 -1
- package/dist/src/components/atoms/SvgIcon/WarningIcon.js +8 -0
- package/dist/src/components/atoms/SvgIcon/index.js +2 -0
- package/dist/src/components/core/App/App.d.ts +1 -1
- package/dist/src/components/core/App/App.js +35 -0
- package/dist/src/components/core/App/index.js +2 -0
- package/dist/src/components/core/OverlayContainer.js +58 -0
- package/dist/src/components/core/PanelManager/PanelManager.d.ts +1 -1
- package/dist/src/components/core/PanelManager/PanelManager.js +86 -0
- package/dist/src/components/core/PanelManager/index.js +2 -0
- package/dist/src/components/core/ScrollableContainer/FocusableItem.js +38 -0
- package/dist/src/components/core/ScrollableContainer/ScrollableContainer.d.ts +8 -7
- package/dist/src/components/core/ScrollableContainer/ScrollableContainer.js +169 -0
- package/dist/src/components/core/ScrollableContainer/index.js +2 -0
- package/dist/src/components/molecules/ActionButton/ActionButton.d.ts +53 -7
- package/dist/src/components/molecules/ActionButton/ActionButton.js +10 -0
- package/dist/src/components/molecules/ActionButton/index.js +2 -0
- package/dist/src/components/molecules/HeadshotImage/HeadshotImage.d.ts +1 -1
- package/dist/src/components/molecules/HeadshotImage/HeadshotImage.js +50 -0
- package/dist/src/components/molecules/HeadshotImage/index.js +2 -0
- package/dist/src/components/molecules/Overlay/Overlay.d.ts +1 -1
- package/dist/src/components/molecules/Overlay/Overlay.js +139 -0
- package/dist/src/components/molecules/Overlay/index.js +2 -0
- package/dist/src/components/molecules/PanelNavButton/PanelNavButton.d.ts +57 -10
- package/dist/src/components/molecules/PanelNavButton/PanelNavButton.js +27 -0
- package/dist/src/components/molecules/PanelNavButton/index.js +2 -0
- package/dist/src/components/molecules/SegmentButton/SegmentButton.js +10 -0
- package/dist/src/components/molecules/SegmentButton/index.js +2 -0
- package/dist/src/components/molecules/TabLoadError/TabLoadError.d.ts +53 -7
- package/dist/src/components/molecules/TabLoadError/TabLoadError.js +14 -0
- package/dist/src/components/molecules/TabLoadError/index.js +2 -0
- package/dist/src/components/molecules/WatchButton/WatchButton.d.ts +1 -1
- package/dist/src/components/molecules/WatchButton/WatchButton.js +15 -0
- package/dist/src/components/molecules/WatchButton/index.js +2 -0
- package/dist/src/components/organisms/PanelNavigation/PanelNavigation.d.ts +1 -1
- package/dist/src/components/organisms/PanelNavigation/PanelNavigation.js +60 -0
- package/dist/src/components/organisms/PanelNavigation/index.js +2 -0
- package/dist/src/components/organisms/SegmentController/SegmentController.d.ts +5 -4
- package/dist/src/components/organisms/SegmentController/SegmentController.js +76 -0
- package/dist/src/components/organisms/SegmentController/index.js +2 -0
- package/dist/src/development/MaestroEventDelegate.js +109 -0
- package/dist/src/development/TimeSeek.d.ts +1 -1
- package/dist/src/development/TimeSeek.js +218 -0
- package/dist/src/development/development.js +36 -0
- package/dist/src/external/AxiosNetworkClient.js +110 -0
- package/dist/src/external/LocalStorageCacheManager.js +213 -0
- package/dist/src/external/ReactRenderer.js +65 -0
- package/dist/src/external/mocks/MockExternalNetworkClient.js +187 -0
- package/dist/src/external/ports/cacheManager.js +1 -0
- package/dist/src/external/ports/networkClient.js +1 -0
- package/dist/src/external/ports/renderer.d.ts +1 -2
- package/dist/src/external/ports/renderer.js +1 -0
- package/dist/src/external/spatial-navigation/__mocks__/withFocusable.d.ts +8 -0
- package/dist/src/external/spatial-navigation/__mocks__/withFocusable.js +7 -0
- package/dist/src/external/spatial-navigation/index.js +3 -0
- package/dist/src/external/spatial-navigation/measureLayout.js +30 -0
- package/dist/src/external/spatial-navigation/spatialNavigation.js +876 -0
- package/dist/src/external/spatial-navigation/utils.js +6 -0
- package/dist/src/external/spatial-navigation/visualDebugger.js +76 -0
- package/dist/src/external/spatial-navigation/withFocusable.d.ts +53 -7
- package/dist/src/external/spatial-navigation/withFocusable.js +245 -0
- package/dist/src/helpers/Observable.js +37 -0
- package/dist/src/helpers/strings.js +14 -0
- package/dist/src/helpers/url.js +12 -0
- package/dist/src/index.d.ts +5 -5
- package/dist/src/index.js +165 -0
- package/dist/src/interfaces/IMaestroEvent.js +18 -0
- package/dist/src/interfaces/IMaestroEventDelegate.js +1 -0
- package/dist/src/interfaces/IMaestroManager.js +1 -0
- package/dist/src/interfaces/IUserSettings.js +20 -0
- package/dist/src/models/IModel.js +1 -0
- package/dist/src/models/IPanel.js +40 -0
- package/dist/src/models/ITheme.js +20 -0
- package/dist/src/models/IWinningBet.js +1 -0
- package/dist/src/modules/bets/interfaces/IBets.js +1 -0
- package/dist/src/modules/bets/mocks.js +573 -0
- package/dist/src/modules/bets/types/BetsAnalyticsTypes.js +1 -0
- package/dist/src/modules/bets/view/BetsView.d.ts +3 -3
- package/dist/src/modules/bets/view/BetsView.js +143 -0
- package/dist/src/modules/bets/view/HotProps/HotPropsView.d.ts +53 -7
- package/dist/src/modules/bets/view/HotProps/HotPropsView.js +150 -0
- package/dist/src/modules/bets/view/SixPack/SixPackView.d.ts +5 -4
- package/dist/src/modules/bets/view/SixPack/SixPackView.js +110 -0
- package/dist/src/modules/bets/view/UserBets/BetResult/BetResult.d.ts +1 -1
- package/dist/src/modules/bets/view/UserBets/BetResult/BetResult.js +6 -0
- package/dist/src/modules/bets/view/UserBets/BetsCard/BetsCard.d.ts +53 -7
- package/dist/src/modules/bets/view/UserBets/BetsCard/BetsCard.js +149 -0
- package/dist/src/modules/bets/view/UserBets/BetsCard/BetsCardEvent.d.ts +5 -4
- package/dist/src/modules/bets/view/UserBets/BetsCard/BetsCardEvent.js +34 -0
- package/dist/src/modules/bets/view/UserBets/BetsCard/BetsCardFooter.d.ts +1 -2
- package/dist/src/modules/bets/view/UserBets/BetsCard/BetsCardFooter.js +18 -0
- package/dist/src/modules/bets/view/UserBets/Boost/Boost.d.ts +1 -2
- package/dist/src/modules/bets/view/UserBets/Boost/Boost.js +6 -0
- package/dist/src/modules/bets/view/UserBets/OutcomeBadge/OutcomeBadge.d.ts +1 -2
- package/dist/src/modules/bets/view/UserBets/OutcomeBadge/OutcomeBadge.js +9 -0
- package/dist/src/modules/bets/view/UserBets/Parlay/Parlay.d.ts +1 -2
- package/dist/src/modules/bets/view/UserBets/Parlay/Parlay.js +13 -0
- package/dist/src/modules/bets/view/UserBets/Straight/Straight.d.ts +1 -2
- package/dist/src/modules/bets/view/UserBets/Straight/Straight.js +6 -0
- package/dist/src/modules/bets/view/UserBets/Teaser/Teaser.d.ts +1 -2
- package/dist/src/modules/bets/view/UserBets/Teaser/Teaser.js +13 -0
- package/dist/src/modules/bets/view/UserBets/UserBetsView.d.ts +3 -3
- package/dist/src/modules/bets/view/UserBets/UserBetsView.js +107 -0
- package/dist/src/modules/bets/view/components/Bet/Bet.d.ts +99 -11
- package/dist/src/modules/bets/view/components/Bet/Bet.js +32 -0
- package/dist/src/modules/bets/view/components/BetPill/BetPill.d.ts +1 -1
- package/dist/src/modules/bets/view/components/BetPill/BetPill.js +6 -0
- package/dist/src/modules/bets/view/components/BetsCard/BetsCard.js +15 -0
- package/dist/src/modules/bets/view/components/BetsCard/BetsCardHeader.d.ts +1 -1
- package/dist/src/modules/bets/view/components/BetsCard/BetsCardHeader.js +20 -0
- package/dist/src/modules/bets/view/components/GamblingDisclaimer/GamblingDisclaimer.d.ts +1 -1
- package/dist/src/modules/bets/view/components/GamblingDisclaimer/GamblingDisclaimer.js +14 -0
- package/dist/src/modules/bets/view/components/LocationWarning/LocationWarning.d.ts +1 -1
- package/dist/src/modules/bets/view/components/LocationWarning/LocationWarning.js +16 -0
- package/dist/src/modules/bets/view/components/PromoCodeBanner/PromoCodeBanner.d.ts +5 -4
- package/dist/src/modules/bets/view/components/PromoCodeBanner/PromoCodeBanner.js +78 -0
- package/dist/src/modules/bets/view/components/PromoCodeBanner/index.js +1 -0
- package/dist/src/modules/bets/view-model/BetsViewModel.js +974 -0
- package/dist/src/modules/fantasy/components/ExpandedAthleteList/ExpandedAthletesList.d.ts +1 -1
- package/dist/src/modules/fantasy/components/ExpandedAthleteList/ExpandedAthletesList.js +107 -0
- package/dist/src/modules/fantasy/components/ExpandedAthleteList/index.js +1 -0
- package/dist/src/modules/fantasy/components/LeagueCard/LeagueCard.d.ts +53 -7
- package/dist/src/modules/fantasy/components/LeagueCard/LeagueCard.js +20 -0
- package/dist/src/modules/fantasy/components/LeagueCard/index.js +2 -0
- package/dist/src/modules/fantasy/components/TopPlayerCard/TopPlayerCard.d.ts +53 -7
- package/dist/src/modules/fantasy/components/TopPlayerCard/TopPlayerCard.js +29 -0
- package/dist/src/modules/fantasy/components/TopPlayerCard/index.js +2 -0
- package/dist/src/modules/fantasy/mocks.js +3682 -0
- package/dist/src/modules/fantasy/types.js +6 -0
- package/dist/src/modules/fantasy/view/ActiveAthletesMarquee/ActiveAthletesMarquee.d.ts +1 -1
- package/dist/src/modules/fantasy/view/ActiveAthletesMarquee/ActiveAthletesMarquee.js +74 -0
- package/dist/src/modules/fantasy/view/ActiveAthletesMarquee/index.js +2 -0
- package/dist/src/modules/fantasy/view/ErrorBoundary.d.ts +13 -0
- package/dist/src/modules/fantasy/view/FantasyItemView.d.ts +6 -5
- package/dist/src/modules/fantasy/view/FantasyItemView.js +74 -0
- package/dist/src/modules/fantasy/view/FantasyView.d.ts +3 -3
- package/dist/src/modules/fantasy/view/FantasyView.js +133 -0
- package/dist/src/modules/fantasy/view/InactiveLeague/DraftDateCountdown.d.ts +1 -1
- package/dist/src/modules/fantasy/view/InactiveLeague/DraftDateCountdown.js +95 -0
- package/dist/src/modules/fantasy/view/InactiveLeague/InactiveLeague.d.ts +53 -7
- package/dist/src/modules/fantasy/view/InactiveLeague/InactiveLeague.js +13 -0
- package/dist/src/modules/fantasy/view/InactiveLeague/index.js +2 -0
- package/dist/src/modules/fantasy/view/LoginView/LoginView.d.ts +53 -7
- package/dist/src/modules/fantasy/view/LoginView/LoginView.js +27 -0
- package/dist/src/modules/fantasy/view/LoginView/index.js +2 -0
- package/dist/src/modules/fantasy/view/MatchupPair/DoubleAthleteCard/DoubleAthleteCard.d.ts +53 -7
- package/dist/src/modules/fantasy/view/MatchupPair/DoubleAthleteCard/DoubleAthleteCard.js +25 -0
- package/dist/src/modules/fantasy/view/MatchupPair/DoubleAthleteCard/index.js +2 -0
- package/dist/src/modules/fantasy/view/MatchupPair/ExpandedDoubleAthleteCards.d.ts +1 -1
- package/dist/src/modules/fantasy/view/MatchupPair/ExpandedDoubleAthleteCards.js +9 -0
- package/dist/src/modules/fantasy/view/MatchupPair/MatchupPair.d.ts +53 -7
- package/dist/src/modules/fantasy/view/MatchupPair/MatchupPair.js +118 -0
- package/dist/src/modules/fantasy/view/MatchupPair/index.js +2 -0
- package/dist/src/modules/fantasy/view/MatchupSingle/ExpandedSingleAthleteCards.d.ts +1 -1
- package/dist/src/modules/fantasy/view/MatchupSingle/ExpandedSingleAthleteCards.js +9 -0
- package/dist/src/modules/fantasy/view/MatchupSingle/MatchupSingle.d.ts +53 -7
- package/dist/src/modules/fantasy/view/MatchupSingle/MatchupSingle.js +108 -0
- package/dist/src/modules/fantasy/view/MatchupSingle/SingleAthleteCard/SingleAthleteCard.d.ts +53 -7
- package/dist/src/modules/fantasy/view/MatchupSingle/SingleAthleteCard/SingleAthleteCard.js +18 -0
- package/dist/src/modules/fantasy/view/MatchupSingle/SingleAthleteCard/index.js +2 -0
- package/dist/src/modules/fantasy/view/MatchupSingle/index.js +2 -0
- package/dist/src/modules/fantasy/view/PromoView/PromoView.d.ts +53 -7
- package/dist/src/modules/fantasy/view/PromoView/PromoView.js +12 -0
- package/dist/src/modules/fantasy/view/PromoView/index.js +2 -0
- package/dist/src/modules/fantasy/view/index.js +2 -0
- package/dist/src/modules/fantasy/view-model/FantasyViewModel.FantasyPolling.js +132 -0
- package/dist/src/modules/fantasy/view-model/FantasyViewModel.LeagueManagerPolling.js +141 -0
- package/dist/src/modules/fantasy/view-model/FantasyViewModel.js +534 -0
- package/dist/src/modules/key-plays/constants.js +292 -0
- package/dist/src/modules/key-plays/interfaces/IKeyPlays.js +14 -0
- package/dist/src/modules/key-plays/interfaces/IKeyPlaysResponse.js +1 -0
- package/dist/src/modules/key-plays/view/KeyPlayCardScoreTagView.d.ts +1 -1
- package/dist/src/modules/key-plays/view/KeyPlayCardScoreTagView.js +16 -0
- package/dist/src/modules/key-plays/view/KeyPlayCardView.d.ts +7 -6
- package/dist/src/modules/key-plays/view/KeyPlayCardView.js +139 -0
- package/dist/src/modules/key-plays/view/KeyPlayErrorStateView.d.ts +1 -1
- package/dist/src/modules/key-plays/view/KeyPlayErrorStateView.js +65 -0
- package/dist/src/modules/key-plays/view/KeyPlaysView.d.ts +3 -3
- package/dist/src/modules/key-plays/view/KeyPlaysView.js +151 -0
- package/dist/src/modules/key-plays/view-model/KeyPlaysViewModel.js +247 -0
- package/dist/src/modules/shop/mocks.js +390 -0
- package/dist/src/modules/shop/types.js +7 -0
- package/dist/src/modules/shop/view/ProductDetailView/ProductDetailView.d.ts +1 -2
- package/dist/src/modules/shop/view/ProductDetailView/ProductDetailView.js +56 -0
- package/dist/src/modules/shop/view/ProductDetailView/index.js +2 -0
- package/dist/src/modules/shop/view/ShopView.d.ts +3 -3
- package/dist/src/modules/shop/view/ShopView.js +182 -0
- package/dist/src/modules/shop/view/components/BrowseCard/BrowseCard.d.ts +54 -8
- package/dist/src/modules/shop/view/components/BrowseCard/BrowseCard.js +23 -0
- package/dist/src/modules/shop/view/components/BrowseCard/index.js +2 -0
- package/dist/src/modules/shop/view/components/ProductSummaryCard/ProductSummaryCard.d.ts +53 -7
- package/dist/src/modules/shop/view/components/ProductSummaryCard/ProductSummaryCard.js +26 -0
- package/dist/src/modules/shop/view/components/ProductSummaryCard/index.js +1 -0
- package/dist/src/modules/shop/view/components/ShopPromoView/ShopPromoView.d.ts +1 -2
- package/dist/src/modules/shop/view/components/ShopPromoView/ShopPromoView.js +19 -0
- package/dist/src/modules/shop/view/components/ShopPromoView/index.js +1 -0
- package/dist/src/modules/shop/view/components/ShopSection/ShopSection.d.ts +6 -4
- package/dist/src/modules/shop/view/components/ShopSection/ShopSection.js +61 -0
- package/dist/src/modules/shop/view/components/ShopSection/ShopSectionItem.d.ts +18 -0
- package/dist/src/modules/shop/view/components/ShopSection/ShopSectionItem.js +22 -0
- package/dist/src/modules/shop/view/components/ShopSection/index.js +1 -0
- package/dist/src/modules/shop/view/index.js +2 -0
- package/dist/src/modules/shop/view-model/ShopViewModel.ShopPolling.js +111 -0
- package/dist/src/modules/shop/view-model/ShopViewModel.js +353 -0
- package/dist/src/modules/stats/interfaces/IStats.js +1 -0
- package/dist/src/modules/stats/mocks.js +746 -0
- package/dist/src/modules/stats/utils/driveSummaryUtils.js +48 -0
- package/dist/src/modules/stats/utils/renderTeamStatistic.d.ts +1 -2
- package/dist/src/modules/stats/utils/renderTeamStatistic.js +16 -0
- package/dist/src/modules/stats/utils.js +62 -0
- package/dist/src/modules/stats/view/ActiveAthletes/ActiveAthletes.d.ts +2 -2
- package/dist/src/modules/stats/view/ActiveAthletes/ActiveAthletes.js +98 -0
- package/dist/src/modules/stats/view/ActiveAthletes/CollapsedAthletes/CollapsedAthletes.d.ts +1 -2
- package/dist/src/modules/stats/view/ActiveAthletes/CollapsedAthletes/CollapsedAthletes.js +27 -0
- package/dist/src/modules/stats/view/ActiveAthletes/ExpandedAthletes/ExpandedAthletes.d.ts +1 -1
- package/dist/src/modules/stats/view/ActiveAthletes/ExpandedAthletes/ExpandedAthletes.js +89 -0
- package/dist/src/modules/stats/view/ActiveAthletes/index.js +2 -0
- package/dist/src/modules/stats/view/DriveSummary/DrivePlayCard.d.ts +53 -7
- package/dist/src/modules/stats/view/DriveSummary/DrivePlayCard.js +70 -0
- package/dist/src/modules/stats/view/DriveSummary/DriveSummary.d.ts +1 -1
- package/dist/src/modules/stats/view/DriveSummary/DriveSummary.js +87 -0
- package/dist/src/modules/stats/view/DriveSummary/ExpandedItems/DriveSummaryExpanded.d.ts +1 -1
- package/dist/src/modules/stats/view/DriveSummary/ExpandedItems/DriveSummaryExpanded.js +129 -0
- package/dist/src/modules/stats/view/DriveSummary/Header/DriveSummaryHeader.d.ts +1 -2
- package/dist/src/modules/stats/view/DriveSummary/Header/DriveSummaryHeader.js +26 -0
- package/dist/src/modules/stats/view/DriveSummary/MainStat/MainStat.d.ts +1 -2
- package/dist/src/modules/stats/view/DriveSummary/MainStat/MainStat.js +24 -0
- package/dist/src/modules/stats/view/DriveSummary/index.js +2 -0
- package/dist/src/modules/stats/view/GameLeaders/GameLeaders.d.ts +5 -4
- package/dist/src/modules/stats/view/GameLeaders/GameLeaders.js +48 -0
- package/dist/src/modules/stats/view/GameLeaders/index.js +2 -0
- package/dist/src/modules/stats/view/MatchPredictor/DonutChart/DonutChart.d.ts +2 -2
- package/dist/src/modules/stats/view/MatchPredictor/DonutChart/DonutChart.js +55 -0
- package/dist/src/modules/stats/view/MatchPredictor/DonutChart/index.js +1 -0
- package/dist/src/modules/stats/view/MatchPredictor/MatchPredictorView.d.ts +53 -7
- package/dist/src/modules/stats/view/MatchPredictor/MatchPredictorView.js +60 -0
- package/dist/src/modules/stats/view/MatchPredictor/index.js +2 -0
- package/dist/src/modules/stats/view/Penalties/Penalties.d.ts +1 -2
- package/dist/src/modules/stats/view/Penalties/Penalties.js +6 -0
- package/dist/src/modules/stats/view/Penalties/index.js +2 -0
- package/dist/src/modules/stats/view/RecentGames/RecentGames.d.ts +53 -7
- package/dist/src/modules/stats/view/RecentGames/RecentGames.js +23 -0
- package/dist/src/modules/stats/view/RecentGames/index.js +2 -0
- package/dist/src/modules/stats/view/ScoringSummary/ExpandedScores/ExpandedScores.d.ts +1 -1
- package/dist/src/modules/stats/view/ScoringSummary/ExpandedScores/ExpandedScores.js +121 -0
- package/dist/src/modules/stats/view/ScoringSummary/ExpandedScores/index.js +2 -0
- package/dist/src/modules/stats/view/ScoringSummary/ScoreItem/ScoreItem.d.ts +53 -7
- package/dist/src/modules/stats/view/ScoringSummary/ScoreItem/ScoreItem.js +62 -0
- package/dist/src/modules/stats/view/ScoringSummary/ScoreItem/index.js +2 -0
- package/dist/src/modules/stats/view/ScoringSummary/ScoresSection/ScoresSection.d.ts +1 -2
- package/dist/src/modules/stats/view/ScoringSummary/ScoresSection/ScoresSection.js +23 -0
- package/dist/src/modules/stats/view/ScoringSummary/ScoresSection/index.js +2 -0
- package/dist/src/modules/stats/view/ScoringSummary/ScoringSummary.d.ts +2 -2
- package/dist/src/modules/stats/view/ScoringSummary/ScoringSummary.js +106 -0
- package/dist/src/modules/stats/view/ScoringSummary/index.js +2 -0
- package/dist/src/modules/stats/view/StatsItemView.d.ts +6 -5
- package/dist/src/modules/stats/view/StatsItemView.js +92 -0
- package/dist/src/modules/stats/view/StatsQRCode/StatsQRCodeView.d.ts +53 -7
- package/dist/src/modules/stats/view/StatsQRCode/StatsQRCodeView.js +36 -0
- package/dist/src/modules/stats/view/StatsQRCode/index.js +1 -0
- package/dist/src/modules/stats/view/StatsView.d.ts +3 -3
- package/dist/src/modules/stats/view/StatsView.js +137 -0
- package/dist/src/modules/stats/view/TeamStats/TeamStatsView.d.ts +53 -7
- package/dist/src/modules/stats/view/TeamStats/TeamStatsView.js +43 -0
- package/dist/src/modules/stats/view/TeamStats/index.js +1 -0
- package/dist/src/modules/stats/view/Teams/StatsCarousel.d.ts +2 -2
- package/dist/src/modules/stats/view/Teams/StatsCarousel.js +83 -0
- package/dist/src/modules/stats/view/Teams/StatsProgressBar.d.ts +1 -2
- package/dist/src/modules/stats/view/Teams/StatsProgressBar.js +19 -0
- package/dist/src/modules/stats/view/Teams/Teams.d.ts +53 -7
- package/dist/src/modules/stats/view/Teams/Teams.js +43 -0
- package/dist/src/modules/stats/view/Teams/index.js +2 -0
- package/dist/src/modules/stats/view/WinProbability/WinProbability.d.ts +53 -7
- package/dist/src/modules/stats/view/WinProbability/WinProbability.js +28 -0
- package/dist/src/modules/stats/view/WinProbability/index.js +2 -0
- package/dist/src/modules/stats/view/components/AthletesStatistics/AthletesStatistics.d.ts +53 -7
- package/dist/src/modules/stats/view/components/AthletesStatistics/AthletesStatistics.js +89 -0
- package/dist/src/modules/stats/view/components/AthletesStatistics/StatisticTable.d.ts +1 -2
- package/dist/src/modules/stats/view/components/AthletesStatistics/StatisticTable.js +12 -0
- package/dist/src/modules/stats/view/components/AthletesStatistics/index.js +2 -0
- package/dist/src/modules/stats/view/index.js +2 -0
- package/dist/src/modules/stats/view-model/StatsViewModel.js +966 -0
- package/dist/src/sentry.js +31 -0
- package/dist/src/services/AnalyticsService/AnalyticsService.d.ts +12 -7
- package/dist/src/services/AnalyticsService/AnalyticsService.js +402 -0
- package/dist/src/services/AnalyticsService/types.js +1 -0
- package/dist/src/services/BetsService.js +122 -0
- package/dist/src/services/FantasyService.js +92 -0
- package/dist/src/services/GlobalService/GlobalService.d.ts +9 -0
- package/dist/src/services/GlobalService/PageService.d.ts +9 -0
- package/dist/src/services/GlobalService/index.d.ts +2 -0
- package/dist/src/services/GlobalService/mocks.d.ts +2 -0
- package/dist/src/services/GlobalService/types.d.ts +11 -0
- package/dist/src/services/InsightsService/InsightsPayloadBuilder.d.ts +1 -2
- package/dist/src/services/InsightsService/InsightsPayloadBuilder.js +386 -0
- package/dist/src/services/InsightsService/InsightsService.js +74 -0
- package/dist/src/services/NetworkManager/NetworkManager.js +457 -0
- package/dist/src/services/NetworkManager/NetworkManagerFactory.js +101 -0
- package/dist/src/services/NetworkManager/errors.js +45 -0
- package/dist/src/services/NetworkManager/types.js +10 -0
- package/dist/src/services/PageService/PageService.d.ts +9 -0
- package/dist/src/services/PageService/PageService.js +39 -0
- package/dist/src/services/PageService/index.d.ts +2 -0
- package/dist/src/services/PageService/index.js +2 -0
- package/dist/src/services/PageService/mocks.d.ts +2 -0
- package/dist/src/services/PageService/mocks.js +104 -0
- package/dist/src/services/PageService/types.d.ts +76 -0
- package/dist/src/services/PageService/types.js +1 -0
- package/dist/src/services/ShopService.js +46 -0
- package/dist/src/services/StaticService/PageService.d.ts +9 -0
- package/dist/src/services/StaticService/StaticService.d.ts +3 -1
- package/dist/src/services/StaticService/StaticService.js +59 -0
- package/dist/src/services/StaticService/index.js +2 -0
- package/dist/src/services/StaticService/mocks.js +104 -0
- package/dist/src/services/StaticService/types.js +1 -0
- package/dist/src/services/StatsService.js +136 -0
- package/dist/src/services/ThemeManager/constants.js +47 -0
- package/dist/src/services/UserSettingsManager.js +155 -0
- package/dist/src/test-polyfills.js +15 -0
- package/dist/src/types/OverlayTypes.js +4 -0
- package/dist/src/view-models/MaestroEventViewModel.d.ts +0 -2
- package/dist/src/view-models/MaestroEventViewModel.js +280 -0
- package/dist/src/view-models/OverlayViewModel.js +222 -0
- package/dist/src/view-models/PanelManagerViewModel.js +212 -0
- package/dist/src/view-models/ViewModel.js +32 -0
- package/package.json +13 -9
|
@@ -0,0 +1,974 @@
|
|
|
1
|
+
import { Observable } from '../../../helpers/Observable';
|
|
2
|
+
import BetsService from '../../../services/BetsService';
|
|
3
|
+
import { UserSettingsManager } from '../../../services/UserSettingsManager';
|
|
4
|
+
import AnalyticsService from '../../../services/AnalyticsService/AnalyticsService';
|
|
5
|
+
// Import ViewModel with correct path
|
|
6
|
+
import { ViewModel } from '../../../view-models/ViewModel';
|
|
7
|
+
import { MOCK_BETS_API_RESPONSE } from '../mocks';
|
|
8
|
+
import SDK from '@/index';
|
|
9
|
+
import { captureException } from '@/sentry';
|
|
10
|
+
import { stringHashCode } from '@/helpers/strings';
|
|
11
|
+
// The interval for polling bet data (in milliseconds)
|
|
12
|
+
const DEFAULT_POLLING_INTERVAL = 30000; // 30 seconds
|
|
13
|
+
const BET_ITEM_TYPE = {
|
|
14
|
+
ODDS: 'odds',
|
|
15
|
+
USER_BETS: 'userBets',
|
|
16
|
+
PROMO: 'promo',
|
|
17
|
+
HOT_PROPS: 'hotProps',
|
|
18
|
+
LOCATION_DISCLAIMER: 'locationDisclaimer',
|
|
19
|
+
GAMBLING_MESSAGE: 'gamblingMessage',
|
|
20
|
+
};
|
|
21
|
+
const BET_ERROR_STATE = {
|
|
22
|
+
NONE: 'none',
|
|
23
|
+
TAB_LOAD_FAILURE: 'tabLoadFailure',
|
|
24
|
+
};
|
|
25
|
+
const isPersonalizedBetsResponse = (data) => {
|
|
26
|
+
return (typeof data === 'object' &&
|
|
27
|
+
data !== null &&
|
|
28
|
+
'event' in data &&
|
|
29
|
+
typeof data.event === 'object');
|
|
30
|
+
};
|
|
31
|
+
export class BetsViewModel extends ViewModel {
|
|
32
|
+
constructor(eventId, delegate, options = {}) {
|
|
33
|
+
super();
|
|
34
|
+
// Observable properties
|
|
35
|
+
Object.defineProperty(this, "betsItems", {
|
|
36
|
+
enumerable: true,
|
|
37
|
+
configurable: true,
|
|
38
|
+
writable: true,
|
|
39
|
+
value: new Observable([])
|
|
40
|
+
});
|
|
41
|
+
Object.defineProperty(this, "isDataLoading", {
|
|
42
|
+
enumerable: true,
|
|
43
|
+
configurable: true,
|
|
44
|
+
writable: true,
|
|
45
|
+
value: new Observable(true)
|
|
46
|
+
});
|
|
47
|
+
Object.defineProperty(this, "errorState", {
|
|
48
|
+
enumerable: true,
|
|
49
|
+
configurable: true,
|
|
50
|
+
writable: true,
|
|
51
|
+
value: new Observable('none')
|
|
52
|
+
});
|
|
53
|
+
Object.defineProperty(this, "hasEverSuccessfullyLoaded", {
|
|
54
|
+
enumerable: true,
|
|
55
|
+
configurable: true,
|
|
56
|
+
writable: true,
|
|
57
|
+
value: new Observable(false)
|
|
58
|
+
});
|
|
59
|
+
Object.defineProperty(this, "hideWagers", {
|
|
60
|
+
enumerable: true,
|
|
61
|
+
configurable: true,
|
|
62
|
+
writable: true,
|
|
63
|
+
value: new Observable(false)
|
|
64
|
+
});
|
|
65
|
+
// Properties
|
|
66
|
+
Object.defineProperty(this, "eventId", {
|
|
67
|
+
enumerable: true,
|
|
68
|
+
configurable: true,
|
|
69
|
+
writable: true,
|
|
70
|
+
value: void 0
|
|
71
|
+
});
|
|
72
|
+
Object.defineProperty(this, "delegate", {
|
|
73
|
+
enumerable: true,
|
|
74
|
+
configurable: true,
|
|
75
|
+
writable: true,
|
|
76
|
+
value: void 0
|
|
77
|
+
});
|
|
78
|
+
Object.defineProperty(this, "betsService", {
|
|
79
|
+
enumerable: true,
|
|
80
|
+
configurable: true,
|
|
81
|
+
writable: true,
|
|
82
|
+
value: void 0
|
|
83
|
+
});
|
|
84
|
+
Object.defineProperty(this, "analyticsService", {
|
|
85
|
+
enumerable: true,
|
|
86
|
+
configurable: true,
|
|
87
|
+
writable: true,
|
|
88
|
+
value: void 0
|
|
89
|
+
});
|
|
90
|
+
Object.defineProperty(this, "pollingInterval", {
|
|
91
|
+
enumerable: true,
|
|
92
|
+
configurable: true,
|
|
93
|
+
writable: true,
|
|
94
|
+
value: void 0
|
|
95
|
+
});
|
|
96
|
+
Object.defineProperty(this, "pollingTask", {
|
|
97
|
+
enumerable: true,
|
|
98
|
+
configurable: true,
|
|
99
|
+
writable: true,
|
|
100
|
+
value: null
|
|
101
|
+
});
|
|
102
|
+
Object.defineProperty(this, "lastNonPersonalizedResponseHash", {
|
|
103
|
+
enumerable: true,
|
|
104
|
+
configurable: true,
|
|
105
|
+
writable: true,
|
|
106
|
+
value: null
|
|
107
|
+
});
|
|
108
|
+
Object.defineProperty(this, "lastPersonalizedResponseHash", {
|
|
109
|
+
enumerable: true,
|
|
110
|
+
configurable: true,
|
|
111
|
+
writable: true,
|
|
112
|
+
value: null
|
|
113
|
+
});
|
|
114
|
+
Object.defineProperty(this, "useMockData", {
|
|
115
|
+
enumerable: true,
|
|
116
|
+
configurable: true,
|
|
117
|
+
writable: true,
|
|
118
|
+
value: false
|
|
119
|
+
});
|
|
120
|
+
Object.defineProperty(this, "userSettingsManager", {
|
|
121
|
+
enumerable: true,
|
|
122
|
+
configurable: true,
|
|
123
|
+
writable: true,
|
|
124
|
+
value: void 0
|
|
125
|
+
});
|
|
126
|
+
Object.defineProperty(this, "settingsSubscription", {
|
|
127
|
+
enumerable: true,
|
|
128
|
+
configurable: true,
|
|
129
|
+
writable: true,
|
|
130
|
+
value: null
|
|
131
|
+
});
|
|
132
|
+
Object.defineProperty(this, "initialized", {
|
|
133
|
+
enumerable: true,
|
|
134
|
+
configurable: true,
|
|
135
|
+
writable: true,
|
|
136
|
+
value: false
|
|
137
|
+
});
|
|
138
|
+
this.eventId = eventId;
|
|
139
|
+
this.delegate = delegate;
|
|
140
|
+
this.betsService = new BetsService(delegate);
|
|
141
|
+
this.analyticsService = new AnalyticsService();
|
|
142
|
+
this.pollingInterval = DEFAULT_POLLING_INTERVAL;
|
|
143
|
+
this.useMockData = options.useMockData || false;
|
|
144
|
+
this.userSettingsManager = UserSettingsManager.getInstance();
|
|
145
|
+
// Initialize hide_wagers setting
|
|
146
|
+
this.hideWagers.value = this.userSettingsManager.shouldHideWagers();
|
|
147
|
+
// Subscribe to settings changes
|
|
148
|
+
this.settingsSubscription = this.userSettingsManager.settings.subscribe(() => {
|
|
149
|
+
this.updateHideWagersFromSettings();
|
|
150
|
+
});
|
|
151
|
+
this.betsService = new BetsService(delegate);
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Initialize the ViewModel and start data fetching
|
|
155
|
+
*/
|
|
156
|
+
async init() {
|
|
157
|
+
// Track panel view on initialization
|
|
158
|
+
this.trackPanelView();
|
|
159
|
+
await this.fetchNewData();
|
|
160
|
+
this.refreshPolling();
|
|
161
|
+
this.initialized = true;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Clean up resources when the ViewModel is no longer needed
|
|
165
|
+
*/
|
|
166
|
+
cleanup() {
|
|
167
|
+
this.stopPolling();
|
|
168
|
+
// Clean up settings subscription
|
|
169
|
+
if (this.settingsSubscription) {
|
|
170
|
+
this.settingsSubscription();
|
|
171
|
+
this.settingsSubscription = null;
|
|
172
|
+
}
|
|
173
|
+
this.initialized = false;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Track panel view event
|
|
177
|
+
*/
|
|
178
|
+
async trackPanelView() {
|
|
179
|
+
try {
|
|
180
|
+
const betCounts = this.getUserBetCounts();
|
|
181
|
+
await this.analyticsService.panelView('espnBet', betCounts);
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
captureException(error, {
|
|
185
|
+
context: 'BetsViewModel.trackPanelView',
|
|
186
|
+
});
|
|
187
|
+
console.error('[BET] Error tracking panel view:', error);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Track card click event
|
|
192
|
+
*/
|
|
193
|
+
async trackCardClick(cardType, betType) {
|
|
194
|
+
try {
|
|
195
|
+
const betCounts = this.getUserBetCounts();
|
|
196
|
+
const metadata = {
|
|
197
|
+
...betCounts,
|
|
198
|
+
card: cardType,
|
|
199
|
+
bet_type: betType || null,
|
|
200
|
+
};
|
|
201
|
+
await this.analyticsService.panelClick({
|
|
202
|
+
type: 'espnBet',
|
|
203
|
+
name: 'bets_item_clicked',
|
|
204
|
+
metadata,
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
catch (error) {
|
|
208
|
+
captureException(error, {
|
|
209
|
+
context: 'BetsViewModel.trackCardClick',
|
|
210
|
+
cardType,
|
|
211
|
+
betType,
|
|
212
|
+
});
|
|
213
|
+
console.error('[BET] Error tracking card click:', error);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Get user bet counts for analytics
|
|
218
|
+
*/
|
|
219
|
+
getUserBetCounts() {
|
|
220
|
+
try {
|
|
221
|
+
let inGameBets = 0;
|
|
222
|
+
let totalBets = 0;
|
|
223
|
+
// Count bets from current data
|
|
224
|
+
for (const item of this.betsItems.value) {
|
|
225
|
+
if (item.type === 'userBets') {
|
|
226
|
+
const userBetsItem = item;
|
|
227
|
+
const allBets = [
|
|
228
|
+
...userBetsItem.data.bets.live,
|
|
229
|
+
...userBetsItem.data.bets.settled,
|
|
230
|
+
...userBetsItem.data.bets.upcoming,
|
|
231
|
+
];
|
|
232
|
+
totalBets = allBets.length;
|
|
233
|
+
inGameBets = userBetsItem.data.bets.live.length;
|
|
234
|
+
break;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return {
|
|
238
|
+
in_game_bets: inGameBets,
|
|
239
|
+
total_bets: totalBets,
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
catch (error) {
|
|
243
|
+
captureException(error, {
|
|
244
|
+
context: 'BetsViewModel.getUserBetCounts',
|
|
245
|
+
});
|
|
246
|
+
console.error('[BET] Error getting user bet counts:', error);
|
|
247
|
+
return {
|
|
248
|
+
in_game_bets: 0,
|
|
249
|
+
total_bets: 0,
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Refresh polling for bet data
|
|
255
|
+
*/
|
|
256
|
+
refreshPolling() {
|
|
257
|
+
// First stop any existing polling
|
|
258
|
+
this.stopPolling();
|
|
259
|
+
if (this.useMockData) {
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
// We'll determine whether to use authenticated polling in the polling task
|
|
263
|
+
this.pollingTask = {
|
|
264
|
+
stop: () => {
|
|
265
|
+
// This will be replaced when actual polling starts
|
|
266
|
+
},
|
|
267
|
+
};
|
|
268
|
+
// Start the poll loop
|
|
269
|
+
this.pollWithInterval();
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Get user credentials from delegate
|
|
273
|
+
*/
|
|
274
|
+
async getUserCredentials() {
|
|
275
|
+
const swid = (await this.delegate.getUserSWID()) || '';
|
|
276
|
+
const jwt = (await this.delegate.getUserToken()) || '';
|
|
277
|
+
return { swid, jwt };
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* @description Update polling interval checking either response header or panel config.
|
|
281
|
+
* Refresh polling if necessary.
|
|
282
|
+
*/
|
|
283
|
+
updatePollingInterval(headers) {
|
|
284
|
+
const headerInterval = this.getResponseHeaderPollingIntervalValue(headers);
|
|
285
|
+
const panelConfigInterval = this.getPanelConfigInterval();
|
|
286
|
+
const newInterval = headerInterval || panelConfigInterval; // order matters here
|
|
287
|
+
if (newInterval && newInterval !== this.pollingInterval) {
|
|
288
|
+
this.pollingInterval = newInterval;
|
|
289
|
+
console.log(`[BET] Updating polling interval to ${this.pollingInterval} milliseconds`);
|
|
290
|
+
// If we have an active polling task, restart it with the new interval
|
|
291
|
+
this.refreshPolling();
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
getPanelConfigInterval() {
|
|
295
|
+
const config = SDK.getPageConfig();
|
|
296
|
+
const panel = config?.panels?.find((p) => p.panel_type === 'espnBet');
|
|
297
|
+
if (!panel) {
|
|
298
|
+
return null;
|
|
299
|
+
}
|
|
300
|
+
const oddsPollingInterval = panel.renderer?.block_data?.odds_polling_interval;
|
|
301
|
+
if (!oddsPollingInterval) {
|
|
302
|
+
return null;
|
|
303
|
+
}
|
|
304
|
+
const parsedInterval = parseInt(oddsPollingInterval, 10);
|
|
305
|
+
if (isNaN(parsedInterval) || parsedInterval <= 0) {
|
|
306
|
+
console.warn(`[BET] Invalid polling interval from panel config: ${oddsPollingInterval}.`);
|
|
307
|
+
return null;
|
|
308
|
+
}
|
|
309
|
+
return parsedInterval * 1000; // Convert seconds to milliseconds
|
|
310
|
+
}
|
|
311
|
+
getResponseHeaderPollingIntervalValue(headers) {
|
|
312
|
+
const newInterval = headers['polling-interval'];
|
|
313
|
+
if (!newInterval) {
|
|
314
|
+
return null;
|
|
315
|
+
}
|
|
316
|
+
const parsedInterval = parseInt(newInterval, 10);
|
|
317
|
+
if (isNaN(parsedInterval) || parsedInterval <= 0) {
|
|
318
|
+
console.warn(`[BET] Invalid polling interval header received: ${newInterval}.`);
|
|
319
|
+
return null;
|
|
320
|
+
}
|
|
321
|
+
return parsedInterval * 1000; // Convert seconds to milliseconds
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Poll with the personalized endpoint for both authenticated and anonymous users
|
|
325
|
+
*
|
|
326
|
+
* SWID format is provided by the client app delegate:
|
|
327
|
+
* - Logged in: {6D201B58-440C-47A6-970B-0F8C78C0BAB8} (with curly braces)
|
|
328
|
+
* - Anonymous: 6D201B58-440C-47A6-970B-0F8C78C0BAB8 (without curly braces)
|
|
329
|
+
* - Failsafe: Empty string if local storage fails
|
|
330
|
+
*/
|
|
331
|
+
async pollWithInterval() {
|
|
332
|
+
try {
|
|
333
|
+
// Always use personalized endpoint
|
|
334
|
+
const { swid, jwt } = await this.getUserCredentials();
|
|
335
|
+
// Start personalized polling for both authenticated and anonymous users with headers
|
|
336
|
+
this.pollingTask = this.betsService.pollPersonalizedBetsWithHeaders(this.eventId, swid, jwt, this.pollingInterval, (response) => {
|
|
337
|
+
this.updatePollingInterval(response.headers);
|
|
338
|
+
this.processPolledData(response.data);
|
|
339
|
+
}, this.handlePollingError.bind(this));
|
|
340
|
+
}
|
|
341
|
+
catch (error) {
|
|
342
|
+
captureException(error, {
|
|
343
|
+
context: 'BetsViewModel.pollWithInterval',
|
|
344
|
+
});
|
|
345
|
+
console.error('[BET] Error setting up polling:', error);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Process data received from polling
|
|
350
|
+
*/
|
|
351
|
+
processPolledData(data) {
|
|
352
|
+
// Calculate hash for the response to check if it's different from the last one
|
|
353
|
+
const responseHash = stringHashCode(JSON.stringify(data));
|
|
354
|
+
const isPersonalized = isPersonalizedBetsResponse(data);
|
|
355
|
+
if (isPersonalized) {
|
|
356
|
+
// Check if this is the same as the last successful response
|
|
357
|
+
if (this.lastPersonalizedResponseHash === responseHash &&
|
|
358
|
+
this.hasEverSuccessfullyLoaded.value) {
|
|
359
|
+
console.log('[BET] Response hash is the same as last successful response - skipping update');
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
// Update tracking variables
|
|
363
|
+
this.lastPersonalizedResponseHash = responseHash;
|
|
364
|
+
// this.lastSuccessfulResponsePersonalized =
|
|
365
|
+
// data as IPersonalizedBetsResponse;
|
|
366
|
+
}
|
|
367
|
+
else {
|
|
368
|
+
// Check if this is the same as the last successful response
|
|
369
|
+
if (this.lastNonPersonalizedResponseHash === responseHash &&
|
|
370
|
+
this.hasEverSuccessfullyLoaded.value) {
|
|
371
|
+
console.log('[BET] Response hash is the same as last successful response - skipping update');
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
// Update tracking variables
|
|
375
|
+
this.lastNonPersonalizedResponseHash = responseHash;
|
|
376
|
+
// this.lastSuccessfulResponseNonPersonalized = data as IBetsResponse;
|
|
377
|
+
}
|
|
378
|
+
// Update state
|
|
379
|
+
this.hasEverSuccessfullyLoaded.value = true;
|
|
380
|
+
this.errorState.value = 'none';
|
|
381
|
+
// Process the response and update betsItems
|
|
382
|
+
// This is a placeholder - you would need to implement the actual logic
|
|
383
|
+
// for parsing different parts of the response (sixPacks, hot props, etc.)
|
|
384
|
+
this.processBetsData(data);
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Process the bets data and update the betsItems
|
|
388
|
+
*/
|
|
389
|
+
processBetsData(data) {
|
|
390
|
+
// Clear current items
|
|
391
|
+
const newItems = [];
|
|
392
|
+
if (!Object.keys(data).length) {
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
// 1. Process regular odds (always available in both response types)
|
|
396
|
+
const sixPack = this.processSixPackData(data);
|
|
397
|
+
if (sixPack) {
|
|
398
|
+
newItems.push(sixPack);
|
|
399
|
+
}
|
|
400
|
+
// 2. Process location disclaimer if this is a personalized response
|
|
401
|
+
const locationDisclaimer = this.processLocationDisclaimer(data);
|
|
402
|
+
if (locationDisclaimer) {
|
|
403
|
+
newItems.push(locationDisclaimer);
|
|
404
|
+
}
|
|
405
|
+
// 3. Process user bets if this is a personalized response
|
|
406
|
+
const userBets = this.processUserBetsData(data);
|
|
407
|
+
if (userBets) {
|
|
408
|
+
newItems.push(userBets);
|
|
409
|
+
}
|
|
410
|
+
// 4. Process featured(hot props) bets if available
|
|
411
|
+
const hotProps = this.processHotProps(data);
|
|
412
|
+
if (hotProps) {
|
|
413
|
+
newItems.push(hotProps);
|
|
414
|
+
}
|
|
415
|
+
// 5. Process promo code
|
|
416
|
+
const promoCode = this.processPromoCode(data);
|
|
417
|
+
if (promoCode) {
|
|
418
|
+
newItems.push(promoCode);
|
|
419
|
+
}
|
|
420
|
+
// 6. Process gambling message if available
|
|
421
|
+
const gamblingMessage = this.processGamblingMessage(data);
|
|
422
|
+
if (gamblingMessage) {
|
|
423
|
+
newItems.push(gamblingMessage);
|
|
424
|
+
}
|
|
425
|
+
// Update the observable
|
|
426
|
+
this.betsItems.value = newItems;
|
|
427
|
+
}
|
|
428
|
+
processLocationDisclaimer(data) {
|
|
429
|
+
const isPersonalized = isPersonalizedBetsResponse(data);
|
|
430
|
+
if (!isPersonalized || !data.disclaimers?.location) {
|
|
431
|
+
return null;
|
|
432
|
+
}
|
|
433
|
+
return {
|
|
434
|
+
type: 'locationDisclaimer',
|
|
435
|
+
id: 'locationDisclaimer',
|
|
436
|
+
data: {
|
|
437
|
+
text: data.disclaimers.location,
|
|
438
|
+
},
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
processPromoCode(data) {
|
|
442
|
+
const isPersonalized = isPersonalizedBetsResponse(data);
|
|
443
|
+
if (!isPersonalized || !data.promotion) {
|
|
444
|
+
return null;
|
|
445
|
+
}
|
|
446
|
+
return {
|
|
447
|
+
type: 'promo',
|
|
448
|
+
data: {
|
|
449
|
+
title: data.promotion.title || '',
|
|
450
|
+
description: data.promotion.description || '',
|
|
451
|
+
logo: data.promotion.logo || '',
|
|
452
|
+
qrCode: data.promotion.qrCode || '',
|
|
453
|
+
backgroundImage: data.promotion.backgroundImage || '',
|
|
454
|
+
},
|
|
455
|
+
id: `promo-${data.event?.id || data.id}`,
|
|
456
|
+
};
|
|
457
|
+
}
|
|
458
|
+
processGamblingMessage(data) {
|
|
459
|
+
const isPersonalized = isPersonalizedBetsResponse(data);
|
|
460
|
+
if (!isPersonalized || !data.disclaimers?.gambling) {
|
|
461
|
+
return null;
|
|
462
|
+
}
|
|
463
|
+
return {
|
|
464
|
+
type: 'gamblingMessage',
|
|
465
|
+
id: 'gamblingMessage',
|
|
466
|
+
data: {
|
|
467
|
+
text: data.disclaimers.gambling,
|
|
468
|
+
},
|
|
469
|
+
};
|
|
470
|
+
}
|
|
471
|
+
processSixPackData(response) {
|
|
472
|
+
const isPersonalized = isPersonalizedBetsResponse(response);
|
|
473
|
+
const teams = response.entities?.teams;
|
|
474
|
+
const odds = !isPersonalized
|
|
475
|
+
? response.bets?.odds
|
|
476
|
+
: response.event?.bets?.odds;
|
|
477
|
+
const gameState = !isPersonalized
|
|
478
|
+
? response.gameState
|
|
479
|
+
: response.event?.gameState;
|
|
480
|
+
const sport = !isPersonalized ? response.sport : response.event?.sport;
|
|
481
|
+
const eventId = !isPersonalized ? response.id : response.event?.id;
|
|
482
|
+
const isSoccer = !isPersonalized
|
|
483
|
+
? response.sport === 'soccer'
|
|
484
|
+
: response.event?.sport === 'soccer';
|
|
485
|
+
if (!odds || !gameState || !sport || !eventId || !teams) {
|
|
486
|
+
return null;
|
|
487
|
+
}
|
|
488
|
+
const teamArray = Object.values(teams);
|
|
489
|
+
let awayTeam;
|
|
490
|
+
let homeTeam;
|
|
491
|
+
// Find home and away teams from odds
|
|
492
|
+
for (const team of Object.values(teams)) {
|
|
493
|
+
const spreadOdds = odds.find((odd) => odd.type === 'pointSpread');
|
|
494
|
+
if (spreadOdds) {
|
|
495
|
+
if (spreadOdds.values.some((v) => v.team === team.id && v.type === 'home')) {
|
|
496
|
+
homeTeam = team;
|
|
497
|
+
}
|
|
498
|
+
else if (spreadOdds.values.some((v) => v.team === team.id && v.type === 'away')) {
|
|
499
|
+
awayTeam = team;
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
// Fallback logic if we couldn't determine from odds
|
|
504
|
+
if (!homeTeam || !awayTeam) {
|
|
505
|
+
console.warn('Could not determine home/away teams from odds, using first two teams');
|
|
506
|
+
switch (teamArray.length) {
|
|
507
|
+
case 0:
|
|
508
|
+
throw new Error('No teams found in response');
|
|
509
|
+
case 1:
|
|
510
|
+
// Only one team - unusual case, but handle gracefully
|
|
511
|
+
homeTeam = teamArray[0];
|
|
512
|
+
awayTeam = teamArray[0]; // Same team as both home and away (shouldn't happen)
|
|
513
|
+
break;
|
|
514
|
+
case 2:
|
|
515
|
+
// Default to first team as home, second as away
|
|
516
|
+
homeTeam = teamArray[0];
|
|
517
|
+
awayTeam = teamArray[1];
|
|
518
|
+
break;
|
|
519
|
+
default:
|
|
520
|
+
// More than 2 teams - take first two and log warning
|
|
521
|
+
homeTeam = teamArray[0];
|
|
522
|
+
awayTeam = teamArray[1];
|
|
523
|
+
console.warn(`Warning: Unexpected team count (${teamArray.length}) in six pack response`);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
if (!awayTeam || !homeTeam) {
|
|
527
|
+
throw new Error('Could not determine home or away team from response');
|
|
528
|
+
}
|
|
529
|
+
const isInProgress = gameState === 'in';
|
|
530
|
+
const isHomeFavoured = (() => {
|
|
531
|
+
if (isSoccer && !isInProgress) {
|
|
532
|
+
return homeTeam.favoredAtOpen ?? true;
|
|
533
|
+
}
|
|
534
|
+
return homeTeam.favored ?? true;
|
|
535
|
+
})();
|
|
536
|
+
const isAwayFavoured = (() => {
|
|
537
|
+
if (isSoccer && !isInProgress) {
|
|
538
|
+
return awayTeam.favoredAtOpen ?? false;
|
|
539
|
+
}
|
|
540
|
+
return awayTeam.favored ?? false;
|
|
541
|
+
})();
|
|
542
|
+
let awayTeamStartGameFirstLine = '';
|
|
543
|
+
let awayTeamStartGameSecondLine = '';
|
|
544
|
+
let homeTeamStartGameFirstLine = '';
|
|
545
|
+
let homeTeamStartGameSecondLine = '';
|
|
546
|
+
let awaySpreadFirstLine = '';
|
|
547
|
+
let awaySpreadSecondLine = '';
|
|
548
|
+
let homeSpreadFirstLine = '';
|
|
549
|
+
let homeSpreadSecondLine = '';
|
|
550
|
+
let awayTotalFirstLine = '';
|
|
551
|
+
let awayTotalSecondLine = '';
|
|
552
|
+
let homeTotalFirstLine = '';
|
|
553
|
+
let homeTotalSecondLine = '';
|
|
554
|
+
let awayMoneylineFirstLine = '';
|
|
555
|
+
let homeMoneylineFirstLine = '';
|
|
556
|
+
let drawGameStateFirstLine = '';
|
|
557
|
+
let drawGameStateSecondLine = '';
|
|
558
|
+
let drawMoneylineFirstLine = '';
|
|
559
|
+
const itemTypeSet = new Set();
|
|
560
|
+
const orderedColumns = [];
|
|
561
|
+
for (const oddsItem of odds) {
|
|
562
|
+
if (!itemTypeSet.has(oddsItem.type)) {
|
|
563
|
+
orderedColumns.push({
|
|
564
|
+
type: oddsItem.type,
|
|
565
|
+
abbreviation: oddsItem.abbreviation,
|
|
566
|
+
});
|
|
567
|
+
itemTypeSet.add(oddsItem.type);
|
|
568
|
+
}
|
|
569
|
+
const isLive = oddsItem.state === 'live';
|
|
570
|
+
const isClose = oddsItem.state === 'close';
|
|
571
|
+
const isOpen = oddsItem.state === 'open';
|
|
572
|
+
// For every odd type and using the correct state based on game state, get the odds and lines for the home and away team.
|
|
573
|
+
// There are special handlings for the 'start of game' lines. It can be from 'spread', 'total' or 'moneyline' depending on which team is favoured, sport, etc.
|
|
574
|
+
switch (oddsItem.type) {
|
|
575
|
+
case 'pointSpread': {
|
|
576
|
+
const spreadCorrectState = isInProgress ? isLive : isClose;
|
|
577
|
+
if (spreadCorrectState) {
|
|
578
|
+
for (const value of oddsItem.values) {
|
|
579
|
+
if (value.type === 'home') {
|
|
580
|
+
homeSpreadFirstLine = value.line ?? '';
|
|
581
|
+
homeSpreadSecondLine = value.odds ?? '';
|
|
582
|
+
}
|
|
583
|
+
if (value.type === 'away') {
|
|
584
|
+
awaySpreadFirstLine = value.line ?? '';
|
|
585
|
+
awaySpreadSecondLine = value.odds ?? '';
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
const pointsSpreadStartOfGameCorrectState = isInProgress
|
|
590
|
+
? isClose
|
|
591
|
+
: isOpen;
|
|
592
|
+
if (pointsSpreadStartOfGameCorrectState && !isSoccer) {
|
|
593
|
+
if (isHomeFavoured) {
|
|
594
|
+
for (const value of oddsItem.values) {
|
|
595
|
+
if (value.type === 'home') {
|
|
596
|
+
homeTeamStartGameFirstLine = value.line ?? '';
|
|
597
|
+
homeTeamStartGameSecondLine = value.odds ?? '';
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
if (isAwayFavoured) {
|
|
602
|
+
for (const value of oddsItem.values) {
|
|
603
|
+
if (value.type === 'away') {
|
|
604
|
+
awayTeamStartGameFirstLine = value.line ?? '';
|
|
605
|
+
awayTeamStartGameSecondLine = value.odds ?? '';
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
break;
|
|
611
|
+
}
|
|
612
|
+
case 'total': {
|
|
613
|
+
const totalCorrectState = isInProgress ? isLive : isClose;
|
|
614
|
+
if (totalCorrectState) {
|
|
615
|
+
for (const value of oddsItem.values) {
|
|
616
|
+
if (value.type === 'over') {
|
|
617
|
+
if (isSoccer) {
|
|
618
|
+
homeTotalFirstLine = value.line ?? '';
|
|
619
|
+
homeTotalSecondLine = value.odds ?? '';
|
|
620
|
+
}
|
|
621
|
+
else {
|
|
622
|
+
awayTotalFirstLine = value.line ?? '';
|
|
623
|
+
awayTotalSecondLine = value.odds ?? '';
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
if (value.type === 'under') {
|
|
627
|
+
if (isSoccer) {
|
|
628
|
+
awayTotalFirstLine = value.line ?? '';
|
|
629
|
+
awayTotalSecondLine = value.odds ?? '';
|
|
630
|
+
}
|
|
631
|
+
else {
|
|
632
|
+
homeTotalFirstLine = value.line ?? '';
|
|
633
|
+
homeTotalSecondLine = value.odds ?? '';
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
const totalStartOfGameCorrectState = isInProgress ? isClose : isOpen;
|
|
639
|
+
if (totalStartOfGameCorrectState) {
|
|
640
|
+
// If home is not favoured, use total as the start of the game line
|
|
641
|
+
if (!isHomeFavoured) {
|
|
642
|
+
for (const value of oddsItem.values) {
|
|
643
|
+
if ((isSoccer && value.type === 'over') ||
|
|
644
|
+
(!isSoccer && value.type === 'under')) {
|
|
645
|
+
homeTeamStartGameFirstLine = value.line ?? '';
|
|
646
|
+
homeTeamStartGameSecondLine = value.odds ?? '';
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
// If away is not favoured, use total as the start of the game line
|
|
651
|
+
if (!isAwayFavoured) {
|
|
652
|
+
for (const value of oddsItem.values) {
|
|
653
|
+
if ((isSoccer && value.type === 'under') ||
|
|
654
|
+
(!isSoccer && value.type === 'over')) {
|
|
655
|
+
awayTeamStartGameFirstLine = value.line ?? '';
|
|
656
|
+
awayTeamStartGameSecondLine = value.odds ?? '';
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
break;
|
|
662
|
+
}
|
|
663
|
+
case 'moneyline': {
|
|
664
|
+
const mlCorrectState = isInProgress ? isLive : isClose;
|
|
665
|
+
if (mlCorrectState) {
|
|
666
|
+
for (const value of oddsItem.values) {
|
|
667
|
+
if (value.type === 'home') {
|
|
668
|
+
homeMoneylineFirstLine = value.odds ?? '';
|
|
669
|
+
}
|
|
670
|
+
if (value.type === 'away') {
|
|
671
|
+
awayMoneylineFirstLine = value.odds ?? '';
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
// soccer logic
|
|
676
|
+
if (isSoccer) {
|
|
677
|
+
const moneyLineStartOfGameCorrectState = isInProgress
|
|
678
|
+
? isClose
|
|
679
|
+
: isOpen;
|
|
680
|
+
// find draw value
|
|
681
|
+
for (const value of oddsItem.values) {
|
|
682
|
+
if (value.type === 'draw') {
|
|
683
|
+
if (moneyLineStartOfGameCorrectState) {
|
|
684
|
+
drawGameStateFirstLine = value.odds ?? '';
|
|
685
|
+
drawGameStateSecondLine = 'DRAW';
|
|
686
|
+
}
|
|
687
|
+
if (mlCorrectState) {
|
|
688
|
+
drawMoneylineFirstLine = value.odds ?? '';
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
if (moneyLineStartOfGameCorrectState) {
|
|
693
|
+
if (isHomeFavoured) {
|
|
694
|
+
for (const value of oddsItem.values) {
|
|
695
|
+
if (value.type === 'home') {
|
|
696
|
+
homeTeamStartGameFirstLine = value.odds ?? '';
|
|
697
|
+
homeTeamStartGameSecondLine = oddsItem.abbreviation ?? '';
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
if (isAwayFavoured) {
|
|
702
|
+
for (const value of oddsItem.values) {
|
|
703
|
+
if (value.type === 'away') {
|
|
704
|
+
awayTeamStartGameFirstLine = value.odds ?? '';
|
|
705
|
+
awayTeamStartGameSecondLine = oddsItem.abbreviation ?? '';
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
break;
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
// Create the six pack data structure
|
|
716
|
+
const awayTeamOdds = {
|
|
717
|
+
teamAbbreviation: awayTeam.abbreviation ?? '',
|
|
718
|
+
startOfGameFirstLine: awayTeamStartGameFirstLine,
|
|
719
|
+
startOfGameSecondLine: awayTeamStartGameSecondLine,
|
|
720
|
+
gameSpreadFirstLine: awaySpreadFirstLine,
|
|
721
|
+
gameSpreadSecondLine: awaySpreadSecondLine,
|
|
722
|
+
totalPointsFirstLine: awayTotalFirstLine,
|
|
723
|
+
totalPointsSecondLine: awayTotalSecondLine,
|
|
724
|
+
moneylineFirstLine: awayMoneylineFirstLine,
|
|
725
|
+
};
|
|
726
|
+
const homeTeamOdds = {
|
|
727
|
+
teamAbbreviation: homeTeam.abbreviation ?? '',
|
|
728
|
+
startOfGameFirstLine: homeTeamStartGameFirstLine,
|
|
729
|
+
startOfGameSecondLine: homeTeamStartGameSecondLine,
|
|
730
|
+
gameSpreadFirstLine: homeSpreadFirstLine,
|
|
731
|
+
gameSpreadSecondLine: homeSpreadSecondLine,
|
|
732
|
+
totalPointsFirstLine: homeTotalFirstLine,
|
|
733
|
+
totalPointsSecondLine: homeTotalSecondLine,
|
|
734
|
+
moneylineFirstLine: homeMoneylineFirstLine,
|
|
735
|
+
};
|
|
736
|
+
const drawOdds = {
|
|
737
|
+
teamAbbreviation: 'DRAW',
|
|
738
|
+
startOfGameFirstLine: drawGameStateFirstLine,
|
|
739
|
+
startOfGameSecondLine: drawGameStateSecondLine,
|
|
740
|
+
gameSpreadFirstLine: '',
|
|
741
|
+
gameSpreadSecondLine: '',
|
|
742
|
+
totalPointsFirstLine: '',
|
|
743
|
+
totalPointsSecondLine: '',
|
|
744
|
+
moneylineFirstLine: drawMoneylineFirstLine,
|
|
745
|
+
};
|
|
746
|
+
const sixPack = {
|
|
747
|
+
topTeamOdds: isSoccer ? homeTeamOdds : awayTeamOdds,
|
|
748
|
+
bottomTeamOdds: isSoccer ? awayTeamOdds : homeTeamOdds,
|
|
749
|
+
drawOdds: drawGameStateFirstLine &&
|
|
750
|
+
drawGameStateSecondLine &&
|
|
751
|
+
drawMoneylineFirstLine
|
|
752
|
+
? drawOdds
|
|
753
|
+
: undefined,
|
|
754
|
+
orderedColumns,
|
|
755
|
+
gameState,
|
|
756
|
+
};
|
|
757
|
+
return {
|
|
758
|
+
id: `sixpack-${eventId}`,
|
|
759
|
+
type: 'sixPack',
|
|
760
|
+
data: sixPack,
|
|
761
|
+
teamInfo: {
|
|
762
|
+
home: homeTeam,
|
|
763
|
+
away: awayTeam,
|
|
764
|
+
},
|
|
765
|
+
hideWagers: this.hideWagers.value,
|
|
766
|
+
};
|
|
767
|
+
}
|
|
768
|
+
processUserBetsData(data) {
|
|
769
|
+
const isPersonalized = isPersonalizedBetsResponse(data);
|
|
770
|
+
if (!isPersonalized || !data.event || !data.betsModule) {
|
|
771
|
+
return null;
|
|
772
|
+
}
|
|
773
|
+
const betItems = {
|
|
774
|
+
live: data.betsModule.live.filter((bet) => bet.type !== 'promo'),
|
|
775
|
+
settled: data.betsModule.settled.filter((bet) => bet.type !== 'promo'),
|
|
776
|
+
upcoming: data.betsModule.upcoming.filter((bet) => bet.type !== 'promo'),
|
|
777
|
+
};
|
|
778
|
+
return {
|
|
779
|
+
data: {
|
|
780
|
+
bets: betItems,
|
|
781
|
+
defaultTab: data.betsModule.defaultTab,
|
|
782
|
+
},
|
|
783
|
+
id: `userBets-${data.event.id}`,
|
|
784
|
+
type: 'userBets',
|
|
785
|
+
hideWagers: this.hideWagers.value,
|
|
786
|
+
};
|
|
787
|
+
}
|
|
788
|
+
processHotProps(response) {
|
|
789
|
+
const isPersonalized = isPersonalizedBetsResponse(response);
|
|
790
|
+
const hotProps = isPersonalized
|
|
791
|
+
? response.event?.featured
|
|
792
|
+
: response.featured;
|
|
793
|
+
if (!hotProps || !Array.isArray(hotProps)) {
|
|
794
|
+
return null;
|
|
795
|
+
}
|
|
796
|
+
const hasData = hotProps.every((hotProp) => Boolean(hotProp && hotProp.id));
|
|
797
|
+
if (!hasData) {
|
|
798
|
+
return null;
|
|
799
|
+
}
|
|
800
|
+
const filteredHotProps = hotProps.filter((hotProp) => hotProp.selections.length > 0);
|
|
801
|
+
return {
|
|
802
|
+
type: 'hotProps',
|
|
803
|
+
hideWagers: this.hideWagers.value,
|
|
804
|
+
id: 'hotProps',
|
|
805
|
+
data: {
|
|
806
|
+
items: filteredHotProps.map((hotProp) => {
|
|
807
|
+
const bet = hotProp.selections[0];
|
|
808
|
+
return {
|
|
809
|
+
id: bet.id,
|
|
810
|
+
odds: bet.odds.current || '',
|
|
811
|
+
marketText: bet.text,
|
|
812
|
+
selectionText: hotProp.text,
|
|
813
|
+
status: bet.status,
|
|
814
|
+
type: bet.type,
|
|
815
|
+
icon: bet.icon,
|
|
816
|
+
iconDark: bet.iconDark,
|
|
817
|
+
outcome: bet.outcome,
|
|
818
|
+
};
|
|
819
|
+
}),
|
|
820
|
+
},
|
|
821
|
+
};
|
|
822
|
+
}
|
|
823
|
+
/**
|
|
824
|
+
* Handle errors that occur during polling
|
|
825
|
+
*/
|
|
826
|
+
handlePollingError(error) {
|
|
827
|
+
console.error('Polling error:', error);
|
|
828
|
+
if (!this.hasEverSuccessfullyLoaded.value) {
|
|
829
|
+
// If we've never had a successful load, show an error state
|
|
830
|
+
this.errorState.value = 'tabLoadFailure';
|
|
831
|
+
this.betsItems.value = [];
|
|
832
|
+
}
|
|
833
|
+
else {
|
|
834
|
+
// If we had a previous successful load, keep showing the old data
|
|
835
|
+
// No need to update errorState or betsItems
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
/**
|
|
839
|
+
* Stop polling for bet data
|
|
840
|
+
*/
|
|
841
|
+
stopPolling() {
|
|
842
|
+
if (this.pollingTask) {
|
|
843
|
+
this.pollingTask.stop();
|
|
844
|
+
this.pollingTask = null;
|
|
845
|
+
}
|
|
846
|
+
if (this.isDataLoading.value) {
|
|
847
|
+
this.isDataLoading.value = false;
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
/**
|
|
851
|
+
* Fetch new bet data immediately (one-time)
|
|
852
|
+
*/
|
|
853
|
+
async fetchNewData() {
|
|
854
|
+
this.isDataLoading.value = true;
|
|
855
|
+
try {
|
|
856
|
+
// Handle mock data if enabled
|
|
857
|
+
if (this.useMockData) {
|
|
858
|
+
this.betsItems.value = [];
|
|
859
|
+
await this.fetchMockData();
|
|
860
|
+
return;
|
|
861
|
+
}
|
|
862
|
+
// Always use personalized endpoint for both authenticated and anonymous users
|
|
863
|
+
await this.fetchPersonalizedData();
|
|
864
|
+
this.isDataLoading.value = false;
|
|
865
|
+
}
|
|
866
|
+
catch (error) {
|
|
867
|
+
captureException(error, {
|
|
868
|
+
context: 'BetsViewModel.fetchNewData',
|
|
869
|
+
});
|
|
870
|
+
console.error('[BET] Error fetching bet data:', error);
|
|
871
|
+
if (!this.hasEverSuccessfullyLoaded.value) {
|
|
872
|
+
this.errorState.value = 'tabLoadFailure';
|
|
873
|
+
this.betsItems.value = [];
|
|
874
|
+
}
|
|
875
|
+
this.isDataLoading.value = false;
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
/**
|
|
879
|
+
* Fetch personalized bet data
|
|
880
|
+
*/
|
|
881
|
+
async fetchPersonalizedData() {
|
|
882
|
+
try {
|
|
883
|
+
const { swid, jwt } = await this.getUserCredentials();
|
|
884
|
+
const response = await this.betsService.getPersonalizedBets(this.eventId, swid, jwt);
|
|
885
|
+
// Process the response
|
|
886
|
+
this.processPolledData(response);
|
|
887
|
+
}
|
|
888
|
+
catch (error) {
|
|
889
|
+
captureException(error, {
|
|
890
|
+
context: 'BetsViewModel.fetchPersonalizedData',
|
|
891
|
+
});
|
|
892
|
+
console.error('[BET] Error fetching personalized bets:', error);
|
|
893
|
+
throw error;
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
/**
|
|
897
|
+
* Fetch mock data for testing
|
|
898
|
+
*/
|
|
899
|
+
async fetchMockData() {
|
|
900
|
+
this.processBetsData(MOCK_BETS_API_RESPONSE);
|
|
901
|
+
this.hasEverSuccessfullyLoaded.value = true;
|
|
902
|
+
this.errorState.value = 'none';
|
|
903
|
+
this.isDataLoading.value = false;
|
|
904
|
+
}
|
|
905
|
+
simulateUseCase(useCase, _) {
|
|
906
|
+
switch (useCase) {
|
|
907
|
+
case 'betsTabLoadFailure':
|
|
908
|
+
this.errorState.value = 'tabLoadFailure';
|
|
909
|
+
break;
|
|
910
|
+
case 'betsMockData':
|
|
911
|
+
this.stopPolling();
|
|
912
|
+
this.useMockData = true;
|
|
913
|
+
this.lastPersonalizedResponseHash = null;
|
|
914
|
+
this.lastNonPersonalizedResponseHash = null;
|
|
915
|
+
this.errorState.value = 'none';
|
|
916
|
+
this.fetchNewData();
|
|
917
|
+
break;
|
|
918
|
+
case 'betsLiveData':
|
|
919
|
+
this.useMockData = false;
|
|
920
|
+
this.lastPersonalizedResponseHash = null;
|
|
921
|
+
this.lastNonPersonalizedResponseHash = null;
|
|
922
|
+
this.hasEverSuccessfullyLoaded.value = false;
|
|
923
|
+
this.errorState.value = 'none';
|
|
924
|
+
this.fetchNewData();
|
|
925
|
+
this.refreshPolling();
|
|
926
|
+
break;
|
|
927
|
+
default:
|
|
928
|
+
throw new Error(`Unsupported use case: ${useCase}`);
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
clearTabLoadFailure() {
|
|
932
|
+
this.errorState.value = 'none';
|
|
933
|
+
setTimeout(() => {
|
|
934
|
+
this.refreshPolling();
|
|
935
|
+
}, 100);
|
|
936
|
+
}
|
|
937
|
+
/**
|
|
938
|
+
* Check if wagers should be hidden based on user settings
|
|
939
|
+
*/
|
|
940
|
+
shouldHideWagers() {
|
|
941
|
+
return this.hideWagers.value;
|
|
942
|
+
}
|
|
943
|
+
/**
|
|
944
|
+
* Update hideWagers Observable from current settings
|
|
945
|
+
*/
|
|
946
|
+
updateHideWagersFromSettings() {
|
|
947
|
+
this.hideWagers.value = this.userSettingsManager.shouldHideWagers();
|
|
948
|
+
this.refreshBetItemsWithNewSettings();
|
|
949
|
+
}
|
|
950
|
+
refreshBetItemsWithNewSettings() {
|
|
951
|
+
this.betsItems.value = this.betsItems.value.map((item) => {
|
|
952
|
+
if (item.type === 'sixPack') {
|
|
953
|
+
return {
|
|
954
|
+
...item,
|
|
955
|
+
hideWagers: this.hideWagers.value,
|
|
956
|
+
};
|
|
957
|
+
}
|
|
958
|
+
if (item.type === 'userBets') {
|
|
959
|
+
return {
|
|
960
|
+
...item,
|
|
961
|
+
hideWagers: this.hideWagers.value,
|
|
962
|
+
};
|
|
963
|
+
}
|
|
964
|
+
if (item.type === 'hotProps') {
|
|
965
|
+
return {
|
|
966
|
+
...item,
|
|
967
|
+
hideWagers: this.hideWagers.value,
|
|
968
|
+
};
|
|
969
|
+
}
|
|
970
|
+
return item;
|
|
971
|
+
});
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
export default BetsViewModel;
|