@xbrain-swe/nova-chat-widget 0.1.7 → 0.1.8

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.cjs CHANGED
@@ -1552,6 +1552,28 @@ function XbNovaChat({
1552
1552
  nudgeNodeId: activeNudgeNodeId,
1553
1553
  onDismissSheet: () => setOpen(false)
1554
1554
  });
1555
+ const effectiveBotId = activeBotId ?? botId;
1556
+ const [cachedBranding, setCachedBranding] = (0, import_react9.useState)(null);
1557
+ (0, import_react9.useEffect)(() => {
1558
+ try {
1559
+ const raw = window.localStorage.getItem(`xbnova_branding:${effectiveBotId}`);
1560
+ setCachedBranding(raw ? JSON.parse(raw) : null);
1561
+ } catch {
1562
+ setCachedBranding(null);
1563
+ }
1564
+ }, [effectiveBotId]);
1565
+ (0, import_react9.useEffect)(() => {
1566
+ if (!onboarding?.branding) return;
1567
+ try {
1568
+ window.localStorage.setItem(
1569
+ `xbnova_branding:${effectiveBotId}`,
1570
+ JSON.stringify({ logo_url: onboarding.branding.logo_url, avatar_text: onboarding.branding.avatar_text })
1571
+ );
1572
+ } catch {
1573
+ }
1574
+ }, [onboarding?.branding, effectiveBotId]);
1575
+ const branding = onboarding?.branding ?? cachedBranding ?? void 0;
1576
+ const brandingReady = Boolean(onboarding) || cachedBranding !== null || Boolean(error);
1555
1577
  (0, import_react9.useEffect)(() => {
1556
1578
  bottomRef.current?.scrollIntoView({ behavior: "smooth" });
1557
1579
  }, [messages]);
@@ -1679,7 +1701,8 @@ function XbNovaChat({
1679
1701
  children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1680
1702
  Avatar,
1681
1703
  {
1682
- branding: onboarding?.branding,
1704
+ branding,
1705
+ ready: brandingReady,
1683
1706
  size: avatarSize,
1684
1707
  className: "shadow-md",
1685
1708
  gradient: avatarGradientStyle
@@ -1728,7 +1751,8 @@ function XbNovaChat({
1728
1751
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1729
1752
  Avatar,
1730
1753
  {
1731
- branding: onboarding?.branding,
1754
+ branding,
1755
+ ready: brandingReady,
1732
1756
  size: headerAvatarSize,
1733
1757
  className: "shrink-0",
1734
1758
  gradient: avatarGradientStyle
@@ -1848,6 +1872,7 @@ function XbNovaChat({
1848
1872
  }
1849
1873
  function Avatar({
1850
1874
  branding,
1875
+ ready,
1851
1876
  size,
1852
1877
  className = "",
1853
1878
  gradient
@@ -1855,27 +1880,26 @@ function Avatar({
1855
1880
  const box = { width: size, height: size };
1856
1881
  const logoUrl = branding?.logo_url?.trim() ?? "";
1857
1882
  const [failedUrl, setFailedUrl] = (0, import_react9.useState)("");
1883
+ const [loadedUrl, setLoadedUrl] = (0, import_react9.useState)("");
1884
+ const base = `${className} relative flex flex-none items-center justify-center overflow-hidden rounded-full font-bold text-white`;
1885
+ if (!ready) {
1886
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: base, style: { ...gradient, ...box }, "aria-hidden": true });
1887
+ }
1858
1888
  if (logoUrl && failedUrl !== logoUrl) {
1859
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1889
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: base, style: { ...gradient, ...box }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1860
1890
  "img",
1861
1891
  {
1862
1892
  src: logoUrl,
1863
1893
  alt: "",
1894
+ onLoad: () => setLoadedUrl(logoUrl),
1864
1895
  onError: () => setFailedUrl(logoUrl),
1865
- style: box,
1866
- className: `${className} flex-none rounded-full bg-white object-cover`
1896
+ className: "absolute inset-0 h-full w-full rounded-full bg-white object-cover transition-opacity duration-200",
1897
+ style: { opacity: loadedUrl === logoUrl ? 1 : 0 }
1867
1898
  }
1868
- );
1899
+ ) });
1869
1900
  }
1870
1901
  const text = branding?.avatar_text?.trim() || "AI";
1871
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1872
- "span",
1873
- {
1874
- className: `${className} flex flex-none items-center justify-center rounded-full font-bold text-white`,
1875
- style: { ...gradient, ...box, fontSize: Math.max(10, Math.round(size * 0.4)) },
1876
- children: text
1877
- }
1878
- );
1902
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: base, style: { ...gradient, ...box, fontSize: Math.max(10, Math.round(size * 0.4)) }, children: text });
1879
1903
  }
1880
1904
  function Bubble({ role, children }) {
1881
1905
  const mine = role === "user";