@sensiblestats/widget-react 0.4.0 → 0.5.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 +15 -0
- package/dist/index.cjs +96 -39
- 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 +84 -27
- package/dist/index.js.map +1 -1
- package/dist/styles.css +23 -10
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# @sensiblestats/widget-react
|
|
2
2
|
|
|
3
|
+
## 0.5.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Redesigned betting-insight card with scoped supporting stats.
|
|
8
|
+
|
|
9
|
+
- **widget-sdk:** extend `BettingInsight` with `homeTeamName`, `awayTeamName`, and `scopes` (`{ key, label, stats }[]`), so consumers can type the fixture line and the per-scope stat sets (this league / all competitions / head-to-head) the server now streams.
|
|
10
|
+
- **widget-react:** rebuild the betting card around the new payload — a phase-aware live/pre-match status line with the fixture, a promoted market with clearly labeled odds (and an optional bookmaker name), and scope chips that switch the supporting stats in place (shown only when ≥2 scopes are present, otherwise flat stat rows with a "show more" expander). The responsible-gambling disclaimer always renders. Type scale and spacing match the surrounding chat cards.
|
|
11
|
+
- **widget-embed:** rebuild against `@sensiblestats/widget-react` so the hosted embed renders the redesigned card.
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- Updated dependencies
|
|
16
|
+
- @sensiblestats/widget-sdk@0.4.0
|
|
17
|
+
|
|
3
18
|
## 0.4.0
|
|
4
19
|
|
|
5
20
|
### Minor Changes
|
package/dist/index.cjs
CHANGED
|
@@ -36,7 +36,7 @@ __export(index_exports, {
|
|
|
36
36
|
module.exports = __toCommonJS(index_exports);
|
|
37
37
|
|
|
38
38
|
// src/StatsWidget.tsx
|
|
39
|
-
var
|
|
39
|
+
var import_react7 = require("react");
|
|
40
40
|
var import_widget_sdk3 = require("@sensiblestats/widget-sdk");
|
|
41
41
|
|
|
42
42
|
// src/i18n.ts
|
|
@@ -52,7 +52,9 @@ var STRINGS = {
|
|
|
52
52
|
somethingWentWrong: "Something went wrong.",
|
|
53
53
|
retry: "Retry",
|
|
54
54
|
showLess: "Show less",
|
|
55
|
-
showMore: (n) => `Show ${n} more
|
|
55
|
+
showMore: (n) => `Show ${n} more`,
|
|
56
|
+
oddsLabel: "Odds",
|
|
57
|
+
liveLabel: "Live"
|
|
56
58
|
},
|
|
57
59
|
tr: {
|
|
58
60
|
launcherLabel: "SensibleStats ile sohbet et",
|
|
@@ -65,7 +67,9 @@ var STRINGS = {
|
|
|
65
67
|
somethingWentWrong: "Bir \u015Feyler ters gitti.",
|
|
66
68
|
retry: "Tekrar dene",
|
|
67
69
|
showLess: "Daha az g\xF6ster",
|
|
68
|
-
showMore: (n) => `${n} tane daha g\xF6ster
|
|
70
|
+
showMore: (n) => `${n} tane daha g\xF6ster`,
|
|
71
|
+
oddsLabel: "Oran",
|
|
72
|
+
liveLabel: "Canl\u0131"
|
|
69
73
|
}
|
|
70
74
|
};
|
|
71
75
|
function resolveLocaleStrings(locale) {
|
|
@@ -95,7 +99,9 @@ function normalizeUi(cfg) {
|
|
|
95
99
|
somethingWentWrong: strings.somethingWentWrong,
|
|
96
100
|
retry: strings.retry,
|
|
97
101
|
showLess: strings.showLess,
|
|
98
|
-
showMore: strings.showMore
|
|
102
|
+
showMore: strings.showMore,
|
|
103
|
+
oddsLabel: strings.oddsLabel,
|
|
104
|
+
liveLabel: strings.liveLabel
|
|
99
105
|
};
|
|
100
106
|
}
|
|
101
107
|
function toClientOptions(cfg) {
|
|
@@ -175,6 +181,10 @@ function toInsightVM(insight) {
|
|
|
175
181
|
const selection = [str(insight.selectionLabel), str(insight.line)].filter(Boolean).join(" ") || void 0;
|
|
176
182
|
const value = insight.odds?.value;
|
|
177
183
|
const odds = typeof value === "number" && Number.isFinite(value) ? value.toFixed(2) : void 0;
|
|
184
|
+
const home = str(insight.homeTeamName);
|
|
185
|
+
const away = str(insight.awayTeamName);
|
|
186
|
+
const fixture = home && away ? `${home} vs ${away}` : void 0;
|
|
187
|
+
const scopes = Array.isArray(insight.scopes) ? insight.scopes.map((s) => ({ key: str(s.key), label: str(s.label), stats: readStatCells(s.stats) })).filter((s) => !!s.key && !!s.label) : void 0;
|
|
178
188
|
return {
|
|
179
189
|
id: str(insight.insightId) ?? `${str(insight.ruleId) ?? "insight"}:${num(insight.matchId) ?? ""}`,
|
|
180
190
|
market,
|
|
@@ -183,6 +193,9 @@ function toInsightVM(insight) {
|
|
|
183
193
|
// The wire payload carries bookmakerId (not a name); render a name only if one is present.
|
|
184
194
|
bookmaker: str(insight.odds?.bookmakerName),
|
|
185
195
|
isLive: insight.odds?.isLive === true,
|
|
196
|
+
phase: str(insight.phase),
|
|
197
|
+
fixture,
|
|
198
|
+
scopes,
|
|
186
199
|
text: str(insight.text) ?? "",
|
|
187
200
|
stats: readStatCells(insight.stats),
|
|
188
201
|
disclaimer: str(insight.disclaimer)
|
|
@@ -369,7 +382,7 @@ function ChatFab({ label, greeting, popupText, onOpen, onDismissPopup, dismissLa
|
|
|
369
382
|
}
|
|
370
383
|
|
|
371
384
|
// src/components/ChatPanel.tsx
|
|
372
|
-
var
|
|
385
|
+
var import_react6 = require("react");
|
|
373
386
|
|
|
374
387
|
// src/components/ChatHeader.tsx
|
|
375
388
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
@@ -382,7 +395,7 @@ function ChatHeader({ onClose, closeLabel = "Close chat" }) {
|
|
|
382
395
|
}
|
|
383
396
|
|
|
384
397
|
// src/components/MessageList.tsx
|
|
385
|
-
var
|
|
398
|
+
var import_react4 = require("react");
|
|
386
399
|
|
|
387
400
|
// src/components/Markdown.tsx
|
|
388
401
|
var import_react_markdown = __toESM(require("react-markdown"), 1);
|
|
@@ -436,28 +449,59 @@ function EntityCardList({ cards, disabled, showLessLabel = "Show less", showMore
|
|
|
436
449
|
}
|
|
437
450
|
|
|
438
451
|
// src/components/BettingInsightList.tsx
|
|
452
|
+
var import_react3 = require("react");
|
|
439
453
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
454
|
+
var MAX_ROWS = 3;
|
|
455
|
+
function StatRows({ stats, ui }) {
|
|
456
|
+
const [expanded, setExpanded] = (0, import_react3.useState)(false);
|
|
457
|
+
const shown = expanded ? stats : stats.slice(0, MAX_ROWS);
|
|
458
|
+
const overflow = stats.length - MAX_ROWS;
|
|
459
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "ss-w-bi-rows", children: [
|
|
460
|
+
shown.map((s) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "ss-w-bi-row", children: [
|
|
461
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "ss-w-bi-row-lbl", children: s.label }),
|
|
462
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "ss-w-bi-row-dots", "aria-hidden": "true" }),
|
|
463
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "ss-w-bi-row-num", children: s.value })
|
|
464
|
+
] }, `${s.label}:${s.value}`)),
|
|
465
|
+
overflow > 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: "ss-w-bi-more", onClick: () => setExpanded((v) => !v), children: expanded ? ui?.showLess ?? "Show less" : (ui?.showMore ?? ((n) => `Show ${n} more`))(overflow) }) : null
|
|
466
|
+
] });
|
|
467
|
+
}
|
|
468
|
+
function ScopedStats({ scopes, ui }) {
|
|
469
|
+
const [active, setActive] = (0, import_react3.useState)(0);
|
|
470
|
+
const current = scopes[active] ?? scopes[0] ?? { key: "", label: "", stats: [] };
|
|
471
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "ss-w-bi-scoped", children: [
|
|
472
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "ss-w-bi-scopes", role: "group", children: scopes.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: "ss-w-bi-chip", "aria-pressed": i === active, onClick: () => setActive(i), children: s.label }, s.key)) }),
|
|
473
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(StatRows, { stats: current.stats, ui }, current.key)
|
|
474
|
+
] });
|
|
475
|
+
}
|
|
476
|
+
function InsightCard({ it, ui }) {
|
|
477
|
+
const live = it.isLive || it.phase === "live";
|
|
478
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "ss-w-binsight", children: [
|
|
479
|
+
live || it.fixture ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "ss-w-bi-status", children: [
|
|
480
|
+
live ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "ss-w-bi-live", children: [
|
|
481
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "ss-w-bi-live-dot", "aria-hidden": "true" }),
|
|
482
|
+
ui?.liveLabel ?? "Live"
|
|
483
|
+
] }) : null,
|
|
484
|
+
it.fixture ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "ss-w-bi-fixture", children: it.fixture }) : null
|
|
485
|
+
] }) : null,
|
|
443
486
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "ss-w-bi-head", children: [
|
|
444
487
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "ss-w-bi-mkt", children: [
|
|
445
488
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "ss-w-bi-market", children: it.market }),
|
|
446
489
|
it.selection ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "ss-w-bi-sel", children: it.selection }) : null
|
|
447
490
|
] }),
|
|
448
491
|
it.odds ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "ss-w-bi-odds", children: [
|
|
449
|
-
|
|
492
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "ss-w-bi-odds-cap", children: ui?.oddsLabel ?? "Odds" }),
|
|
450
493
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("b", { children: it.odds }),
|
|
451
494
|
it.bookmaker ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "ss-w-bi-book", children: it.bookmaker }) : null
|
|
452
495
|
] }) : null
|
|
453
496
|
] }),
|
|
454
497
|
it.text ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "ss-w-bi-text", children: it.text }) : null,
|
|
455
|
-
it.
|
|
456
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("b", { children: s.value }),
|
|
457
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: s.label })
|
|
458
|
-
] }, `${s.label}:${s.value}`)) }) : null,
|
|
498
|
+
it.scopes && it.scopes.length >= 2 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ScopedStats, { scopes: it.scopes, ui }) : it.stats.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(StatRows, { stats: it.stats, ui }) : null,
|
|
459
499
|
it.disclaimer ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "ss-w-bi-disc", children: it.disclaimer }) : null
|
|
460
|
-
] }
|
|
500
|
+
] });
|
|
501
|
+
}
|
|
502
|
+
function BettingInsightList({ insights, ui }) {
|
|
503
|
+
if (!insights || insights.length === 0) return null;
|
|
504
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "ss-w-binsights", children: insights.map((it) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(InsightCard, { it, ui }, it.id)) });
|
|
461
505
|
}
|
|
462
506
|
|
|
463
507
|
// src/components/ActionButtons.tsx
|
|
@@ -482,7 +526,7 @@ function ChatMessage({ message, disabled, onAct, ui }) {
|
|
|
482
526
|
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "ss-w-msg ss-w-bot", children: [
|
|
483
527
|
message.text ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Markdown, { text: message.text }) : null,
|
|
484
528
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(EntityCardList, { cards: message.cards, disabled, showLessLabel: ui?.showLess, showMoreLabel: ui?.showMore }),
|
|
485
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(BettingInsightList, { insights: message.insights }),
|
|
529
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(BettingInsightList, { insights: message.insights, ui }),
|
|
486
530
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ActionButtons, { actions: message.actions, loading: false, disabled, onAct })
|
|
487
531
|
] });
|
|
488
532
|
}
|
|
@@ -504,10 +548,10 @@ function isPinnedToBottom(el, threshold = PIN_THRESHOLD) {
|
|
|
504
548
|
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
505
549
|
function MessageList({ controller, ui }) {
|
|
506
550
|
const { state, send } = controller;
|
|
507
|
-
const listRef = (0,
|
|
508
|
-
const endRef = (0,
|
|
509
|
-
const pinnedRef = (0,
|
|
510
|
-
(0,
|
|
551
|
+
const listRef = (0, import_react4.useRef)(null);
|
|
552
|
+
const endRef = (0, import_react4.useRef)(null);
|
|
553
|
+
const pinnedRef = (0, import_react4.useRef)(true);
|
|
554
|
+
(0, import_react4.useEffect)(() => {
|
|
511
555
|
if (pinnedRef.current) endRef.current?.scrollIntoView({ block: "end" });
|
|
512
556
|
}, [state.messages, state.status]);
|
|
513
557
|
const empty = state.messages.length === 0;
|
|
@@ -546,10 +590,10 @@ function MessageList({ controller, ui }) {
|
|
|
546
590
|
}
|
|
547
591
|
|
|
548
592
|
// src/components/ChatInput.tsx
|
|
549
|
-
var
|
|
593
|
+
var import_react5 = require("react");
|
|
550
594
|
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
551
595
|
function ChatInput({ placeholder, streaming, onSend, onStop, stopLabel = "Stop response", sendLabel = "Send message" }) {
|
|
552
|
-
const [value, setValue] = (0,
|
|
596
|
+
const [value, setValue] = (0, import_react5.useState)("");
|
|
553
597
|
const submit = () => {
|
|
554
598
|
const t = value.trim();
|
|
555
599
|
if (!t) return;
|
|
@@ -572,8 +616,8 @@ function ChatInput({ placeholder, streaming, onSend, onStop, stopLabel = "Stop r
|
|
|
572
616
|
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
573
617
|
var FULLSCREEN_QUERY = "(max-width: 639px)";
|
|
574
618
|
function useIsModal() {
|
|
575
|
-
const [modal, setModal] = (0,
|
|
576
|
-
(0,
|
|
619
|
+
const [modal, setModal] = (0, import_react6.useState)(false);
|
|
620
|
+
(0, import_react6.useEffect)(() => {
|
|
577
621
|
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
578
622
|
const mql = window.matchMedia(FULLSCREEN_QUERY);
|
|
579
623
|
const sync = () => setModal(mql.matches);
|
|
@@ -586,7 +630,7 @@ function useIsModal() {
|
|
|
586
630
|
function ChatPanel({ controller, ui }) {
|
|
587
631
|
const { state, close, stop, send } = controller;
|
|
588
632
|
const isModal = useIsModal();
|
|
589
|
-
(0,
|
|
633
|
+
(0, import_react6.useEffect)(() => {
|
|
590
634
|
const onKey = (e) => {
|
|
591
635
|
if (e.key === "Escape") close();
|
|
592
636
|
};
|
|
@@ -698,19 +742,32 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
698
742
|
/* betting insights */
|
|
699
743
|
.ss-w-binsights { display: flex; flex-direction: column; gap: 7px; }
|
|
700
744
|
.ss-w-binsight { 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; }
|
|
745
|
+
.ss-w-bi-status { display: flex; align-items: center; gap: 6px; min-width: 0; }
|
|
746
|
+
.ss-w-bi-fixture { font-size: 11px; color: var(--ss-w-ink); font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
747
|
+
.ss-w-bi-live { font-size: 8.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: #fff; background: #c0392b; border-radius: 4px; padding: 1px 5px; display: inline-flex; align-items: center; gap: 4px; flex: none; }
|
|
748
|
+
.ss-w-bi-live-dot { width: 5px; height: 5px; border-radius: 50%; background: #fff; }
|
|
701
749
|
.ss-w-bi-head { display: flex; align-items: flex-start; gap: 10px; }
|
|
702
|
-
.ss-w-bi-mkt { display: flex; flex-direction: column; min-width: 0; }
|
|
703
|
-
.ss-w-bi-market { font-size:
|
|
704
|
-
.ss-w-bi-sel { font-
|
|
705
|
-
.ss-w-bi-odds { margin-left: auto; display: flex; align-items: center;
|
|
706
|
-
.ss-w-bi-odds
|
|
707
|
-
.ss-w-bi-
|
|
708
|
-
.ss-w-bi-
|
|
750
|
+
.ss-w-bi-mkt { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
|
|
751
|
+
.ss-w-bi-market { font-size: 13px; font-weight: 660; line-height: 1.3; color: var(--ss-w-ink); }
|
|
752
|
+
.ss-w-bi-sel { font-size: 11px; line-height: 1.3; color: var(--ss-w-faint); }
|
|
753
|
+
.ss-w-bi-odds { margin-left: auto; flex: none; display: flex; flex-direction: column; align-items: center; justify-content: center; background: color-mix(in srgb, var(--ss-w-accent) 12%, var(--ss-w-panel)); border: 1px solid color-mix(in srgb, var(--ss-w-accent) 24%, var(--ss-w-line)); border-radius: 8px; padding: 3px 9px; min-width: 56px; }
|
|
754
|
+
.ss-w-bi-odds-cap { font-size: 8px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--ss-w-faint); }
|
|
755
|
+
.ss-w-bi-odds b { font-size: 15px; font-family: ui-monospace, monospace; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--ss-w-accent); line-height: 1.15; }
|
|
756
|
+
.ss-w-bi-book { font-size: 9.5px; color: var(--ss-w-faint); }
|
|
709
757
|
.ss-w-bi-text { font-size: 12px; color: var(--ss-w-ink); }
|
|
710
|
-
.ss-w-bi-
|
|
711
|
-
.ss-w-bi-
|
|
712
|
-
.ss-w-bi-
|
|
758
|
+
.ss-w-bi-rows { display: flex; flex-direction: column; }
|
|
759
|
+
.ss-w-bi-row { display: flex; align-items: baseline; gap: 8px; padding: 4px 0; border-top: 1px solid var(--ss-w-line); }
|
|
760
|
+
.ss-w-bi-row:first-child { border-top: none; }
|
|
761
|
+
.ss-w-bi-row-lbl { font-size: 11px; color: var(--ss-w-faint); min-width: 0; }
|
|
762
|
+
.ss-w-bi-row-dots { flex: 1; border-bottom: 1px dotted var(--ss-w-line); transform: translateY(-3px); min-width: 12px; }
|
|
763
|
+
.ss-w-bi-row-num { font-family: ui-monospace, monospace; font-weight: 700; font-variant-numeric: tabular-nums; font-size: 12.5px; flex: none; color: var(--ss-w-ink); }
|
|
764
|
+
.ss-w-bi-more { align-self: flex-start; background: none; border: none; color: var(--ss-w-accent); font: inherit; font-size: 11px; font-weight: 560; padding: 2px 0; cursor: pointer; }
|
|
765
|
+
.ss-w-bi-more:hover { text-decoration: underline; }
|
|
713
766
|
.ss-w-bi-disc { font-size: 10px; font-style: italic; color: var(--ss-w-faint); }
|
|
767
|
+
.ss-w-bi-scoped { display: flex; flex-direction: column; gap: 6px; }
|
|
768
|
+
.ss-w-bi-scopes { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; }
|
|
769
|
+
.ss-w-bi-chip { font-size: 11px; font-weight: 550; border: 1px solid var(--ss-w-line); border-radius: 14px; padding: 3px 10px; color: var(--ss-w-ink); background: var(--ss-w-bubble); cursor: pointer; }
|
|
770
|
+
.ss-w-bi-chip[aria-pressed="true"] { color: #fff; background: var(--ss-w-accent); border-color: var(--ss-w-accent); }
|
|
714
771
|
|
|
715
772
|
/* action buttons */
|
|
716
773
|
.ss-w-actions { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }
|
|
@@ -766,11 +823,11 @@ function injectStyles(root) {
|
|
|
766
823
|
function StatsWidget(props) {
|
|
767
824
|
const injectedClient = "client" in props ? props.client : void 0;
|
|
768
825
|
const cfg = props.config;
|
|
769
|
-
const built = (0,
|
|
770
|
-
const ui = (0,
|
|
771
|
-
const rootRef = (0,
|
|
826
|
+
const built = (0, import_react7.useMemo)(() => buildClient(props), [injectedClient, cfg?.operatorId, cfg?.publicKey, cfg?.baseUrl]);
|
|
827
|
+
const ui = (0, import_react7.useMemo)(() => normalizeUi(props.config ?? { operatorId: "", publicKey: "" }), [props.config]);
|
|
828
|
+
const rootRef = (0, import_react7.useRef)(null);
|
|
772
829
|
const controller = useChatStream(built?.conversation ?? emptyConversation(), ui.starters, built ? ui.greetingMessage : void 0);
|
|
773
|
-
(0,
|
|
830
|
+
(0, import_react7.useEffect)(() => {
|
|
774
831
|
if (!built || !ui.injectStyles) return;
|
|
775
832
|
const node = rootRef.current?.getRootNode();
|
|
776
833
|
if (node) injectStyles(node);
|