@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.
- package/dist/beagle-ui.js +58 -19
- package/package.json +1 -1
package/dist/beagle-ui.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export const BEAGLE_UI_VERSION = "0.2.
|
|
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
|
-
|
|
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 } }),
|
|
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 && !
|
|
4518
|
-
dkChime(reqs && !
|
|
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
|
-
|
|
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