@decentnetwork/beagle-ui 0.2.11 → 0.2.13

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.
Files changed (2) hide show
  1. package/dist/beagle-ui.js +58 -19
  2. package/package.json +1 -1
package/dist/beagle-ui.js CHANGED
@@ -1,4 +1,4 @@
1
- export const BEAGLE_UI_VERSION = "0.2.11";
1
+ export const BEAGLE_UI_VERSION = "0.2.13";
2
2
  // src/icons.jsx
3
3
  var ICON_PATHS = {
4
4
  // ---- tab bar (the four must feel like one set) ----
@@ -110,6 +110,7 @@ Object.assign(ICON_PATHS, {
110
110
  unlink: '<path d="M9 15 5.5 18.5a3.5 3.5 0 0 1-5-5L4 10"/><path d="m15 9 3.5-3.5a3.5 3.5 0 0 1 5 5L20 14"/><path d="M8 8 4 4M16 16l4 4M3 11h2M11 3v2"/>',
111
111
  zap: '<path d="M13 2 4 13h7l-1 9 9-11h-7l1-9Z"/>',
112
112
  clock: '<circle cx="12" cy="12" r="9"/><path d="M12 7v5l3.5 2"/>',
113
+ bellOff: '<path d="M8.7 3.4A6 6 0 0 1 18 8.5c0 3 .5 5 1.1 6.3M6.1 6.1A6 6 0 0 0 6 8.5c0 6.5-2.5 8-2.5 8H16"/><path d="M13.7 20.5a2 2 0 0 1-3.4 0"/><path d="m3 3 18 18"/>',
113
114
  plug: '<path d="M9 2v6M15 2v6"/><path d="M7 8h10v3a5 5 0 0 1-10 0V8Z"/><path d="M12 16v6"/>'
114
115
  });
115
116
 
@@ -499,7 +500,7 @@ function RequestsBlock({ T, requests, onAct }) {
499
500
  paddingLeft: 8
500
501
  } }, r.descr), failed[r.id] && /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--ui)", fontSize: 11, color: "var(--danger)" } }, failed[r.id]), /* @__PURE__ */ React.createElement("div", { style: { display: "flex", gap: 6 } }, /* @__PURE__ */ React.createElement(Btn, { tone: "ok", icon: "check", size: "sm", onClick: () => act(r, "accept"), style: { flex: 1 } }, T.accept), /* @__PURE__ */ React.createElement(Btn, { tone: "danger", icon: "x", size: "sm", onClick: () => act(r, "reject"), style: { flex: 1 } }, T.reject))))));
501
502
  }
