@sensiblestats/widget-react 0.70.1 → 0.72.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,34 @@
1
1
  # @sensiblestats/widget-react
2
2
 
3
+ ## 0.72.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Onboarding presets, stage 3: the open pick pool.
8
+
9
+ - widget-sdk: `ComboLeg.insight` is optional and may be null; `getPricePresets` and
10
+ `Conversation.getPricePresets(locale, { pool })` take `pool: 'open'`.
11
+ - widget-react: a combo leg with no stat is drawn with its price and no stat line, and its slip
12
+ selection carries no `insightId`, instead of the whole card being dropped; every chat request
13
+ declares `price_presets_open`; the preset grid is asked with `pool=open`. Picking a combo total that exists only at another match count moves the match count to the nearest count that has it.
14
+ - widget-embed: rebuilt against the new widget-react and widget-sdk.
15
+
16
+ ### Patch Changes
17
+
18
+ - Updated dependencies
19
+ - @sensiblestats/widget-sdk@0.47.0
20
+
21
+ ## 0.71.0
22
+
23
+ ### Minor Changes
24
+
25
+ - 8fd2f53: Combo card legs now carry a match pin and no longer link to the match page: a tap on the pin adds the match to the Following tab, and the right arrow that closed the widget on a phone is gone. Adds optional `pinEnabled` to `ComboLeg`; an older server that omits it shows no pin.
26
+
27
+ ### Patch Changes
28
+
29
+ - Updated dependencies [8fd2f53]
30
+ - @sensiblestats/widget-sdk@0.46.0
31
+
3
32
  ## 0.70.1
4
33
 
5
34
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -1140,7 +1140,8 @@ function toComboLegVM(leg) {
1140
1140
  const insight = leg.insight && typeof leg.insight === "object" ? leg.insight : void 0;
1141
1141
  const insightId = str(insight?.insightId);
1142
1142
  const statText = str(insight?.text);
1143
- if (price === void 0 || matchOddsId === void 0 || matchId === void 0 || !home || !away || !selectionLabel || !insightId || !statText) return null;
1143
+ const hasStat = !!insightId && !!statText;
1144
+ if (price === void 0 || matchOddsId === void 0 || matchId === void 0 || !home || !away || !selectionLabel) return null;
1144
1145
  const line = str(leg.line);
1145
1146
  return {
1146
1147
  key: `${matchOddsId}`,
@@ -1161,8 +1162,8 @@ function toComboLegVM(leg) {
1161
1162
  oddsDecimal: price,
1162
1163
  matchOddsId,
1163
1164
  quotedAtUtc: str(leg.quotedAtUtc),
1164
- insightId,
1165
- statText
1165
+ ...hasStat ? { insightId, statText } : {},
1166
+ pinEnabled: leg.pinEnabled === true
1166
1167
  };
1167
1168
  }
1168
1169
  function toComboCardVM(card) {
@@ -1189,9 +1190,9 @@ function comboLegToSlipSelection(leg, conversationId) {
1189
1190
  const selection = {
1190
1191
  matchOddsId: leg.matchOddsId,
1191
1192
  matchId: leg.matchId,
1192
- oddsDecimal: leg.oddsDecimal,
1193
- insightId: leg.insightId
1193
+ oddsDecimal: leg.oddsDecimal
1194
1194
  };
1195
+ if (leg.insightId !== void 0) selection.insightId = leg.insightId;
1195
1196
  if (leg.quotedAtUtc !== void 0) selection.quotedAtUtc = leg.quotedAtUtc;
1196
1197
  if (conversationId !== void 0) selection.conversationId = conversationId;
1197
1198
  return selection;
@@ -1410,7 +1411,7 @@ function ChatHeader({
1410
1411
  var import_react22 = require("react");
1411
1412
 
1412
1413
  // src/presets.ts
1413
- var CLIENT_CAPABILITIES = ["price_presets"];
1414
+ var CLIENT_CAPABILITIES = ["price_presets", "price_presets_open"];
1414
1415
  var PRICE_TILE_PREFIX = "goal-preset-";
1415
1416
  function isPriceTile(tile) {
1416
1417
  const id = tile.signal?.entityId;
@@ -2083,16 +2084,20 @@ function usePresetTools() {
2083
2084
 
2084
2085
  // src/components/ComboCardList.tsx
2085
2086
  var import_jsx_runtime14 = require("react/jsx-runtime");
2086
- function ComboLegRow({ leg, addToSlipEnabled, ui, slip }) {
2087
+ function ComboLegRow({ leg, addToSlipEnabled, ui, slip, monitor }) {
2087
2088
  const kickoffFallback = !leg.kickoffLabel && leg.kickoffUtc && ui?.bettingKickoff ? ui.bettingKickoff(leg.kickoffUtc) : void 0;
2088
2089
  const kickoff = leg.kickoffLabel ?? (kickoffFallback ? `${kickoffFallback.dayLabel} ${kickoffFallback.time}` : void 0);
2089
2090
  const selection = addToSlipEnabled ? comboLegToSlipSelection(leg, slip.conversationId) : null;
2091
+ const showPin = !!monitor && leg.pinEnabled && !!ui;
2090
2092
  return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("li", { className: "ss-w-combo-leg", children: [
2091
- leg.competition || kickoff ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "ss-w-combo-leg-meta", children: [
2093
+ leg.competition || kickoff || showPin ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "ss-w-combo-leg-meta", children: [
2092
2094
  /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "ss-w-bi-comp", children: leg.competition ?? "" }),
2093
- kickoff ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "ss-w-bi-kick", children: kickoff }) : null
2095
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "ss-w-bi-meta-right", children: [
2096
+ kickoff ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "ss-w-bi-kick", children: kickoff }) : null,
2097
+ showPin && ui ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(PinToggle, { ui, monitor, pin: { kind: "match", matchId: leg.matchId } }) : null
2098
+ ] })
2094
2099
  ] }) : null,
2095
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(MatchLink, { as: "div", matchId: leg.matchId, home: leg.homeTeamName, away: leg.awayTeamName, className: "ss-w-bi-fixture-line", children: [
2100
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "ss-w-bi-fixture-line", children: [
2096
2101
  /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Crest2, { kind: "team", url: leg.homeCrest, name: leg.homeTeamName }),
2097
2102
  /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "ss-w-bi-team", children: leg.homeTeamName }),
2098
2103
  /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "ss-w-bi-vs", "aria-hidden": "true", children: "vs" }),
@@ -2119,22 +2124,22 @@ function ComboLegRow({ leg, addToSlipEnabled, ui, slip }) {
2119
2124
  }
2120
2125
  )
2121
2126
  ] }),
