@sensiblestats/widget-react 0.48.0 → 0.48.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/CHANGELOG.md +12 -0
- package/dist/index.cjs +25 -63
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +25 -63
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1498,56 +1498,22 @@ function writeSchedule(operatorId, localDate, payload, nowMs) {
|
|
|
1498
1498
|
}
|
|
1499
1499
|
|
|
1500
1500
|
// src/dueSet.ts
|
|
1501
|
-
var
|
|
1501
|
+
var TERMINAL_PHASES = /* @__PURE__ */ new Set(["fullTime", "postponed"]);
|
|
1502
1502
|
function dueMatchIds(groups, states, nowMs) {
|
|
1503
1503
|
const due = /* @__PURE__ */ new Set();
|
|
1504
1504
|
for (const group of groups) {
|
|
1505
1505
|
for (const match of group.matches) {
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
if (
|
|
1506
|
+
if (nowMs - match.kickoffUnix * 1e3 < 0) continue;
|
|
1507
|
+
const phase = states[match.matchId]?.phase;
|
|
1508
|
+
if (phase !== void 0 && TERMINAL_PHASES.has(phase)) continue;
|
|
1509
|
+
due.add(match.matchId);
|
|
1509
1510
|
}
|
|
1510
1511
|
}
|
|
1511
1512
|
return [...due];
|
|
1512
1513
|
}
|
|
1513
1514
|
|
|
1514
|
-
// src/liveClock.ts
|
|
1515
|
-
var STALE_READING_MS = 5 * 6e4;
|
|
1516
|
-
function parseMinute(label) {
|
|
1517
|
-
if (!label) return null;
|
|
1518
|
-
const plus = /^(\d+)\+(\d+)'$/.exec(label);
|
|
1519
|
-
if (plus) return Number(plus[1]) + Number(plus[2]);
|
|
1520
|
-
const plain = /^(\d+)'$/.exec(label);
|
|
1521
|
-
return plain ? Number(plain[1]) : null;
|
|
1522
|
-
}
|
|
1523
|
-
function readingAgeMs(state, nowMs) {
|
|
1524
|
-
if (!state?.stateAsOfUtc) return null;
|
|
1525
|
-
const t = Date.parse(state.stateAsOfUtc);
|
|
1526
|
-
return Number.isNaN(t) ? null : Math.max(0, nowMs - t);
|
|
1527
|
-
}
|
|
1528
|
-
function isReadingStale(state, nowMs) {
|
|
1529
|
-
if (state?.isHalfTime) return false;
|
|
1530
|
-
const age = readingAgeMs(state, nowMs);
|
|
1531
|
-
return age !== null && age > STALE_READING_MS;
|
|
1532
|
-
}
|
|
1533
|
-
function displayMinute(state, nowMs) {
|
|
1534
|
-
if (!state || state.phase !== "live") return null;
|
|
1535
|
-
if (state.isHalfTime) return null;
|
|
1536
|
-
if (isReadingStale(state, nowMs)) return null;
|
|
1537
|
-
const base = parseMinute(state.minuteLabel);
|
|
1538
|
-
if (base === null) return null;
|
|
1539
|
-
const age = readingAgeMs(state, nowMs);
|
|
1540
|
-
if (age === null) return state.minuteLabel ?? null;
|
|
1541
|
-
const advanced = base + Math.floor(age / 6e4);
|
|
1542
|
-
return `${advanced}'`;
|
|
1543
|
-
}
|
|
1544
|
-
function isTreatedLive(state, pollStale, nowMs) {
|
|
1545
|
-
return state?.phase === "live" && !pollStale && !isReadingStale(state, nowMs);
|
|
1546
|
-
}
|
|
1547
|
-
|
|
1548
1515
|
// src/useMatchDiscovery.ts
|
|
1549
1516
|
var POLL_MS = 6e4;
|
|
1550
|
-
var CLOCK_MS = 1e4;
|
|
1551
1517
|
var ROLLOVER_CHECK_MS = 6e4;
|
|
1552
1518
|
var STALE_AFTER_FAILURES = 2;
|
|
1553
1519
|
function localDateOf(now) {
|
|
@@ -1560,7 +1526,6 @@ function useMatchDiscovery(opts) {
|
|
|
1560
1526
|
const [groups, setGroups] = useState2([]);
|
|
1561
1527
|
const [states, setStates] = useState2({});
|
|
1562
1528
|
const [failures, setFailures] = useState2(0);
|
|
1563
|
-
const [nowMs, setNowMs] = useState2(() => Date.now());
|
|
1564
1529
|
const [expanded, setExpanded] = useState2({});
|
|
1565
1530
|
const [touched, setTouched] = useState2({});
|
|
1566
1531
|
const groupsRef = useRef4(groups);
|
|
@@ -1638,21 +1603,16 @@ function useMatchDiscovery(opts) {
|
|
|
1638
1603
|
}, POLL_MS);
|
|
1639
1604
|
return () => clearInterval(id);
|
|
1640
1605
|
}, [opts.isOpen, tick, groups]);
|
|
1641
|
-
useEffect4(() => {
|
|
1642
|
-
if (!opts.isOpen) return;
|
|
1643
|
-
const id = setInterval(() => setNowMs(Date.now()), CLOCK_MS);
|
|
1644
|
-
return () => clearInterval(id);
|
|
1645
|
-
}, [opts.isOpen]);
|
|
1646
1606
|
const stale = failures >= STALE_AFTER_FAILURES;
|
|
1647
1607
|
const liveCount = useMemo2(
|
|
1648
|
-
() => stale ? 0 : Object.values(states).filter((s) => s.phase === "live"
|
|
1649
|
-
[states, stale
|
|
1608
|
+
() => stale ? 0 : Object.values(states).filter((s) => s.phase === "live").length,
|
|
1609
|
+
[states, stale]
|
|
1650
1610
|
);
|
|
1651
1611
|
const toggleGroup = useCallback3((competitionId) => {
|
|
1652
1612
|
setTouched((prev) => ({ ...prev, [competitionId]: true }));
|
|
1653
1613
|
setExpanded((prev) => ({ ...prev, [competitionId]: !prev[competitionId] }));
|
|
1654
1614
|
}, []);
|
|
1655
|
-
return { groups, states,
|
|
1615
|
+
return { groups, states, liveCount, stale, expanded, toggleGroup, _tick: tick };
|
|
1656
1616
|
}
|
|
1657
1617
|
|
|
1658
1618
|
// src/eventLogContext.ts
|
|
@@ -3010,7 +2970,7 @@ function computeDisplayMinute(minute, clockRunning, receivedAtMs) {
|
|
|
3010
2970
|
return minute + Math.min(Math.max(0, elapsedMinutes), MAX_LIVE_TICK_MINUTES);
|
|
3011
2971
|
}
|
|
3012
2972
|
function useLiveClock(minute, clockRunning, receivedAtMs) {
|
|
3013
|
-
const [
|
|
2973
|
+
const [displayMinute, setDisplayMinute] = useState15(
|
|
3014
2974
|
() => computeDisplayMinute(minute, clockRunning, receivedAtMs)
|
|
3015
2975
|
);
|
|
3016
2976
|
useEffect9(() => {
|
|
@@ -3021,7 +2981,7 @@ function useLiveClock(minute, clockRunning, receivedAtMs) {
|
|
|
3021
2981
|
}, TICK_MS);
|
|
3022
2982
|
return () => window.clearInterval(id);
|
|
3023
2983
|
}, [minute, clockRunning, receivedAtMs]);
|
|
3024
|
-
return
|
|
2984
|
+
return displayMinute;
|
|
3025
2985
|
}
|
|
3026
2986
|
|
|
3027
2987
|
// src/components/dashboard/LiveScoreCard.tsx
|
|
@@ -3053,7 +3013,7 @@ function LiveScoreCard({
|
|
|
3053
3013
|
if (!seedRef.current || seedRef.current.key !== seedKey) {
|
|
3054
3014
|
seedRef.current = { key: seedKey, receivedAtMs: Date.now() };
|
|
3055
3015
|
}
|
|
3056
|
-
const
|
|
3016
|
+
const displayMinute = useLiveClock(data.minute, data.clockRunning, seedRef.current.receivedAtMs);
|
|
3057
3017
|
const minuteSuffix = data.minuteLabel.replace(/^\d+/, "");
|
|
3058
3018
|
const scorers = scorersLine(goalEvents);
|
|
3059
3019
|
return /* @__PURE__ */ jsxs32("div", { className: "ss-w-fandash-card ss-w-fandash-live-score", children: [
|
|
@@ -3063,7 +3023,7 @@ function LiveScoreCard({
|
|
|
3063
3023
|
/* @__PURE__ */ jsx36("span", { className: "ss-w-fandash-live-dot", "aria-hidden": "true" }),
|
|
3064
3024
|
data.statusLabel
|
|
3065
3025
|
] }),
|
|
3066
|
-
/* @__PURE__ */ jsx36("span", { className: "ss-w-fandash-live-minute", children: `${
|
|
3026
|
+
/* @__PURE__ */ jsx36("span", { className: "ss-w-fandash-live-minute", children: `${displayMinute}${minuteSuffix}` }),
|
|
3067
3027
|
data.competition ? /* @__PURE__ */ jsx36("span", { className: "ss-w-fandash-live-competition", children: data.competition }) : null
|
|
3068
3028
|
] }),
|
|
3069
3029
|
/* @__PURE__ */ jsxs32("div", { className: "ss-w-fandash-live-main", children: [
|
|
@@ -3745,11 +3705,10 @@ function Side({ name, crest }) {
|
|
|
3745
3705
|
/* @__PURE__ */ jsx49("span", { className: "ss-w-drow-nm", children: name })
|
|
3746
3706
|
] });
|
|
3747
3707
|
}
|
|
3748
|
-
function FixtureRow({ match, state, stale,
|
|
3749
|
-
const
|
|
3750
|
-
const isLive = state?.phase === "live" && !stale && !readingStale;
|
|
3708
|
+
function FixtureRow({ match, state, stale, ui, monitor }) {
|
|
3709
|
+
const isLive = state?.phase === "live" && !stale;
|
|
3751
3710
|
const hasScore = (state?.phase === "live" || state?.phase === "fullTime") && typeof state.homeScore === "number" && typeof state.awayScore === "number";
|
|
3752
|
-
const ticked =
|
|
3711
|
+
const ticked = state?.phase === "live" ? state.minuteLabel ?? null : null;
|
|
3753
3712
|
const isFinished = state?.phase === "fullTime";
|
|
3754
3713
|
const when = state?.isHalfTime && !stale ? ui.halfTime : isLive ? ticked ?? "\u2014" : state?.phase === "live" ? "\u2014" : isFinished ? ui.fullTime : kickoffLabel(match.kickoffUnix);
|
|
3755
3714
|
const pin = { kind: "match", matchId: match.matchId };
|
|
@@ -3765,10 +3724,15 @@ function FixtureRow({ match, state, stale, nowMs, ui, monitor }) {
|
|
|
3765
3724
|
] });
|
|
3766
3725
|
}
|
|
3767
3726
|
|
|
3727
|
+
// src/liveClock.ts
|
|
3728
|
+
function isTreatedLive(state, pollStale) {
|
|
3729
|
+
return state?.phase === "live" && !pollStale;
|
|
3730
|
+
}
|
|
3731
|
+
|
|
3768
3732
|
// src/components/CompetitionGroup.tsx
|
|
3769
3733
|
import { jsx as jsx50, jsxs as jsxs45 } from "react/jsx-runtime";
|
|
3770
|
-
function CompetitionGroup({ group, open, onToggle, states, stale,
|
|
3771
|
-
const own = group.matches.filter((m) => !isTreatedLive(states[m.matchId], stale
|
|
3734
|
+
function CompetitionGroup({ group, open, onToggle, states, stale, ui, monitor, disambiguate = false }) {
|
|
3735
|
+
const own = group.matches.filter((m) => !isTreatedLive(states[m.matchId], stale));
|
|
3772
3736
|
const hasLive = own.length !== group.matches.length;
|
|
3773
3737
|
if (own.length === 0) {
|
|
3774
3738
|
return null;
|
|
@@ -3787,15 +3751,15 @@ function CompetitionGroup({ group, open, onToggle, states, stale, nowMs, ui, mon
|
|
|
3787
3751
|
] }),
|
|
3788
3752
|
/* @__PURE__ */ jsx50("span", { className: "ss-w-grp-count", children: own.length })
|
|
3789
3753
|
] }),
|
|
3790
|
-
open && /* @__PURE__ */ jsx50("div", { className: "ss-w-grp-body", children: own.map((m) => /* @__PURE__ */ jsx50(FixtureRow, { match: m, state: states[m.matchId], stale,
|
|
3754
|
+
open && /* @__PURE__ */ jsx50("div", { className: "ss-w-grp-body", children: own.map((m) => /* @__PURE__ */ jsx50(FixtureRow, { match: m, state: states[m.matchId], stale, ui, monitor }, m.matchId)) })
|
|
3791
3755
|
] });
|
|
3792
3756
|
}
|
|
3793
3757
|
|
|
3794
3758
|
// src/components/TodayPanel.tsx
|
|
3795
3759
|
import { Fragment as Fragment7, jsx as jsx51, jsxs as jsxs46 } from "react/jsx-runtime";
|
|
3796
3760
|
function TodayPanel({ discovery, ui, monitor }) {
|
|
3797
|
-
const { groups, states,
|
|
3798
|
-
const liveRows = stale ? [] : groups.flatMap((group) => group.matches.filter((m) => isTreatedLive(states[m.matchId], stale
|
|
3761
|
+
const { groups, states, stale, expanded, toggleGroup } = discovery;
|
|
3762
|
+
const liveRows = stale ? [] : groups.flatMap((group) => group.matches.filter((m) => isTreatedLive(states[m.matchId], stale)).map((match) => ({ match, rank: group.rank }))).sort((a, b) => a.rank - b.rank);
|
|
3799
3763
|
const nameCounts = groups.reduce((acc, g) => {
|
|
3800
3764
|
acc[g.competitionName] = (acc[g.competitionName] ?? 0) + 1;
|
|
3801
3765
|
return acc;
|
|
@@ -3813,7 +3777,6 @@ function TodayPanel({ discovery, ui, monitor }) {
|
|
|
3813
3777
|
match,
|
|
3814
3778
|
state: states[match.matchId],
|
|
3815
3779
|
stale,
|
|
3816
|
-
nowMs,
|
|
3817
3780
|
ui,
|
|
3818
3781
|
monitor
|
|
3819
3782
|
},
|
|
@@ -3829,7 +3792,6 @@ function TodayPanel({ discovery, ui, monitor }) {
|
|
|
3829
3792
|
disambiguate: (nameCounts[group.competitionName] ?? 0) > 1,
|
|
3830
3793
|
states,
|
|
3831
3794
|
stale,
|
|
3832
|
-
nowMs,
|
|
3833
3795
|
ui,
|
|
3834
3796
|
monitor
|
|
3835
3797
|
},
|