502
- function PeerRow({ peer, T, active, onClick }) {
503
+ function PeerRow({ peer, T, active, onClick, muted }) {
503
504
  const name = peer.alias || peer.userId;
504
505
  return /* @__PURE__ */ React.createElement("button", { onClick, style: {
505
506
  display: "flex",
@@ -521,7 +522,7 @@ function PeerRow({ peer, T, active, onClick }) {
521
522
  whiteSpace: "nowrap",
522
523
  overflow: "hidden",
523
524
  textOverflow: "ellipsis"
524
- } }, peer.alias || shortKey(peer.userId, 8, 5)), peer.agent && /* @__PURE__ */ React.createElement(Icon, { name: "bot", size: 13, color: "var(--faint)", stroke: 2 }), peer.wire === "64" && /* @__PURE__ */ React.createElement(Tag, { tone: "off", style: { height: 15, fontSize: 9.5, padding: "0 4px" } }, "w64")), /* @__PURE__ */ React.createElement("div", { style: { display: "flex", alignItems: "center", gap: 6, marginTop: 2 } }, /* @__PURE__ */ React.createElement("span", { style: { fontFamily: "var(--mono)", fontSize: 11, color: "var(--faint)" } }, peer.ip), /* @__PURE__ */ React.createElement("span", { style: { color: "var(--line)", fontSize: 11 } }, "\xB7"), /* @__PURE__ */ React.createElement("span", { style: {
525
+ } }, peer.alias || shortKey(peer.userId, 8, 5)), peer.agent && /* @__PURE__ */ React.createElement(Icon, { name: "bot", size: 13, color: "var(--faint)", stroke: 2 }), muted && /* @__PURE__ */ React.createElement(Icon, { name: "bellOff", size: 12, color: "var(--faint)", stroke: 2, title: T && T.mutedTag || "sound muted" }), peer.wire === "64" && /* @__PURE__ */ React.createElement(Tag, { tone: "off", style: { height: 15, fontSize: 9.5, padding: "0 4px" } }, "w64")), /* @__PURE__ */ React.createElement("div", { style: { display: "flex", alignItems: "center", gap: 6, marginTop: 2 } }, /* @__PURE__ */ React.createElement("span", { style: { fontFamily: "var(--mono)", fontSize: 11, color: "var(--faint)" } }, peer.ip), /* @__PURE__ */ React.createElement("span", { style: { color: "var(--line)", fontSize: 11 } }, "\xB7"), /* @__PURE__ */ React.createElement("span", { style: {
525
526
  fontSize: 11,
526
527
  color: "var(--dim)",
527
528
  whiteSpace: "nowrap",
@@ -534,7 +535,7 @@ function PeerRow({ peer, T, active, onClick }) {
534
535
  function dkActivityTs(p) {
535
536
  return Math.max(p.lastTs || 0, p.acceptedAt || 0, p.requestedAt || 0);
536
537
  }
537
- function PeerSidebar({ T, peers, requests, activeId, onSelect, onAct, onAdd, prefillAddr, onPrefillConsumed }) {
538
+ function PeerSidebar({ T, peers, requests, activeId, onSelect, onAct, onAdd, prefillAddr, onPrefillConsumed, muted }) {
538
539
  const [q, setQ] = React.useState("");
539
540
  const [addr, setAddr] = React.useState("");
540
541
  const [addState, setAddState] = React.useState(null);
@@ -545,6 +546,10 @@ function PeerSidebar({ T, peers, requests, activeId, onSelect, onAct, onAdd, pre
545
546
  setFromDeepLink(true);
546
547
  }
547
548
  }, [prefillAddr]);
549
+ const dismissDeepLink = () => {
550
+ setFromDeepLink(false);
551
+ onPrefillConsumed && onPrefillConsumed();
552
+ };
548
553
  const submitAddr = () => {
549
554
  const v = addr.trim();
550
555
  if (!v || addState && addState.kind === "sending")
@@ -557,9 +562,11 @@ function PeerSidebar({ T, peers, requests, activeId, onSelect, onAct, onAdd, pre
557
562
  onPrefillConsumed && onPrefillConsumed();
558
563
  setAddState({ kind: "ok", msg: T.addSent });
559
564
  } else {
565
+ dismissDeepLink();
560
566
  setAddState({ kind: "err", msg: r && r.error ? `${T.addFailed}: ${r.error}` : T.addFailed });
561
567
  }
562
568
  }).catch((e) => {
569
+ dismissDeepLink();
563
570
  setAddState({ kind: "err", msg: `${T.addFailed}: ${e && e.message || e}` });
564
571
  }).finally(() => {
565
572
  setTimeout(() => setAddState((s) => s && s.kind !== "sending" ? null : s), 6e3);
@@ -585,8 +592,11 @@ function PeerSidebar({ T, peers, requests, activeId, onSelect, onAct, onAdd, pre
585
592
  background: "color-mix(in oklab, var(--accent), transparent 88%)",
586
593
  border: "1px solid var(--accent)",
587
594
  borderRadius: 8,
588
- padding: "7px 10px"
589
- } }, T.deepLinkConfirm || "\u901A\u8FC7\u94FE\u63A5\u6DFB\u52A0\u8FD9\u4F4D\u597D\u53CB? \u70B9\u300C\u6DFB\u52A0\u300D\u53D1\u9001\u597D\u53CB\u8BF7\u6C42 / Add this contact from the link? Tap Add to send a friend request."), /* @__PURE__ */ React.createElement("div", { style: { display: "flex", gap: 7 } }, /* @__PURE__ */ React.createElement(
595
+ padding: "7px 10px",
596
+ display: "flex",
597
+ alignItems: "flex-start",
598
+ gap: 8
599
+ } }, /* @__PURE__ */ React.createElement("span", { style: { flex: 1 } }, T.deepLinkConfirm || "\u901A\u8FC7\u94FE\u63A5\u6DFB\u52A0\u8FD9\u4F4D\u597D\u53CB? \u70B9\u300C\u6DFB\u52A0\u300D\u53D1\u9001\u597D\u53CB\u8BF7\u6C42 / Add this contact from the link? Tap Add to send a friend request."), /* @__PURE__ */ React.createElement(Btn, { size: "sm", icon: "x", title: T.cancel || "Dismiss", onClick: dismissDeepLink, style: { flexShrink: 0 } })), /* @__PURE__ */ React.createElement("div", { style: { display: "flex", gap: 7 } }, /* @__PURE__ */ React.createElement(
590
600
  "input",
591
601
  {
592
602
  value: addr,
@@ -607,7 +617,7 @@ function PeerSidebar({ T, peers, requests, activeId, onSelect, onAct, onAdd, pre
607
617
  fontSize: 11.5,
608
618
  lineHeight: 1.35,
609
619
  color: addState.kind === "err" ? "var(--bad, #e5484d)" : addState.kind === "ok" ? "var(--good, #46a758)" : "var(--faint)"
610
- } }, addState.msg), /* @__PURE__ */ React.createElement("div", { style: { position: "relative", display: "flex", alignItems: "center" } }, /* @__PURE__ */ React.createElement(Icon, { name: "search", size: 15, color: "var(--faint)", stroke: 2, style: { position: "absolute", left: 9 } }), /* @__PURE__ */ React.createElement("input", { value: q, onChange: (e) => setQ(e.target.value), placeholder: T.search, style: { ...inputStyle, paddingLeft: 30 } }))), /* @__PURE__ */ React.createElement("div", { style: { flex: 1, overflow: "auto", padding: "10px 8px 16px" } }, /* @__PURE__ */ React.createElement(RequestsBlock, { T, requests, onAct }), /* @__PURE__ */ React.createElement(Section, { label: T.peers, count: `${online}/${peers.length}`, style: { margin: "6px 4px 8px" } }), /* @__PURE__ */ React.createElement("div", { style: { display: "flex", flexDirection: "column", gap: 2 } }, filtered.map((p) => /* @__PURE__ */ React.createElement(PeerRow, { key: p.id, peer: p, T, active: p.id === activeId, onClick: () => onSelect(p.id) })), !filtered.length && /* @__PURE__ */ React.createElement("div", { style: { padding: 16, textAlign: "center", fontFamily: "var(--mono)", fontSize: 12, color: "var(--faint)" } }, "no matches"))));
620
+ } }, addState.msg), /* @__PURE__ */ React.createElement("div", { style: { position: "relative", display: "flex", alignItems: "center" } }, /* @__PURE__ */ React.createElement(Icon, { name: "search", size: 15, color: "var(--faint)", stroke: 2, style: { position: "absolute", left: 9 } }), /* @__PURE__ */ React.createElement("input", { value: q, onChange: (e) => setQ(e.target.value), placeholder: T.search, style: { ...inputStyle, paddingLeft: 30 } }))), /* @__PURE__ */ React.createElement("div", { style: { flex: 1, overflow: "auto", padding: "10px 8px 16px" } }, /* @__PURE__ */ React.createElement(RequestsBlock, { T, requests, onAct }), /* @__PURE__ */ React.createElement(Section, { label: T.peers, count: `${online}/${peers.length}`, style: { margin: "6px 4px 8px" } }), /* @__PURE__ */ React.createElement("div", { style: { display: "flex", flexDirection: "column", gap: 2 } }, filtered.map((p) => /* @__PURE__ */ React.createElement(PeerRow, { key: p.id, peer: p, T, active: p.id === activeId, onClick: () => onSelect(p.id), muted: !!muted && muted.includes(p.id) })), !filtered.length && /* @__PURE__ */ React.createElement("div", { style: { padding: 16, textAlign: "center", fontFamily: "var(--mono)", fontSize: 12, color: "var(--faint)" } }, "no matches"))));
611
621
  }
612
622
  var inputStyle = {
613
623
  flex: 1,
@@ -1592,7 +1602,7 @@ function Msg({ m, peer, T, onTheater, onDelete, onCancel, onRetry, onRetryMsg, o
1592
1602
  ) : mine && m.status === "sent" && m.confirmed === false ? /* @__PURE__ */ React.createElement(Icon, { name: "check", size: 12, stroke: 2.2, color: "var(--faint)", title: T.sentUnconfirmed || "sent \u2014 not confirmed by the peer" }) : mine && m.status && /* @__PURE__ */ React.createElement(Icon, { name: "checkCheck", size: 12, stroke: 2.2, color: m.status === "read" ? "var(--accent)" : "var(--faint)" })))
1593
1603
  );
1594
1604
  }
