@decentnetwork/beagle 0.1.114 → 0.1.116
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 +222 -109
- 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.116";
|
|
2
2
|
"use strict";
|
|
3
3
|
(() => {
|
|
4
4
|
// packages/beagle-ui/dist/beagle-ui.js
|
|
@@ -163,6 +163,140 @@ window.__DK_UI_VERSION="0.1.114";
|
|
|
163
163
|
function DkBrowserNotice(props) {
|
|
164
164
|
return H.DkBrowserNotice ? /* @__PURE__ */ React.createElement(H.DkBrowserNotice, { ...props }) : null;
|
|
165
165
|
}
|
|
166
|
+
function protocolTest(rule) {
|
|
167
|
+
if (typeof rule !== "function")
|
|
168
|
+
return () => false;
|
|
169
|
+
return (msg) => {
|
|
170
|
+
if (!msg)
|
|
171
|
+
return false;
|
|
172
|
+
try {
|
|
173
|
+
const v = rule(msg);
|
|
174
|
+
return typeof v === "string" ? v || true : !!v;
|
|
175
|
+
} catch (e) {
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
function stripOwnPrefix(text) {
|
|
181
|
+
return String(text == null ? "" : text).replace(/^you:\s*/i, "");
|
|
182
|
+
}
|
|
183
|
+
function lastMessageOf(peer) {
|
|
184
|
+
const raw = String(peer && peer.lastMsg || "");
|
|
185
|
+
return {
|
|
186
|
+
text: stripOwnPrefix(raw),
|
|
187
|
+
dir: peer && peer.lastDir || (/^you:\s*/i.test(raw) ? "out" : "in"),
|
|
188
|
+
ts: peer && peer.lastTs || 0
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
function lastIsProtocol(peer, isProto) {
|
|
192
|
+
const last = lastMessageOf(peer);
|
|
193
|
+
if (!last.text)
|
|
194
|
+
return false;
|
|
195
|
+
return isProto(last);
|
|
196
|
+
}
|
|
197
|
+
function newestHumanMessage(msgs, isProto) {
|
|
198
|
+
const arr = msgs || [];
|
|
199
|
+
for (let i = arr.length - 1; i >= 0; i--) {
|
|
200
|
+
const m = arr[i];
|
|
201
|
+
if (!m)
|
|
202
|
+
continue;
|
|
203
|
+
if (m.file)
|
|
204
|
+
return m;
|
|
205
|
+
if (!m.text)
|
|
206
|
+
continue;
|
|
207
|
+
if (isProto({ text: m.text, dir: m.dir, ts: m.ts }))
|
|
208
|
+
continue;
|
|
209
|
+
return m;
|
|
210
|
+
}
|
|
211
|
+
return null;
|
|
212
|
+
}
|
|
213
|
+
function humanUnread(msgs, unread, isProto) {
|
|
214
|
+
const want = Number(unread) || 0;
|
|
215
|
+
if (want <= 0)
|
|
216
|
+
return { count: 0, exact: true };
|
|
217
|
+
const arr = msgs || [];
|
|
218
|
+
const window2 = arr.slice(Math.max(0, arr.length - want));
|
|
219
|
+
let n = 0;
|
|
220
|
+
for (const m of window2) {
|
|
221
|
+
if (!m || m.dir !== "in")
|
|
222
|
+
continue;
|
|
223
|
+
if (m.text && !m.file && isProto({ text: m.text, dir: m.dir, ts: m.ts }))
|
|
224
|
+
continue;
|
|
225
|
+
n++;
|
|
226
|
+
}
|
|
227
|
+
return { count: n, exact: window2.length >= want };
|
|
228
|
+
}
|
|
229
|
+
function rosterRow(peer, isProto, fix) {
|
|
230
|
+
const hidden = lastIsProtocol(peer, isProto);
|
|
231
|
+
if (!hidden) {
|
|
232
|
+
return {
|
|
233
|
+
preview: peer && peer.lastMsg || "",
|
|
234
|
+
lastTime: peer && peer.lastTime || "",
|
|
235
|
+
unread: Number(peer && peer.unread || 0),
|
|
236
|
+
activityTs: Number(peer && peer.lastTs || 0),
|
|
237
|
+
hidden: false
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
return {
|
|
241
|
+
preview: fix && fix.preview || "",
|
|
242
|
+
lastTime: fix && fix.lastTime || "",
|
|
243
|
+
unread: fix && fix.unreadExact ? fix.unread : 0,
|
|
244
|
+
activityTs: fix && fix.ts || 0,
|
|
245
|
+
hidden: true,
|
|
246
|
+
pending: !fix
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
function rosterUnreadTotal(peers, isProto, fixes) {
|
|
250
|
+
return (peers || []).reduce((n, p) => n + rosterRow(p, isProto, fixes && fixes[p.id]).unread, 0);
|
|
251
|
+
}
|
|
252
|
+
function collapseProtocol(thread, isProto, lang) {
|
|
253
|
+
const out = [];
|
|
254
|
+
let run = null;
|
|
255
|
+
const flush = () => {
|
|
256
|
+
if (!run)
|
|
257
|
+
return;
|
|
258
|
+
out.push({
|
|
259
|
+
protocol: true,
|
|
260
|
+
id: `proto-${run.first.id || run.startIndex}`,
|
|
261
|
+
count: run.items.length,
|
|
262
|
+
label: run.label,
|
|
263
|
+
dir: run.first.from === "me" ? "out" : "in",
|
|
264
|
+
text: run.items.map((m) => m.text).join("\n"),
|
|
265
|
+
line: protocolLine(run, lang)
|
|
266
|
+
});
|
|
267
|
+
run = null;
|
|
268
|
+
};
|
|
269
|
+
(thread || []).forEach((m, i) => {
|
|
270
|
+
const hit = m && !m.day ? isProto({ text: m.text, dir: m && m.from === "me" ? "out" : "in", ts: m && m.ts }) : false;
|
|
271
|
+
if (!hit || m && m.file) {
|
|
272
|
+
flush();
|
|
273
|
+
out.push(m);
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
if (!run)
|
|
277
|
+
run = { first: m, startIndex: i, items: [], label: typeof hit === "string" ? hit : "" };
|
|
278
|
+
if (!run.label && typeof hit === "string")
|
|
279
|
+
run.label = hit;
|
|
280
|
+
run.items.push(m);
|
|
281
|
+
});
|
|
282
|
+
flush();
|
|
283
|
+
return out;
|
|
284
|
+
}
|
|
285
|
+
function protocolLine(run, lang) {
|
|
286
|
+
const arrow = run.first.from === "me" ? "\u2192" : "\u2190";
|
|
287
|
+
const n = run.items.length;
|
|
288
|
+
if (run.label) {
|
|
289
|
+
return `\u2699 ${arrow} ${run.label}${n > 1 ? ` \xB7 ${n}` : ""}`;
|
|
290
|
+
}
|
|
291
|
+
if (n > 1) {
|
|
292
|
+
return lang === "zh" ? `\u2699 ${arrow} ${n} \u6761\u534F\u8BAE\u6D88\u606F` : `\u2699 ${arrow} ${n} protocol messages`;
|
|
293
|
+
}
|
|
294
|
+
return `\u2699 ${arrow} ${protocolSummary(run.first.text)}`;
|
|
295
|
+
}
|
|
296
|
+
function protocolSummary(text, max = 72) {
|
|
297
|
+
const s = String(text == null ? "" : text).replace(/\s+/g, " ").trim();
|
|
298
|
+
return s.length > max ? s.slice(0, max - 1) + "\u2026" : s;
|
|
299
|
+
}
|
|
166
300
|
function dkHash(s) {
|
|
167
301
|
let h = 2166136261;
|
|
168
302
|
for (let i = 0; i < s.length; i++) {
|
|
@@ -394,6 +528,48 @@ window.__DK_UI_VERSION="0.1.114";
|
|
|
394
528
|
components: m.components
|
|
395
529
|
};
|
|
396
530
|
}
|
|
531
|
+
var DK_TAIL_MIN = 30;
|
|
532
|
+
var DK_TAIL_MAX = 200;
|
|
533
|
+
function useProtocolTails(peers, isProtocol, enabled) {
|
|
534
|
+
const [fixes, setFixes] = React.useState({});
|
|
535
|
+
const cache = React.useRef(/* @__PURE__ */ new Map());
|
|
536
|
+
const inFlight = React.useRef(/* @__PURE__ */ new Set());
|
|
537
|
+
React.useEffect(() => {
|
|
538
|
+
if (!enabled)
|
|
539
|
+
return;
|
|
540
|
+
for (const p of peers || []) {
|
|
541
|
+
if (!p || !lastIsProtocol(p, isProtocol))
|
|
542
|
+
continue;
|
|
543
|
+
const unread = Number(p.unread) || 0;
|
|
544
|
+
const key = `${p.lastTs || 0}:${unread}`;
|
|
545
|
+
const had = cache.current.get(p.id);
|
|
546
|
+
if (had && had.key === key)
|
|
547
|
+
continue;
|
|
548
|
+
if (inFlight.current.has(p.id))
|
|
549
|
+
continue;
|
|
550
|
+
const limit = Math.min(DK_TAIL_MAX, Math.max(DK_TAIL_MIN, unread + 5));
|
|
551
|
+
inFlight.current.add(p.id);
|
|
552
|
+
dkGet("/api/chat-history?peer=" + encodeURIComponent(p.id) + "&limit=" + limit).then((d) => {
|
|
553
|
+
const msgs = d && d.chats && d.chats[p.id] || [];
|
|
554
|
+
const human = newestHumanMessage(msgs, isProtocol);
|
|
555
|
+
const count = humanUnread(msgs, unread, isProtocol);
|
|
556
|
+
const fix = {
|
|
557
|
+
preview: human ? (human.dir === "out" ? "you: " : "") + (human.file ? human.file.name : human.text || "") : "",
|
|
558
|
+
lastTime: human ? dkClock(human.ts) : "",
|
|
559
|
+
ts: human ? human.ts : 0,
|
|
560
|
+
unread: count.count,
|
|
561
|
+
unreadExact: count.exact
|
|
562
|
+
};
|
|
563
|
+
cache.current.set(p.id, { key, fix });
|
|
564
|
+
setFixes((f) => Object.assign({}, f, { [p.id]: fix }));
|
|
565
|
+
}).catch(() => {
|
|
566
|
+
}).finally(() => {
|
|
567
|
+
inFlight.current.delete(p.id);
|
|
568
|
+
});
|
|
569
|
+
}
|
|
570
|
+
}, [peers, isProtocol, enabled]);
|
|
571
|
+
return fixes;
|
|
572
|
+
}
|
|
397
573
|
function useDaemonData() {
|
|
398
574
|
const [snap, setSnap] = React.useState({
|
|
399
575
|
me: DK_ME_FALLBACK,
|
|
@@ -1145,6 +1321,20 @@ window.__DK_UI_VERSION="0.1.114";
|
|
|
1145
1321
|
return service_peers_default;
|
|
1146
1322
|
}
|
|
1147
1323
|
}
|
|
1324
|
+
var ASSISTANT_TS_KEY = "beagle.assistant.lastTs";
|
|
1325
|
+
function loadAssistantTs() {
|
|
1326
|
+
try {
|
|
1327
|
+
return Number(localStorage.getItem(ASSISTANT_TS_KEY)) || 0;
|
|
1328
|
+
} catch (e) {
|
|
1329
|
+
return 0;
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1332
|
+
function saveAssistantTs(ts) {
|
|
1333
|
+
try {
|
|
1334
|
+
localStorage.setItem(ASSISTANT_TS_KEY, String(ts));
|
|
1335
|
+
} catch (e) {
|
|
1336
|
+
}
|
|
1337
|
+
}
|
|
1148
1338
|
var ASSISTANT_PEER = {
|
|
1149
1339
|
id: ASSISTANT_ID,
|
|
1150
1340
|
userId: ASSISTANT_ID,
|
|
@@ -1152,7 +1342,6 @@ window.__DK_UI_VERSION="0.1.114";
|
|
|
1152
1342
|
address: "",
|
|
1153
1343
|
online: true,
|
|
1154
1344
|
app: true,
|
|
1155
|
-
pinned: true,
|
|
1156
1345
|
agent: false,
|
|
1157
1346
|
pending: false,
|
|
1158
1347
|
via: null,
|
|
@@ -1257,9 +1446,18 @@ ${tail}`;
|
|
|
1257
1446
|
}).finally(() => setBusy(false));
|
|
1258
1447
|
} }, busy ? T.working || "Working\u2026" : label), /* @__PURE__ */ React.createElement("span", { style: { fontSize: 12, color: "var(--faint)" } }, adopt ? lang === "zh" ? "\u53D6\u6D88\u52FE\u9009\u5373\u4FDD\u6301\u4E3A\u597D\u53CB" : "Untick any you want to keep as a friend" : lang === "zh" ? "\u53D6\u6D88\u52FE\u9009\u53EF\u4FDD\u7559" : "Untick anyone you want to keep"))));
|
|
1259
1448
|
}
|
|
1260
|
-
function useAssistant({ lang, T, muted, onToggleMute, sound, flash, setAlert, onReloadFriends }) {
|
|
1449
|
+
function useAssistant({ lang, T, muted, onToggleMute, sound, flash, setAlert, onReloadFriends, onActivity }) {
|
|
1261
1450
|
const [thread, setThread] = React.useState(() => [{ day: (/* @__PURE__ */ new Date()).toLocaleDateString() }, asMsg("them", helpText(lang))]);
|
|
1262
|
-
const
|
|
1451
|
+
const bump = React.useCallback(() => {
|
|
1452
|
+
const ts = Date.now();
|
|
1453
|
+
saveAssistantTs(ts);
|
|
1454
|
+
if (onActivity)
|
|
1455
|
+
onActivity(ts);
|
|
1456
|
+
}, [onActivity]);
|
|
1457
|
+
const append = React.useCallback((...ms) => {
|
|
1458
|
+
bump();
|
|
1459
|
+
setThread((t) => t.concat(ms));
|
|
1460
|
+
}, [bump]);
|
|
1263
1461
|
React.useEffect(() => {
|
|
1264
1462
|
setThread((t) => t.length === 2 ? [t[0], asMsg("them", helpText(lang))] : t);
|
|
1265
1463
|
}, [lang]);
|
|
@@ -1493,98 +1691,6 @@ ${lines}`, { assistant: { kind: "adopt", rows: fresh } }));
|
|
|
1493
1691
|
}, [append, lang, onReloadFriends]);
|
|
1494
1692
|
return { thread, handle, removeFriends, adoptServicePeers };
|
|
1495
1693
|
}
|
|
1496
|
-
function protocolTest(rule) {
|
|
1497
|
-
if (typeof rule !== "function")
|
|
1498
|
-
return () => false;
|
|
1499
|
-
return (msg) => {
|
|
1500
|
-
if (!msg)
|
|
1501
|
-
return false;
|
|
1502
|
-
try {
|
|
1503
|
-
const v = rule(msg);
|
|
1504
|
-
return typeof v === "string" ? v || true : !!v;
|
|
1505
|
-
} catch (e) {
|
|
1506
|
-
return false;
|
|
1507
|
-
}
|
|
1508
|
-
};
|
|
1509
|
-
}
|
|
1510
|
-
function stripOwnPrefix(text) {
|
|
1511
|
-
return String(text == null ? "" : text).replace(/^you:\s*/i, "");
|
|
1512
|
-
}
|
|
1513
|
-
function lastMessageOf(peer) {
|
|
1514
|
-
const raw = String(peer && peer.lastMsg || "");
|
|
1515
|
-
return {
|
|
1516
|
-
text: stripOwnPrefix(raw),
|
|
1517
|
-
dir: peer && peer.lastDir || (/^you:\s*/i.test(raw) ? "out" : "in"),
|
|
1518
|
-
ts: peer && peer.lastTs || 0
|
|
1519
|
-
};
|
|
1520
|
-
}
|
|
1521
|
-
function lastIsProtocol(peer, isProto) {
|
|
1522
|
-
const last = lastMessageOf(peer);
|
|
1523
|
-
if (!last.text)
|
|
1524
|
-
return false;
|
|
1525
|
-
return isProto(last);
|
|
1526
|
-
}
|
|
1527
|
-
function rosterRow(peer, isProto) {
|
|
1528
|
-
const hidden = lastIsProtocol(peer, isProto);
|
|
1529
|
-
return {
|
|
1530
|
-
preview: hidden ? "" : peer && peer.lastMsg || "",
|
|
1531
|
-
lastTime: hidden ? "" : peer && peer.lastTime || "",
|
|
1532
|
-
unread: hidden ? 0 : Number(peer && peer.unread || 0),
|
|
1533
|
-
activityTs: hidden ? 0 : Number(peer && peer.lastTs || 0),
|
|
1534
|
-
hidden
|
|
1535
|
-
};
|
|
1536
|
-
}
|
|
1537
|
-
function rosterUnreadTotal(peers, isProto) {
|
|
1538
|
-
return (peers || []).reduce((n, p) => n + rosterRow(p, isProto).unread, 0);
|
|
1539
|
-
}
|
|
1540
|
-
function collapseProtocol(thread, isProto, lang) {
|
|
1541
|
-
const out = [];
|
|
1542
|
-
let run = null;
|
|
1543
|
-
const flush = () => {
|
|
1544
|
-
if (!run)
|
|
1545
|
-
return;
|
|
1546
|
-
out.push({
|
|
1547
|
-
protocol: true,
|
|
1548
|
-
id: `proto-${run.first.id || run.startIndex}`,
|
|
1549
|
-
count: run.items.length,
|
|
1550
|
-
label: run.label,
|
|
1551
|
-
dir: run.first.from === "me" ? "out" : "in",
|
|
1552
|
-
text: run.items.map((m) => m.text).join("\n"),
|
|
1553
|
-
line: protocolLine(run, lang)
|
|
1554
|
-
});
|
|
1555
|
-
run = null;
|
|
1556
|
-
};
|
|
1557
|
-
(thread || []).forEach((m, i) => {
|
|
1558
|
-
const hit = m && !m.day ? isProto({ text: m.text, dir: m && m.from === "me" ? "out" : "in", ts: m && m.ts }) : false;
|
|
1559
|
-
if (!hit || m && m.file) {
|
|
1560
|
-
flush();
|
|
1561
|
-
out.push(m);
|
|
1562
|
-
return;
|
|
1563
|
-
}
|
|
1564
|
-
if (!run)
|
|
1565
|
-
run = { first: m, startIndex: i, items: [], label: typeof hit === "string" ? hit : "" };
|
|
1566
|
-
if (!run.label && typeof hit === "string")
|
|
1567
|
-
run.label = hit;
|
|
1568
|
-
run.items.push(m);
|
|
1569
|
-
});
|
|
1570
|
-
flush();
|
|
1571
|
-
return out;
|
|
1572
|
-
}
|
|
1573
|
-
function protocolLine(run, lang) {
|
|
1574
|
-
const arrow = run.first.from === "me" ? "\u2192" : "\u2190";
|
|
1575
|
-
const n = run.items.length;
|
|
1576
|
-
if (run.label) {
|
|
1577
|
-
return `\u2699 ${arrow} ${run.label}${n > 1 ? ` \xB7 ${n}` : ""}`;
|
|
1578
|
-
}
|
|
1579
|
-
if (n > 1) {
|
|
1580
|
-
return lang === "zh" ? `\u2699 ${arrow} ${n} \u6761\u534F\u8BAE\u6D88\u606F` : `\u2699 ${arrow} ${n} protocol messages`;
|
|
1581
|
-
}
|
|
1582
|
-
return `\u2699 ${arrow} ${protocolSummary(run.first.text)}`;
|
|
1583
|
-
}
|
|
1584
|
-
function protocolSummary(text, max = 72) {
|
|
1585
|
-
const s = String(text == null ? "" : text).replace(/\s+/g, " ").trim();
|
|
1586
|
-
return s.length > max ? s.slice(0, max - 1) + "\u2026" : s;
|
|
1587
|
-
}
|
|
1588
1694
|
var DK_CMD_HIST_KEY = "beagle.assistant.history";
|
|
1589
1695
|
var DK_CMD_HIST_MAX = 50;
|
|
1590
1696
|
function RequestsBlock({ T, requests, onAct }) {
|
|
@@ -1645,9 +1751,9 @@ ${lines}`, { assistant: { kind: "adopt", rows: fresh } }));
|
|
|
1645
1751
|
paddingLeft: 8
|
|
1646
1752
|
} }, 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))))));
|
|
1647
1753
|
}
|
|
1648
|
-
function PeerRow({ peer, T, active, onClick, muted, isProtocol }) {
|
|
1754
|
+
function PeerRow({ peer, T, active, onClick, muted, isProtocol, fix }) {
|
|
1649
1755
|
const name = peer.alias || peer.userId;
|
|
1650
|
-
const row = rosterRow(peer, isProtocol || (() => false));
|
|
1756
|
+
const row = rosterRow(peer, isProtocol || (() => false), fix);
|
|
1651
1757
|
return /* @__PURE__ */ React.createElement("button", { onClick, style: {
|
|
1652
1758
|
display: "flex",
|
|
1653
1759
|
alignItems: "center",
|
|
@@ -1678,11 +1784,11 @@ ${lines}`, { assistant: { kind: "adopt", rows: fresh } }));
|
|
|
1678
1784
|
minWidth: 0
|
|
1679
1785
|
} }, 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 })));
|
|
1680
1786
|
}
|
|
1681
|
-
function dkActivityTs(p, isProtocol) {
|
|
1682
|
-
const row = rosterRow(p, isProtocol || (() => false));
|
|
1787
|
+
function dkActivityTs(p, isProtocol, fix) {
|
|
1788
|
+
const row = rosterRow(p, isProtocol || (() => false), fix);
|
|
1683
1789
|
return Math.max(row.activityTs, p.acceptedAt || 0, p.requestedAt || 0);
|
|
1684
1790
|
}
|
|
1685
|
-
function PeerSidebar({ T, peers, requests, activeId, onSelect, onAct, onAdd, prefillAddr, onPrefillConsumed, muted, wide, isProtocol }) {
|
|
1791
|
+
function PeerSidebar({ T, peers, requests, activeId, onSelect, onAct, onAdd, prefillAddr, onPrefillConsumed, muted, wide, isProtocol, protocolFix }) {
|
|
1686
1792
|
const [q, setQ] = React.useState("");
|
|
1687
1793
|
const [addr, setAddr] = React.useState("");
|
|
1688
1794
|
const [addState, setAddState] = React.useState(null);
|
|
@@ -1727,7 +1833,8 @@ ${lines}`, { assistant: { kind: "adopt", rows: fresh } }));
|
|
|
1727
1833
|
}).slice().sort((a, b) => {
|
|
1728
1834
|
if (!!a.pinned !== !!b.pinned)
|
|
1729
1835
|
return a.pinned ? -1 : 1;
|
|
1730
|
-
const ta = dkActivityTs(a, isProtocol
|
|
1836
|
+
const ta = dkActivityTs(a, isProtocol, protocolFix && protocolFix[a.id]);
|
|
1837
|
+
const tb = dkActivityTs(b, isProtocol, protocolFix && protocolFix[b.id]);
|
|
1731
1838
|
if (ta !== tb)
|
|
1732
1839
|
return tb - ta;
|
|
1733
1840
|
return String(a.alias || a.userId || "").localeCompare(String(b.alias || b.userId || ""));
|
|
@@ -1766,7 +1873,7 @@ ${lines}`, { assistant: { kind: "adopt", rows: fresh } }));
|
|
|
1766
1873
|
fontSize: 11.5,
|
|
1767
1874
|
lineHeight: 1.35,
|
|
1768
1875
|
color: addState.kind === "err" ? "var(--bad, #e5484d)" : addState.kind === "ok" ? "var(--good, #46a758)" : "var(--faint)"
|
|
1769
|
-
} }, 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"))));
|
|
1876
|
+
} }, 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"))));
|
|
1770
1877
|
}
|
|
1771
1878
|
var inputStyle = {
|
|
1772
1879
|
flex: 1,
|
|
@@ -3367,12 +3474,12 @@ ${peer.address}`
|
|
|
3367
3474
|
function ChatEmpty({ T }) {
|
|
3368
3475
|
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));
|
|
3369
3476
|
}
|
|
3370
|
-
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 }) {
|
|
3477
|
+
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 }) {
|
|
3371
3478
|
const peer = peers.find((p) => p.id === activeId);
|
|
3372
3479
|
if (phone) {
|
|
3373
|
-
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 });
|
|
3480
|
+
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 });
|
|
3374
3481
|
}
|
|
3375
|
-
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 }));
|
|
3482
|
+
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 }));
|
|
3376
3483
|
}
|
|
3377
3484
|
Object.assign(window, { ChatTab });
|
|
3378
3485
|
function CopyBtn({ value, copiedText = "Copied", copyFailedText = "Copy failed", copyTitle = "Copy" }) {
|
|
@@ -6829,7 +6936,11 @@ ${peer.address}`
|
|
|
6829
6936
|
sessionStorage.setItem(key, "1");
|
|
6830
6937
|
window.location.reload();
|
|
6831
6938
|
}, [me && me.beagleVer]);
|
|
6832
|
-
const
|
|
6939
|
+
const [assistantTs, setAssistantTs] = React.useState(loadAssistantTs);
|
|
6940
|
+
const peers = React.useMemo(() => (data.peers || []).concat([Object.assign({}, ASSISTANT_PEER, {
|
|
6941
|
+
lastTs: assistantTs,
|
|
6942
|
+
lastTime: assistantTs ? dkClock(assistantTs) : ""
|
|
6943
|
+
})]), [data.peers, assistantTs]);
|
|
6833
6944
|
const [pendingAddr, setPendingAddr] = React.useState(() => dkParseDeepLinkAddress());
|
|
6834
6945
|
React.useEffect(() => {
|
|
6835
6946
|
const onHash = () => {
|
|
@@ -6884,6 +6995,7 @@ ${peer.address}`
|
|
|
6884
6995
|
const mutedIds = Array.isArray(t.alertMuted) ? t.alertMuted : [];
|
|
6885
6996
|
const onToggleMute = (id) => setTweak("alertMuted", mutedIds.includes(id) ? mutedIds.filter((x) => x !== id) : mutedIds.concat(id));
|
|
6886
6997
|
const isProtocol = React.useMemo(() => protocolTest(hostIsProtocolMessage), []);
|
|
6998
|
+
const protocolFix = useProtocolTails(peers, isProtocol, !!hostIsProtocolMessage);
|
|
6887
6999
|
useIncomingAlerts({
|
|
6888
7000
|
T,
|
|
6889
7001
|
peers,
|
|
@@ -6900,6 +7012,7 @@ ${peer.address}`
|
|
|
6900
7012
|
T,
|
|
6901
7013
|
muted: mutedIds,
|
|
6902
7014
|
onToggleMute,
|
|
7015
|
+
onActivity: setAssistantTs,
|
|
6903
7016
|
sound: t.alertSound !== false,
|
|
6904
7017
|
flash: t.alertFlash !== false,
|
|
6905
7018
|
setAlert: (which, on) => setTweak(which === "sound" ? "alertSound" : "alertFlash", on),
|
|
@@ -7145,7 +7258,7 @@ ${peer.address}`
|
|
|
7145
7258
|
const lastPeople = React.useRef("here");
|
|
7146
7259
|
if (peopleTab)
|
|
7147
7260
|
lastPeople.current = tab;
|
|
7148
|
-
const unreadTotal = rosterUnreadTotal(peers, isProtocol) + (requests || []).length;
|
|
7261
|
+
const unreadTotal = rosterUnreadTotal(peers, isProtocol, protocolFix) + (requests || []).length;
|
|
7149
7262
|
const NAV_FOR = {
|
|
7150
7263
|
chat: { icon: "message", label: T.chat, active: tab === "chat", badge: unreadTotal, go: () => setTab("chat") },
|
|
7151
7264
|
people: { icon: "users", label: T.people, active: peopleTab, go: () => setTab(lastPeople.current) },
|
|
@@ -7203,7 +7316,7 @@ ${peer.address}`
|
|
|
7203
7316
|
fontWeight: 600,
|
|
7204
7317
|
background: tab === n.id ? "var(--accent)" : "transparent",
|
|
7205
7318
|
color: tab === n.id ? "#fff" : "var(--dim)"
|
|
7206
|
-
} }, /* @__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(
|
|
7319
|
+
} }, /* @__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(
|
|
7207
7320
|
ProfileTab,
|
|
7208
7321
|
{
|
|
7209
7322
|
T,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@decentnetwork/beagle",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.116",
|
|
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.30",
|
|
39
39
|
"@types/js-yaml": "^4.0.9",
|
|
40
40
|
"@types/node": "^20.11.0",
|
|
41
41
|
"@types/yargs": "^17.0.32",
|