@lumiastream/ui 0.8.3 → 0.8.5

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/se-import.js CHANGED
@@ -4839,7 +4839,7 @@ async function diagnoseSEAuth(jwt) {
4839
4839
  }
4840
4840
 
4841
4841
  // src/se-import/ui/SEImportWizard.tsx
4842
- import { useCallback as useCallback4, useEffect as useEffect10, useMemo as useMemo8, useRef as useRef9, useState as useState14 } from "react";
4842
+ import { useCallback as useCallback4, useEffect as useEffect10, useMemo as useMemo8, useRef as useRef9, useState as useState13 } from "react";
4843
4843
 
4844
4844
  // src/components/LSButton/LSButton.tsx
4845
4845
  import Button from "@mui/material/Button";
@@ -8088,7 +8088,6 @@ function EventListItem({
8088
8088
  avatar,
8089
8089
  fallbackAvatar,
8090
8090
  timestamp,
8091
- amountBadge,
8092
8091
  platformIcon,
8093
8092
  alertIcon,
8094
8093
  eventType,
@@ -8137,14 +8136,6 @@ function EventListItem({
8137
8136
  style: accentColor ? { color: accentColor } : void 0,
8138
8137
  children: resolvedAlertIcon
8139
8138
  }
8140
- ) : null,
8141
- amountBadge != null && amountBadge !== false ? /* @__PURE__ */ jsx24(
8142
- "span",
8143
- {
8144
- className: "ls-eventlist-item__amount-badge",
8145
- style: accentColor ? { color: accentColor, backgroundColor: `color-mix(in srgb, ${accentColor} 18%, transparent)`, borderColor: `color-mix(in srgb, ${accentColor} 45%, transparent)` } : void 0,
8146
- children: amountBadge
8147
- }
8148
8139
  ) : null
8149
8140
  ] }),
