@decentnetwork/beagle 0.1.104 → 0.1.105
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/desktop/app.js +132 -45
- package/package.json +2 -2
package/dist/desktop/app.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
window.__DK_UI_VERSION="0.1.
|
|
1
|
+
window.__DK_UI_VERSION="0.1.105";
|
|
2
2
|
"use strict";
|
|
3
3
|
(() => {
|
|
4
4
|
// packages/beagle-ui/dist/beagle-ui.js
|
|
@@ -341,6 +341,42 @@ window.__DK_UI_VERSION="0.1.104";
|
|
|
341
341
|
channel: "@next",
|
|
342
342
|
wire: "163"
|
|
343
343
|
};
|
|
344
|
+
var DK_PAGE = 30;
|
|
345
|
+
function dkMsgKey(m) {
|
|
346
|
+
return m.id || m.ts + ":" + m.dir;
|
|
347
|
+
}
|
|
348
|
+
function dkThreadMsg(m) {
|
|
349
|
+
return {
|
|
350
|
+
id: m.id,
|
|
351
|
+
from: m.dir === "out" ? "me" : "them",
|
|
352
|
+
time: dkClock(m.ts),
|
|
353
|
+
text: m.text,
|
|
354
|
+
file: m.file ? {
|
|
355
|
+
name: m.file.name,
|
|
356
|
+
size: dkFileSize(m.file.size),
|
|
357
|
+
dir: m.dir,
|
|
358
|
+
media: dkFileMediaKind(m.file.name),
|
|
359
|
+
status: m.file.status,
|
|
360
|
+
pct: m.file.status === "sending" && m.file.size ? Math.min(100, (m.file.sent || 0) / m.file.size * 100) : void 0,
|
|
361
|
+
kbps: m.file.kbps
|
|
362
|
+
} : void 0,
|
|
363
|
+
// Pass the real state through. Collapsing everything that was not
|
|
364
|
+
// 'queued' to 'read' meant a message still in flight — or one that
|
|
365
|
+
// never went out at all — rendered as delivered.
|
|
366
|
+
status: m.dir === "out" ? m.status === "queued" || m.status === "sending" || m.status === "failed" || m.status === "sent" ? m.status : "read" : void 0,
|
|
367
|
+
error: m.error,
|
|
368
|
+
// false = went to a live session but nobody acknowledged it (one tick).
|
|
369
|
+
// Dropped here before, so that state could never render.
|
|
370
|
+
confirmed: m.confirmed,
|
|
371
|
+
// Delivery path: "online" = live session, "offline" = express relay.
|
|
372
|
+
// Both directions carry it now; the bubble labels them the same way.
|
|
373
|
+
via: m.via,
|
|
374
|
+
// Brief 30: a validated component form, already whitelisted host-side.
|
|
375
|
+
// Passed through untouched — the renderer treats every string as text,
|
|
376
|
+
// never markup.
|
|
377
|
+
components: m.components
|
|
378
|
+
};
|
|
379
|
+
}
|
|
344
380
|
function useDaemonData() {
|
|
345
381
|
const [snap, setSnap] = React.useState({
|
|
346
382
|
me: DK_ME_FALLBACK,
|
|
@@ -386,52 +422,74 @@ window.__DK_UI_VERSION="0.1.104";
|
|
|
386
422
|
return () => clearInterval(t);
|
|
387
423
|
}, [refresh]);
|
|
388
424
|
const inFlight = React.useRef(/* @__PURE__ */ new Set());
|
|
389
|
-
const
|
|
390
|
-
|
|
425
|
+
const cache = React.useRef({});
|
|
426
|
+
const [earlier, setEarlier] = React.useState({});
|
|
427
|
+
const publish = React.useCallback((peerId) => {
|
|
428
|
+
const c = cache.current[peerId];
|
|
429
|
+
if (!c)
|
|
430
|
+
return;
|
|
431
|
+
const arr = [...c.byId.values()].sort((a, b) => a.ts - b.ts);
|
|
432
|
+
const msgs = arr.map(dkThreadMsg);
|
|
433
|
+
const withDay = msgs.length ? [{ day: dkDayLabel(arr[0].ts) }].concat(msgs) : [];
|
|
434
|
+
setThreads((t) => Object.assign({}, t, { [peerId]: withDay }));
|
|
435
|
+
setEarlier((e) => e[peerId] === c.more ? e : Object.assign({}, e, { [peerId]: c.more }));
|
|
436
|
+
}, []);
|
|
437
|
+
const loadThread = React.useCallback(async (peerId, opts) => {
|
|
438
|
+
if (!peerId)
|
|
439
|
+
return;
|
|
440
|
+
if (opts && opts.reset)
|
|
441
|
+
delete cache.current[peerId];
|
|
442
|
+
if (inFlight.current.has(peerId))
|
|
391
443
|
return;
|
|
392
444
|
inFlight.current.add(peerId);
|
|
393
445
|
try {
|
|
394
|
-
const d = await dkGet("/api/chat-history?peer=" + encodeURIComponent(peerId) + "&limit=
|
|
446
|
+
const d = await dkGet("/api/chat-history?peer=" + encodeURIComponent(peerId) + "&limit=" + DK_PAGE);
|
|
395
447
|
const arr = d.chats && d.chats[peerId] || [];
|
|
396
448
|
await prefetchThreadFiles(arr);
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
kbps: m.file.kbps
|
|
410
|
-
} : void 0,
|
|
411
|
-
// Pass the real state through. Collapsing everything that was not
|
|
412
|
-
// 'queued' to 'read' meant a message still in flight — or one that
|
|
413
|
-
// never went out at all — rendered as delivered.
|
|
414
|
-
status: m.dir === "out" ? m.status === "queued" || m.status === "sending" || m.status === "failed" || m.status === "sent" ? m.status : "read" : void 0,
|
|
415
|
-
error: m.error,
|
|
416
|
-
// false = went to a live session but nobody acknowledged it (one tick).
|
|
417
|
-
// Dropped here before, so that state could never render.
|
|
418
|
-
confirmed: m.confirmed,
|
|
419
|
-
// Delivery path: "online" = live session, "offline" = express relay.
|
|
420
|
-
// Both directions carry it now; the bubble labels them the same way.
|
|
421
|
-
via: m.via,
|
|
422
|
-
// Brief 30: a validated component form, already whitelisted host-side.
|
|
423
|
-
// Passed through untouched — the renderer treats every string as text,
|
|
424
|
-
// never markup.
|
|
425
|
-
components: m.components
|
|
426
|
-
}));
|
|
427
|
-
const withDay = msgs.length ? [{ day: dkDayLabel(arr[0].ts) }].concat(msgs) : [];
|
|
428
|
-
setThreads((t) => Object.assign({}, t, { [peerId]: withDay }));
|
|
449
|
+
let c = cache.current[peerId];
|
|
450
|
+
if (!c)
|
|
451
|
+
c = cache.current[peerId] = { byId: /* @__PURE__ */ new Map(), more: arr.length >= DK_PAGE };
|
|
452
|
+
if (arr.length) {
|
|
453
|
+
const from = arr[0].ts;
|
|
454
|
+
for (const [k, m] of c.byId)
|
|
455
|
+
if (m.ts >= from)
|
|
456
|
+
c.byId.delete(k);
|
|
457
|
+
}
|
|
458
|
+
for (const m of arr)
|
|
459
|
+
c.byId.set(dkMsgKey(m), m);
|
|
460
|
+
publish(peerId);
|
|
429
461
|
} catch (e) {
|
|
430
462
|
} finally {
|
|
431
463
|
inFlight.current.delete(peerId);
|
|
432
464
|
}
|
|
433
|
-
}, []);
|
|
434
|
-
|
|
465
|
+
}, [publish]);
|
|
466
|
+
const loadEarlier = React.useCallback(async (peerId) => {
|
|
467
|
+
const c = cache.current[peerId];
|
|
468
|
+
if (!c || !c.more || c.loadingEarlier)
|
|
469
|
+
return;
|
|
470
|
+
let oldest = Infinity;
|
|
471
|
+
for (const m of c.byId.values())
|
|
472
|
+
if (m.ts < oldest)
|
|
473
|
+
oldest = m.ts;
|
|
474
|
+
if (!Number.isFinite(oldest))
|
|
475
|
+
return;
|
|
476
|
+
c.loadingEarlier = true;
|
|
477
|
+
try {
|
|
478
|
+
const d = await dkGet("/api/chat-history?peer=" + encodeURIComponent(peerId) + "&limit=" + DK_PAGE + "&before=" + oldest);
|
|
479
|
+
const arr = d.chats && d.chats[peerId] || [];
|
|
480
|
+
await prefetchThreadFiles(arr);
|
|
481
|
+
if (cache.current[peerId] !== c)
|
|
482
|
+
return;
|
|
483
|
+
for (const m of arr)
|
|
484
|
+
c.byId.set(dkMsgKey(m), m);
|
|
485
|
+
c.more = arr.length >= DK_PAGE;
|
|
486
|
+
publish(peerId);
|
|
487
|
+
} catch (e) {
|
|
488
|
+
} finally {
|
|
489
|
+
c.loadingEarlier = false;
|
|
490
|
+
}
|
|
491
|
+
}, [publish]);
|
|
492
|
+
return Object.assign({}, snap, { threads, earlier, refresh, loadThread, loadEarlier });
|
|
435
493
|
}
|
|
436
494
|
Object.assign(window, {
|
|
437
495
|
dkHash,
|
|
@@ -1368,6 +1426,8 @@ window.__DK_UI_VERSION="0.1.104";
|
|
|
1368
1426
|
{
|
|
1369
1427
|
src: dkFileUrl(m.file.name),
|
|
1370
1428
|
alt: m.file.name,
|
|
1429
|
+
loading: "lazy",
|
|
1430
|
+
decoding: "async",
|
|
1371
1431
|
onError: (e) => {
|
|
1372
1432
|
const w = e.currentTarget.closest("[data-media]");
|
|
1373
1433
|
if (w)
|
|
@@ -1616,8 +1676,10 @@ window.__DK_UI_VERSION="0.1.104";
|
|
|
1616
1676
|
) : mine && m.via === "offline" && m.status !== "queued" && m.status !== "sending" ? /* @__PURE__ */ React.createElement(Icon, { name: "check", size: 12, stroke: 2.2, color: "#f59e0b", title: T.viaOutOffline || "posted to the offline relay \u2014 they get it when they come online" }) : 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)" })))
|
|
1617
1677
|
);
|
|
1618
1678
|
}
|
|
1619
|
-
function Conversation({ T, peer, lang, peers, onOpenChat, thread: threadProp, onSend, onSendFile, onSendRtcFile, onAlias, onRemove, onOpenNet, onCall, onReloadThread, muted, onToggleMute, phone, onBack }) {
|
|
1679
|
+
function Conversation({ T, peer, lang, peers, onOpenChat, thread: threadProp, onSend, onSendFile, onSendRtcFile, onAlias, onRemove, onOpenNet, onCall, onReloadThread, hasEarlier, onLoadEarlier, muted, onToggleMute, phone, onBack }) {
|
|
1620
1680
|
const scrollRef = React.useRef(null);
|
|
1681
|
+
const prependRef = React.useRef(null);
|
|
1682
|
+
const [earlierBusy, setEarlierBusy] = React.useState(false);
|
|
1621
1683
|
const isGroup = React.useMemo(() => dkThreadIsGroup(threadProp), [threadProp]);
|
|
1622
1684
|
const followScrollRef = React.useRef(true);
|
|
1623
1685
|
const fileRef = React.useRef(null);
|
|
@@ -1695,9 +1757,30 @@ window.__DK_UI_VERSION="0.1.104";
|
|
|
1695
1757
|
followScrollRef.current = el.scrollHeight - el.scrollTop - el.clientHeight < 80;
|
|
1696
1758
|
};
|
|
1697
1759
|
React.useLayoutEffect(() => {
|
|
1760
|
+
const el = scrollRef.current;
|
|
1761
|
+
const pre = prependRef.current;
|
|
1762
|
+
if (pre && el && el.scrollHeight !== pre.h) {
|
|
1763
|
+
el.scrollTop = pre.top + (el.scrollHeight - pre.h);
|
|
1764
|
+
prependRef.current = null;
|
|
1765
|
+
return;
|
|
1766
|
+
}
|
|
1698
1767
|
if (followScrollRef.current)
|
|
1699
1768
|
scrollToBottom();
|
|
1700
1769
|
}, [peer.id, thread]);
|
|
1770
|
+
React.useEffect(() => {
|
|
1771
|
+
prependRef.current = null;
|
|
1772
|
+
setEarlierBusy(false);
|
|
1773
|
+
}, [peer.id]);
|
|
1774
|
+
const loadEarlier = () => {
|
|
1775
|
+
const el = scrollRef.current;
|
|
1776
|
+
if (!onLoadEarlier || earlierBusy)
|
|
1777
|
+
return;
|
|
1778
|
+
if (el)
|
|
1779
|
+
prependRef.current = { h: el.scrollHeight, top: el.scrollTop };
|
|
1780
|
+
followScrollRef.current = false;
|
|
1781
|
+
setEarlierBusy(true);
|
|
1782
|
+
Promise.resolve(onLoadEarlier()).finally(() => setEarlierBusy(false));
|
|
1783
|
+
};
|
|
1701
1784
|
const toggleSel = (id) => setSel((s) => {
|
|
1702
1785
|
const n = new Set(s);
|
|
1703
1786
|
n.has(id) ? n.delete(id) : n.add(id);
|
|
@@ -1957,7 +2040,7 @@ ${peer.address}`
|
|
|
1957
2040
|
fontSize: 12.5,
|
|
1958
2041
|
color: "var(--text)"
|
|
1959
2042
|
} }, /* @__PURE__ */ React.createElement(Icon, { name: "clock", size: 13, stroke: 2.2, color: "#d29922" }), /* @__PURE__ */ React.createElement("span", null, T.pendingFriend || "Waiting for them to accept your friend request \u2014 messages will queue and deliver once they do.")),
|
|
1960
|
-
/* @__PURE__ */ React.createElement("div", { ref: scrollRef, onScroll: updateFollowScroll, style: { flex: 1, overflow: "auto", padding: phone ? "12px 10px" : "18px 22px", WebkitOverflowScrolling: "touch" } }, /* @__PURE__ */ React.createElement("div", { style: { maxWidth: 1200, margin: "0 auto" } }, thread.filter((m) => m.day || !hidden.has(m.id)).map((m, i) => m.day ? /* @__PURE__ */ React.createElement("div", { key: i, style: { display: "flex", justifyContent: "center", margin: "14px 0" } }, /* @__PURE__ */ React.createElement("span", { style: { fontFamily: "var(--mono)", fontSize: 10.5, fontWeight: 600, color: "var(--faint)", background: "var(--chip)", padding: "3px 10px", borderRadius: 999 } }, m.day)) : /* @__PURE__ */ React.createElement(
|
|
2043
|
+
/* @__PURE__ */ React.createElement("div", { ref: scrollRef, onScroll: updateFollowScroll, style: { flex: 1, overflow: "auto", padding: phone ? "12px 10px" : "18px 22px", WebkitOverflowScrolling: "touch" } }, /* @__PURE__ */ React.createElement("div", { style: { maxWidth: 1200, margin: "0 auto" } }, hasEarlier && /* @__PURE__ */ React.createElement("div", { style: { display: "flex", justifyContent: "center", margin: "4px 0 10px" } }, /* @__PURE__ */ React.createElement(Btn, { size: "sm", onClick: loadEarlier, disabled: earlierBusy }, earlierBusy ? T.loadingEarlier || "Loading\u2026" : T.loadEarlier || "Load earlier messages")), thread.filter((m) => m.day || !hidden.has(m.id)).map((m, i) => m.day ? /* @__PURE__ */ React.createElement("div", { key: i, style: { display: "flex", justifyContent: "center", margin: "14px 0" } }, /* @__PURE__ */ React.createElement("span", { style: { fontFamily: "var(--mono)", fontSize: 10.5, fontWeight: 600, color: "var(--faint)", background: "var(--chip)", padding: "3px 10px", borderRadius: 999 } }, m.day)) : /* @__PURE__ */ React.createElement(
|
|
1961
2044
|
Msg,
|
|
1962
2045
|
{
|
|
1963
2046
|
key: m.id || i,
|
|
@@ -2117,12 +2200,12 @@ ${peer.address}`
|
|
|
2117
2200
|
function ChatEmpty({ T }) {
|
|
2118
2201
|
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));
|
|
2119
2202
|
}
|
|
2120
|
-
function ChatTab({ T, lang, peers, requests, activeId, thread, onSelect, onAct, onAdd, onSend, onSendFile, onSendRtcFile, onAlias, onRemove, onOpenNet, onCall, onReloadThread, prefillAddr, onPrefillConsumed, muted, onToggleMute, phone, onBack }) {
|
|
2203
|
+
function ChatTab({ T, lang, peers, requests, activeId, thread, onSelect, onAct, onAdd, onSend, onSendFile, onSendRtcFile, onAlias, onRemove, onOpenNet, onCall, onReloadThread, hasEarlier, onLoadEarlier, prefillAddr, onPrefillConsumed, muted, onToggleMute, phone, onBack }) {
|
|
2121
2204
|
const peer = peers.find((p) => p.id === activeId);
|
|
2122
2205
|
if (phone) {
|
|
2123
|
-
return 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, phone: true, onBack }) : /* @__PURE__ */ React.createElement(PeerSidebar, { T, peers, requests, activeId, onSelect, onAct, onAdd, prefillAddr, onPrefillConsumed, muted, wide: true });
|
|
2206
|
+
return peer ? /* @__PURE__ */ React.createElement(Conversation, { T, peer, lang, peers, onOpenChat: onSelect, thread, onSend, onSendFile, onSendRtcFile, onAlias, onRemove, onOpenNet, onCall, onReloadThread, hasEarlier, onLoadEarlier, muted: !!muted && muted.includes(peer.id), onToggleMute, phone: true, onBack }) : /* @__PURE__ */ React.createElement(PeerSidebar, { T, peers, requests, activeId, onSelect, onAct, onAdd, prefillAddr, onPrefillConsumed, muted, wide: true });
|
|
2124
2207
|
}
|
|
2125
|
-
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 }));
|
|
2208
|
+
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, hasEarlier, onLoadEarlier, muted: !!muted && muted.includes(peer.id), onToggleMute }) : /* @__PURE__ */ React.createElement(ChatEmpty, { T }));
|
|
2126
2209
|
}
|
|
2127
2210
|
Object.assign(window, { ChatTab });
|
|
2128
2211
|
function CopyBtn({ value, copiedText = "Copied", copyFailedText = "Copy failed", copyTitle = "Copy" }) {
|
|
@@ -4885,6 +4968,8 @@ ${peer.address}`
|
|
|
4885
4968
|
autoAcceptLabel: "Auto-accept friend requests",
|
|
4886
4969
|
autoAcceptSub: "Off: requests wait in the sidebar for your approval.",
|
|
4887
4970
|
groupSenderUnknown: "The group relays only this display name. Register Beagle as a group agent (/agent add <beagle address> in the group) to receive full member identities you can add as friends.",
|
|
4971
|
+
loadEarlier: "Load earlier messages",
|
|
4972
|
+
loadingEarlier: "Loading\u2026",
|
|
4888
4973
|
pendingFriend: "Waiting for them to accept your friend request \u2014 messages will queue and deliver once they do.",
|
|
4889
4974
|
cancelling: "Cancelling\u2026",
|
|
4890
4975
|
cancelled: "Transfer cancelled",
|
|
@@ -5077,6 +5162,8 @@ ${peer.address}`
|
|
|
5077
5162
|
autoAcceptLabel: "\u81EA\u52A8\u63A5\u53D7\u597D\u53CB\u8BF7\u6C42",
|
|
5078
5163
|
autoAcceptSub: "\u5173\u95ED\u540E\uFF0C\u597D\u53CB\u8BF7\u6C42\u4F1A\u7B49\u5F85\u4F60\u5728\u4FA7\u8FB9\u680F\u624B\u52A8\u786E\u8BA4\u3002",
|
|
5079
5164
|
groupSenderUnknown: "\u7FA4\u670D\u52A1\u53EA\u8F6C\u53D1\u4E86\u663E\u793A\u540D\uFF0C\u62FF\u4E0D\u5230\u8BE5\u6210\u5458\u7684\u5B8C\u6574\u8EAB\u4EFD\u3002\u5728\u7FA4\u91CC\u6267\u884C /agent add <beagle \u5730\u5740> \u628A Beagle \u6CE8\u518C\u4E3A\u7FA4 agent \u540E\uFF0C\u5373\u53EF\u6536\u5230\u5B8C\u6574\u8EAB\u4EFD\u5E76\u4E00\u952E\u52A0\u597D\u53CB\u3002",
|
|
5165
|
+
loadEarlier: "\u52A0\u8F7D\u66F4\u65E9\u7684\u6D88\u606F",
|
|
5166
|
+
loadingEarlier: "\u52A0\u8F7D\u4E2D\u2026",
|
|
5080
5167
|
pendingFriend: "\u7B49\u5F85\u5BF9\u65B9\u63A5\u53D7\u597D\u53CB\u8BF7\u6C42 \u2014 \u6D88\u606F\u4F1A\u5148\u6392\u961F\uFF0C\u5BF9\u65B9\u63A5\u53D7\u540E\u81EA\u52A8\u9001\u8FBE\u3002",
|
|
5081
5168
|
cancelling: "\u6B63\u5728\u53D6\u6D88\u2026",
|
|
5082
5169
|
cancelled: "\u5DF2\u53D6\u6D88\u4F20\u8F93",
|
|
@@ -5547,7 +5634,7 @@ ${peer.address}`
|
|
|
5547
5634
|
React.useEffect(() => {
|
|
5548
5635
|
if (!activeId)
|
|
5549
5636
|
return;
|
|
5550
|
-
data.loadThread(activeId);
|
|
5637
|
+
data.loadThread(activeId, { reset: true });
|
|
5551
5638
|
dkApi.markRead(activeId).then(data.refresh);
|
|
5552
5639
|
const iv = setInterval(() => {
|
|
5553
5640
|
data.loadThread(activeId);
|
|
@@ -5697,7 +5784,7 @@ ${peer.address}`
|
|
|
5697
5784
|
fontWeight: 600,
|
|
5698
5785
|
background: tab === n.id ? "var(--accent)" : "transparent",
|
|
5699
5786
|
color: tab === n.id ? "#fff" : "var(--dim)"
|
|
5700
|
-
} }, /* @__PURE__ */ React.createElement(Icon, { name: n.icon, size: 14, stroke: 2, color: tab === n.id ? "#fff" : "var(--dim)" }), n.label))), tab === "chat" && /* @__PURE__ */ React.createElement(ChatTab, { T, lang: t.lang, phone, onBack: closeConversation, 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, onSetAvatar: (p) => dkApi.setProfileFull(p).then((r) => {
|
|
5787
|
+
} }, /* @__PURE__ */ React.createElement(Icon, { name: n.icon, size: 14, stroke: 2, color: tab === n.id ? "#fff" : "var(--dim)" }), n.label))), tab === "chat" && /* @__PURE__ */ React.createElement(ChatTab, { T, lang: t.lang, phone, onBack: closeConversation, peers, requests, activeId, thread: data.threads[activeId], onSelect, onAct, onAdd, onSend, onSendFile, onSendRtcFile, onAlias, onRemove, onOpenNet, onCall, onReloadThread: () => activeId && data.loadThread(activeId), hasEarlier: !!(activeId && data.earlier[activeId]), onLoadEarlier: () => activeId && data.loadEarlier(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, onSetAvatar: (p) => dkApi.setProfileFull(p).then((r) => {
|
|
5701
5788
|
data.refresh();
|
|
5702
5789
|
return r;
|
|
5703
5790
|
}) })), phone && !inConversation && /* @__PURE__ */ React.createElement("div", { style: { flexShrink: 0, display: "flex", borderTop: "1px solid var(--line)", background: "var(--rail)", paddingBottom: "env(safe-area-inset-bottom, 0px)" } }, phoneNav.map((n) => /* @__PURE__ */ React.createElement(TabBarBtn, { key: n.id, icon: n.icon, label: n.label, active: n.active, badge: n.badge, onClick: n.go }))), data.locked && /* @__PURE__ */ React.createElement(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@decentnetwork/beagle",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.105",
|
|
4
4
|
"description": "Beagle — P2P chat, file transfer and calls for regular users, on the Decent Network. No admin privilege required.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"yargs": "^17.7.2"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
|
-
"@decentnetwork/beagle-ui": "^0.2.
|
|
38
|
+
"@decentnetwork/beagle-ui": "^0.2.20",
|
|
39
39
|
"@types/js-yaml": "^4.0.9",
|
|
40
40
|
"@types/node": "^20.11.0",
|
|
41
41
|
"@types/yargs": "^17.0.32",
|