2122
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "ss-w-combo-leg-stat", children: leg.statText })
2127
+ leg.statText ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "ss-w-combo-leg-stat", children: leg.statText }) : null
2123
2128
  ] });
2124
2129
  }
2125
- function ComboCardView({ vm, ui, slip }) {
2130
+ function ComboCardView({ vm, ui, slip, monitor }) {
2126
2131
  const tools = usePresetTools();
2127
2132
  const { target, legCount } = vm;
2128
2133
  return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "ss-w-combo", children: [
2129
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("ol", { className: "ss-w-combo-legs", role: "list", children: vm.legs.map((leg) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ComboLegRow, { leg, addToSlipEnabled: vm.addToSlipEnabled, ui, slip }, leg.key)) }),
2134
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("ol", { className: "ss-w-combo-legs", role: "list", children: vm.legs.map((leg) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ComboLegRow, { leg, addToSlipEnabled: vm.addToSlipEnabled, ui, slip, monitor }, leg.key)) }),
2130
2135
  /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "ss-w-combo-math", children: vm.multiplication }),
2131
2136
  vm.replacedNote ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "ss-w-combo-note", children: vm.replacedNote }) : null,
2132
2137
  tools && target !== void 0 && legCount !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", className: "ss-w-combo-change", onClick: () => tools.openBuilder(target, legCount), children: tools.changeLabel }) : null
2133
2138
  ] });
2134
2139
  }
2135
- function ComboCardList({ cards, ui, slip }) {
2140
+ function ComboCardList({ cards, ui, slip, monitor }) {
2136
2141
  if (!cards || cards.length === 0) return null;
2137
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "ss-w-combos", children: cards.map((vm) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ComboCardView, { vm, ui, slip }, vm.id)) });
2142
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "ss-w-combos", children: cards.map((vm) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ComboCardView, { vm, ui, slip, monitor }, vm.id)) });
2138
2143
  }
2139
2144
 
2140
2145
  // src/components/MarketOddsCardList.tsx
