@sensiblestats/widget-react 0.46.0 → 0.47.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 +21 -0
- package/dist/index.cjs +65 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +65 -17
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -91,6 +91,7 @@ var STRINGS = {
|
|
|
91
91
|
accordionSuspended: "Suspended",
|
|
92
92
|
tabToday: "Today",
|
|
93
93
|
sectionLive: "Live",
|
|
94
|
+
halfTime: "HT",
|
|
94
95
|
staleStates: "Live scores can't be updated \u2014 showing the last known state."
|
|
95
96
|
},
|
|
96
97
|
tr: {
|
|
@@ -168,6 +169,7 @@ var STRINGS = {
|
|
|
168
169
|
accordionSuspended: "Ask\u0131da",
|
|
169
170
|
tabToday: "Bug\xFCn",
|
|
170
171
|
sectionLive: "Canl\u0131",
|
|
172
|
+
halfTime: "\u0130Y",
|
|
171
173
|
staleStates: "Canl\u0131 skorlar g\xFCncellenemiyor \u2014 son bilinen durum g\xF6steriliyor."
|
|
172
174
|
}
|
|
173
175
|
};
|
|
@@ -246,6 +248,7 @@ function normalizeUi(cfg) {
|
|
|
246
248
|
tabOdds: strings.tabOdds,
|
|
247
249
|
tabToday: strings.tabToday,
|
|
248
250
|
sectionLive: strings.sectionLive,
|
|
251
|
+
halfTime: strings.halfTime,
|
|
249
252
|
staleStates: strings.staleStates,
|
|
250
253
|
pinLabel: strings.pinLabel,
|
|
251
254
|
unpinLabel: strings.unpinLabel,
|
|
@@ -1505,8 +1508,43 @@ function dueMatchIds(groups, states, nowMs) {
|
|
|
1505
1508
|
return [...due];
|
|
1506
1509
|
}
|
|
1507
1510
|
|
|
1511
|
+
// src/liveClock.ts
|
|
1512
|
+
var STALE_READING_MS = 5 * 6e4;
|
|
1513
|
+
function parseMinute(label) {
|
|
1514
|
+
if (!label) return null;
|
|
1515
|
+
const plus = /^(\d+)\+(\d+)'$/.exec(label);
|
|
1516
|
+
if (plus) return Number(plus[1]) + Number(plus[2]);
|
|
1517
|
+
const plain = /^(\d+)'$/.exec(label);
|
|
1518
|
+
return plain ? Number(plain[1]) : null;
|
|
1519
|
+
}
|
|
1520
|
+
function readingAgeMs(state, nowMs) {
|
|
1521
|
+
if (!state?.stateAsOfUtc) return null;
|
|
1522
|
+
const t = Date.parse(state.stateAsOfUtc);
|
|
1523
|
+
return Number.isNaN(t) ? null : Math.max(0, nowMs - t);
|
|
1524
|
+
}
|
|
1525
|
+
function isReadingStale(state, nowMs) {
|
|
1526
|
+
if (state?.isHalfTime) return false;
|
|
1527
|
+
const age = readingAgeMs(state, nowMs);
|
|
1528
|
+
return age !== null && age > STALE_READING_MS;
|
|
1529
|
+
}
|
|
1530
|
+
function displayMinute(state, nowMs) {
|
|
1531
|
+
if (!state || state.phase !== "live") return null;
|
|
1532
|
+
if (state.isHalfTime) return null;
|
|
1533
|
+
if (isReadingStale(state, nowMs)) return null;
|
|
1534
|
+
const base = parseMinute(state.minuteLabel);
|
|
1535
|
+
if (base === null) return null;
|
|
1536
|
+
const age = readingAgeMs(state, nowMs);
|
|
1537
|
+
if (age === null) return state.minuteLabel ?? null;
|
|
1538
|
+
const advanced = base + Math.floor(age / 6e4);
|
|
1539
|
+
return `${advanced}'`;
|
|
1540
|
+
}
|
|
1541
|
+
function isTreatedLive(state, pollStale, nowMs) {
|
|
1542
|
+
return state?.phase === "live" && !pollStale && !isReadingStale(state, nowMs);
|
|
1543
|
+
}
|
|
1544
|
+
|
|
1508
1545
|
// src/useMatchDiscovery.ts
|
|
1509
1546
|
var POLL_MS = 6e4;
|
|
1547
|
+
var CLOCK_MS = 1e4;
|
|
1510
1548
|
var ROLLOVER_CHECK_MS = 6e4;
|
|
1511
1549
|
var STALE_AFTER_FAILURES = 2;
|
|
1512
1550
|
function localDateOf(now) {
|
|
@@ -1519,6 +1557,7 @@ function useMatchDiscovery(opts) {
|
|
|
1519
1557
|
const [groups, setGroups] = useState2([]);
|
|
1520
1558
|
const [states, setStates] = useState2({});
|
|
1521
1559
|
const [failures, setFailures] = useState2(0);
|
|
1560
|
+
const [nowMs, setNowMs] = useState2(() => Date.now());
|
|
1522
1561
|
const [expanded, setExpanded] = useState2({});
|
|
1523
1562
|
const [touched, setTouched] = useState2({});
|
|
1524
1563
|
const groupsRef = useRef4(groups);
|
|
@@ -1596,16 +1635,21 @@ function useMatchDiscovery(opts) {
|
|
|
1596
1635
|
}, POLL_MS);
|
|
1597
1636
|
return () => clearInterval(id);
|
|
1598
1637
|
}, [opts.isOpen, tick, groups]);
|
|
1638
|
+
useEffect4(() => {
|
|
1639
|
+
if (!opts.isOpen) return;
|
|
1640
|
+
const id = setInterval(() => setNowMs(Date.now()), CLOCK_MS);
|
|
1641
|
+
return () => clearInterval(id);
|
|
1642
|
+
}, [opts.isOpen]);
|
|
1599
1643
|
const stale = failures >= STALE_AFTER_FAILURES;
|
|
1600
1644
|
const liveCount = useMemo2(
|
|
1601
|
-
() => stale ? 0 : Object.values(states).filter((s) => s.phase === "live").length,
|
|
1602
|
-
[states, stale]
|
|
1645
|
+
() => stale ? 0 : Object.values(states).filter((s) => s.phase === "live" && !isReadingStale(s, nowMs)).length,
|
|
1646
|
+
[states, stale, nowMs]
|
|
1603
1647
|
);
|
|
1604
1648
|
const toggleGroup = useCallback3((competitionId) => {
|
|
1605
1649
|
setTouched((prev) => ({ ...prev, [competitionId]: true }));
|
|
1606
1650
|
setExpanded((prev) => ({ ...prev, [competitionId]: !prev[competitionId] }));
|
|
1607
1651
|
}, []);
|
|
1608
|
-
return { groups, states, liveCount, stale, expanded, toggleGroup, _tick: tick };
|
|
1652
|
+
return { groups, states, nowMs, liveCount, stale, expanded, toggleGroup, _tick: tick };
|
|
1609
1653
|
}
|
|
1610
1654
|
|
|
1611
1655
|
// src/eventLogContext.ts
|
|
@@ -2963,7 +3007,7 @@ function computeDisplayMinute(minute, clockRunning, receivedAtMs) {
|
|
|
2963
3007
|
return minute + Math.min(Math.max(0, elapsedMinutes), MAX_LIVE_TICK_MINUTES);
|
|
2964
3008
|
}
|
|
2965
3009
|
function useLiveClock(minute, clockRunning, receivedAtMs) {
|
|
2966
|
-
const [
|
|
3010
|
+
const [displayMinute2, setDisplayMinute] = useState15(
|
|
2967
3011
|
() => computeDisplayMinute(minute, clockRunning, receivedAtMs)
|
|
2968
3012
|
);
|
|
2969
3013
|
useEffect9(() => {
|
|
@@ -2974,7 +3018,7 @@ function useLiveClock(minute, clockRunning, receivedAtMs) {
|
|
|
2974
3018
|
}, TICK_MS);
|
|
2975
3019
|
return () => window.clearInterval(id);
|
|
2976
3020
|
}, [minute, clockRunning, receivedAtMs]);
|
|
2977
|
-
return
|
|
3021
|
+
return displayMinute2;
|
|
2978
3022
|
}
|
|
2979
3023
|
|
|
2980
3024
|
// src/components/dashboard/LiveScoreCard.tsx
|
|
@@ -3006,7 +3050,7 @@ function LiveScoreCard({
|
|
|
3006
3050
|
if (!seedRef.current || seedRef.current.key !== seedKey) {
|
|
3007
3051
|
seedRef.current = { key: seedKey, receivedAtMs: Date.now() };
|
|
3008
3052
|
}
|
|
3009
|
-
const
|
|
3053
|
+
const displayMinute2 = useLiveClock(data.minute, data.clockRunning, seedRef.current.receivedAtMs);
|
|
3010
3054
|
const minuteSuffix = data.minuteLabel.replace(/^\d+/, "");
|
|
3011
3055
|
const scorers = scorersLine(goalEvents);
|
|
3012
3056
|
return /* @__PURE__ */ jsxs32("div", { className: "ss-w-fandash-card ss-w-fandash-live-score", children: [
|
|
@@ -3016,7 +3060,7 @@ function LiveScoreCard({
|
|
|
3016
3060
|
/* @__PURE__ */ jsx36("span", { className: "ss-w-fandash-live-dot", "aria-hidden": "true" }),
|
|
3017
3061
|
data.statusLabel
|
|
3018
3062
|
] }),
|
|
3019
|
-
/* @__PURE__ */ jsx36("span", { className: "ss-w-fandash-live-minute", children: `${
|
|
3063
|
+
/* @__PURE__ */ jsx36("span", { className: "ss-w-fandash-live-minute", children: `${displayMinute2}${minuteSuffix}` }),
|
|
3020
3064
|
data.competition ? /* @__PURE__ */ jsx36("span", { className: "ss-w-fandash-live-competition", children: data.competition }) : null
|
|
3021
3065
|
] }),
|
|
3022
3066
|
/* @__PURE__ */ jsxs32("div", { className: "ss-w-fandash-live-main", children: [
|
|
@@ -3698,12 +3742,14 @@ function Side({ name, crest }) {
|
|
|
3698
3742
|
/* @__PURE__ */ jsx49("span", { className: "ss-w-drow-nm", children: name })
|
|
3699
3743
|
] });
|
|
3700
3744
|
}
|
|
3701
|
-
function FixtureRow({ match, state, stale, ui, monitor }) {
|
|
3702
|
-
const
|
|
3745
|
+
function FixtureRow({ match, state, stale, nowMs, ui, monitor }) {
|
|
3746
|
+
const readingStale = isReadingStale(state, nowMs);
|
|
3747
|
+
const isLive = state?.phase === "live" && !stale && !readingStale;
|
|
3703
3748
|
const hasScore = (state?.phase === "live" || state?.phase === "fullTime") && typeof state.homeScore === "number" && typeof state.awayScore === "number";
|
|
3704
|
-
const
|
|
3705
|
-
|
|
3706
|
-
|
|
3749
|
+
const ticked = displayMinute(state, nowMs);
|
|
3750
|
+
const when = state?.isHalfTime && !stale ? ui.halfTime : isLive ? ticked ?? "\u2014" : state?.phase === "live" ? "\u2014" : kickoffLabel(match.kickoffUnix);
|
|
3751
|
+
return /* @__PURE__ */ jsxs44("div", { className: isLive || state?.isHalfTime ? "ss-w-drow ss-w-drow--live" : "ss-w-drow", children: [
|
|
3752
|
+
/* @__PURE__ */ jsx49("span", { className: isLive || state?.isHalfTime ? "ss-w-drow-when ss-w-drow-when--live" : "ss-w-drow-when", children: when }),
|
|
3707
3753
|
/* @__PURE__ */ jsxs44("span", { className: "ss-w-drow-fx", children: [
|
|
3708
3754
|
/* @__PURE__ */ jsx49(Side, { name: match.homeTeamName, crest: match.homeTeamImagePath }),
|
|
3709
3755
|
/* @__PURE__ */ jsx49("span", { className: "ss-w-drow-dash", children: "\u2013" }),
|
|
@@ -3716,8 +3762,8 @@ function FixtureRow({ match, state, stale, ui, monitor }) {
|
|
|
3716
3762
|
|
|
3717
3763
|
// src/components/CompetitionGroup.tsx
|
|
3718
3764
|
import { jsx as jsx50, jsxs as jsxs45 } from "react/jsx-runtime";
|
|
3719
|
-
function CompetitionGroup({ group, open, onToggle, states, stale, ui, monitor, disambiguate = false }) {
|
|
3720
|
-
const own = group.matches.filter((m) => states[m.matchId]
|
|
3765
|
+
function CompetitionGroup({ group, open, onToggle, states, stale, nowMs, ui, monitor, disambiguate = false }) {
|
|
3766
|
+
const own = group.matches.filter((m) => !isTreatedLive(states[m.matchId], stale, nowMs));
|
|
3721
3767
|
const hasLive = own.length !== group.matches.length;
|
|
3722
3768
|
return /* @__PURE__ */ jsxs45("div", { className: "ss-w-grp", children: [
|
|
3723
3769
|
/* @__PURE__ */ jsxs45("button", { type: "button", className: "ss-w-grp-head", "aria-expanded": open, onClick: onToggle, children: [
|
|
@@ -3733,15 +3779,15 @@ function CompetitionGroup({ group, open, onToggle, states, stale, ui, monitor, d
|
|
|
3733
3779
|
] }),
|
|
3734
3780
|
/* @__PURE__ */ jsx50("span", { className: "ss-w-grp-count", children: own.length })
|
|
3735
3781
|
] }),
|
|
3736
|
-
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)) })
|
|
3782
|
+
open && /* @__PURE__ */ jsx50("div", { className: "ss-w-grp-body", children: own.map((m) => /* @__PURE__ */ jsx50(FixtureRow, { match: m, state: states[m.matchId], stale, nowMs, ui, monitor }, m.matchId)) })
|
|
3737
3783
|
] });
|
|
3738
3784
|
}
|
|
3739
3785
|
|
|
3740
3786
|
// src/components/TodayPanel.tsx
|
|
3741
3787
|
import { Fragment as Fragment7, jsx as jsx51, jsxs as jsxs46 } from "react/jsx-runtime";
|
|
3742
3788
|
function TodayPanel({ discovery, ui, monitor }) {
|
|
3743
|
-
const { groups, states, stale, expanded, toggleGroup } = discovery;
|
|
3744
|
-
const liveRows = stale ? [] : groups.flatMap((group) => group.matches.filter((m) => states[m.matchId]
|
|
3789
|
+
const { groups, states, nowMs, stale, expanded, toggleGroup } = discovery;
|
|
3790
|
+
const liveRows = stale ? [] : groups.flatMap((group) => group.matches.filter((m) => isTreatedLive(states[m.matchId], stale, nowMs)).map((match) => ({ match, rank: group.rank }))).sort((a, b) => a.rank - b.rank);
|
|
3745
3791
|
const nameCounts = groups.reduce((acc, g) => {
|
|
3746
3792
|
acc[g.competitionName] = (acc[g.competitionName] ?? 0) + 1;
|
|
3747
3793
|
return acc;
|
|
@@ -3759,6 +3805,7 @@ function TodayPanel({ discovery, ui, monitor }) {
|
|
|
3759
3805
|
match,
|
|
3760
3806
|
state: states[match.matchId],
|
|
3761
3807
|
stale,
|
|
3808
|
+
nowMs,
|
|
3762
3809
|
ui,
|
|
3763
3810
|
monitor
|
|
3764
3811
|
},
|
|
@@ -3774,6 +3821,7 @@ function TodayPanel({ discovery, ui, monitor }) {
|
|
|
3774
3821
|
disambiguate: (nameCounts[group.competitionName] ?? 0) > 1,
|
|
3775
3822
|
states,
|
|
3776
3823
|
stale,
|
|
3824
|
+
nowMs,
|
|
3777
3825
|
ui,
|
|
3778
3826
|
monitor
|
|
3779
3827
|
},
|