@sensiblestats/widget-react 0.36.0 → 0.37.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/CHANGELOG.md +17 -0
- package/dist/index.cjs +281 -134
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +281 -134
- package/dist/index.js.map +1 -1
- package/dist/styles.css +21 -3
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -120,7 +120,10 @@ var STRINGS = {
|
|
|
120
120
|
fullTimeLabel: "Full time",
|
|
121
121
|
inSlipLabel: "In slip",
|
|
122
122
|
oddsUnavailable: "Odds unavailable right now",
|
|
123
|
-
momentumLabel: "Momentum"
|
|
123
|
+
momentumLabel: "Momentum",
|
|
124
|
+
accordionValueLabel: "Value",
|
|
125
|
+
accordionRetry: "Couldn't load odds \u2014 tap to retry",
|
|
126
|
+
accordionSuspended: "Suspended"
|
|
124
127
|
},
|
|
125
128
|
tr: {
|
|
126
129
|
launcherLabel: "SensibleStats ile sohbet et",
|
|
@@ -189,7 +192,10 @@ var STRINGS = {
|
|
|
189
192
|
fullTimeLabel: "Ma\xE7 sonu",
|
|
190
193
|
inSlipLabel: "Kuponda",
|
|
191
194
|
oddsUnavailable: "Oranlar \u015Fu anda kullan\u0131lam\u0131yor",
|
|
192
|
-
momentumLabel: "Momentum"
|
|
195
|
+
momentumLabel: "Momentum",
|
|
196
|
+
accordionValueLabel: "De\u011Fer",
|
|
197
|
+
accordionRetry: "Oranlar y\xFCklenemedi \u2014 yeniden dene",
|
|
198
|
+
accordionSuspended: "Ask\u0131da"
|
|
193
199
|
}
|
|
194
200
|
};
|
|
195
201
|
function resolveLocaleStrings(locale) {
|
|
@@ -277,7 +283,10 @@ function normalizeUi(cfg) {
|
|
|
277
283
|
fullTimeLabel: strings.fullTimeLabel,
|
|
278
284
|
inSlipLabel: strings.inSlipLabel,
|
|
279
285
|
oddsUnavailable: strings.oddsUnavailable,
|
|
280
|
-
momentumLabel: strings.momentumLabel
|
|
286
|
+
momentumLabel: strings.momentumLabel,
|
|
287
|
+
accordionValueLabel: strings.accordionValueLabel,
|
|
288
|
+
accordionRetry: strings.accordionRetry,
|
|
289
|
+
accordionSuspended: strings.accordionSuspended
|
|
281
290
|
};
|
|
282
291
|
}
|
|
283
292
|
function toClientOptions(cfg) {
|
|
@@ -1031,6 +1040,8 @@ function useLiveMonitor(opts) {
|
|
|
1031
1040
|
const [oddsDot, setOddsDot] = (0, import_react3.useState)(false);
|
|
1032
1041
|
const [lastViewedPrices, setLastViewedPrices] = (0, import_react3.useState)({});
|
|
1033
1042
|
const [inSlip, setInSlip] = (0, import_react3.useState)({});
|
|
1043
|
+
const [openMarket, setOpenMarket] = (0, import_react3.useState)({});
|
|
1044
|
+
const [marketOdds, setMarketOdds] = (0, import_react3.useState)({});
|
|
1034
1045
|
const pinsRef = (0, import_react3.useRef)(pins);
|
|
1035
1046
|
pinsRef.current = pins;
|
|
1036
1047
|
const activeTabRef = (0, import_react3.useRef)(activeTab);
|
|
@@ -1039,6 +1050,46 @@ function useLiveMonitor(opts) {
|
|
|
1039
1050
|
snapshotRef.current = snapshot;
|
|
1040
1051
|
const lastViewedPricesRef = (0, import_react3.useRef)(lastViewedPrices);
|
|
1041
1052
|
lastViewedPricesRef.current = lastViewedPrices;
|
|
1053
|
+
const openMarketRef = (0, import_react3.useRef)(openMarket);
|
|
1054
|
+
openMarketRef.current = openMarket;
|
|
1055
|
+
const marketOddsRef = (0, import_react3.useRef)(marketOdds);
|
|
1056
|
+
marketOddsRef.current = marketOdds;
|
|
1057
|
+
const marketKey = (matchId, dev) => `${matchId}:${dev}`;
|
|
1058
|
+
const getMarketOddsRef = (0, import_react3.useRef)(opts.getMarketOdds);
|
|
1059
|
+
getMarketOddsRef.current = opts.getMarketOdds;
|
|
1060
|
+
const fetchMarket = (0, import_react3.useCallback)((matchId, dev) => {
|
|
1061
|
+
const key = marketKey(matchId, dev);
|
|
1062
|
+
const existing = marketOddsRef.current[key];
|
|
1063
|
+
if (existing?.loading) return;
|
|
1064
|
+
const loadingEntry = { ...existing, loading: true, error: false };
|
|
1065
|
+
marketOddsRef.current = { ...marketOddsRef.current, [key]: loadingEntry };
|
|
1066
|
+
setMarketOdds((prev) => ({ ...prev, [key]: loadingEntry }));
|
|
1067
|
+
const fn = getMarketOddsRef.current;
|
|
1068
|
+
if (!fn) return;
|
|
1069
|
+
void fn(matchId, dev).then((block) => {
|
|
1070
|
+
const entry = { block: block ?? void 0, loading: false, error: false };
|
|
1071
|
+
marketOddsRef.current = { ...marketOddsRef.current, [key]: entry };
|
|
1072
|
+
setMarketOdds((prev) => ({ ...prev, [key]: entry }));
|
|
1073
|
+
}).catch(() => {
|
|
1074
|
+
const entry = { ...marketOddsRef.current[key], loading: false, error: true };
|
|
1075
|
+
marketOddsRef.current = { ...marketOddsRef.current, [key]: entry };
|
|
1076
|
+
setMarketOdds((prev) => ({ ...prev, [key]: entry }));
|
|
1077
|
+
});
|
|
1078
|
+
}, []);
|
|
1079
|
+
const toggleMarket = (0, import_react3.useCallback)((matchId, dev) => {
|
|
1080
|
+
const key = marketKey(matchId, dev);
|
|
1081
|
+
const wasOpen = openMarketRef.current[matchId] === dev;
|
|
1082
|
+
const nextValue = wasOpen ? null : dev;
|
|
1083
|
+
openMarketRef.current = { ...openMarketRef.current, [matchId]: nextValue };
|
|
1084
|
+
setOpenMarket((prev) => ({ ...prev, [matchId]: nextValue }));
|
|
1085
|
+
const existing = marketOddsRef.current[key];
|
|
1086
|
+
if (!wasOpen && !(existing?.loading || existing?.block)) {
|
|
1087
|
+
fetchMarket(matchId, dev);
|
|
1088
|
+
}
|
|
1089
|
+
}, [fetchMarket]);
|
|
1090
|
+
const retryMarket = (0, import_react3.useCallback)((matchId, dev) => {
|
|
1091
|
+
fetchMarket(matchId, dev);
|
|
1092
|
+
}, [fetchMarket]);
|
|
1042
1093
|
const applySnapshot = (0, import_react3.useCallback)((next) => {
|
|
1043
1094
|
if (next === null) {
|
|
1044
1095
|
setEnabled(false);
|
|
@@ -1058,6 +1109,16 @@ function useLiveMonitor(opts) {
|
|
|
1058
1109
|
}
|
|
1059
1110
|
}
|
|
1060
1111
|
if (sawNewGoalOrRed && activeTabRef.current !== "matches") setMatchesDot(true);
|
|
1112
|
+
for (const m of next.matches) {
|
|
1113
|
+
if (!pinnedMatchIds.has(m.matchId)) continue;
|
|
1114
|
+
const first = m.availableMarkets?.[0];
|
|
1115
|
+
if (!first) continue;
|
|
1116
|
+
if (m.matchId in openMarketRef.current) continue;
|
|
1117
|
+
const dev = first.marketDeveloperName;
|
|
1118
|
+
openMarketRef.current = { ...openMarketRef.current, [m.matchId]: dev };
|
|
1119
|
+
setOpenMarket((prevOpen) => ({ ...prevOpen, [m.matchId]: dev }));
|
|
1120
|
+
fetchMarket(m.matchId, dev);
|
|
1121
|
+
}
|
|
1061
1122
|
const marketPins = currentPins.filter((p) => p.kind !== "match");
|
|
1062
1123
|
if (activeTabRef.current === "odds") {
|
|
1063
1124
|
setLastViewedPrices((prevMap) => {
|
|
@@ -1108,12 +1169,17 @@ function useLiveMonitor(opts) {
|
|
|
1108
1169
|
return;
|
|
1109
1170
|
}
|
|
1110
1171
|
applySnapshot(snap);
|
|
1172
|
+
for (const m of snap.matches) {
|
|
1173
|
+
if (m.phase !== "live") continue;
|
|
1174
|
+
const dev = openMarketRef.current[m.matchId];
|
|
1175
|
+
if (dev) fetchMarket(m.matchId, dev);
|
|
1176
|
+
}
|
|
1111
1177
|
} catch {
|
|
1112
1178
|
} finally {
|
|
1113
1179
|
inFlightRef.current = false;
|
|
1114
1180
|
scheduleRef.current();
|
|
1115
1181
|
}
|
|
1116
|
-
}, [applySnapshot]);
|
|
1182
|
+
}, [applySnapshot, fetchMarket]);
|
|
1117
1183
|
const scheduleRef = (0, import_react3.useRef)(() => {
|
|
1118
1184
|
});
|
|
1119
1185
|
scheduleRef.current = () => {
|
|
@@ -1191,6 +1257,10 @@ function useLiveMonitor(opts) {
|
|
|
1191
1257
|
lastViewedPrices,
|
|
1192
1258
|
inSlip,
|
|
1193
1259
|
markInSlip,
|
|
1260
|
+
openMarket,
|
|
1261
|
+
marketOdds,
|
|
1262
|
+
toggleMarket,
|
|
1263
|
+
retryMarket,
|
|
1194
1264
|
_setSnapshot: applySnapshot
|
|
1195
1265
|
};
|
|
1196
1266
|
}
|
|
@@ -1731,48 +1801,50 @@ function OddsRow({ vm, row, ui, slip, inSlipIds }) {
|
|
|
1731
1801
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(SlipButton, { selection, shownOdds: row.odds, marketName: vm.market, slip, ui })
|
|
1732
1802
|
] });
|
|
1733
1803
|
}
|
|
1734
|
-
function MarketOddsCard({ vm, ui, slip, monitor, inSlipIds }) {
|
|
1804
|
+
function MarketOddsCard({ vm, ui, slip, monitor, inSlipIds, hideHeader }) {
|
|
1735
1805
|
const [open, setOpen] = (0, import_react12.useState)(false);
|
|
1736
1806
|
const kickoff = vm.kickoffUtc && ui?.bettingKickoff ? ui.bettingKickoff(vm.kickoffUtc) : void 0;
|
|
1737
1807
|
const hasNamedTeams = !!vm.homeTeamName && !!vm.awayTeamName;
|
|
1738
1808
|
const showPin = !!monitor && vm.pinEnabled;
|
|
1739
1809
|
const showHeader = !!vm.competition || vm.isLive || !!kickoff || showPin;
|
|
1740
|
-
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "ss-w-mocard", children: [
|
|
1741
|
-
|
|
1742
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.
|
|
1743
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
kickoff.
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
hasNamedTeams ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "ss-w-
|
|
1768
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1810
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: hideHeader ? "ss-w-mocard ss-w-mocard--bare" : "ss-w-mocard", children: [
|
|
1811
|
+
!hideHeader && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
1812
|
+
showHeader ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "ss-w-bi-header", children: [
|
|
1813
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "ss-w-bi-header-left", children: vm.competition ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
1814
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Crest2, { kind: "comp", url: vm.competitionCrest, name: vm.competition }),
|
|
1815
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "ss-w-bi-comp", children: vm.competition })
|
|
1816
|
+
] }) : null }),
|
|
1817
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "ss-w-bi-header-right", children: [
|
|
1818
|
+
vm.isLive ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "ss-w-bi-live", children: [
|
|
1819
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "ss-w-bi-live-dot", "aria-hidden": "true" }),
|
|
1820
|
+
ui?.liveLabel ?? "Live"
|
|
1821
|
+
] }) : null,
|
|
1822
|
+
kickoff ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "ss-w-bi-kick", children: [
|
|
1823
|
+
kickoff.dayLabel,
|
|
1824
|
+
" ",
|
|
1825
|
+
kickoff.time
|
|
1826
|
+
] }) : null,
|
|
1827
|
+
showPin && ui ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1828
|
+
PinToggle,
|
|
1829
|
+
{
|
|
1830
|
+
ui,
|
|
1831
|
+
monitor,
|
|
1832
|
+
pin: { kind: "market", matchId: vm.matchId, marketDeveloperName: vm.marketDeveloperName, line: vm.mainLine }
|
|
1833
|
+
}
|
|
1834
|
+
) : null
|
|
1835
|
+
] })
|
|
1836
|
+
] }) : null,
|
|
1837
|
+
hasNamedTeams || vm.fixture || vm.market ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "ss-w-mo-sub", children: [
|
|
1838
|
+
hasNamedTeams ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "ss-w-bi-fixture", children: [
|
|
1839
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Crest2, { kind: "team", url: vm.homeCrest, name: vm.homeTeamName }),
|
|
1840
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "ss-w-bi-team", children: vm.homeTeamName }),
|
|
1841
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "ss-w-bi-vs", "aria-hidden": "true", children: "vs" }),
|
|
1842
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "ss-w-bi-team", children: vm.awayTeamName }),
|
|
1843
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Crest2, { kind: "team", url: vm.awayCrest, name: vm.awayTeamName })
|
|
1844
|
+
] }) : vm.fixture ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "ss-w-mo-teams", children: vm.fixture }) : null,
|
|
1845
|
+
vm.market ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "ss-w-mo-market", children: vm.market }) : null
|
|
1846
|
+
] }) : null
|
|
1847
|
+
] }),
|
|
1776
1848
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "ss-w-mo-rows", children: [
|
|
1777
1849
|
vm.mainRows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(OddsRow, { vm, row, ui, slip, inSlipIds }, row.key)),
|
|
1778
1850
|
open ? vm.moreRows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(OddsRow, { vm, row, ui, slip, inSlipIds }, row.key)) : null
|
|
@@ -1785,9 +1857,9 @@ function MarketOddsCard({ vm, ui, slip, monitor, inSlipIds }) {
|
|
|
1785
1857
|
vm.disclaimer ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "ss-w-bi-disc", children: vm.disclaimer }) : null
|
|
1786
1858
|
] });
|
|
1787
1859
|
}
|
|
1788
|
-
function MarketOddsCardList({ cards, ui, slip, monitor, inSlipIds }) {
|
|
1860
|
+
function MarketOddsCardList({ cards, ui, slip, monitor, inSlipIds, hideHeader }) {
|
|
1789
1861
|
if (!cards || cards.length === 0) return null;
|
|
1790
|
-
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "ss-w-mocards", children: cards.map((vm) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(MarketOddsCard, { vm, ui, slip, monitor, inSlipIds }, vm.id)) });
|
|
1862
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "ss-w-mocards", children: cards.map((vm) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(MarketOddsCard, { vm, ui, slip, monitor, inSlipIds, hideHeader }, vm.id)) });
|
|
1791
1863
|
}
|
|
1792
1864
|
|
|
1793
1865
|
// src/components/OddsMovementCard.tsx
|
|
@@ -2897,8 +2969,63 @@ function TabBar({ monitor, ui, matchCount, oddsCount }) {
|
|
|
2897
2969
|
}) });
|
|
2898
2970
|
}
|
|
2899
2971
|
|
|
2900
|
-
// src/components/
|
|
2972
|
+
// src/components/MarketAccordion.tsx
|
|
2901
2973
|
var import_jsx_runtime46 = require("react/jsx-runtime");
|
|
2974
|
+
function MarketAccordion({ match, monitor, ui, slip }) {
|
|
2975
|
+
const markets = match.availableMarkets ?? [];
|
|
2976
|
+
if (markets.length === 0) return null;
|
|
2977
|
+
const open = monitor.openMarket[match.matchId] ?? null;
|
|
2978
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "ss-w-acc", children: markets.map((m) => {
|
|
2979
|
+
const isOpen = open === m.marketDeveloperName;
|
|
2980
|
+
const key = `${match.matchId}:${m.marketDeveloperName}`;
|
|
2981
|
+
const entry = monitor.marketOdds[key];
|
|
2982
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: isOpen ? "ss-w-acc-row ss-w-acc-row-open" : "ss-w-acc-row", children: [
|
|
2983
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
|
|
2984
|
+
"button",
|
|
2985
|
+
{
|
|
2986
|
+
type: "button",
|
|
2987
|
+
className: "ss-w-acc-head",
|
|
2988
|
+
onClick: () => monitor.toggleMarket(match.matchId, m.marketDeveloperName),
|
|
2989
|
+
children: [
|
|
2990
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "ss-w-acc-chevron", children: isOpen ? "\u25BE" : "\u25B8" }),
|
|
2991
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "ss-w-acc-label", children: m.marketLabel }),
|
|
2992
|
+
m.hasInsight && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "ss-w-acc-badge", children: "\u2605" }),
|
|
2993
|
+
m.suspended && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "ss-w-acc-susp", children: ui.accordionSuspended })
|
|
2994
|
+
]
|
|
2995
|
+
}
|
|
2996
|
+
),
|
|
2997
|
+
isOpen && /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "ss-w-acc-panel", children: [
|
|
2998
|
+
entry?.error && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
2999
|
+
"div",
|
|
3000
|
+
{
|
|
3001
|
+
className: "ss-w-acc-retry",
|
|
3002
|
+
onClick: () => monitor.retryMarket(match.matchId, m.marketDeveloperName),
|
|
3003
|
+
children: ui.accordionRetry
|
|
3004
|
+
}
|
|
3005
|
+
),
|
|
3006
|
+
entry?.block?.insight?.text && /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "ss-w-acc-insight", children: [
|
|
3007
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "ss-w-acc-badge", children: ui.accordionValueLabel }),
|
|
3008
|
+
" ",
|
|
3009
|
+
entry.block.insight.text
|
|
3010
|
+
] }),
|
|
3011
|
+
entry?.block?.card && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
3012
|
+
MarketOddsCardList,
|
|
3013
|
+
{
|
|
3014
|
+
cards: [toMarketOddsVM(entry.block.card)],
|
|
3015
|
+
ui,
|
|
3016
|
+
slip,
|
|
3017
|
+
monitor,
|
|
3018
|
+
inSlipIds: monitor.inSlip,
|
|
3019
|
+
hideHeader: true
|
|
3020
|
+
}
|
|
3021
|
+
)
|
|
3022
|
+
] })
|
|
3023
|
+
] }, m.marketDeveloperName);
|
|
3024
|
+
}) });
|
|
3025
|
+
}
|
|
3026
|
+
|
|
3027
|
+
// src/components/MonitorMatchCard.tsx
|
|
3028
|
+
var import_jsx_runtime47 = require("react/jsx-runtime");
|
|
2902
3029
|
function chipSelection(row, matchId, conversationId) {
|
|
2903
3030
|
const chip = row.market;
|
|
2904
3031
|
if (!chip || !chip.addToSlipEnabled || typeof chip.matchOddsId !== "number" || typeof chip.price !== "number") return null;
|
|
@@ -2921,63 +3048,63 @@ function MonitorMatchCard({ match, promotedPins, monitor, ui, slip }) {
|
|
|
2921
3048
|
const otherRows = match.statRows.filter((row) => !isPromoted(row, promotedPins));
|
|
2922
3049
|
const orderedRows = [...promotedRows, ...otherRows];
|
|
2923
3050
|
const kickoff = match.phase === "preMatch" && match.kickoffUtc ? ui.bettingKickoff(match.kickoffUtc) : void 0;
|
|
2924
|
-
return /* @__PURE__ */ (0,
|
|
2925
|
-
/* @__PURE__ */ (0,
|
|
2926
|
-
live && /* @__PURE__ */ (0,
|
|
2927
|
-
/* @__PURE__ */ (0,
|
|
3051
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "ss-w-mon", children: [
|
|
3052
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "ss-w-mon-top", children: [
|
|
3053
|
+
live && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("span", { className: "ss-w-fandash-live-pill", children: [
|
|
3054
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "ss-w-fandash-live-dot", "aria-hidden": "true" }),
|
|
2928
3055
|
ui.liveLabel
|
|
2929
3056
|
] }),
|
|
2930
|
-
match.phase === "fullTime" && /* @__PURE__ */ (0,
|
|
2931
|
-
kickoff && /* @__PURE__ */ (0,
|
|
3057
|
+
match.phase === "fullTime" && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "ss-w-mon-pill", children: ui.fullTimeLabel }),
|
|
3058
|
+
kickoff && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("span", { className: "ss-w-mon-pill", children: [
|
|
2932
3059
|
kickoff.dayLabel,
|
|
2933
3060
|
" \xB7 ",
|
|
2934
3061
|
kickoff.time
|
|
2935
3062
|
] }),
|
|
2936
|
-
live && match.minuteLabel && /* @__PURE__ */ (0,
|
|
2937
|
-
match.competitionName && /* @__PURE__ */ (0,
|
|
2938
|
-
/* @__PURE__ */ (0,
|
|
3063
|
+
live && match.minuteLabel && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "ss-w-mon-min", children: match.minuteLabel }),
|
|
3064
|
+
match.competitionName && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "ss-w-mon-comp", children: match.competitionName }),
|
|
3065
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(PinToggle, { ui, monitor, pin: { kind: "match", matchId: match.matchId } })
|
|
2939
3066
|
] }),
|
|
2940
|
-
/* @__PURE__ */ (0,
|
|
2941
|
-
/* @__PURE__ */ (0,
|
|
2942
|
-
/* @__PURE__ */ (0,
|
|
2943
|
-
/* @__PURE__ */ (0,
|
|
3067
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "ss-w-mon-main", children: [
|
|
3068
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("span", { className: "ss-w-mon-side", children: [
|
|
3069
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Crest2, { kind: "team", url: match.homeCrestUrl ?? void 0, name: match.homeTeamName ?? void 0 }),
|
|
3070
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "ss-w-mon-name", children: match.homeTeamName })
|
|
2944
3071
|
] }),
|
|
2945
|
-
match.phase === "preMatch" ? /* @__PURE__ */ (0,
|
|
3072
|
+
match.phase === "preMatch" ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "ss-w-mon-vs", children: "vs" }) : /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("span", { className: "ss-w-mon-score", children: [
|
|
2946
3073
|
match.homeScore,
|
|
2947
|
-
/* @__PURE__ */ (0,
|
|
3074
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("i", { children: "\u2013" }),
|
|
2948
3075
|
match.awayScore
|
|
2949
3076
|
] }),
|
|
2950
|
-
/* @__PURE__ */ (0,
|
|
2951
|
-
/* @__PURE__ */ (0,
|
|
2952
|
-
/* @__PURE__ */ (0,
|
|
3077
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("span", { className: "ss-w-mon-side ss-w-mon-side--away", children: [
|
|
3078
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Crest2, { kind: "team", url: match.awayCrestUrl ?? void 0, name: match.awayTeamName ?? void 0 }),
|
|
3079
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "ss-w-mon-name", children: match.awayTeamName })
|
|
2953
3080
|
] })
|
|
2954
3081
|
] }),
|
|
2955
|
-
scorers.length > 0 && /* @__PURE__ */ (0,
|
|
2956
|
-
/* @__PURE__ */ (0,
|
|
3082
|
+
scorers.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "ss-w-mon-scorers", children: scorers.map((e) => `${e.player ?? ""} ${e.minuteLabel}`).join(", ") }),
|
|
3083
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "ss-w-mon-stats", children: orderedRows.map((row) => {
|
|
2957
3084
|
const total = row.homeNum + row.awayNum;
|
|
2958
3085
|
const homePct = total > 0 ? row.homeNum / total * 75 : 0;
|
|
2959
3086
|
const awayPct = total > 0 ? row.awayNum / total * 75 : 0;
|
|
2960
3087
|
const promoted = isPromoted(row, promotedPins);
|
|
2961
3088
|
const selection = chipSelection(row, match.matchId, slip.conversationId);
|
|
2962
|
-
return /* @__PURE__ */ (0,
|
|
2963
|
-
/* @__PURE__ */ (0,
|
|
2964
|
-
/* @__PURE__ */ (0,
|
|
2965
|
-
/* @__PURE__ */ (0,
|
|
2966
|
-
/* @__PURE__ */ (0,
|
|
3089
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: promoted ? "ss-w-mon-stat ss-w-mon-pstrip" : "ss-w-mon-stat", children: [
|
|
3090
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "ss-w-mon-stat-row", children: [
|
|
3091
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "ss-w-mon-stat-v ss-w-mon-stat-v--home", children: row.homeValue }),
|
|
3092
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "ss-w-mon-stat-l", children: row.label }),
|
|
3093
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "ss-w-mon-stat-v ss-w-mon-stat-v--away", children: row.awayValue })
|
|
2967
3094
|
] }),
|
|
2968
|
-
/* @__PURE__ */ (0,
|
|
2969
|
-
/* @__PURE__ */ (0,
|
|
2970
|
-
/* @__PURE__ */ (0,
|
|
3095
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "ss-w-mon-bar", children: [
|
|
3096
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("b", { className: "ss-w-mon-bar-home", style: { width: `${homePct}%` } }),
|
|
3097
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("i", { className: "ss-w-mon-bar-away", style: { width: `${awayPct}%` } })
|
|
2971
3098
|
] }),
|
|
2972
|
-
row.market && /* @__PURE__ */ (0,
|
|
2973
|
-
/* @__PURE__ */ (0,
|
|
3099
|
+
row.market && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: promoted ? "ss-w-mon-stat-mkt ss-w-mon-mkt" : "ss-w-mon-stat-mkt", children: [
|
|
3100
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("span", { children: [
|
|
2974
3101
|
row.market.marketLabel,
|
|
2975
3102
|
" \xB7 ",
|
|
2976
3103
|
row.market.selectionLabel
|
|
2977
3104
|
] }),
|
|
2978
|
-
/* @__PURE__ */ (0,
|
|
2979
|
-
row.market.isSuspended ? /* @__PURE__ */ (0,
|
|
2980
|
-
/* @__PURE__ */ (0,
|
|
3105
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("span", { className: "ss-w-mon-stat-mkt-right", children: [
|
|
3106
|
+
row.market.isSuspended ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "ss-w-mon-susp", children: ui.suspendedLabel }) : typeof row.market.price === "number" && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "ss-w-mon-price", children: row.market.price.toFixed(2) }),
|
|
3107
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
2981
3108
|
SlipButton,
|
|
2982
3109
|
{
|
|
2983
3110
|
selection,
|
|
@@ -2991,68 +3118,69 @@ function MonitorMatchCard({ match, promotedPins, monitor, ui, slip }) {
|
|
|
2991
3118
|
] })
|
|
2992
3119
|
] }, row.label);
|
|
2993
3120
|
}) }),
|
|
2994
|
-
match.status === "stale" && /* @__PURE__ */ (0,
|
|
2995
|
-
match.momentum.length > 0 && /* @__PURE__ */ (0,
|
|
2996
|
-
/* @__PURE__ */ (0,
|
|
2997
|
-
/* @__PURE__ */ (0,
|
|
2998
|
-
/* @__PURE__ */ (0,
|
|
2999
|
-
/* @__PURE__ */ (0,
|
|
3121
|
+
match.status === "stale" && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "ss-w-mon-asof", children: ui.asOf(formatTime(match.asOfUtc)) }),
|
|
3122
|
+
match.momentum.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "ss-w-mon-mom", children: [
|
|
3123
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "ss-w-mon-stat-row", children: [
|
|
3124
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "ss-w-mon-stat-v ss-w-mon-stat-v--home", children: typeof match.momentumHomePct === "number" ? `${match.momentumHomePct}%` : "" }),
|
|
3125
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "ss-w-mon-stat-l", children: ui.momentumLabel }),
|
|
3126
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "ss-w-mon-stat-v ss-w-mon-stat-v--away", children: typeof match.momentumHomePct === "number" ? `${100 - match.momentumHomePct}%` : "" })
|
|
3000
3127
|
] }),
|
|
3001
|
-
/* @__PURE__ */ (0,
|
|
3128
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(MomentumWave, { points: match.momentum, clubIsHome: true })
|
|
3002
3129
|
] }),
|
|
3003
|
-
match.
|
|
3004
|
-
match.phase === "fullTime" && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "ss-w-mon-grace", children: ui.graceNote })
|
|
3130
|
+
match.phase === "fullTime" && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "ss-w-mon-grace", children: ui.graceNote })
|
|
3005
3131
|
] });
|
|
3006
3132
|
}
|
|
3007
3133
|
|
|
3008
3134
|
// src/components/MonitorTabs.tsx
|
|
3009
|
-
var
|
|
3135
|
+
var import_jsx_runtime48 = require("react/jsx-runtime");
|
|
3010
3136
|
function ContextLine({ m, monitor, ui }) {
|
|
3011
3137
|
const kick = m.kickoffUtc ? ui.bettingKickoff(m.kickoffUtc) : void 0;
|
|
3012
|
-
return /* @__PURE__ */ (0,
|
|
3013
|
-
/* @__PURE__ */ (0,
|
|
3014
|
-
/* @__PURE__ */ (0,
|
|
3015
|
-
/* @__PURE__ */ (0,
|
|
3138
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "ss-w-mk-ctx", children: [
|
|
3139
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("span", { className: "ss-w-mk-ctx-side", children: [
|
|
3140
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(Crest2, { kind: "team", url: m.homeCrestUrl ?? void 0, name: m.homeTeamName ?? void 0 }),
|
|
3141
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "ss-w-mon-name", children: m.homeTeamName })
|
|
3016
3142
|
] }),
|
|
3017
|
-
m.phase === "preMatch" ? kick && /* @__PURE__ */ (0,
|
|
3143
|
+
m.phase === "preMatch" ? kick && /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("span", { className: "ss-w-mon-pill", children: [
|
|
3018
3144
|
kick.dayLabel,
|
|
3019
3145
|
" ",
|
|
3020
3146
|
kick.time
|
|
3021
|
-
] }) : typeof m.homeScore === "number" && /* @__PURE__ */ (0,
|
|
3147
|
+
] }) : typeof m.homeScore === "number" && /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("b", { children: [
|
|
3022
3148
|
m.homeScore,
|
|
3023
3149
|
"\u2013",
|
|
3024
3150
|
m.awayScore
|
|
3025
3151
|
] }),
|
|
3026
|
-
/* @__PURE__ */ (0,
|
|
3027
|
-
/* @__PURE__ */ (0,
|
|
3028
|
-
/* @__PURE__ */ (0,
|
|
3152
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("span", { className: "ss-w-mk-ctx-side", children: [
|
|
3153
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "ss-w-mon-name", children: m.awayTeamName }),
|
|
3154
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(Crest2, { kind: "team", url: m.awayCrestUrl ?? void 0, name: m.awayTeamName ?? void 0 })
|
|
3029
3155
|
] }),
|
|
3030
|
-
m.minuteLabel && /* @__PURE__ */ (0,
|
|
3031
|
-
/* @__PURE__ */ (0,
|
|
3032
|
-
m.isSuspended && !m.isSettled && /* @__PURE__ */ (0,
|
|
3033
|
-
m.isSettled && /* @__PURE__ */ (0,
|
|
3034
|
-
m.status === "stale" && /* @__PURE__ */ (0,
|
|
3156
|
+
m.minuteLabel && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "ss-w-mon-min", children: m.minuteLabel }),
|
|
3157
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("span", { className: "ss-w-mk-ctx-right", children: [
|
|
3158
|
+
m.isSuspended && !m.isSettled && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "ss-w-mon-susp", children: ui.suspendedLabel }),
|
|
3159
|
+
m.isSettled && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "ss-w-mon-pill", children: ui.fullTimeLabel }),
|
|
3160
|
+
m.status === "stale" && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "ss-w-mon-asof", children: ui.asOf(new Date(m.asOfUtc).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })) }),
|
|
3035
3161
|
(() => {
|
|
3036
3162
|
const pin = monitor.pins.find((p) => p.key === m.key);
|
|
3037
|
-
return pin ? /* @__PURE__ */ (0,
|
|
3163
|
+
return pin ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(PinToggle, { ui, monitor, pin }) : null;
|
|
3038
3164
|
})()
|
|
3039
3165
|
] })
|
|
3040
3166
|
] });
|
|
3041
3167
|
}
|
|
3042
3168
|
function MatchesPanel({ monitor, ui, slip }) {
|
|
3043
3169
|
const matches = (monitor.snapshot?.matches ?? []).filter((m) => monitor.pins.some((p) => p.kind === "match" && p.matchId === m.matchId));
|
|
3044
|
-
if (matches.length === 0) return /* @__PURE__ */ (0,
|
|
3045
|
-
return /* @__PURE__ */ (0,
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3170
|
+
if (matches.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "ss-w-mon-empty", children: ui.emptyMatchesTab });
|
|
3171
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "ss-w-mon-list", children: matches.map((m) => /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "ss-w-mon-item", children: [
|
|
3172
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
3173
|
+
MonitorMatchCard,
|
|
3174
|
+
{
|
|
3175
|
+
match: m,
|
|
3176
|
+
promotedPins: monitor.pins.filter((p) => p.kind !== "match" && p.matchId === m.matchId),
|
|
3177
|
+
monitor,
|
|
3178
|
+
ui,
|
|
3179
|
+
slip
|
|
3180
|
+
}
|
|
3181
|
+
),
|
|
3182
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(MarketAccordion, { match: m, monitor, ui, slip })
|
|
3183
|
+
] }, m.matchId)) });
|
|
3056
3184
|
}
|
|
3057
3185
|
function withSinceViewMovement(vm, prev) {
|
|
3058
3186
|
const primary = vm.mainRows[0];
|
|
@@ -3066,10 +3194,10 @@ function withSinceViewMovement(vm, prev) {
|
|
|
3066
3194
|
}
|
|
3067
3195
|
function OddsPanel({ monitor, ui, slip }) {
|
|
3068
3196
|
const markets = (monitor.snapshot?.markets ?? []).filter((m) => monitor.pins.some((p) => p.key === m.key));
|
|
3069
|
-
if (markets.length === 0) return /* @__PURE__ */ (0,
|
|
3070
|
-
return /* @__PURE__ */ (0,
|
|
3071
|
-
/* @__PURE__ */ (0,
|
|
3072
|
-
m.card && /* @__PURE__ */ (0,
|
|
3197
|
+
if (markets.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "ss-w-mon-empty", children: ui.emptyOddsTab });
|
|
3198
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "ss-w-mon-list", children: markets.map((m) => /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "ss-w-mon-oddspin", "data-settled": m.isSettled || void 0, children: [
|
|
3199
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ContextLine, { m, monitor, ui }),
|
|
3200
|
+
m.card && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
3073
3201
|
MarketOddsCardList,
|
|
3074
3202
|
{
|
|
3075
3203
|
cards: [withSinceViewMovement(toMarketOddsVM(m.card), monitor.lastViewedPrices[m.key])],
|
|
@@ -3078,13 +3206,13 @@ function OddsPanel({ monitor, ui, slip }) {
|
|
|
3078
3206
|
inSlipIds: monitor.inSlip
|
|
3079
3207
|
}
|
|
3080
3208
|
),
|
|
3081
|
-
m.history && /* @__PURE__ */ (0,
|
|
3082
|
-
!m.card && !m.history && /* @__PURE__ */ (0,
|
|
3209
|
+
m.history && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(OddsMovementCardList, { cards: [toOddsMovementVM(m.history)], ui }),
|
|
3210
|
+
!m.card && !m.history && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "ss-w-mon-empty-card", children: ui.oddsUnavailable })
|
|
3083
3211
|
] }, m.key)) });
|
|
3084
3212
|
}
|
|
3085
3213
|
|
|
3086
3214
|
// src/components/ChatPanel.tsx
|
|
3087
|
-
var
|
|
3215
|
+
var import_jsx_runtime49 = require("react/jsx-runtime");
|
|
3088
3216
|
var FULLSCREEN_QUERY = "(max-width: 639px)";
|
|
3089
3217
|
function useIsModal() {
|
|
3090
3218
|
const [modal, setModal] = (0, import_react22.useState)(false);
|
|
@@ -3115,9 +3243,9 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor }) {
|
|
|
3115
3243
|
(0, import_react22.useEffect)(() => {
|
|
3116
3244
|
if (monitor && monitor.activeTab !== "chat" && state.isStreaming) monitor.markChatActivity();
|
|
3117
3245
|
}, [monitor, state.isStreaming, state.messages.length]);
|
|
3118
|
-
return /* @__PURE__ */ (0,
|
|
3119
|
-
/* @__PURE__ */ (0,
|
|
3120
|
-
monitor && /* @__PURE__ */ (0,
|
|
3246
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "ss-w-panel", role: "dialog", "aria-modal": isModal, "aria-label": ui.chatDialogLabel, children: [
|
|
3247
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(ChatHeader, { onClose: close, closeLabel: ui.closeChat, logoUrl: ui.logoUrl, headerTitle: ui.headerTitle }),
|
|
3248
|
+
monitor && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
3121
3249
|
TabBar,
|
|
3122
3250
|
{
|
|
3123
3251
|
monitor,
|
|
@@ -3126,16 +3254,16 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor }) {
|
|
|
3126
3254
|
oddsCount: monitor.pins.filter((p) => p.kind !== "match").length
|
|
3127
3255
|
}
|
|
3128
3256
|
),
|
|
3129
|
-
/* @__PURE__ */ (0,
|
|
3257
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
3130
3258
|
"div",
|
|
3131
3259
|
{
|
|
3132
3260
|
style: !monitor || monitor.activeTab === "chat" ? { display: "contents" } : { position: "absolute", inset: 0, visibility: "hidden", display: "flex", flexDirection: "column" },
|
|
3133
|
-
children: /* @__PURE__ */ (0,
|
|
3261
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(MessageList, { controller, ui, slip, onDashboardTap, monitor })
|
|
3134
3262
|
}
|
|
3135
3263
|
),
|
|
3136
|
-
monitor && monitor.activeTab === "matches" && /* @__PURE__ */ (0,
|
|
3137
|
-
monitor && monitor.activeTab === "odds" && /* @__PURE__ */ (0,
|
|
3138
|
-
/* @__PURE__ */ (0,
|
|
3264
|
+
monitor && monitor.activeTab === "matches" && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(MatchesPanel, { monitor, ui, slip }),
|
|
3265
|
+
monitor && monitor.activeTab === "odds" && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(OddsPanel, { monitor, ui, slip }),
|
|
3266
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(ChatInput, { placeholder: ui.placeholder, streaming: state.isStreaming, onSend: handleSend, onStop: stop, stopLabel: ui.stopResponse, sendLabel: ui.sendMessage })
|
|
3139
3267
|
] });
|
|
3140
3268
|
}
|
|
3141
3269
|
|
|
@@ -3385,6 +3513,9 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
3385
3513
|
/* market odds card */
|
|
3386
3514
|
.ss-w-mocards { display: flex; flex-direction: column; gap: 7px; }
|
|
3387
3515
|
.ss-w-mocard { background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 12px; border-left: 3px solid var(--ss-w-accent); padding: 9px 11px; display: flex; flex-direction: column; gap: 6px; }
|
|
3516
|
+
/* Embedded inside the market accordion, which already provides the card frame + accent rail --
|
|
3517
|
+
drop the inner frame so odds rows aren't double-bordered. */
|
|
3518
|
+
.ss-w-mocard--bare { border: none; border-radius: 0; padding: 0; background: none; }
|
|
3388
3519
|
.ss-w-mo-sub { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
|
|
3389
3520
|
.ss-w-mo-teams { font-size: 13px; font-weight: 650; color: var(--ss-w-ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
3390
3521
|
.ss-w-mo-market { font-size: 11.5px; font-weight: 600; color: var(--ss-w-faint); }
|
|
@@ -3395,7 +3526,7 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
3395
3526
|
.ss-w-mo-rows { display: flex; flex-direction: column; gap: 4px; }
|
|
3396
3527
|
.ss-w-mo-row { display: flex; align-items: center; gap: 10px; padding: 4px 0; border-bottom: 1px dashed var(--ss-w-line); }
|
|
3397
3528
|
.ss-w-mo-row:last-child { border-bottom: none; }
|
|
3398
|
-
.ss-w-mo-sel { font-size: 12.5px; font-weight: 600; color: var(--ss-w-ink); }
|
|
3529
|
+
.ss-w-mo-sel { font-size: 12.5px; font-weight: 600; color: var(--ss-w-ink); flex: 1; min-width: 0; }
|
|
3399
3530
|
.ss-w-mo-price { margin-left: auto; font-family: ui-monospace, monospace; font-variant-numeric: tabular-nums; font-size: 14px; font-weight: 700; color: var(--ss-w-accent); }
|
|
3400
3531
|
/* Movement: BOTH directions share --ss-w-faint on purpose. Green-good/red-bad would frame a
|
|
3401
3532
|
shortening price as a discount, which inverts what it actually means for the bettor. */
|
|
@@ -3406,7 +3537,7 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
3406
3537
|
a flex row, and must NOT follow the badge into the insight card's odds column. */
|
|
3407
3538
|
.ss-w-mo-row .ss-w-move { margin-left: auto; }
|
|
3408
3539
|
.ss-w-mo-row .ss-w-move + .ss-w-mo-price { margin-left: 0; }
|
|
3409
|
-
.ss-w-mo-row .ss-w-slip { margin: 0; }
|
|
3540
|
+
.ss-w-mo-row .ss-w-slip { margin: 0; flex: none; }
|
|
3410
3541
|
.ss-w-mo-foot { display: flex; align-items: center; gap: 8px; font-size: 10.5px; color: var(--ss-w-faint); }
|
|
3411
3542
|
|
|
3412
3543
|
/* odds movement card */
|
|
@@ -3458,7 +3589,7 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
3458
3589
|
|
|
3459
3590
|
/* add to slip */
|
|
3460
3591
|
.ss-w-slip { position: relative; display: flex; }
|
|
3461
|
-
.ss-w-slip-btn { font-size: 11.5px; font-weight: 620; color: var(--ss-w-cta-ink); background: var(--ss-w-cta); border: 1px solid var(--ss-w-cta); border-radius: 14px; padding: 5px 12px; cursor: pointer; }
|
|
3592
|
+
.ss-w-slip-btn { font-size: 11.5px; font-weight: 620; color: var(--ss-w-cta-ink); background: var(--ss-w-cta); border: 1px solid var(--ss-w-cta); border-radius: 14px; padding: 5px 12px; cursor: pointer; white-space: nowrap; }
|
|
3462
3593
|
.ss-w-slip-btn:disabled { opacity: .6; cursor: default; background: var(--ss-w-bubble); color: var(--ss-w-faint); border-color: var(--ss-w-line); }
|
|
3463
3594
|
/* Anchored to the RIGHT of its (narrow) button wrapper and sized by content, growing leftward
|
|
3464
3595
|
into the card -- inheriting the wrapper's width squeezes the text to one character per line.
|
|
@@ -3920,10 +4051,25 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
3920
4051
|
.ss-w-mon-oddspin { display: flex; flex-direction: column; gap: 10px; padding: 12px; border: 1px solid var(--ss-w-line); border-radius: 12px; background: var(--ss-w-panel); }
|
|
3921
4052
|
.ss-w-mon-oddspin[data-settled] .ss-w-mo-price,
|
|
3922
4053
|
.ss-w-mon-oddspin[data-settled] .ss-w-mon-price { text-decoration: line-through; color: var(--ss-w-faint); }
|
|
4054
|
+
|
|
4055
|
+
/* market accordion (Task 9): one collapsed row per available market, expanding into a reused
|
|
4056
|
+
MarketOddsCardList ladder (hideHeader -- the row header already carries the market label). */
|
|
4057
|
+
/* Pinned-match tile: the match card + its odds accordion, spaced apart. */
|
|
4058
|
+
.ss-w-mon-item { display: flex; flex-direction: column; gap: 10px; }
|
|
4059
|
+
.ss-w-acc { display: flex; flex-direction: column; gap: 6px; }
|
|
4060
|
+
.ss-w-acc-row { background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 12px; border-left: 3px solid var(--ss-w-accent); overflow: hidden; }
|
|
4061
|
+
.ss-w-acc-head { display: flex; align-items: center; gap: 8px; width: 100%; padding: 9px 11px; background: none; border: none; cursor: pointer; text-align: left; font: inherit; color: var(--ss-w-ink); }
|
|
4062
|
+
.ss-w-acc-chevron { color: var(--ss-w-faint); font-size: 11px; }
|
|
4063
|
+
.ss-w-acc-label { font-size: 12.5px; font-weight: 600; }
|
|
4064
|
+
.ss-w-acc-badge { font-size: 10.5px; font-weight: 700; color: var(--ss-w-accent); }
|
|
4065
|
+
.ss-w-acc-susp { margin-left: auto; font-size: 10.5px; color: var(--ss-w-faint); }
|
|
4066
|
+
.ss-w-acc-panel { padding: 0 11px 10px; display: flex; flex-direction: column; gap: 8px; }
|
|
4067
|
+
.ss-w-acc-insight { font-size: 12px; color: var(--ss-w-ink); background: color-mix(in srgb, var(--ss-w-accent) 9%, var(--ss-w-panel)); border-radius: 8px; padding: 7px 9px; }
|
|
4068
|
+
.ss-w-acc-retry { font-size: 12px; color: var(--ss-w-neg); cursor: pointer; padding: 6px 0; }
|
|
3923
4069
|
`;
|
|
3924
4070
|
|
|
3925
4071
|
// src/StatsWidget.tsx
|
|
3926
|
-
var
|
|
4072
|
+
var import_jsx_runtime50 = require("react/jsx-runtime");
|
|
3927
4073
|
function buildClient(props) {
|
|
3928
4074
|
try {
|
|
3929
4075
|
if ("client" in props && props.client) {
|
|
@@ -3958,6 +4104,7 @@ function StatsWidget(props) {
|
|
|
3958
4104
|
const controller = useChatStream(built?.conversation ?? emptyConversation(), ui.starters, built ? ui.greetingMessage : void 0);
|
|
3959
4105
|
const monitor = useLiveMonitor({
|
|
3960
4106
|
getLiveMonitor: (pins) => built ? built.conversation.getLiveMonitor(pins) : Promise.resolve(null),
|
|
4107
|
+
getMarketOdds: (matchId, dev) => built ? built.conversation.getMarketOdds(matchId, dev) : Promise.resolve(null),
|
|
3961
4108
|
storageKey: `ss-w-pins:${cfg?.operatorId ?? ""}:${cfg?.userContext?.operatorUserId ?? "anon"}`,
|
|
3962
4109
|
isOpen: controller.state.isOpen
|
|
3963
4110
|
});
|
|
@@ -3995,7 +4142,7 @@ function StatsWidget(props) {
|
|
|
3995
4142
|
}, [built, ui.injectStyles]);
|
|
3996
4143
|
if (!built) return null;
|
|
3997
4144
|
const attrs = themeAttrs(ui);
|
|
3998
|
-
return /* @__PURE__ */ (0,
|
|
4145
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { ref: rootRef, className: "ss-w-root", "data-ss-w-theme": attrs["data-ss-w-theme"], "data-ss-w-pos": attrs["data-ss-w-pos"], style: attrs.style, children: controller.state.isOpen ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(ChatPanel, { controller, ui, slip, onDashboardTap, monitor: monitor.enabled ? monitor : void 0 }) : /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
3999
4146
|
ChatFab,
|
|
4000
4147
|
{
|
|
4001
4148
|
label: ui.launcherLabel,
|