@sensiblestats/widget-react 0.60.0 → 0.60.2

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/index.js CHANGED
@@ -138,6 +138,18 @@ var STRINGS = {
138
138
  alreadyPlayedTitle: "Played today",
139
139
  guess: "Guess",
140
140
  formatDayTime: (iso) => new Intl.DateTimeFormat("en-GB", { weekday: "short", hour: "2-digit", minute: "2-digit" }).format(new Date(iso)),
141
+ titles: {
142
+ "mystery-tiger": "Mystery Player",
143
+ "daily-quiz": "Daily Quiz",
144
+ "career-path": "Career Path",
145
+ "beat-the-grid": "Beat the Grid",
146
+ "guess-the-xi": "Guess the XI",
147
+ "higher-or-lower": "Higher or Lower",
148
+ "matchday-predictor": "Matchday Predictor",
149
+ "starting-xi": "Starting XI",
150
+ "stat-ladder": "Stat Ladder",
151
+ "fan-motm": "Fan MOTM"
152
+ },
141
153
  taglines: {
142
154
  "mystery-tiger": "One player. Six guesses.",
143
155
  "higher-or-lower": "Who had more?",
@@ -421,6 +433,18 @@ var STRINGS = {
421
433
  alreadyPlayedTitle: "Bug\xFCn oynad\u0131n",
422
434
  guess: "Tahmin",
423
435
  formatDayTime: (iso) => new Intl.DateTimeFormat("tr-TR", { weekday: "short", hour: "2-digit", minute: "2-digit" }).format(new Date(iso)),
436
+ titles: {
437
+ "mystery-tiger": "Gizemli Oyuncu",
438
+ "daily-quiz": "G\xFCn\xFCn Testi",
439
+ "career-path": "Kariyer Yolu",
440
+ "beat-the-grid": "Tabloyu Tamamla",
441
+ "guess-the-xi": "Bu 11 Kimin?",
442
+ "higher-or-lower": "Fazla m\u0131, Az m\u0131?",
443
+ "matchday-predictor": "Skor Tahmini",
444
+ "starting-xi": "\u0130lk 11 Tahmini",
445
+ "stat-ladder": "\u0130statistik Merdiveni",
446
+ "fan-motm": "Ma\xE7\u0131n Oyuncusu"
447
+ },
424
448
  taglines: {
425
449
  "mystery-tiger": "Bir oyuncu. Alt\u0131 tahmin.",
426
450
  "higher-or-lower": "Kimin daha fazlas\u0131 var?",
@@ -2150,6 +2174,7 @@ function useLeaderboard(conversation, { activeTab }) {
2150
2174
  void doFetch();
2151
2175
  return () => {
2152
2176
  active = false;
2177
+ inFlightRef.current = false;
2153
2178
  };
2154
2179
  }, [activeTab, refreshCount]);
2155
2180
  const refresh = useCallback5(() => {
@@ -4385,23 +4410,11 @@ function GamesLoginWall({ ui }) {
4385
4410
  import { useEffect as useEffect13, useState as useState22 } from "react";
4386
4411
 
4387
4412
  // src/components/games/ui/gameMeta.ts
4388
- var GAME_TITLES = {
4389
- "mystery-tiger": "Mystery Tiger",
4390
- "daily-quiz": "Daily Quiz",
4391
- "career-path": "Career Path",
4392
- "beat-the-grid": "Beat the Grid",
4393
- "guess-the-xi": "Guess the XI",
4394
- "higher-or-lower": "Higher or Lower",
4395
- "matchday-predictor": "Matchday Predictor",
4396
- "starting-xi": "Starting XI",
4397
- "stat-ladder": "Stat Ladder",
4398
- "fan-motm": "Fan MOTM"
4399
- };
4400
4413
  function prettifyGameId(gameId) {
4401
4414
  return gameId.split("-").map((w) => w ? w[0].toUpperCase() + w.slice(1) : w).join(" ");
4402
4415
  }
4403
- function gameTitle(g) {
4404
- return g.title ?? GAME_TITLES[g.gameId] ?? prettifyGameId(g.gameId);
4416
+ function gameTitle(g, titles) {
4417
+ return g.title ?? titles[g.gameId] ?? prettifyGameId(g.gameId);
4405
4418
  }
4406
4419
  function splitName(full) {
4407
4420
  const parts = full.trim().split(/\s+/).filter(Boolean);
@@ -4534,7 +4547,7 @@ var DISABLED = /* @__PURE__ */ new Set(["locked", "voided"]);
4534
4547
  function GameTile({ game, onOpen, ui, variant = "tile" }) {
4535
4548
  const status = tileStatus(game, ui);
4536
4549
  const disabled = DISABLED.has(game.status);
4537
- const title = gameTitle(game);
4550
+ const title = gameTitle(game, ui.games.titles);
4538
4551
  const body = variant === "hero" ? /* @__PURE__ */ jsxs49(Fragment9, { children: [
4539
4552
  /* @__PURE__ */ jsxs49("span", { className: "ss-g-hero-text", children: [
4540
4553
  /* @__PURE__ */ jsx56("span", { className: "ss-g-hero-eyebrow", children: ui.games.dailyChallenge }),
@@ -5069,7 +5082,7 @@ function MysteryTigerGame({
5069
5082
  /* @__PURE__ */ jsx67(
5070
5083
  GameHeader,
5071
5084
  {
5072
- title: gameTitle({ gameId: "mystery-tiger" }),
5085
+ title: gameTitle({ gameId: "mystery-tiger" }, ui.games.titles),
5073
5086
  eyebrow: t.eyebrow,
5074
5087
  right: headerRight,
5075
5088
  onBack,
@@ -5241,7 +5254,7 @@ function HigherOrLowerGame({
5241
5254
  /* @__PURE__ */ jsx68(
5242
5255
  GameHeader,
5243
5256
  {
5244
- title: gameTitle({ gameId: "higher-or-lower" }),
5257
+ title: gameTitle({ gameId: "higher-or-lower" }, ui.games.titles),
5245
5258
  eyebrow: t.eyebrow(POINTS_PER_CORRECT),
5246
5259
  right: config ? /* @__PURE__ */ jsx68(StatStack, { value: runLength, label: t.streak }) : void 0,
5247
5260
  onBack,
@@ -5342,7 +5355,7 @@ function CareerPathGame({
5342
5355
  ui
5343
5356
  }) {
5344
5357
  const s = ui.games.careerPath;
5345
- const title = gameTitle({ gameId: "career-path" });
5358
+ const title = gameTitle({ gameId: "career-path" }, ui.games.titles);
5346
5359
  const [query, setQuery] = useState27("");
5347
5360
  const inputId = useId3();
5348
5361
  const clientState = parseClientState3(result?.clientStateJson);
@@ -5592,7 +5605,7 @@ function BeatTheGridGame({
5592
5605
  playerPool
5593
5606
  }) {
5594
5607
  const s = ui.games.beatTheGrid;
5595
- const title = gameTitle({ gameId: "beat-the-grid" });
5608
+ const title = gameTitle({ gameId: "beat-the-grid" }, ui.games.titles);
5596
5609
  const [activeCell, setActiveCell] = useState28(null);
5597
5610
  const clientState = parseClientState4(result?.clientStateJson);
5598
5611
  const filledCells = clientState?.cells ?? [];
@@ -5846,7 +5859,7 @@ function GuessTheXiGame({
5846
5859
  /* @__PURE__ */ jsx73(
5847
5860
  GameHeader,
5848
5861
  {
5849
- title: gameTitle({ gameId: "guess-the-xi" }),
5862
+ title: gameTitle({ gameId: "guess-the-xi" }, ui.games.titles),
5850
5863
  eyebrow: config?.poolLabel,
5851
5864
  right: formation ? /* @__PURE__ */ jsx73(Chip, { variant: "accent", children: formation }) : void 0,
5852
5865
  onBack,
@@ -5967,7 +5980,7 @@ function DailyQuizGame({
5967
5980
  ui
5968
5981
  }) {
5969
5982
  const s = ui.games.dailyQuiz;
5970
- const title = gameTitle({ gameId: "daily-quiz" });
5983
+ const title = gameTitle({ gameId: "daily-quiz" }, ui.games.titles);
5971
5984
  const [selections, setSelections] = useState30(/* @__PURE__ */ new Map());
5972
5985
  const [page, setPage] = useState30(0);
5973
5986
  const clientState = parseClientState6(result?.clientStateJson);
@@ -6183,7 +6196,7 @@ function MatchdayPredictorGame({
6183
6196
  const header = /* @__PURE__ */ jsx75(
6184
6197
  GameHeader,
6185
6198
  {
6186
- title: gameTitle({ gameId: "matchday-predictor" }),
6199
+ title: gameTitle({ gameId: "matchday-predictor" }, ui.games.titles),
6187
6200
  eyebrow: config ? t.eyebrow(config.homeTeam.name, config.awayTeam.name) : void 0,
6188
6201
  right: config ? /* @__PURE__ */ jsx75(Chip, { icon: /* @__PURE__ */ jsx75(IconLock, {}), children: ui.games.formatDayTime(config.kickoffUtc) }) : void 0,
6189
6202
  onBack,
@@ -6397,7 +6410,7 @@ function StartingXiGame({
6397
6410
  const header = /* @__PURE__ */ jsx76(
6398
6411
  GameHeader,
6399
6412
  {
6400
- title: gameTitle({ gameId: "starting-xi" }),
6413
+ title: gameTitle({ gameId: "starting-xi" }, ui.games.titles),
6401
6414
  eyebrow: t.eyebrow,
6402
6415
  right: /* @__PURE__ */ jsx76(Chip, { variant: "accent", children: t.perStarter(POINTS_PER_STARTER) }),
6403
6416
  onBack,
@@ -6572,7 +6585,7 @@ function StatLadderGame({
6572
6585
  const searchId = useId8();
6573
6586
  const clientState = parseClientState9(result?.clientStateJson);
6574
6587
  const revealed = clientState != null;
6575
- const header = /* @__PURE__ */ jsx77(GameHeader, { title: gameTitle({ gameId: "stat-ladder" }), eyebrow: t.eyebrow, onBack, backLabel: ui.back });
6588
+ const header = /* @__PURE__ */ jsx77(GameHeader, { title: gameTitle({ gameId: "stat-ladder" }, ui.games.titles), eyebrow: t.eyebrow, onBack, backLabel: ui.back });
6576
6589
  if (!config) {
6577
6590
  return /* @__PURE__ */ jsxs65("div", { className: "ss-g-screen", "data-testid": "game-screen-stat-ladder", children: [
6578
6591
  header,
@@ -6769,6 +6782,7 @@ function safeParseConfig(json) {
6769
6782
  function GameScreenHost({
6770
6783
  selected,
6771
6784
  onBack,
6785
+ onPlayed,
6772
6786
  conversation,
6773
6787
  ui
6774
6788
  }) {
@@ -6812,7 +6826,11 @@ function GameScreenHost({
6812
6826
  const sharedProps = {
6813
6827
  result,
6814
6828
  submitting,
6815
- onSubmit: submit,
6829
+ // Refresh only after the play is saved: a fan can tap Back while a submit is still in flight,
6830
+ // and a refetch fired from Back alone would read the hub's pre-play state.
6831
+ onSubmit: (answerJson) => {
6832
+ void submit(answerJson).then(() => onPlayed?.());
6833
+ },
6816
6834
  ui,
6817
6835
  onBack,
6818
6836
  lockAtUtc
@@ -6903,7 +6921,7 @@ function GameScreenHost({
6903
6921
  }
6904
6922
  );
6905
6923
  default:
6906
- return /* @__PURE__ */ jsx79("div", { className: "ss-g-screen", "data-testid": `game-screen-${gameId}`, children: /* @__PURE__ */ jsx79(GameHeader, { title: gameTitle({ gameId }), onBack, backLabel: ui.back }) });
6924
+ return /* @__PURE__ */ jsx79("div", { className: "ss-g-screen", "data-testid": `game-screen-${gameId}`, children: /* @__PURE__ */ jsx79(GameHeader, { title: gameTitle({ gameId }, ui.games.titles), onBack, backLabel: ui.back }) });
6907
6925
  }
6908
6926
  }
6909
6927
  return /* @__PURE__ */ jsx79("div", { className: "ss-w-gscreen", "data-testid": "gscreen", "data-lock-at": lockAtUtc ?? void 0, children: renderScreen() });
@@ -6929,7 +6947,8 @@ function GamesPanel({
6929
6947
  games,
6930
6948
  ui,
6931
6949
  conversation,
6932
- leaderboard
6950
+ leaderboard,
6951
+ refreshHub
6933
6952
  }) {
6934
6953
  const [selected, setSelected] = useState35(null);
6935
6954
  useEffect16(() => {
@@ -6941,7 +6960,11 @@ function GamesPanel({
6941
6960
  GameScreenHost,
6942
6961
  {
6943
6962
  selected,
6944
- onBack: () => setSelected(null),
6963
+ onBack: () => {
6964
+ setSelected(null);
6965
+ refreshHub?.();
6966
+ },
6967
+ onPlayed: refreshHub,
6945
6968
  conversation: conversation ?? null,
6946
6969
  ui
6947
6970
  }
@@ -7191,7 +7214,20 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
7191
7214
  monitor && discovery && monitor.activeTab === "today" && /* @__PURE__ */ jsx85(TodayPanel, { discovery, ui, monitor }),
7192
7215
  monitor && monitor.activeTab === "following" && /* @__PURE__ */ jsx85(MatchesPanel, { monitor, ui, slip }),
7193
7216
  monitor && monitor.activeTab === "odds" && /* @__PURE__ */ jsx85(OddsPanel, { monitor, ui, slip }),
7194
- monitor && monitor.activeTab === "games" && gamesResult && /* @__PURE__ */ jsx85(GamesPanel, { loggedIn: !!loggedIn, games: gamesResult.games, ui, conversation, leaderboard: leaderboardResult?.data ?? null }),
7217
+ monitor && monitor.activeTab === "games" && gamesResult && /* @__PURE__ */ jsx85(
7218
+ GamesPanel,
7219
+ {
7220
+ loggedIn: !!loggedIn,
7221
+ games: gamesResult.games,
7222
+ ui,
7223
+ conversation,
7224
+ leaderboard: leaderboardResult?.data ?? null,
7225
+ refreshHub: () => {
7226
+ gamesResult.refresh();
7227
+ leaderboardResult?.refresh();
7228
+ }
7229
+ }
7230
+ ),
7195
7231
  monitor && monitor.activeTab === "leaderboard" && leaderboardResult && /* @__PURE__ */ jsx85(
7196
7232
  LeaderboardPanel,
7197
7233
  {