@decentnetwork/beagle-ui 0.2.28 → 0.2.29
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 +193 -107
- 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.29";
|
|
2
2
|
// src/icons.jsx
|
|
3
3
|
var ICON_PATHS = {
|
|
4
4
|
// ---- tab bar (the four must feel like one set) ----
|
|
@@ -166,6 +166,142 @@ function DkBrowserNotice(props) {
|
|
|
166
166
|
return H.DkBrowserNotice ? /* @__PURE__ */ React.createElement(H.DkBrowserNotice, { ...props }) : null;
|
|
167
167
|
}
|
|
168
168
|
|
|
169
|
+
// src/host-messages.js
|
|
170
|
+
function protocolTest(rule) {
|
|
171
|
+
if (typeof rule !== "function")
|
|
172
|
+
return () => false;
|
|
173
|
+
return (msg) => {
|
|
174
|
+
if (!msg)
|
|
175
|
+
return false;
|
|
176
|
+
try {
|
|
177
|
+
const v = rule(msg);
|
|
178
|
+
return typeof v === "string" ? v || true : !!v;
|
|
179
|
+
} catch (e) {
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
function stripOwnPrefix(text) {
|
|
185
|
+
return String(text == null ? "" : text).replace(/^you:\s*/i, "");
|
|
186
|
+
}
|
|
187
|
+
function lastMessageOf(peer) {
|
|
188
|
+
const raw = String(peer && peer.lastMsg || "");
|
|
189
|
+
return {
|
|
190
|
+
text: stripOwnPrefix(raw),
|
|
191
|
+
dir: peer && peer.lastDir || (/^you:\s*/i.test(raw) ? "out" : "in"),
|
|
192
|
+
ts: peer && peer.lastTs || 0
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
function lastIsProtocol(peer, isProto) {
|
|
196
|
+
const last = lastMessageOf(peer);
|
|
197
|
+
if (!last.text)
|
|
198
|
+
return false;
|
|
199
|
+
return isProto(last);
|
|
200
|
+
}
|
|
201
|
+
function newestHumanMessage(msgs, isProto) {
|
|
202
|
+
const arr = msgs || [];
|
|
203
|
+
for (let i = arr.length - 1; i >= 0; i--) {
|
|
204
|
+
const m = arr[i];
|
|
205
|
+
if (!m)
|
|
206
|
+
continue;
|
|
207
|
+
if (m.file)
|
|
208
|
+
return m;
|
|
209
|
+
if (!m.text)
|
|
210
|
+
continue;
|
|
211
|
+
if (isProto({ text: m.text, dir: m.dir, ts: m.ts }))
|
|
212
|
+
continue;
|
|
213
|
+
return m;
|
|
214
|
+
}
|
|
215
|
+
return null;
|
|
216
|
+
}
|
|
217
|
+
function humanUnread(msgs, unread, isProto) {
|
|
218
|
+
const want = Number(unread) || 0;
|
|
219
|
+
if (want <= 0)
|
|
220
|
+
return { count: 0, exact: true };
|
|
221
|
+
const arr = msgs || [];
|
|
222
|
+
const window2 = arr.slice(Math.max(0, arr.length - want));
|
|
223
|
+
let n = 0;
|
|
224
|
+
for (const m of window2) {
|
|
225
|
+
if (!m || m.dir !== "in")
|
|
226
|
+
continue;
|
|
227
|
+
if (m.text && !m.file && isProto({ text: m.text, dir: m.dir, ts: m.ts }))
|
|
228
|
+
continue;
|
|
229
|
+
n++;
|
|
230
|
+
}
|
|
231
|
+
return { count: n, exact: window2.length >= want };
|
|
232
|
+
}
|
|
233
|
+
function rosterRow(peer, isProto, fix) {
|
|
234
|
+
const hidden = lastIsProtocol(peer, isProto);
|
|
235
|
+
if (!hidden) {
|
|
236
|
+
return {
|
|
237
|
+
preview: peer && peer.lastMsg || "",
|
|
238
|
+
lastTime: peer && peer.lastTime || "",
|
|
239
|
+
unread: Number(peer && peer.unread || 0),
|
|
240
|
+
activityTs: Number(peer && peer.lastTs || 0),
|
|
241
|
+
hidden: false
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
return {
|
|
245
|
+
preview: fix && fix.preview || "",
|
|
246
|
+
lastTime: fix && fix.lastTime || "",
|
|
247
|
+
unread: fix && fix.unreadExact ? fix.unread : 0,
|
|
248
|
+
activityTs: fix && fix.ts || 0,
|
|
249
|
+
hidden: true,
|
|
250
|
+
pending: !fix
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
function rosterUnreadTotal(peers, isProto, fixes) {
|
|
254
|
+
return (peers || []).reduce((n, p) => n + rosterRow(p, isProto, fixes && fixes[p.id]).unread, 0);
|
|
255
|
+
}
|
|
256
|
+
function collapseProtocol(thread, isProto, lang) {
|
|
257
|
+
const out = [];
|
|
258
|
+
let run = null;
|
|
259
|
+
const flush = () => {
|
|
260
|
+
if (!run)
|
|
261
|
+
return;
|
|
262
|
+
out.push({
|
|
263
|
+
protocol: true,
|
|
264
|
+
id: `proto-${run.first.id || run.startIndex}`,
|
|
265
|
+
count: run.items.length,
|
|
266
|
+
label: run.label,
|
|
267
|
+
dir: run.first.from === "me" ? "out" : "in",
|
|
268
|
+
text: run.items.map((m) => m.text).join("\n"),
|
|
269
|
+
line: protocolLine(run, lang)
|
|
270
|
+
});
|
|
271
|
+
run = null;
|
|
272
|
+
};
|
|
273
|
+
(thread || []).forEach((m, i) => {
|
|
274
|
+
const hit = m && !m.day ? isProto({ text: m.text, dir: m && m.from === "me" ? "out" : "in", ts: m && m.ts }) : false;
|
|
275
|
+
if (!hit || m && m.file) {
|
|
276
|
+
flush();
|
|
277
|
+
out.push(m);
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
if (!run)
|
|
281
|
+
run = { first: m, startIndex: i, items: [], label: typeof hit === "string" ? hit : "" };
|
|
282
|
+
if (!run.label && typeof hit === "string")
|
|
283
|
+
run.label = hit;
|
|
284
|
+
run.items.push(m);
|
|
285
|
+
});
|
|
286
|
+
flush();
|
|
287
|
+
return out;
|
|
288
|
+
}
|
|
289
|
+
function protocolLine(run, lang) {
|
|
290
|
+
const arrow = run.first.from === "me" ? "\u2192" : "\u2190";
|
|
291
|
+
const n = run.items.length;
|
|
292
|
+
if (run.label) {
|
|
293
|
+
return `\u2699 ${arrow} ${run.label}${n > 1 ? ` \xB7 ${n}` : ""}`;
|
|
294
|
+
}
|
|
295
|
+
if (n > 1) {
|
|
296
|
+
return lang === "zh" ? `\u2699 ${arrow} ${n} \u6761\u534F\u8BAE\u6D88\u606F` : `\u2699 ${arrow} ${n} protocol messages`;
|
|
297
|
+
}
|
|
298
|
+
return `\u2699 ${arrow} ${protocolSummary(run.first.text)}`;
|
|
299
|
+
}
|
|
300
|
+
function protocolSummary(text, max = 72) {
|
|
301
|
+
const s = String(text == null ? "" : text).replace(/\s+/g, " ").trim();
|
|
302
|
+
return s.length > max ? s.slice(0, max - 1) + "\u2026" : s;
|
|
303
|
+
}
|
|
304
|
+
|
|
169
305
|
// src/data-ipc.jsx
|
|
170
306
|
function dkHash(s) {
|
|
171
307
|
let h = 2166136261;
|
|
@@ -398,6 +534,48 @@ function dkThreadMsg(m) {
|
|
|
398
534
|
components: m.components
|
|
399
535
|
};
|
|
400
536
|
}
|
|
537
|
+
var DK_TAIL_MIN = 30;
|
|
538
|
+
var DK_TAIL_MAX = 200;
|
|
539
|
+
function useProtocolTails(peers, isProtocol, enabled) {
|
|
540
|
+
const [fixes, setFixes] = React.useState({});
|
|
541
|
+
const cache = React.useRef(/* @__PURE__ */ new Map());
|
|
542
|
+
const inFlight = React.useRef(/* @__PURE__ */ new Set());
|
|
543
|
+
React.useEffect(() => {
|
|
544
|
+
if (!enabled)
|
|
545
|
+
return;
|
|
546
|
+
for (const p of peers || []) {
|
|
547
|
+
if (!p || !lastIsProtocol(p, isProtocol))
|
|
548
|
+
continue;
|
|
549
|
+
const unread = Number(p.unread) || 0;
|
|
550
|
+
const key = `${p.lastTs || 0}:${unread}`;
|
|
551
|
+
const had = cache.current.get(p.id);
|
|
552
|
+
if (had && had.key === key)
|
|
553
|
+
continue;
|
|
554
|
+
if (inFlight.current.has(p.id))
|
|
555
|
+
continue;
|
|
556
|
+
const limit = Math.min(DK_TAIL_MAX, Math.max(DK_TAIL_MIN, unread + 5));
|
|
557
|
+
inFlight.current.add(p.id);
|
|
558
|
+
dkGet("/api/chat-history?peer=" + encodeURIComponent(p.id) + "&limit=" + limit).then((d) => {
|
|
559
|
+
const msgs = d && d.chats && d.chats[p.id] || [];
|
|
560
|
+
const human = newestHumanMessage(msgs, isProtocol);
|
|
561
|
+
const count = humanUnread(msgs, unread, isProtocol);
|
|
562
|
+
const fix = {
|
|
563
|
+
preview: human ? (human.dir === "out" ? "you: " : "") + (human.file ? human.file.name : human.text || "") : "",
|
|
564
|
+
lastTime: human ? dkClock(human.ts) : "",
|
|
565
|
+
ts: human ? human.ts : 0,
|
|
566
|
+
unread: count.count,
|
|
567
|
+
unreadExact: count.exact
|
|
568
|
+
};
|
|
569
|
+
cache.current.set(p.id, { key, fix });
|
|
570
|
+
setFixes((f) => Object.assign({}, f, { [p.id]: fix }));
|
|
571
|
+
}).catch(() => {
|
|
572
|
+
}).finally(() => {
|
|
573
|
+
inFlight.current.delete(p.id);
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
}, [peers, isProtocol, enabled]);
|
|
577
|
+
return fixes;
|
|
578
|
+
}
|
|
401
579
|
function useDaemonData() {
|
|
402
580
|
const [snap, setSnap] = React.useState({
|
|
403
581
|
me: DK_ME_FALLBACK,
|
|
@@ -1506,100 +1684,6 @@ ${lines}`, { assistant: { kind: "adopt", rows: fresh } }));
|
|
|
1506
1684
|
return { thread, handle, removeFriends, adoptServicePeers };
|
|
1507
1685
|
}
|
|
1508
1686
|
|
|
1509
|
-
// src/host-messages.js
|
|
1510
|
-
function protocolTest(rule) {
|
|
1511
|
-
if (typeof rule !== "function")
|
|
1512
|
-
return () => false;
|
|
1513
|
-
return (msg) => {
|
|
1514
|
-
if (!msg)
|
|
1515
|
-
return false;
|
|
1516
|
-
try {
|
|
1517
|
-
const v = rule(msg);
|
|
1518
|
-
return typeof v === "string" ? v || true : !!v;
|
|
1519
|
-
} catch (e) {
|
|
1520
|
-
return false;
|
|
1521
|
-
}
|
|
1522
|
-
};
|
|
1523
|
-
}
|
|
1524
|
-
function stripOwnPrefix(text) {
|
|
1525
|
-
return String(text == null ? "" : text).replace(/^you:\s*/i, "");
|
|
1526
|
-
}
|
|
1527
|
-
function lastMessageOf(peer) {
|
|
1528
|
-
const raw = String(peer && peer.lastMsg || "");
|
|
1529
|
-
return {
|
|
1530
|
-
text: stripOwnPrefix(raw),
|
|
1531
|
-
dir: peer && peer.lastDir || (/^you:\s*/i.test(raw) ? "out" : "in"),
|
|
1532
|
-
ts: peer && peer.lastTs || 0
|
|
1533
|
-
};
|
|
1534
|
-
}
|
|
1535
|
-
function lastIsProtocol(peer, isProto) {
|
|
1536
|
-
const last = lastMessageOf(peer);
|
|
1537
|
-
if (!last.text)
|
|
1538
|
-
return false;
|
|
1539
|
-
return isProto(last);
|
|
1540
|
-
}
|
|
1541
|
-
function rosterRow(peer, isProto) {
|
|
1542
|
-
const hidden = lastIsProtocol(peer, isProto);
|
|
1543
|
-
return {
|
|
1544
|
-
preview: hidden ? "" : peer && peer.lastMsg || "",
|
|
1545
|
-
lastTime: hidden ? "" : peer && peer.lastTime || "",
|
|
1546
|
-
unread: hidden ? 0 : Number(peer && peer.unread || 0),
|
|
1547
|
-
activityTs: hidden ? 0 : Number(peer && peer.lastTs || 0),
|
|
1548
|
-
hidden
|
|
1549
|
-
};
|
|
1550
|
-
}
|
|
1551
|
-
function rosterUnreadTotal(peers, isProto) {
|
|
1552
|
-
return (peers || []).reduce((n, p) => n + rosterRow(p, isProto).unread, 0);
|
|
1553
|
-
}
|
|
1554
|
-
function collapseProtocol(thread, isProto, lang) {
|
|
1555
|
-
const out = [];
|
|
1556
|
-
let run = null;
|
|
1557
|
-
const flush = () => {
|
|
1558
|
-
if (!run)
|
|
1559
|
-
return;
|
|
1560
|
-
out.push({
|
|
1561
|
-
protocol: true,
|
|
1562
|
-
id: `proto-${run.first.id || run.startIndex}`,
|
|
1563
|
-
count: run.items.length,
|
|
1564
|
-
label: run.label,
|
|
1565
|
-
dir: run.first.from === "me" ? "out" : "in",
|
|
1566
|
-
text: run.items.map((m) => m.text).join("\n"),
|
|
1567
|
-
line: protocolLine(run, lang)
|
|
1568
|
-
});
|
|
1569
|
-
run = null;
|
|
1570
|
-
};
|
|
1571
|
-
(thread || []).forEach((m, i) => {
|
|
1572
|
-
const hit = m && !m.day ? isProto({ text: m.text, dir: m && m.from === "me" ? "out" : "in", ts: m && m.ts }) : false;
|
|
1573
|
-
if (!hit || m && m.file) {
|
|
1574
|
-
flush();
|
|
1575
|
-
out.push(m);
|
|
1576
|
-
return;
|
|
1577
|
-
}
|
|
1578
|
-
if (!run)
|
|
1579
|
-
run = { first: m, startIndex: i, items: [], label: typeof hit === "string" ? hit : "" };
|
|
1580
|
-
if (!run.label && typeof hit === "string")
|
|
1581
|
-
run.label = hit;
|
|
1582
|
-
run.items.push(m);
|
|
1583
|
-
});
|
|
1584
|
-
flush();
|
|
1585
|
-
return out;
|
|
1586
|
-
}
|
|
1587
|
-
function protocolLine(run, lang) {
|
|
1588
|
-
const arrow = run.first.from === "me" ? "\u2192" : "\u2190";
|
|
1589
|
-
const n = run.items.length;
|
|
1590
|
-
if (run.label) {
|
|
1591
|
-
return `\u2699 ${arrow} ${run.label}${n > 1 ? ` \xB7 ${n}` : ""}`;
|
|
1592
|
-
}
|
|
1593
|
-
if (n > 1) {
|
|
1594
|
-
return lang === "zh" ? `\u2699 ${arrow} ${n} \u6761\u534F\u8BAE\u6D88\u606F` : `\u2699 ${arrow} ${n} protocol messages`;
|
|
1595
|
-
}
|
|
1596
|
-
return `\u2699 ${arrow} ${protocolSummary(run.first.text)}`;
|
|
1597
|
-
}
|
|
1598
|
-
function protocolSummary(text, max = 72) {
|
|
1599
|
-
const s = String(text == null ? "" : text).replace(/\s+/g, " ").trim();
|
|
1600
|
-
return s.length > max ? s.slice(0, max - 1) + "\u2026" : s;
|
|
1601
|
-
}
|
|
1602
|
-
|
|
1603
1687
|
// src/chat.jsx
|
|
1604
1688
|
var DK_CMD_HIST_KEY = "beagle.assistant.history";
|
|
1605
1689
|
var DK_CMD_HIST_MAX = 50;
|
|
@@ -1661,9 +1745,9 @@ function RequestsBlock({ T, requests, onAct }) {
|
|
|
1661
1745
|
paddingLeft: 8
|
|
1662
1746
|
} }, 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))))));
|
|
1663
1747
|
}
|
|
1664
|
-
function PeerRow({ peer, T, active, onClick, muted, isProtocol }) {
|
|
1748
|
+
function PeerRow({ peer, T, active, onClick, muted, isProtocol, fix }) {
|
|
1665
1749
|
const name = peer.alias || peer.userId;
|
|
1666
|
-
const row = rosterRow(peer, isProtocol || (() => false));
|
|
1750
|
+
const row = rosterRow(peer, isProtocol || (() => false), fix);
|
|
1667
1751
|
return /* @__PURE__ */ React.createElement("button", { onClick, style: {
|
|
1668
1752
|
display: "flex",
|
|
1669
1753
|
alignItems: "center",
|
|
@@ -1694,11 +1778,11 @@ function PeerRow({ peer, T, active, onClick, muted, isProtocol }) {
|
|
|
1694
1778
|
minWidth: 0
|
|
1695
1779
|
} }, dkRowPreview(row.preview)))), /* @__PURE__ */ React.createElement("div", { style: { display: "flex", flexDirection: "column", alignItems: "flex-end", gap: 4, flexShrink: 0 } }, /* @__PURE__ */ React.createElement("span", { style: { fontFamily: "var(--mono)", fontSize: 10.5, color: "var(--faint)" } }, row.lastTime), row.unread ? /* @__PURE__ */ React.createElement(Unread, { n: row.unread }) : peer.pending ? /* @__PURE__ */ React.createElement(Icon, { name: "clock", size: 11, stroke: 2.2, color: "var(--warn, #d29922)", title: "friend request pending" }) : /* @__PURE__ */ React.createElement(StatusDot, { online: peer.online })));
|
|
1696
1780
|
}
|
|
1697
|
-
function dkActivityTs(p, isProtocol) {
|
|
1698
|
-
const row = rosterRow(p, isProtocol || (() => false));
|
|
1781
|
+
function dkActivityTs(p, isProtocol, fix) {
|
|
1782
|
+
const row = rosterRow(p, isProtocol || (() => false), fix);
|
|
1699
1783
|
return Math.max(row.activityTs, p.acceptedAt || 0, p.requestedAt || 0);
|
|
1700
1784
|
}
|
|
1701
|
-
function PeerSidebar({ T, peers, requests, activeId, onSelect, onAct, onAdd, prefillAddr, onPrefillConsumed, muted, wide, isProtocol }) {
|
|
1785
|
+
function PeerSidebar({ T, peers, requests, activeId, onSelect, onAct, onAdd, prefillAddr, onPrefillConsumed, muted, wide, isProtocol, protocolFix }) {
|
|
1702
1786
|
const [q, setQ] = React.useState("");
|
|
1703
1787
|
const [addr, setAddr] = React.useState("");
|
|
1704
1788
|
const [addState, setAddState] = React.useState(null);
|
|
@@ -1743,7 +1827,8 @@ function PeerSidebar({ T, peers, requests, activeId, onSelect, onAct, onAdd, pre
|
|
|
1743
1827
|
}).slice().sort((a, b) => {
|
|
1744
1828
|
if (!!a.pinned !== !!b.pinned)
|
|
1745
1829
|
return a.pinned ? -1 : 1;
|
|
1746
|
-
const ta = dkActivityTs(a, isProtocol
|
|
1830
|
+
const ta = dkActivityTs(a, isProtocol, protocolFix && protocolFix[a.id]);
|
|
1831
|
+
const tb = dkActivityTs(b, isProtocol, protocolFix && protocolFix[b.id]);
|
|
1747
1832
|
if (ta !== tb)
|
|
1748
1833
|
return tb - ta;
|
|
1749
1834
|
return String(a.alias || a.userId || "").localeCompare(String(b.alias || b.userId || ""));
|
|
@@ -1782,7 +1867,7 @@ function PeerSidebar({ T, peers, requests, activeId, onSelect, onAct, onAdd, pre
|
|
|
1782
1867
|
fontSize: 11.5,
|
|
1783
1868
|
lineHeight: 1.35,
|
|
1784
1869
|
color: addState.kind === "err" ? "var(--bad, #e5484d)" : addState.kind === "ok" ? "var(--good, #46a758)" : "var(--faint)"
|
|
1785
|
-
} }, 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), isProtocol })), !filtered.length && /* @__PURE__ */ React.createElement("div", { style: { padding: 16, textAlign: "center", fontFamily: "var(--mono)", fontSize: 12, color: "var(--faint)" } }, "no matches"))));
|
|
1870
|
+
} }, 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), isProtocol, fix: protocolFix && protocolFix[p.id] })), !filtered.length && /* @__PURE__ */ React.createElement("div", { style: { padding: 16, textAlign: "center", fontFamily: "var(--mono)", fontSize: 12, color: "var(--faint)" } }, "no matches"))));
|
|
1786
1871
|
}
|
|
1787
1872
|
var inputStyle = {
|
|
1788
1873
|
flex: 1,
|
|
@@ -3383,12 +3468,12 @@ function MenuItem({ icon, label, onClick, danger }) {
|
|
|
3383
3468
|
function ChatEmpty({ T }) {
|
|
3384
3469
|
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));
|
|
3385
3470
|
}
|
|
3386
|
-
function ChatTab({ T, lang, peers, requests, activeId, thread, isProtocol, onSelect, onAct, onAdd, onSend, onSendFile, onSendRtcFile, onAlias, onRemove, onOpenNet, onCall, onReloadThread, hasEarlier, onLoadEarlier, onAssistantRemove, onAssistantAdopt, prefillAddr, onPrefillConsumed, muted, onToggleMute, phone, onBack }) {
|
|
3471
|
+
function ChatTab({ T, lang, peers, requests, activeId, thread, isProtocol, protocolFix, onSelect, onAct, onAdd, onSend, onSendFile, onSendRtcFile, onAlias, onRemove, onOpenNet, onCall, onReloadThread, hasEarlier, onLoadEarlier, onAssistantRemove, onAssistantAdopt, prefillAddr, onPrefillConsumed, muted, onToggleMute, phone, onBack }) {
|
|
3387
3472
|
const peer = peers.find((p) => p.id === activeId);
|
|
3388
3473
|
if (phone) {
|
|
3389
|
-
return peer ? /* @__PURE__ */ React.createElement(Conversation, { T, peer, lang, peers, onOpenChat: onSelect, thread, isProtocol, onSend, onSendFile, onSendRtcFile, onAlias, onRemove, onOpenNet, onCall, onReloadThread, hasEarlier, onLoadEarlier, onAssistantRemove, onAssistantAdopt, muted: !!muted && muted.includes(peer.id), onToggleMute, phone: true, onBack }) : /* @__PURE__ */ React.createElement(PeerSidebar, { T, peers, requests, activeId, onSelect, onAct, onAdd, prefillAddr, onPrefillConsumed, muted, isProtocol, wide: true });
|
|
3474
|
+
return peer ? /* @__PURE__ */ React.createElement(Conversation, { T, peer, lang, peers, onOpenChat: onSelect, thread, isProtocol, onSend, onSendFile, onSendRtcFile, onAlias, onRemove, onOpenNet, onCall, onReloadThread, hasEarlier, onLoadEarlier, onAssistantRemove, onAssistantAdopt, muted: !!muted && muted.includes(peer.id), onToggleMute, phone: true, onBack }) : /* @__PURE__ */ React.createElement(PeerSidebar, { T, peers, requests, activeId, onSelect, onAct, onAdd, prefillAddr, onPrefillConsumed, muted, isProtocol, protocolFix, wide: true });
|
|
3390
3475
|
}
|
|
3391
|
-
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, isProtocol }), peer ? /* @__PURE__ */ React.createElement(Conversation, { T, peer, lang, peers, onOpenChat: onSelect, thread, isProtocol, onSend, onSendFile, onSendRtcFile, onAlias, onRemove, onOpenNet, onCall, onReloadThread, hasEarlier, onLoadEarlier, onAssistantRemove, onAssistantAdopt, muted: !!muted && muted.includes(peer.id), onToggleMute }) : /* @__PURE__ */ React.createElement(ChatEmpty, { T }));
|
|
3476
|
+
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, isProtocol, protocolFix }), peer ? /* @__PURE__ */ React.createElement(Conversation, { T, peer, lang, peers, onOpenChat: onSelect, thread, isProtocol, onSend, onSendFile, onSendRtcFile, onAlias, onRemove, onOpenNet, onCall, onReloadThread, hasEarlier, onLoadEarlier, onAssistantRemove, onAssistantAdopt, muted: !!muted && muted.includes(peer.id), onToggleMute }) : /* @__PURE__ */ React.createElement(ChatEmpty, { T }));
|
|
3392
3477
|
}
|
|
3393
3478
|
Object.assign(window, { ChatTab });
|
|
3394
3479
|
|
|
@@ -6924,6 +7009,7 @@ function DkApp() {
|
|
|
6924
7009
|
const mutedIds = Array.isArray(t.alertMuted) ? t.alertMuted : [];
|
|
6925
7010
|
const onToggleMute = (id) => setTweak("alertMuted", mutedIds.includes(id) ? mutedIds.filter((x) => x !== id) : mutedIds.concat(id));
|
|
6926
7011
|
const isProtocol = React.useMemo(() => protocolTest(hostIsProtocolMessage), []);
|
|
7012
|
+
const protocolFix = useProtocolTails(peers, isProtocol, !!hostIsProtocolMessage);
|
|
6927
7013
|
useIncomingAlerts({
|
|
6928
7014
|
T,
|
|
6929
7015
|
peers,
|
|
@@ -7185,7 +7271,7 @@ function DkApp() {
|
|
|
7185
7271
|
const lastPeople = React.useRef("here");
|
|
7186
7272
|
if (peopleTab)
|
|
7187
7273
|
lastPeople.current = tab;
|
|
7188
|
-
const unreadTotal = rosterUnreadTotal(peers, isProtocol) + (requests || []).length;
|
|
7274
|
+
const unreadTotal = rosterUnreadTotal(peers, isProtocol, protocolFix) + (requests || []).length;
|
|
7189
7275
|
const NAV_FOR = {
|
|
7190
7276
|
chat: { icon: "message", label: T.chat, active: tab === "chat", badge: unreadTotal, go: () => setTab("chat") },
|
|
7191
7277
|
people: { icon: "users", label: T.people, active: peopleTab, go: () => setTab(lastPeople.current) },
|
|
@@ -7243,7 +7329,7 @@ function DkApp() {
|
|
|
7243
7329
|
fontWeight: 600,
|
|
7244
7330
|
background: tab === n.id ? "var(--accent)" : "transparent",
|
|
7245
7331
|
color: tab === n.id ? "#fff" : "var(--dim)"
|
|
7246
|
-
} }, /* @__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, isProtocol, onBack: closeConversation, peers, requests, activeId, thread: activeId === ASSISTANT_ID ? assistant.thread : data.threads[activeId], onSelect, onAct, onAdd, onSend, onSendFile, onSendRtcFile, onAlias, onRemove, onOpenNet, onCall, onReloadThread: () => activeId && data.loadThread(activeId), hasEarlier: !!(activeId && activeId !== ASSISTANT_ID && data.earlier[activeId]), onAssistantRemove: activeId === ASSISTANT_ID ? assistant.removeFriends : null, onAssistantAdopt: activeId === ASSISTANT_ID ? assistant.adoptServicePeers : null, 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, me, peers, phone, setTab }), tabs.map((x) => x.kind === "host" && tab === x.id ? /* @__PURE__ */ React.createElement(HostTabPane, { key: x.id, tab: x, props: { T, t, me, peers, phone, setTab }, lang: t.lang }) : null), tab === "profile" && /* @__PURE__ */ React.createElement(
|
|
7332
|
+
} }, /* @__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, isProtocol, protocolFix, onBack: closeConversation, peers, requests, activeId, thread: activeId === ASSISTANT_ID ? assistant.thread : data.threads[activeId], onSelect, onAct, onAdd, onSend, onSendFile, onSendRtcFile, onAlias, onRemove, onOpenNet, onCall, onReloadThread: () => activeId && data.loadThread(activeId), hasEarlier: !!(activeId && activeId !== ASSISTANT_ID && data.earlier[activeId]), onAssistantRemove: activeId === ASSISTANT_ID ? assistant.removeFriends : null, onAssistantAdopt: activeId === ASSISTANT_ID ? assistant.adoptServicePeers : null, 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, me, peers, phone, setTab }), tabs.map((x) => x.kind === "host" && tab === x.id ? /* @__PURE__ */ React.createElement(HostTabPane, { key: x.id, tab: x, props: { T, t, me, peers, phone, setTab }, lang: t.lang }) : null), tab === "profile" && /* @__PURE__ */ React.createElement(
|
|
7247
7333
|
ProfileTab,
|
|
7248
7334
|
{
|
|
7249
7335
|
T,
|
package/package.json
CHANGED