8150
8141
  /* @__PURE__ */ jsxs14("div", { className: "ls-eventlist-item__body", children: [
@@ -8163,7 +8154,7 @@ function EventListItem({
8163
8154
  EventListItem.displayName = "EventListItem";
8164
8155
 
8165
8156
  // src/components/EventList/EventList.tsx
8166
- import { useEffect as useEffect7, useRef as useRef7, useState as useState9 } from "react";
8157
+ import { useEffect as useEffect7, useRef as useRef7 } from "react";
8167
8158
  import classNames14 from "classnames";
8168
8159
  import { jsx as jsx25, jsxs as jsxs15 } from "react/jsx-runtime";
8169
8160
  var PIN_THRESHOLD = 24;
@@ -8185,15 +8176,10 @@ function EventList({
8185
8176
  newestAt = "top",
8186
8177
  onEndReached,
8187
8178
  endReachedThreshold = 24,
8188
- showNewItemsPill = false,
8189
- newItemsPillText,
8190
8179
  className
8191
8180
  }) {
8192
8181
  const listRef = useRef7(null);
8193
8182
  const pinnedRef = useRef7(true);
8194
- const prevNewestIdRef = useRef7(null);
8195
- const newItemsInitedRef = useRef7(false);
8196
- const [unreadCount, setUnreadCount] = useState9(0);
8197
8183
  useEffect7(() => {
8198
8184
  const el = listRef.current;
8199
8185
  if (!autoScroll || !el || !pinnedRef.current) {
@@ -8201,34 +8187,6 @@ function EventList({
8201
8187
  }
8202
8188
  el.scrollTop = newestAt === "top" ? 0 : el.scrollHeight;
8203
8189
  }, [items, autoScroll, newestAt]);
8204
- useEffect7(() => {
8205
- if (!showNewItemsPill) {
8206
- return;
8207
- }
8208
- const newestId = (newestAt === "top" ? items[0]?.id : items[items.length - 1]?.id) ?? null;
8209
- const prevNewestId = prevNewestIdRef.current;
8210
- let added = 0;
8211
- if (prevNewestId != null && newestId != null && newestId !== prevNewestId) {
8212
- const idx = newestAt === "top" ? items.findIndex((item) => item.id === prevNewestId) : items.length - 1 - [...items].reverse().findIndex((item) => item.id === prevNewestId);
8213
- added = newestAt === "top" ? idx > 0 ? idx : 0 : idx >= 0 && idx < items.length - 1 ? items.length - 1 - idx : 0;
8214
- }
8215
- prevNewestIdRef.current = newestId;
8216
- if (!newItemsInitedRef.current) {
8217
- newItemsInitedRef.current = true;
8218
- return;
8219
- }
8220
- if (added > 0 && !pinnedRef.current) {
8221
- setUnreadCount((count) => count + added);
8222
- }
8223
- }, [items, showNewItemsPill, newestAt]);
8224
- const scrollToNewest = () => {
8225
- const el = listRef.current;
8226
- if (el) {
8227
- el.scrollTo({ top: newestAt === "top" ? 0 : el.scrollHeight, behavior: "smooth" });
8228
- }
8229
- pinnedRef.current = true;
8230
- setUnreadCount(0);
8231
- };
8232
8190
  const handleScroll = () => {
8233
8191
  const el = listRef.current;
8234
8192
  if (!el) {
@@ -8238,50 +8196,43 @@ function EventList({
8238
8196
  const distanceFromNewest = newestAt === "top" ? el.scrollTop : distanceFromEnd;
8239
8197
  const distanceFromOldest = newestAt === "top" ? distanceFromEnd : el.scrollTop;
8240
8198
  pinnedRef.current = distanceFromNewest <= PIN_THRESHOLD;
8241
- if (pinnedRef.current && unreadCount > 0) {
8242
- setUnreadCount(0);
8243
- }
8244
8199
  if (onEndReached && distanceFromOldest <= endReachedThreshold) {
8245
8200
  onEndReached();
8246
8201
  }
8247
8202
  };
8248
- return /* @__PURE__ */ jsxs15("div", { className: classNames14("ls-eventlist", className), id, children: [
8249
- showNewItemsPill && unreadCount > 0 ? /* @__PURE__ */ jsx25("button", { type: "button", className: classNames14("ls-eventlist__new-pill", { "ls-eventlist__new-pill--bottom": newestAt === "bottom" }), onClick: scrollToNewest, children: newItemsPillText ? newItemsPillText(unreadCount) : `${unreadCount} new` }) : null,
8250
- items.length === 0 ? /* @__PURE__ */ jsxs15("div", { className: classNames14("ls-eventlist__empty", emptyClassName), children: [
8251
- emptyIcon ? /* @__PURE__ */ jsx25("span", { className: "ls-eventlist__empty-icon", children: emptyIcon }) : null,
8252
- /* @__PURE__ */ jsx25("span", { children: emptyText })
8253
- ] }) : /* @__PURE__ */ jsx25(
8254
- "div",
8255
- {
8256
- className: "ls-eventlist__list",
8257
- ref: listRef,
8258
- onScroll: handleScroll,
8259
- style: itemGap != null ? { gap: typeof itemGap === "number" ? `${itemGap}px` : itemGap } : void 0,
8260
- children: items.map((item) => /* @__PURE__ */ jsx25("div", { className: "ls-eventlist__row", children: /* @__PURE__ */ jsx25(
8261
- EventListItem,
8262
- {
8263
- username: item.username,
8264
- message: item.message,
8265
- userMessage: item.userMessage,
8266
- avatar: item.avatar,
8267
- fallbackAvatar: item.fallbackAvatar ?? fallbackAvatar,
8268
- timestamp: item.timestamp,
8269
- amountBadge: item.amountBadge,
8270
- platformIcon: showPlatformIcons ? item.platformIcon ?? (item.platform ? /* @__PURE__ */ jsx25(PlatformIcon, { platform: item.platform }) : void 0) : void 0,
8271
- alertIcon: item.alertIcon,
8272
- eventType: item.eventType,
8273
- accentColor: item.accentColor,
8274
- colorFullBackground,
8275
- showAvatar: showAvatars,
8276
- showTimestamp: showTimestamps,
8277
- showMessage: showMessages,
8278
- actions: showActions ? item.actions : void 0,
8279
- onUsernameClick: item.onUsernameClick
8280
- }
8281
- ) }, item.id))
8282
- }
8283
- )
8284
- ] });
8203
+ return /* @__PURE__ */ jsx25("div", { className: classNames14("ls-eventlist", className), id, children: items.length === 0 ? /* @__PURE__ */ jsxs15("div", { className: classNames14("ls-eventlist__empty", emptyClassName), children: [
8204
+ emptyIcon ? /* @__PURE__ */ jsx25("span", { className: "ls-eventlist__empty-icon", children: emptyIcon }) : null,
8205
+ /* @__PURE__ */ jsx25("span", { children: emptyText })
8206
+ ] }) : /* @__PURE__ */ jsx25(
8207
+ "div",
8208
+ {
8209
+ className: "ls-eventlist__list",
8210
+ ref: listRef,
8211
+ onScroll: handleScroll,
8212
+ style: itemGap != null ? { gap: typeof itemGap === "number" ? `${itemGap}px` : itemGap } : void 0,
8213
+ children: items.map((item) => /* @__PURE__ */ jsx25("div", { className: "ls-eventlist__row", children: /* @__PURE__ */ jsx25(
8214
+ EventListItem,
8215
+ {
8216
+ username: item.username,
8217
+ message: item.message,
8218
+ userMessage: item.userMessage,
8219
+ avatar: item.avatar,
8220
+ fallbackAvatar: item.fallbackAvatar ?? fallbackAvatar,
8221
+ timestamp: item.timestamp,
8222
+ platformIcon: showPlatformIcons ? item.platformIcon ?? (item.platform ? /* @__PURE__ */ jsx25(PlatformIcon, { platform: item.platform }) : void 0) : void 0,
8223
+ alertIcon: item.alertIcon,
8224
+ eventType: item.eventType,
8225
+ accentColor: item.accentColor,
8226
+ colorFullBackground,
8227
+ showAvatar: showAvatars,
8228
+ showTimestamp: showTimestamps,
8229
+ showMessage: showMessages,
8230
+ actions: showActions ? item.actions : void 0,
8231
+ onUsernameClick: item.onUsernameClick
8232
+ }
8233
+ ) }, item.id))
8234
+ }
8235
+ ) });
8285
8236
  }
8286
8237
  EventList.displayName = "EventList";
8287
8238
 
@@ -8390,7 +8341,7 @@ StreamStatusPanel.displayName = "StreamStatusPanel";
8390
8341
 
8391
8342
  // src/components/ViewersList/ViewersList.tsx
8392
8343
  import * as React from "react";
8393
- import { useMemo as useMemo5, useState as useState10 } from "react";
8344
+ import { useMemo as useMemo5, useState as useState9 } from "react";
8394
8345
  import classNames16 from "classnames";
8395
8346
  import { jsx as jsx27, jsxs as jsxs17 } from "react/jsx-runtime";
8396
8347
  function ViewersList({
@@ -8409,7 +8360,7 @@ function ViewersList({
8409
8360
  id,
8410
8361
  className
8411
8362
  }) {
8412
- const [query, setQuery] = useState10("");
8363
+ const [query, setQuery] = useState9("");
8413
8364
  const internalSearch = showSearch && !searchSlot;
8414
8365
  const filtered = useMemo5(
8415
8366
  () => internalSearch && query ? viewers.filter((viewer) => viewer.username.toLowerCase().includes(query.toLowerCase())) : viewers,
@@ -8695,7 +8646,7 @@ function ModQueueItem({
8695
8646
  ModQueueItem.displayName = "ModQueueItem";
8696
8647
 
8697
8648
  // src/components/ModQueueList/ModQueueList.tsx
8698
- import { useMemo as useMemo6, useState as useState11 } from "react";
8649
+ import { useMemo as useMemo6, useState as useState10 } from "react";
8699
8650
  import ButtonBase from "@mui/material/ButtonBase";
8700
8651
  import classNames20 from "classnames";
8701
8652
 
@@ -8769,7 +8720,7 @@ function ModQueueList({
8769
8720
  onDeny,
8770
8721
  className
8771
8722
  }) {
8772
- const [internalQuery, setInternalQuery] = useState11("");
8723
+ const [internalQuery, setInternalQuery] = useState10("");
8773
8724
  const query = searchValue !== void 0 ? searchValue : internalQuery;
8774
8725
  const handleSearchChange = (value) => {
8775
8726
  if (searchValue === void 0) {
@@ -8856,7 +8807,7 @@ function ModActivityLog({ logs, emptyText, onClear, clearLabel = "Clear logs", a
8856
8807
  ModActivityLog.displayName = "ModActivityLog";
8857
8808
 
8858
8809
  // src/components/SongRequestList/SongRequestList.tsx
8859
- import { useState as useState12 } from "react";
8810
+ import { useState as useState11 } from "react";
8860
8811
  import classNames22 from "classnames";
8861
8812
  import { jsx as jsx35, jsxs as jsxs25 } from "react/jsx-runtime";
8862
8813
  function SongRequestList({
@@ -8877,7 +8828,7 @@ function SongRequestList({
8877
8828
  emptyText,
8878
8829
  className
8879
8830
  }) {
8880
- const [addValue, setAddValue] = useState12("");
8831
+ const [addValue, setAddValue] = useState11("");
8881
8832
  const submitAdd = () => {
8882
8833
  const query = addValue.trim();
8883
8834
  if (!query || addDisabled || !onAddSong) {
@@ -8955,13 +8906,13 @@ function SongRequestList({
8955
8906
  SongRequestList.displayName = "SongRequestList";
8956
8907
 
8957
8908
  // src/se-import/ui/MarketplacePicker.tsx
8958
- import { useEffect as useEffect9, useMemo as useMemo7, useState as useState13 } from "react";
8909
+ import { useEffect as useEffect9, useMemo as useMemo7, useState as useState12 } from "react";
8959
8910
  import { jsx as jsx36, jsxs as jsxs26 } from "react/jsx-runtime";
8960
8911
  function MarketplacePicker({ seWidgetType, fetchMarketplaceOverlay, CustomEmbed, onPick, onCancel }) {
8961
8912
  const candidateIds = useMemo7(() => getMarketplaceCandidates(seWidgetType), [seWidgetType]);
8962
- const [candidates, setCandidates] = useState13(() => candidateIds.map((id) => ({ id, loading: true })));
8963
- const [activeId, setActiveId] = useState13(candidateIds[0] ?? null);
8964
- const [activeLayerId, setActiveLayerId] = useState13(null);
8913
+ const [candidates, setCandidates] = useState12(() => candidateIds.map((id) => ({ id, loading: true })));
8914
+ const [activeId, setActiveId] = useState12(candidateIds[0] ?? null);
8915
+ const [activeLayerId, setActiveLayerId] = useState12(null);
8965
8916
  useEffect9(() => {
8966
8917
  let cancelled = false;
8967
8918
  candidateIds.forEach(async (id) => {
@@ -11467,8 +11418,8 @@ var CUSTOM_WIDGET_TABS = [
11467
11418
  ];
11468
11419
  function CustomWidgetCard({ widget }) {
11469
11420
  const tabs = CUSTOM_WIDGET_TABS.filter(({ key }) => widget[key].trim().length > 0);
11470
- const [activeKey, setActiveKey] = useState14(tabs[0]?.key ?? "js");
11471
- const [copied, setCopied] = useState14(false);
11421
+ const [activeKey, setActiveKey] = useState13(tabs[0]?.key ?? "js");
11422
+ const [copied, setCopied] = useState13(false);
11472
11423
  const value = widget[activeKey] ?? "";
11473
11424
  useEffect10(() => setCopied(false), [activeKey]);
11474
11425
  const handleCopy = useCallback4(() => {
@@ -11593,47 +11544,47 @@ function SEImportWizard({
11593
11544
  CustomEmbed,
11594
11545
  isAdmin
11595
11546
  } = bindings;
11596
- const [step, setStep] = useState14(
11547
+ const [step, setStep] = useState13(
11597
11548
  initialStep ?? (initialUrl ? "url" : initialJwt ? "connect" : "mode")
11598
11549
  );
11599
- const [entryMode, setEntryMode] = useState14(
11550
+ const [entryMode, setEntryMode] = useState13(
11600
11551
  initialStep === "url" ? "url" : initialStep === "connect" ? "jwt" : initialUrl ? "url" : initialJwt ? "jwt" : null
11601
11552
  );
11602
- const [jwt, setJwt] = useState14(initialJwt);
11603
- const [seClient, setSeClient] = useState14(null);
11604
- const [channels, setChannels] = useState14(null);
11605
- const [selectedChannelId, setSelectedChannelId] = useState14(null);
11606
- const [connectError, setConnectError] = useState14(null);
11607
- const [connecting, setConnecting] = useState14(false);
11608
- const [overlayList, setOverlayList] = useState14(
11553
+ const [jwt, setJwt] = useState13(initialJwt);
11554
+ const [seClient, setSeClient] = useState13(null);
11555
+ const [channels, setChannels] = useState13(null);
11556
+ const [selectedChannelId, setSelectedChannelId] = useState13(null);
11557
+ const [connectError, setConnectError] = useState13(null);
11558
+ const [connecting, setConnecting] = useState13(false);
11559
+ const [overlayList, setOverlayList] = useState13(
11609
11560
  initialOverlayList?.length ? initialOverlayList : null
11610
11561
  );
11611
- const [overlaysLoading, setOverlaysLoading] = useState14(false);
11612
- const [overlaysError, setOverlaysError] = useState14(null);
11613
- const [selectedOverlayIds, setSelectedOverlayIds] = useState14(/* @__PURE__ */ new Set());
11614
- const [activeOverlaySummaries, setActiveOverlaySummaries] = useState14([]);
11615
- const [activeOverlayPreview, setActiveOverlayPreview] = useState14();
11616
- const [url, setUrl] = useState14(initialUrl);
11617
- const [loadError, setLoadError] = useState14(null);
11618
- const [loading, setLoading] = useState14(false);
11619
- const [result, setResult] = useState14(null);
11620
- const [batchImports, setBatchImports] = useState14([]);
11621
- const [originalReviewItems, setOriginalReviewItems] = useState14([]);
11622
- const [options, setOptions] = useState14({
11562
+ const [overlaysLoading, setOverlaysLoading] = useState13(false);
11563
+ const [overlaysError, setOverlaysError] = useState13(null);
11564
+ const [selectedOverlayIds, setSelectedOverlayIds] = useState13(/* @__PURE__ */ new Set());
11565
+ const [activeOverlaySummaries, setActiveOverlaySummaries] = useState13([]);
11566
+ const [activeOverlayPreview, setActiveOverlayPreview] = useState13();
11567
+ const [url, setUrl] = useState13(initialUrl);
11568
+ const [loadError, setLoadError] = useState13(null);
11569
+ const [loading, setLoading] = useState13(false);
11570
+ const [result, setResult] = useState13(null);
11571
+ const [batchImports, setBatchImports] = useState13([]);
11572
+ const [originalReviewItems, setOriginalReviewItems] = useState13([]);
11573
+ const [options, setOptions] = useState13({
11623
11574
  mirrorAssets: true,
11624
11575
  name: ""
11625
11576
  });
11626
- const [mirrorRows, setMirrorRows] = useState14([]);
11627
- const [mirrorRunning, setMirrorRunning] = useState14(false);
11628
- const [rowStates, setRowStates] = useState14({});
11629
- const [reviewIndex, setReviewIndex] = useState14(0);
11630
- const [importing, setImporting] = useState14(false);
11631
- const [marketplacePickerOpen, setMarketplacePickerOpen] = useState14(false);
11577
+ const [mirrorRows, setMirrorRows] = useState13([]);
11578
+ const [mirrorRunning, setMirrorRunning] = useState13(false);
11579
+ const [rowStates, setRowStates] = useState13({});
11580
+ const [reviewIndex, setReviewIndex] = useState13(0);
11581
+ const [importing, setImporting] = useState13(false);
11582
+ const [marketplacePickerOpen, setMarketplacePickerOpen] = useState13(false);
11632
11583
  const mirrorStartedRef = useRef9(false);
11633
11584
  const mirrorAbortRef = useRef9(null);
11634
11585
  const initialOverlayImportStartedRef = useRef9(false);
11635
11586
  const filenameCacheRef = useRef9(/* @__PURE__ */ new Map());
11636
- const [assetUrls, setAssetUrls] = useState14([]);
11587
+ const [assetUrls, setAssetUrls] = useState13([]);
11637
11588
  const currentItem = originalReviewItems[reviewIndex];
11638
11589
  const currentRow = currentItem ? rowStates[currentItem.moduleId] ?? { state: "pending" } : void 0;
11639
11590
  const handleConnect = useCallback4(async () => {
@@ -536,6 +536,10 @@ var resolvePlatformChatterProfileUrl = ({ platform, username, displayname, userI
536
536
  return normalizedUsername ? `https://www.tiktok.com/@${encodeURIComponent(normalizedUsername)}` : null;
537
537
  case "kick":
538
538
  return normalizedUsername ? `https://kick.com/${encodeURIComponent(normalizedUsername)}` : null;
539
+ case "twitter":
540
+ return normalizedUsername ? `https://twitter.com/${encodeURIComponent(normalizedUsername)}` : null;
541
+ case "trovo":
542
+ return normalizedUsername ? `https://trovo.live/s/${encodeURIComponent(normalizedUsername)}` : null;
539
543
  case "discord":
540
544
  return normalizedUserId ? `https://discord.com/users/${encodeURIComponent(normalizedUserId)}` : null;
541
545
  default:
package/dist/utils.d.ts CHANGED
@@ -108,4 +108,13 @@ declare const codeMirrorlinterOptions: (type: "overlay" | "code", language?: "js
108
108
  };
109
109
  };
110
110
 
111
- export { codeMirrorlinterOptions, variableCompletionOptions };
111
+ type PingNote = {
112
+ freq: number;
113
+ at: number;
114
+ };
115
+ declare const PING_NOTES: PingNote[];
116
+ declare const playEventPing: (options?: {
117
+ sinkId?: string;
118
+ }) => void;
119
+
120
+ export { PING_NOTES, type PingNote, codeMirrorlinterOptions, playEventPing, variableCompletionOptions };
package/dist/utils.js CHANGED
@@ -752,6 +752,10 @@ var resolvePlatformChatterProfileUrl = ({ platform, username, displayname, userI
752
752
  return normalizedUsername ? `https://www.tiktok.com/@${encodeURIComponent(normalizedUsername)}` : null;
753
753
  case "kick":
754
754
  return normalizedUsername ? `https://kick.com/${encodeURIComponent(normalizedUsername)}` : null;
755
+ case "twitter":
756
+ return normalizedUsername ? `https://twitter.com/${encodeURIComponent(normalizedUsername)}` : null;
757
+ case "trovo":
758
+ return normalizedUsername ? `https://trovo.live/s/${encodeURIComponent(normalizedUsername)}` : null;
755
759
  case "discord":
756
760
  return normalizedUserId ? `https://discord.com/users/${encodeURIComponent(normalizedUserId)}` : null;
757
761
  default:
@@ -808,8 +812,97 @@ var resolveChatterProfileUrlWithResolvers = async ({
808
812
  userId: normalizedUserId || void 0
809
813
  });
810
814
  };
815
+
816
+ // src/utils/eventPing.ts
817
+ var PING_NOTES = [
818
+ { freq: 1046.5, at: 0 },
819
+ { freq: 1318.51, at: 0.075 },
820
+ { freq: 1567.98, at: 0.15 },
821
+ { freq: 2093, at: 0.235 }
822
+ ];
823
+ var pingAudioContext = null;
824
+ var pingUnlockBound = false;
825
+ var appliedSinkId = null;
826
+ var getPingContext = () => {
827
+ const Ctx = globalThis.AudioContext ?? globalThis.webkitAudioContext;
828
+ if (!Ctx) {
829
+ return null;
830
+ }
831
+ if (!pingAudioContext) {
832
+ pingAudioContext = new Ctx();
833
+ }
834
+ if (!pingUnlockBound) {
835
+ pingUnlockBound = true;
836
+ const unlock = () => {
837
+ pingAudioContext?.resume().catch(() => {
838
+ });
839
+ };
840
+ globalThis.addEventListener?.("pointerdown", unlock);
841
+ globalThis.addEventListener?.("keydown", unlock);
842
+ }
843
+ return pingAudioContext;
844
+ };
845
+ var applyPingSink = (ctx, sinkId) => {
846
+ if (sinkId === void 0 || sinkId === appliedSinkId) {
847
+ return null;
848
+ }
849
+ const sinkCtx = ctx;
850
+ if (typeof sinkCtx.setSinkId !== "function") {
851
+ return null;
852
+ }
853
+ appliedSinkId = sinkId;
854
+ return sinkCtx.setSinkId(sinkId).catch(() => {
855
+ });
856
+ };
857
+ var emitPingTone = (ctx) => {
858
+ const start = ctx.currentTime;
859
+ const master = ctx.createGain();
860
+ master.gain.setValueAtTime(0.85, start);
861
+ master.connect(ctx.destination);
862
+ for (const note of PING_NOTES) {
863
+ const noteStart = start + note.at;
864
+ for (const detune of [-5, 6]) {
865
+ const osc = ctx.createOscillator();
866
+ const gain = ctx.createGain();
867
+ osc.type = "triangle";
868
+ osc.frequency.setValueAtTime(note.freq, noteStart);
869
+ osc.detune.setValueAtTime(detune, noteStart);
870
+ osc.connect(gain);
871
+ gain.connect(master);
872
+ gain.gain.setValueAtTime(1e-4, noteStart);
873
+ gain.gain.exponentialRampToValueAtTime(0.13, noteStart + 0.012);
874
+ gain.gain.exponentialRampToValueAtTime(1e-4, noteStart + 0.4);
875
+ osc.start(noteStart);
876
+ osc.stop(noteStart + 0.42);
877
+ }
878
+ }
879
+ };
880
+ var playEventPing = (options) => {
881
+ try {
882
+ const ctx = getPingContext();
883
+ if (!ctx) {
884
+ return;
885
+ }
886
+ const run = () => {
887
+ if (ctx.state === "suspended") {
888
+ ctx.resume().then(() => emitPingTone(ctx)).catch(() => {
889
+ });
890
+ return;
891
+ }
892
+ emitPingTone(ctx);
893
+ };
894
+ const sinkApplied = applyPingSink(ctx, options?.sinkId);
895
+ if (sinkApplied) {
896
+ sinkApplied.then(run, run);
897
+ } else {
898
+ run();
899
+ }
900
+ } catch {
901
+ }
902
+ };
811
903
  export {
812
904
  MEDIA_PREVIEW_USER_LEVEL_VALUES,
905
+ PING_NOTES,
813
906
  buildChatMessageContent,
814
907
  codeMirrorlinterOptions,
815
908
  getMediaPreviewFromUrl,
@@ -818,6 +911,7 @@ export {
818
911
  normalizeHttpUrl,
819
912
  normalizeMediaPreviewUserLevels,
820
913
  parseMessageLinks,
914
+ playEventPing,
821
915
  resolveChatterProfileUrlWithResolvers,
822
916
  resolveMediaPreviewRoleSettings,
823
917
  resolveMediaPreviewSetting,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lumiastream/ui",
3
- "version": "0.8.3",
3
+ "version": "0.8.5",
4
4
  "author": "Lumia Stream",
5
5
  "license": "ISC",
6
6
  "description": "Lumia UI Kit",
@@ -153,7 +153,6 @@
153
153
  "watch": "tsup --watch",
154
154
  "test": "vitest run",
155
155
  "test:watch": "vitest",
156
- "link-local": "npm run build && node ./scripts/link-local.mjs",
157
156
  "release": "changeset && changeset tag && npm run build && npm publish",
158
157
  "prepublishOnly": "npm run build",
159
158
  "postpublish": "npm cache clean --force && node ./scripts/postpublish-install.mjs",
@@ -193,8 +192,8 @@
193
192
  "vitest": "^4.1.6"
194
193
  },
195
194
  "dependencies": {
196
- "@lumiastream/lumia-translations": "^1.17.9",
197
- "@lumiastream/lumia-types": "3.8.2",
195
+ "@lumiastream/lumia-translations": "1.18.3",
196
+ "@lumiastream/lumia-types": "3.8.4",
198
197
  "classnames": "^2.5.1",
199
198
  "globals": "^17.4.0",
200
199
  "nanoid": "^5.1.11",