1595
- function Conversation({ T, peer, lang, peers, onOpenChat, thread: threadProp, onSend, onSendFile, onSendRtcFile, onAlias, onRemove, onOpenNet, onCall, onReloadThread }) {
1605
+ function Conversation({ T, peer, lang, peers, onOpenChat, thread: threadProp, onSend, onSendFile, onSendRtcFile, onAlias, onRemove, onOpenNet, onCall, onReloadThread, muted, onToggleMute }) {
1596
1606
  const scrollRef = React.useRef(null);
1597
1607
  const isGroup = React.useMemo(() => dkThreadIsGroup(threadProp), [threadProp]);
1598
1608
  const followScrollRef = React.useRef(true);
@@ -1876,7 +1886,14 @@ function Conversation({ T, peer, lang, peers, onOpenChat, thread: threadProp, on
1876
1886
  ${peer.address}`
1877
1887
  },
1878
1888
  shortKey(peer.address, 8, 6)
1879
- )))), /* @__PURE__ */ React.createElement("div", { style: { flex: 1 } }), onCall && /* @__PURE__ */ React.createElement(Btn, { icon: "phone", title: T && T.audioCall || "Audio call", onClick: () => onCall(peer.userId, false) }), onCall && /* @__PURE__ */ React.createElement(Btn, { icon: "video", title: T && T.videoCall || "Video call", onClick: () => onCall(peer.userId, true) }), onSendRtcFile && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
1889
+ )))), /* @__PURE__ */ React.createElement("div", { style: { flex: 1 } }), onToggleMute && /* @__PURE__ */ React.createElement(
1890
+ Btn,
1891
+ {
1892
+ icon: muted ? "bellOff" : "bell",
1893
+ title: muted ? T && T.unmuteSound || "Turn sound back on for this chat" : T && T.muteSound || "Mute sound for this chat",
1894
+ onClick: () => onToggleMute(peer.id)
1895
+ }
1896
+ ), onCall && /* @__PURE__ */ React.createElement(Btn, { icon: "phone", title: T && T.audioCall || "Audio call", onClick: () => onCall(peer.userId, false) }), onCall && /* @__PURE__ */ React.createElement(Btn, { icon: "video", title: T && T.videoCall || "Video call", onClick: () => onCall(peer.userId, true) }), onSendRtcFile && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
1880
1897
  "input",
1881
1898
  {
1882
1899
  ref: rtcFileRef,
@@ -2068,9 +2085,9 @@ function MenuItem({ icon, label, onClick, danger }) {
2068
2085
  function ChatEmpty({ T }) {
2069
2086
  return /* @__PURE__ */ React.createElement("div", { style: { flex: 1, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", gap: 12, color: "var(--faint)", background: "var(--bg)" } }, /* @__PURE__ */ React.createElement(Icon, { name: "message", size: 40, stroke: 1.4, color: "var(--line)" }), /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--mono)", fontSize: 13 } }, T.pickPeer));
2070
2087
  }
2071
- function ChatTab({ T, lang, peers, requests, activeId, thread, onSelect, onAct, onAdd, onSend, onSendFile, onSendRtcFile, onAlias, onRemove, onOpenNet, onCall, onReloadThread, prefillAddr, onPrefillConsumed }) {
2088
+ function ChatTab({ T, lang, peers, requests, activeId, thread, onSelect, onAct, onAdd, onSend, onSendFile, onSendRtcFile, onAlias, onRemove, onOpenNet, onCall, onReloadThread, prefillAddr, onPrefillConsumed, muted, onToggleMute }) {
2072
2089
  const peer = peers.find((p) => p.id === activeId);
2073
- return /* @__PURE__ */ React.createElement("div", { style: { flex: 1, display: "flex", minWidth: 0, minHeight: 0 } }, /* @__PURE__ */ React.createElement(PeerSidebar, { T, peers, requests, activeId, onSelect, onAct, onAdd, prefillAddr, onPrefillConsumed }), peer ? /* @__PURE__ */ React.createElement(Conversation, { T, peer, lang, peers, onOpenChat: onSelect, thread, onSend, onSendFile, onSendRtcFile, onAlias, onRemove, onOpenNet, onCall, onReloadThread }) : /* @__PURE__ */ React.createElement(ChatEmpty, { T }));
2090
+ return /* @__PURE__ */ React.createElement("div", { style: { flex: 1, display: "flex", minWidth: 0, minHeight: 0 } }, /* @__PURE__ */ React.createElement(PeerSidebar, { T, peers, requests, activeId, onSelect, onAct, onAdd, prefillAddr, onPrefillConsumed, muted }), peer ? /* @__PURE__ */ React.createElement(Conversation, { T, peer, lang, peers, onOpenChat: onSelect, thread, onSend, onSendFile, onSendRtcFile, onAlias, onRemove, onOpenNet, onCall, onReloadThread, muted: !!muted && muted.includes(peer.id), onToggleMute }) : /* @__PURE__ */ React.createElement(ChatEmpty, { T }));
2074
2091
  }
2075
2092
  Object.assign(window, { ChatTab });
2076
2093
 
@@ -4462,8 +4479,10 @@ function dkFlashStop() {
4462
4479
  function dkLooking() {
4463
4480
  return document.visibilityState === "visible" && document.hasFocus();
4464
4481
  }
4465
- function useIncomingAlerts({ T, peers, requests, loaded, activeId, sound = true, flash = true }) {
4482
+ function useIncomingAlerts({ T, peers, requests, loaded, activeId, sound = true, flash = true, muted }) {
4466
4483
  const prev = React.useRef(null);
4484
+ const mutedRef = React.useRef(/* @__PURE__ */ new Set());
4485
+ mutedRef.current = new Set(muted || []);
4467
4486
  React.useEffect(() => dkUnlockAudioOnGesture(), []);
4468
4487
  React.useEffect(() => {
4469
4488
  if (!flash)
@@ -4497,7 +4516,7 @@ function useIncomingAlerts({ T, peers, requests, loaded, activeId, sound = true,
4497
4516
  prev.current = { byId, reqIds };
4498
4517
  if (!was)
4499
4518
  return;
4500
- let msgs = 0, elsewhere = 0, reqs = 0;
4519
+ let msgs = 0, elsewhere = 0, reqs = 0, loud = 0, loudElsewhere = 0;
4501
4520
  for (const [id, cur] of byId) {
4502
4521
  if (cur.dir !== "in" || !cur.ts)
4503
4522
  continue;
@@ -4507,6 +4526,11 @@ function useIncomingAlerts({ T, peers, requests, loaded, activeId, sound = true,
4507
4526
  msgs += 1;
4508
4527
  if (id !== activeId)
4509
4528
  elsewhere += 1;
4529
+ if (!mutedRef.current.has(id)) {
4530
+ loud += 1;
4531
+ if (id !== activeId)
4532
+ loudElsewhere += 1;
4533
+ }
4510
4534
  }
4511
4535
  for (const id of reqIds)
4512
4536
  if (!was.reqIds.has(id))
@@ -4514,8 +4538,8 @@ function useIncomingAlerts({ T, peers, requests, loaded, activeId, sound = true,
4514
4538
  if (!msgs && !reqs)
4515
4539
  return;
4516
4540
  const looking = dkLooking();
4517
- if (sound && !(looking && !reqs && !elsewhere))
4518
- dkChime(reqs && !msgs ? "request" : "message");
4541
+ if (sound && (reqs || loud) && !(looking && !reqs && !loudElsewhere))
4542
+ dkChime(reqs && !loud ? "request" : "message");
4519
4543
  if (flash && !looking) {
4520
4544
  const label = msgs ? T && T.alertMsg || "New message" : T && T.alertReq || "New friend request";
4521
4545
  dkFlashStart(label, msgs + reqs);
@@ -4656,6 +4680,9 @@ var STR = {
4656
4680
  profile: "Profile",
4657
4681
  alertMsg: "New message",
4658
4682
  alertReq: "New friend request",
4683
+ muteSound: "Mute sound for this chat",
4684
+ unmuteSound: "Turn sound back on for this chat",
4685
+ mutedTag: "sound muted",
4659
4686
  recommended: "Discover",
4660
4687
  registered: "Names",
4661
4688
  here: "Here",
@@ -4838,6 +4865,9 @@ var STR = {
4838
4865
  profile: "\u6211\u7684",
4839
4866
  alertMsg: "\u65B0\u6D88\u606F",
4840
4867
  alertReq: "\u65B0\u7684\u597D\u53CB\u8BF7\u6C42",
4868
+ muteSound: "\u5173\u95ED\u6B64\u4F1A\u8BDD\u7684\u63D0\u793A\u97F3",
4869
+ unmuteSound: "\u6062\u590D\u6B64\u4F1A\u8BDD\u7684\u63D0\u793A\u97F3",
4870
+ mutedTag: "\u5DF2\u9759\u97F3",
4841
4871
  recommended: "\u63A8\u8350",
4842
4872
  registered: "\u540D\u5F55",
4843
4873
  here: "\u5728\u573A",
@@ -5195,10 +5225,16 @@ function DkApp() {
5195
5225
  window.addEventListener("hashchange", onHash);
5196
5226
  return () => window.removeEventListener("hashchange", onHash);
5197
5227
  }, []);
5228
+ const jumpedFor = React.useRef("");
5198
5229
  React.useEffect(() => {
5199
- if (!pendingAddr)
5230
+ if (!pendingAddr) {
5231
+ jumpedFor.current = "";
5200
5232
  return;
5201
- setTab("chat");
5233
+ }
5234
+ if (jumpedFor.current !== pendingAddr) {
5235
+ jumpedFor.current = pendingAddr;
5236
+ setTab("chat");
5237
+ }
5202
5238
  if (!peers || !peers.length)
5203
5239
  return;
5204
5240
  const hit = peers.find((p) => p.address && p.address === pendingAddr);
@@ -5230,6 +5266,8 @@ function DkApp() {
5230
5266
  const T = STR[t.lang] || STR.en;
5231
5267
  const vars = dkTheme(t.theme, t.accent);
5232
5268
  const rowPad = t.density === "comfortable" ? "11px 12px" : "7px 10px";
5269
+ const mutedIds = Array.isArray(t.alertMuted) ? t.alertMuted : [];
5270
+ const onToggleMute = (id) => setTweak("alertMuted", mutedIds.includes(id) ? mutedIds.filter((x) => x !== id) : mutedIds.concat(id));
5233
5271
  useIncomingAlerts({
5234
5272
  T,
5235
5273
  peers,
@@ -5237,7 +5275,8 @@ function DkApp() {
5237
5275
  loaded: data.loaded,
5238
5276
  activeId,
5239
5277
  sound: t.alertSound !== false,
5240
- flash: t.alertFlash !== false
5278
+ flash: t.alertFlash !== false,
5279
+ muted: mutedIds
5241
5280
  });
5242
5281
  const callCtl = useCallController(me.userId, (peerId, video, direction) => {
5243
5282
  const text = `WebRTC ${video ? "video" : "audio"} call: ${direction}`;
@@ -5389,7 +5428,7 @@ function DkApp() {
5389
5428
  display: "flex",
5390
5429
  border: "1px solid " + (tab === "profile" ? "var(--line)" : "transparent"),
5391
5430
  background: tab === "profile" ? "var(--panel-2)" : "transparent"
5392
- } }, /* @__PURE__ */ React.createElement(DkAvatar, { peer: { ...me, id: me.userId, agent: false }, size: 36, radius: 9 }))), /* @__PURE__ */ React.createElement("div", { style: { flex: 1, minWidth: 0, minHeight: 0, display: "flex", flexDirection: "column" } }, /* @__PURE__ */ React.createElement(DkBrowserNotice, { lang: t.lang }), /* @__PURE__ */ React.createElement("div", { style: { height: 46, flexShrink: 0, borderBottom: "1px solid var(--line)", background: "var(--panel)", display: "flex", alignItems: "center", gap: 12, padding: "0 16px" } }, /* @__PURE__ */ React.createElement("svg", { width: 20, height: 20, viewBox: "0 0 24 24", fill: "none", stroke: "var(--accent)", strokeWidth: 2.2, strokeLinecap: "round", strokeLinejoin: "round", style: { display: "block", flexShrink: 0 } }, /* @__PURE__ */ React.createElement("path", { d: "m4.5 17 6-6-6-6" }), /* @__PURE__ */ React.createElement("path", { d: "M12 18.5h7.5" })), /* @__PURE__ */ React.createElement("span", { style: { fontFamily: "var(--mono)", fontSize: 14, fontWeight: 700, letterSpacing: -0.3, color: "var(--text)" } }, "beagle"), /* @__PURE__ */ React.createElement("span", { style: { fontFamily: "var(--mono)", fontSize: 12, color: "var(--faint)" } }, "\xB7 ", (nav.find((n) => n.id === tab) || { label: T.profile }).label.toLowerCase()), /* @__PURE__ */ React.createElement("div", { style: { flex: 1 } }), /* @__PURE__ */ React.createElement(Tag, { tone: "accent" }, me.channel, " \xB7 lan ", me.lanVer), /* @__PURE__ */ React.createElement("div", { style: { display: "flex", alignItems: "center", gap: 7, padding: "0 4px" } }, /* @__PURE__ */ React.createElement(StatusDot, { online: me.online }), /* @__PURE__ */ React.createElement(Mono, { size: 12.5, copy: me.ip }, me.ip)), /* @__PURE__ */ React.createElement("span", { style: { width: 1, height: 22, background: "var(--line)" } }), /* @__PURE__ */ React.createElement("div", { style: { display: "flex", alignItems: "center", gap: 8 } }, /* @__PURE__ */ React.createElement(DkAvatar, { peer: { ...me, id: me.userId, agent: false }, size: 26, radius: 7 }), /* @__PURE__ */ React.createElement("span", { style: { fontFamily: "var(--mono)", fontSize: 12.5, fontWeight: 600, color: "var(--text)" } }, me.name))), tab === "chat" && /* @__PURE__ */ React.createElement(ChatTab, { T, lang: t.lang, peers, requests, activeId, thread: data.threads[activeId], onSelect, onAct, onAdd, onSend, onSendFile, onSendRtcFile, onAlias, onRemove, onOpenNet, onCall, onReloadThread: () => activeId && data.loadThread(activeId), prefillAddr: pendingAddr, onPrefillConsumed: () => setPendingAddr("") }), tab === "here" && /* @__PURE__ */ React.createElement(DiscoverTab, { T, kind: "bridge", peers, meId: me.userId, onAdd, onOpenChat }), tab === "recommended" && /* @__PURE__ */ React.createElement(DiscoverTab, { T, kind: "recommended", peers, meId: me.userId, onAdd, onOpenChat }), tab === "registered" && /* @__PURE__ */ React.createElement(DiscoverTab, { T, kind: "registered", peers, meId: me.userId, onAdd, onOpenChat }), tab === "network" && /* @__PURE__ */ React.createElement(NetworkTab, { T, me, peers, exits, activeExit, reqCount: requests.length, onSetExit, onOpenChat, backend, onArmLan: armLan, onCancelLan: cancelLan }), tab === "apps" && /* @__PURE__ */ React.createElement(AppsTab, { T, t }), tab === "profile" && /* @__PURE__ */ React.createElement(ProfileTab, { T, me, onEdit, t, setTweak })), data.locked && /* @__PURE__ */ React.createElement(
5431
+ } }, /* @__PURE__ */ React.createElement(DkAvatar, { peer: { ...me, id: me.userId, agent: false }, size: 36, radius: 9 }))), /* @__PURE__ */ React.createElement("div", { style: { flex: 1, minWidth: 0, minHeight: 0, display: "flex", flexDirection: "column" } }, /* @__PURE__ */ React.createElement(DkBrowserNotice, { lang: t.lang }), /* @__PURE__ */ React.createElement("div", { style: { height: 46, flexShrink: 0, borderBottom: "1px solid var(--line)", background: "var(--panel)", display: "flex", alignItems: "center", gap: 12, padding: "0 16px" } }, /* @__PURE__ */ React.createElement("svg", { width: 20, height: 20, viewBox: "0 0 24 24", fill: "none", stroke: "var(--accent)", strokeWidth: 2.2, strokeLinecap: "round", strokeLinejoin: "round", style: { display: "block", flexShrink: 0 } }, /* @__PURE__ */ React.createElement("path", { d: "m4.5 17 6-6-6-6" }), /* @__PURE__ */ React.createElement("path", { d: "M12 18.5h7.5" })), /* @__PURE__ */ React.createElement("span", { style: { fontFamily: "var(--mono)", fontSize: 14, fontWeight: 700, letterSpacing: -0.3, color: "var(--text)" } }, "beagle"), /* @__PURE__ */ React.createElement("span", { style: { fontFamily: "var(--mono)", fontSize: 12, color: "var(--faint)" } }, "\xB7 ", (nav.find((n) => n.id === tab) || { label: T.profile }).label.toLowerCase()), /* @__PURE__ */ React.createElement("div", { style: { flex: 1 } }), /* @__PURE__ */ React.createElement(Tag, { tone: "accent" }, me.channel, " \xB7 lan ", me.lanVer), /* @__PURE__ */ React.createElement("div", { style: { display: "flex", alignItems: "center", gap: 7, padding: "0 4px" } }, /* @__PURE__ */ React.createElement(StatusDot, { online: me.online }), /* @__PURE__ */ React.createElement(Mono, { size: 12.5, copy: me.ip }, me.ip)), /* @__PURE__ */ React.createElement("span", { style: { width: 1, height: 22, background: "var(--line)" } }), /* @__PURE__ */ React.createElement("div", { style: { display: "flex", alignItems: "center", gap: 8 } }, /* @__PURE__ */ React.createElement(DkAvatar, { peer: { ...me, id: me.userId, agent: false }, size: 26, radius: 7 }), /* @__PURE__ */ React.createElement("span", { style: { fontFamily: "var(--mono)", fontSize: 12.5, fontWeight: 600, color: "var(--text)" } }, me.name))), tab === "chat" && /* @__PURE__ */ React.createElement(ChatTab, { T, lang: t.lang, peers, requests, activeId, thread: data.threads[activeId], onSelect, onAct, onAdd, onSend, onSendFile, onSendRtcFile, onAlias, onRemove, onOpenNet, onCall, onReloadThread: () => activeId && data.loadThread(activeId), prefillAddr: pendingAddr, onPrefillConsumed: () => setPendingAddr(""), muted: mutedIds, onToggleMute }), tab === "here" && /* @__PURE__ */ React.createElement(DiscoverTab, { T, kind: "bridge", peers, meId: me.userId, onAdd, onOpenChat }), tab === "recommended" && /* @__PURE__ */ React.createElement(DiscoverTab, { T, kind: "recommended", peers, meId: me.userId, onAdd, onOpenChat }), tab === "registered" && /* @__PURE__ */ React.createElement(DiscoverTab, { T, kind: "registered", peers, meId: me.userId, onAdd, onOpenChat }), tab === "network" && /* @__PURE__ */ React.createElement(NetworkTab, { T, me, peers, exits, activeExit, reqCount: requests.length, onSetExit, onOpenChat, backend, onArmLan: armLan, onCancelLan: cancelLan }), tab === "apps" && /* @__PURE__ */ React.createElement(AppsTab, { T, t }), tab === "profile" && /* @__PURE__ */ React.createElement(ProfileTab, { T, me, onEdit, t, setTweak })), data.locked && /* @__PURE__ */ React.createElement(
5393
5432
  DkLockedOut,
5394
5433
  {
5395
5434
  compact: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decentnetwork/beagle-ui",
3
- "version": "0.2.11",
3
+ "version": "0.2.13",
4
4
  "description": "The Beagle chat UI, minus the machine it runs on — shared by the desktop install and the browser build.",
5
5
  "license": "MIT",
6
6
  "type": "module",