@burdenoff/website-sdk 2026.1104.1 → 2026.1104.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.
@@ -1,4 +1,4 @@
1
- import { turnstileSiteKeyOf, isAvatarLiveLocaleReviewed, isAvatarSite, isAvatarVersion } from '../chunk-K3QZGJEH.mjs';
1
+ import { turnstileSiteKeyOf, isAvatarLiveLocaleReviewed, isAvatarSite, isAvatarVersion } from '../chunk-7MSB3EUI.mjs';
2
2
  import { fill } from '../chunk-TT3MHN42.mjs';
3
3
  import { cn } from '../chunk-R7G6TWIS.mjs';
4
4
  import '../chunk-VNS5WDWO.mjs';
@@ -857,6 +857,8 @@ var PRIVACY_HREF = "/privacy#live-avatar";
857
857
  var SPEAKER_WAIT_MS = 3e4;
858
858
  var END_GRACE_MS = 1e4;
859
859
  var CLOCK_TOLERANCE_MS = 5e3;
860
+ var UNHEARD_GRACE_MS = 5e3;
861
+ var PLAYOUT_TAIL_MS = 5e3;
860
862
  var SERVICE_MAX_AGE_MS = 15 * 6e4;
861
863
  var ANSWER_OFFER_MS = SERVICE_MAX_AGE_MS - 6e4;
862
864
  var MAX_TIMER_MS = 2147483647;
@@ -866,6 +868,12 @@ var USED_ON_KEY = "boff.explore.avatarUsedOn";
866
868
  var PRIMARY = '[data-avatar-primary], [data-boff-explore="panel-continue-chat"]';
867
869
  var IDLE = { name: "idle" };
868
870
  var INERT2 = { name: "inert" };