@@ -3397,7 +3402,7 @@ function ChatMessage({ message, disabled, onAct, onTap, ui, slip, monitor }) {
3397
3402
  message.clubFanDashboard ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(ClubFanDashboard, { dashboard: message.clubFanDashboard, onTap: onFanDashboardTap, ui }) : null,
3398
3403
  /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(EntityCardList, { cards: message.cards, disabled, showLessLabel: ui?.showLess, showMoreLabel: ui?.showMore }),
3399
3404
  /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(BettingInsightList, { insights: message.insights, ui, slip, monitor }),
3400
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(ComboCardList, { cards: message.comboCards ?? [], ui, slip }),
3405
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(ComboCardList, { cards: message.comboCards ?? [], ui, slip, monitor }),
3401
3406
  compact ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(CompactOddsList, { list: compact, ui, slip, monitor }) : /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(MarketOddsCardList, { cards: message.marketOdds, ui, slip, monitor }),
3402
3407
  /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(OddsMovementCardList, { cards: message.oddsMovement, ui, monitor }),
3403
3408
  /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(ActionButtons, { actions: message.actions, loading: false, disabled, onAct })
@@ -7099,6 +7104,20 @@ function findCombo(grid, total, legs) {
7099
7104
  const whole = !!combo && typeof combo.multiplication === "string" && combo.multiplication !== "" && Array.isArray(combo.legs) && combo.legs.length === legs && combo.legs.every(drawable);
7100
7105
  return cell && whole ? cell : null;
7101
7106
  }
7107
+ function legsForTotal(grid, total, legs) {
7108
+ if (findCombo(grid, total, legs)) return legs;
7109
+ let best = legs;
7110
+ let bestGap = Infinity;
7111
+ for (const n of comboLegChoices(grid)) {
7112
+ if (!findCombo(grid, total, n)) continue;
7113
+ const gap = Math.abs(n - legs);
7114
+ if (gap < bestGap) {
7115
+ best = n;
7116
+ bestGap = gap;
7117
+ }
7118
+ }
7119
+ return best;
7120
+ }
7102
7121
  function idsOf(picks) {
7103
7122
  return { matchOddsIds: picks.map((p) => p.matchOddsId), matchIds: picks.map((p) => p.matchId) };
7104
7123
  }
@@ -7242,8 +7261,10 @@ function SetNumbersTool({ grid, strings, streaming, formatKickoff, onSend, onClo
7242
7261
  };
7243
7262
  const nextTotal = () => {
7244
7263
  const v = cycle(totals, total);
7264
+ const l = legsForTotal(grid, v, legs);
7245
7265
  setTotal(v);
7246
- announce(strings.comboDisplay(legs, v), !!findCombo(grid, v, legs));
7266
+ setLegs(l);
7267
+ announce(strings.comboDisplay(l, v), !!findCombo(grid, v, l));
7247
7268
  };
7248
7269
  return /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(PresetToolModal, { title: strings.setNumbers, closeLabel: strings.close, onClose, children: [
7249
7270
  /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("section", { className: "ss-w-tool-row", children: [
@@ -7283,7 +7304,10 @@ function BuildComboTool({ grid, strings, streaming, formatKickoff, initialTotal,
7283
7304
  const totals = comboTotals(grid);
7284
7305
  const legChoices = comboLegChoices(grid);
7285
7306
  const [total, setTotal] = (0, import_react41.useState)(() => initialTotal !== void 0 ? nearest(totals, initialTotal) : startValue(totals, START.comboTotal));
7286
- const [legs, setLegs] = (0, import_react41.useState)(() => initialLegs !== void 0 ? clampLegs(legChoices, initialLegs) : startValue(legChoices, START.comboLegs));
7307
+ const [legs, setLegs] = (0, import_react41.useState)(() => {
7308
+ const start = initialLegs !== void 0 ? clampLegs(legChoices, initialLegs) : startValue(legChoices, START.comboLegs);
7309
+ return initialTotal !== void 0 ? legsForTotal(grid, nearest(totals, initialTotal), start) : start;
7310
+ });
7287
7311
  const [announcement, setAnnouncement] = (0, import_react41.useState)("");
7288
7312
  const cell = findCombo(grid, total, legs);
7289
7313
  const minLegs = legChoices[0] ?? legs;
@@ -7301,7 +7325,7 @@ function BuildComboTool({ grid, strings, streaming, formatKickoff, initialTotal,
7301
7325
  return /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(PresetToolModal, { title: strings.buildCombo, closeLabel: strings.close, onClose, footer, children: [
7302
7326
  /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { className: "ss-w-tool-section", role: "group", "aria-label": strings.totalLabel, children: [
7303
7327
  /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", { className: "ss-w-tool-label", "aria-hidden": "true", children: strings.totalLabel }),
7304
- /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("div", { className: "ss-w-tool-chips", children: totals.map((t) => /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("button", { type: "button", className: "ss-w-tool-chip", "aria-pressed": samePrice(t, total), onClick: () => choose(t, legs), children: t.toFixed(1) }, t)) })
7328
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("div", { className: "ss-w-tool-chips", children: totals.map((t) => /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("button", { type: "button", className: "ss-w-tool-chip", "aria-pressed": samePrice(t, total), onClick: () => choose(t, samePrice(t, total) ? legs : legsForTotal(grid, t, legs)), children: t.toFixed(1) }, t)) })
7305
7329
  ] }),
7306
7330
  /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { className: "ss-w-tool-section", role: "group", "aria-label": strings.matchesLabel, children: [
7307
7331
  /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", { className: "ss-w-tool-label", "aria-hidden": "true", children: strings.matchesLabel }),
@@ -10905,7 +10929,7 @@ function StatsWidget(props) {
10905
10929
  const gamesResult = useGames(built?.conversation ?? null, { activeTab: monitor.activeTab });
10906
10930
  const leaderboardResult = useLeaderboard(built?.conversation ?? null, { activeTab: monitor.activeTab });
10907
10931
  const getPricePresets = (0, import_react55.useCallback)(
10908
- (locale2) => built ? built.conversation.getPricePresets(locale2) : Promise.resolve(null),
10932
+ (locale2) => built ? built.conversation.getPricePresets(locale2, { pool: "open" }) : Promise.resolve(null),
10909
10933
  [built]
10910
10934
  );
10911
10935
  const presetGrid = usePresetGrid({ getPricePresets, isOpen: controller.state.isOpen, locale: ui.presets.lang });