@decentnetwork/beagle-ui 0.2.38 → 0.2.39
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 +47 -9
- 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.39";
|
|
2
2
|
// src/icons.jsx
|
|
3
3
|
var ICON_PATHS = {
|
|
4
4
|
// ---- tab bar (the four must feel like one set) ----
|
|
@@ -306,6 +306,33 @@ function protocolSummary(text, max = 72) {
|
|
|
306
306
|
return s.length > max ? s.slice(0, max - 1) + "\u2026" : s;
|
|
307
307
|
}
|
|
308
308
|
|
|
309
|
+
// src/exit-host.js
|
|
310
|
+
function hostHasExits(d) {
|
|
311
|
+
if (!d || typeof d !== "object")
|
|
312
|
+
return false;
|
|
313
|
+
if (d.exitsSupported === false)
|
|
314
|
+
return false;
|
|
315
|
+
return !!d.exitFeature && typeof d.exitFeature === "object";
|
|
316
|
+
}
|
|
317
|
+
function desktopPollPath({ wantExits, opened, supported }) {
|
|
318
|
+
if (!wantExits || supported !== true)
|
|
319
|
+
return "/api/desktop";
|
|
320
|
+
return opened ? "/api/desktop?exits=1&open=1" : "/api/desktop?exits=1";
|
|
321
|
+
}
|
|
322
|
+
function exitControls({ exitFeature, routeFallback, exits }) {
|
|
323
|
+
const has = hostHasExits({ exitFeature });
|
|
324
|
+
const list = Array.isArray(exits) ? exits : [];
|
|
325
|
+
const anyFailed = list.some((r) => (r.nodes || []).some((n) => n.status === "failed"));
|
|
326
|
+
return {
|
|
327
|
+
refresh: has && list.length > 0,
|
|
328
|
+
reconnect: has,
|
|
329
|
+
reconnectAll: has && anyFailed,
|
|
330
|
+
noExitNotice: has && exitFeature.available === false,
|
|
331
|
+
fallbackNotice: has && !!(routeFallback && routeFallback.from),
|
|
332
|
+
anyFailed: has && anyFailed
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
|
|
309
336
|
// src/data-ipc.jsx
|
|
310
337
|
function dkHash(s) {
|
|
311
338
|
let h = 2166136261;
|
|
@@ -594,6 +621,7 @@ function useDaemonData(opts) {
|
|
|
594
621
|
const wantExitsRef = React.useRef(wantExits);
|
|
595
622
|
wantExitsRef.current = wantExits;
|
|
596
623
|
const exitsOpenedRef = React.useRef(false);
|
|
624
|
+
const exitsSupportedRef = React.useRef(null);
|
|
597
625
|
const [snap, setSnap] = React.useState({
|
|
598
626
|
me: DK_ME_FALLBACK,
|
|
599
627
|
peers: [],
|
|
@@ -610,11 +638,13 @@ function useDaemonData(opts) {
|
|
|
610
638
|
const refresh = React.useCallback(async () => {
|
|
611
639
|
var _a, _b, _c;
|
|
612
640
|
try {
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
641
|
+
const path = desktopPollPath({
|
|
642
|
+
wantExits: wantExitsRef.current,
|
|
643
|
+
opened: exitsOpenedRef.current,
|
|
644
|
+
supported: exitsSupportedRef.current
|
|
645
|
+
});
|
|
646
|
+
if (path.includes("open=1"))
|
|
616
647
|
exitsOpenedRef.current = false;
|
|
617
|
-
}
|
|
618
648
|
const d = await dkGet(path);
|
|
619
649
|
if (d && d.locked) {
|
|
620
650
|
setSnap((s) => ({ ...s, locked: true, loaded: true }));
|
|
@@ -626,6 +656,13 @@ function useDaemonData(opts) {
|
|
|
626
656
|
}, 300);
|
|
627
657
|
return;
|
|
628
658
|
}
|
|
659
|
+
const had = exitsSupportedRef.current;
|
|
660
|
+
exitsSupportedRef.current = hostHasExits(d);
|
|
661
|
+
if (had !== true && exitsSupportedRef.current && wantExitsRef.current && exitsOpenedRef.current) {
|
|
662
|
+
setTimeout(() => {
|
|
663
|
+
refreshRef.current && refreshRef.current();
|
|
664
|
+
}, 0);
|
|
665
|
+
}
|
|
629
666
|
setSnap({
|
|
630
667
|
locked: false,
|
|
631
668
|
me: d.me || DK_ME_FALLBACK,
|
|
@@ -6219,7 +6256,7 @@ function ExitCard({ T, region, activeExit, onSetExit, onReconnect, featureOn })
|
|
|
6219
6256
|
const stuck = n.online && !n.reachable;
|
|
6220
6257
|
const failed = n.status === "failed";
|
|
6221
6258
|
const usable = n.reachable && featureOn !== false;
|
|
6222
|
-
return /* @__PURE__ */ React.createElement("div", { key: n.ip, className: "dk-wrap", style: { display: "flex", alignItems: "center", gap: 12, rowGap: 6, padding: "10px 14px", borderBottom: i < region.nodes.length - 1 ? "1px solid var(--line)" : "none", background: active ? "color-mix(in oklab, var(--accent), transparent 92%)" : "transparent" } }, /* @__PURE__ */ React.createElement(StatusDot, { online: n.reachable }), /* @__PURE__ */ React.createElement(Mono, { size: 13, copy: n.ip }, n.ip), /* @__PURE__ */ React.createElement("span", { style: { fontFamily: "var(--mono)", fontSize: 11, color: "var(--faint)" } }, n.host), /* @__PURE__ */ React.createElement("div", { style: { flex: 1 } }), n.reachable ? /* @__PURE__ */ React.createElement("span", { style: { fontFamily: "var(--mono)", fontSize: 11.5, color: n.ping > 200 ? "var(--warn)" : "var(--dim)" } }, n.ping, "ms") : failed ? /* @__PURE__ */ React.createElement(Tag, { tone: "danger", title: "Failed 3 checks in a row \u2014 no longer checked; Reconnect to try again" }, T.exitFailed || "failed") : n.status === "unknown" ? /* @__PURE__ */ React.createElement(Tag, { tone: "off" }, T.exitNotChecked || "not checked") : stuck ? /* @__PURE__ */ React.createElement(Tag, { tone: "warn", title: "Announces online but IP won't pass \u2014 session desync or NAT-blocked" }, "online \xB7 no route") : n.status === "down" ? /* @__PURE__ */ React.createElement(Tag, { tone: "warn", title: "No answer \u2014 checked again only when you open this panel or press Refresh; 3 in a row and it is no longer checked" }, T.exitDown || "down", " \xB7 ", n.fails, "/3") : /* @__PURE__ */ React.createElement(Tag, { tone: "off" }, "offline"), failed ? /* @__PURE__ */ React.createElement(ReconnectBtn, { T, ip: n.ip, onReconnect }) : active ? /* @__PURE__ */ React.createElement(Btn, { tone: "ok", icon: "check", size: "sm", onClick: () => onSetExit(null) }, T.routing) : /* @__PURE__ */ React.createElement(Btn, { size: "sm", icon: "route", disabled: !usable, onClick: () => usable && onSetExit(n.ip), style: { opacity: usable ? 1 : 0.4 } }, T.routeThru));
|
|
6259
|
+
return /* @__PURE__ */ React.createElement("div", { key: n.ip, className: "dk-wrap", style: { display: "flex", alignItems: "center", gap: 12, rowGap: 6, padding: "10px 14px", borderBottom: i < region.nodes.length - 1 ? "1px solid var(--line)" : "none", background: active ? "color-mix(in oklab, var(--accent), transparent 92%)" : "transparent" } }, /* @__PURE__ */ React.createElement(StatusDot, { online: n.reachable }), /* @__PURE__ */ React.createElement(Mono, { size: 13, copy: n.ip }, n.ip), /* @__PURE__ */ React.createElement("span", { style: { fontFamily: "var(--mono)", fontSize: 11, color: "var(--faint)" } }, n.host), /* @__PURE__ */ React.createElement("div", { style: { flex: 1 } }), n.reachable ? /* @__PURE__ */ React.createElement("span", { style: { fontFamily: "var(--mono)", fontSize: 11.5, color: n.ping > 200 ? "var(--warn)" : "var(--dim)" } }, n.ping, "ms") : failed ? /* @__PURE__ */ React.createElement(Tag, { tone: "danger", title: "Failed 3 checks in a row \u2014 no longer checked; Reconnect to try again" }, T.exitFailed || "failed") : n.status === "unknown" ? /* @__PURE__ */ React.createElement(Tag, { tone: "off" }, T.exitNotChecked || "not checked") : stuck ? /* @__PURE__ */ React.createElement(Tag, { tone: "warn", title: "Announces online but IP won't pass \u2014 session desync or NAT-blocked" }, "online \xB7 no route") : n.status === "down" ? /* @__PURE__ */ React.createElement(Tag, { tone: "warn", title: "No answer \u2014 checked again only when you open this panel or press Refresh; 3 in a row and it is no longer checked" }, T.exitDown || "down", " \xB7 ", n.fails, "/3") : /* @__PURE__ */ React.createElement(Tag, { tone: "off" }, "offline"), failed && onReconnect ? /* @__PURE__ */ React.createElement(ReconnectBtn, { T, ip: n.ip, onReconnect }) : active ? /* @__PURE__ */ React.createElement(Btn, { tone: "ok", icon: "check", size: "sm", onClick: () => onSetExit(null) }, T.routing) : /* @__PURE__ */ React.createElement(Btn, { size: "sm", icon: "route", disabled: !usable, onClick: () => usable && onSetExit(n.ip), style: { opacity: usable ? 1 : 0.4 } }, T.routeThru));
|
|
6223
6260
|
})));
|
|
6224
6261
|
}
|
|
6225
6262
|
function LanEnableCard({ backend, onArm, onCancel }) {
|
|
@@ -6324,13 +6361,14 @@ function LanEnableCard({ backend, onArm, onCancel }) {
|
|
|
6324
6361
|
)));
|
|
6325
6362
|
}
|
|
6326
6363
|
function NetworkTab({ T, me, peers, exits, activeExit, exitFeature, routeFallback, onReconnectExit, onRefreshExits, reqCount, onSetExit, onOpenChat, backend, onArmLan, onCancelLan }) {
|
|
6327
|
-
const
|
|
6328
|
-
const
|
|
6364
|
+
const ctl = exitControls({ exitFeature, routeFallback, exits });
|
|
6365
|
+
const featureOn = !ctl.noExitNotice;
|
|
6366
|
+
const anyFailed = ctl.anyFailed;
|
|
6329
6367
|
if (backend && backend.switchable && !backend.hasVirtualLan) {
|
|
6330
6368
|
return /* @__PURE__ */ React.createElement("div", { style: { flex: 1, overflow: "auto", background: "var(--bg)" } }, /* @__PURE__ */ React.createElement("div", { className: "dk-page", style: { maxWidth: 1040, margin: "0 auto", padding: "24px 28px 60px", display: "flex", flexDirection: "column", gap: 26 } }, /* @__PURE__ */ React.createElement(MyNode, { T, me, activeExit, peers, reqCount }), /* @__PURE__ */ React.createElement(LanEnableCard, { backend, onArm: onArmLan, onCancel: onCancelLan })));
|
|
6331
6369
|
}
|
|
6332
6370
|
const lanless = !!backend && backend.hasVirtualLan === false;
|
|
6333
|
-
return /* @__PURE__ */ React.createElement("div", { style: { flex: 1, overflow: "auto", background: "var(--bg)" } }, /* @__PURE__ */ React.createElement("div", { className: "dk-page", style: { maxWidth: 1040, margin: "0 auto", padding: "24px 28px 60px", display: "flex", flexDirection: "column", gap: 26 } }, /* @__PURE__ */ React.createElement(MyNode, { T, me, activeExit, peers, reqCount }), /* @__PURE__ */ React.createElement("div", { style: { display: "flex", flexDirection: "column", gap: 12 } }, /* @__PURE__ */ React.createElement(Section, { label: T.peerRouting, count: peers.length }), /* @__PURE__ */ React.createElement(PeerTable, { T, peers, onOpenChat }), !peers.length && /* @__PURE__ */ React.createElement("div", { style: { padding: "14px 16px", borderRadius: 11, border: "1px dashed var(--line)", fontFamily: "var(--ui)", fontSize: 12.5, color: "var(--faint)" } }, T.noPeersYet || "No friends yet \u2014 add one from Chat and it shows up here with its route.")), lanless ? null : /* @__PURE__ */ React.createElement("div", { style: { display: "flex", flexDirection: "column", gap: 12 } }, /* @__PURE__ */ React.createElement(Section, { label: T.exitNodes, trailing: /* @__PURE__ */ React.createElement("div", { style: { display: "flex", gap: 6 } },
|
|
6371
|
+
return /* @__PURE__ */ React.createElement("div", { style: { flex: 1, overflow: "auto", background: "var(--bg)" } }, /* @__PURE__ */ React.createElement("div", { className: "dk-page", style: { maxWidth: 1040, margin: "0 auto", padding: "24px 28px 60px", display: "flex", flexDirection: "column", gap: 26 } }, /* @__PURE__ */ React.createElement(MyNode, { T, me, activeExit, peers, reqCount }), /* @__PURE__ */ React.createElement("div", { style: { display: "flex", flexDirection: "column", gap: 12 } }, /* @__PURE__ */ React.createElement(Section, { label: T.peerRouting, count: peers.length }), /* @__PURE__ */ React.createElement(PeerTable, { T, peers, onOpenChat }), !peers.length && /* @__PURE__ */ React.createElement("div", { style: { padding: "14px 16px", borderRadius: 11, border: "1px dashed var(--line)", fontFamily: "var(--ui)", fontSize: 12.5, color: "var(--faint)" } }, T.noPeersYet || "No friends yet \u2014 add one from Chat and it shows up here with its route.")), lanless ? null : /* @__PURE__ */ React.createElement("div", { style: { display: "flex", flexDirection: "column", gap: 12 } }, /* @__PURE__ */ React.createElement(Section, { label: T.exitNodes, trailing: /* @__PURE__ */ React.createElement("div", { style: { display: "flex", gap: 6 } }, ctl.refresh && onRefreshExits && /* @__PURE__ */ React.createElement(ReconnectBtn, { T, ip: null, onReconnect: () => onRefreshExits(), label: T.exitRefresh || "Refresh" }), ctl.reconnectAll && onReconnectExit && /* @__PURE__ */ React.createElement(ReconnectBtn, { T, ip: null, onReconnect: onReconnectExit, label: T.exitReconnectAll || "Reconnect all" }), /* @__PURE__ */ React.createElement(Btn, { icon: "plus", size: "sm" }, T.addExit)) }), ctl.noExitNotice && /* @__PURE__ */ React.createElement("div", { style: { display: "flex", flexDirection: "column", gap: 4, padding: "11px 14px", borderRadius: 10, background: "var(--panel-2)", border: "1px dashed var(--line)" } }, /* @__PURE__ */ React.createElement("span", { style: { fontFamily: "var(--mono)", fontSize: 12.5, fontWeight: 700, color: "var(--text)" } }, T.noExitAvailable || "No exit available \u2014 routing and proxy are off."), anyFailed && /* @__PURE__ */ React.createElement("span", { style: { fontFamily: "var(--ui)", fontSize: 12, color: "var(--dim)" } }, T.noExitHint || "Every exit failed 3 times and is no longer checked automatically. Press Reconnect to try one again.")), ctl.fallbackNotice && /* @__PURE__ */ React.createElement("div", { style: { display: "flex", alignItems: "center", gap: 10, padding: "11px 14px", borderRadius: 10, background: "color-mix(in oklab, var(--warn), transparent 90%)", border: "1px solid color-mix(in oklab, var(--warn), transparent 70%)" } }, /* @__PURE__ */ React.createElement(Icon, { name: "route", size: 17, color: "var(--warn)", stroke: 2 }), /* @__PURE__ */ React.createElement("span", { style: { fontFamily: "var(--mono)", fontSize: 12.5, color: "var(--text)" } }, T.routeFellBack || "Routing fell back to direct: every exit it used failed. Reconnect one to route through it again.")), activeExit && /* @__PURE__ */ React.createElement("div", { style: { display: "flex", alignItems: "center", gap: 10, padding: "11px 14px", borderRadius: 10, background: "color-mix(in oklab, var(--warn), transparent 90%)", border: "1px solid color-mix(in oklab, var(--warn), transparent 70%)" } }, /* @__PURE__ */ React.createElement(Icon, { name: "route", size: 17, color: "var(--warn)", stroke: 2 }), /* @__PURE__ */ React.createElement("span", { style: { fontFamily: "var(--mono)", fontSize: 12.5, color: "var(--text)" } }, T.egressVia), /* @__PURE__ */ React.createElement(Mono, { size: 13, copy: activeExit }, activeExit), /* @__PURE__ */ React.createElement("div", { style: { flex: 1 } }), /* @__PURE__ */ React.createElement(Btn, { tone: "danger", icon: "unlink", size: "sm", onClick: () => onSetExit(null) }, T.stopRouting)), /* @__PURE__ */ React.createElement("div", { className: "dk-grid1", style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 } }, exits.map((r) => /* @__PURE__ */ React.createElement(ExitCard, { key: r.region, T, region: r, activeExit, onSetExit, onReconnect: ctl.reconnect ? onReconnectExit : null, featureOn }))))));
|
|
6334
6372
|
}
|
|
6335
6373
|
Object.assign(window, { NetworkTab });
|
|
6336
6374
|
|
package/package.json
CHANGED