871
+ function stopAttending(handle) {
872
+ if (handle.unheard !== null) clearTimeout(handle.unheard);
873
+ if (handle.tail !== null) clearTimeout(handle.tail);
874
+ handle.unheard = null;
875
+ handle.tail = null;
876
+ }
869
877
  var REFUSAL_TEXT = {
870
878
  busy: "busy",
871
879
  limits: "limits",
@@ -1149,6 +1157,7 @@ function AvatarLiveView({
1149
1157
  const handle = sessionRef.current;
1150
1158
  if (!handle || handle.done) return;
1151
1159
  handle.done = true;
1160
+ stopAttending(handle);
1152
1161
  sessionRef.current = null;
1153
1162
  if (reason !== null) {
1154
1163
  sendEnd({
@@ -1178,6 +1187,33 @@ function AvatarLiveView({
1178
1187
  }
1179
1188
  go({ name: "live", session: current.session });
1180
1189
  }, [go]);
1190
+ const attend = useCallback(() => {
1191
+ const handle = sessionRef.current;
1192
+ if (!handle || handle.done || latest.current.live.endUnattended !== true) {
1193
+ return;
1194
+ }
1195
+ const current = phaseRef.current.name;
1196
+ if (current !== "pending" && current !== "live") return;
1197
+ const away = !inSight();
1198
+ if (away && handle.playedOut && current === "live") {
1199
+ finish("finished", "user");
1200
+ return;
1201
+ }
1202
+ if (!(away && handle.soundHeld && handle.voiceArrived)) {
1203
+ if (handle.unheard !== null) {
1204
+ clearTimeout(handle.unheard);
1205
+ handle.unheard = null;
1206
+ }
1207
+ return;
1208
+ }
1209
+ if (handle.unheard !== null) return;
1210
+ handle.unheard = setTimeout(() => {
1211
+ handle.unheard = null;
1212
+ if (sessionRef.current === handle && !handle.done && latest.current.live.endUnattended === true && handle.soundHeld && handle.voiceArrived && !inSight()) {
1213
+ finish("interrupted", "user");
1214
+ }
1215
+ }, UNHEARD_GRACE_MS);
1216
+ }, [finish, inSight]);
1181
1217
  const cancelStart = useCallback((reason) => {
1182
1218
  const run = startRef.current;
1183
1219
  if (!run) return;
@@ -1254,6 +1290,11 @@ function AvatarLiveView({
1254
1290
  joined: null,
1255
1291
  endsAt,
1256
1292
  speakerArrived: false,
1293
+ voiceArrived: false,
1294
+ soundHeld: false,
1295
+ playedOut: false,
1296
+ unheard: null,
1297
+ tail: null,
1257
1298
  done: false
1258
1299
  };
1259
1300
  setBlocked(false);
@@ -1579,6 +1620,9 @@ function AvatarLiveView({
1579
1620
  check();
1580
1621
  }
1581
1622
  }, [showing, behindChat, check, leave, offeredNow]);
1623
+ useEffect(() => {
1624
+ attend();
1625
+ }, [showing, attend]);
1582
1626
  useEffect(() => {
1583
1627
  if (askedLocale.current === locale) return;
1584
1628
  askedLocale.current = locale;
@@ -1665,12 +1709,29 @@ function AvatarLiveView({
1665
1709
  const wasLive = phaseRef.current.name === "live";
1666
1710
  switch (event.type) {
1667
1711
  case "speaker-track":
1668
- if (event.kind !== "video") return;
1712
+ if (event.kind !== "video") {
1713
+ handle.voiceArrived = true;
1714
+ attend();
1715
+ return;
1716
+ }
1669
1717
  handle.speakerArrived = true;
1670
1718
  if (!inSight()) goLive();
1671
1719
  return;
1672
1720
  case "playback-blocked":
1673
1721
  setBlocked(event.blocked);
1722
+ handle.soundHeld = event.sound ?? event.blocked;
1723
+ attend();
1724
+ return;
1725
+ case "speech-ended":
1726
+ if (latest.current.live.endUnattended !== true || handle.tail !== null || handle.playedOut) {
1727
+ return;
1728
+ }
1729
+ handle.tail = setTimeout(() => {
1730
+ handle.tail = null;
1731
+ if (sessionRef.current !== handle || handle.done) return;
1732
+ handle.playedOut = true;
1733
+ attend();
1734
+ }, PLAYOUT_TAIL_MS);
1674
1735
  return;
1675
1736
  case "speaker-left":
1676
1737
  finish(
@@ -1684,7 +1745,7 @@ function AvatarLiveView({
1684
1745
  return;
1685
1746
  }
1686
1747
  },
1687
- [finish, goLive, inSight]
1748
+ [attend, finish, goLive, inSight]
1688
1749
  );
1689
1750
  useEffect(() => {
1690
1751
  if (phase.name !== "pending") return;
@@ -1771,10 +1832,12 @@ function AvatarLiveView({
1771
1832
  const onVisibility = () => {
1772
1833
  if (document.visibilityState === "hidden") {
1773
1834
  leave("hidden");
1835
+ attend();
1774
1836
  return;
1775
1837
  }
1776
1838
  const current = phaseRef.current.name;
1777
1839
  if (current === "pending" || current === "live") setNow(Date.now());
1840
+ attend();
1778
1841
  };
1779
1842
  window.addEventListener("pagehide", onPageHide);
1780
1843
  document.addEventListener("visibilitychange", onVisibility);
@@ -1782,7 +1845,7 @@ function AvatarLiveView({
1782
1845
  window.removeEventListener("pagehide", onPageHide);
1783
1846
  document.removeEventListener("visibilitychange", onVisibility);
1784
1847
  };
1785
- }, [leave]);
1848
+ }, [attend, leave]);
1786
1849
  useEffect(
1787
1850
  () => () => {
1788
1851
  const controller = checkRef.current;
@@ -1801,6 +1864,7 @@ function AvatarLiveView({
1801
1864
  sessionRef.current = null;
1802
1865
  if (handle && !handle.done) {
1803
1866
  handle.done = true;
1867
+ stopAttending(handle);
1804
1868
  sendEnd({
1805
1869
  base: handle.base,
1806
1870
  headers: handle.headers,