@decentnetwork/beagle-ui 0.2.26 → 0.2.27
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 +244 -38
- 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.27";
|
|
2
2
|
// src/icons.jsx
|
|
3
3
|
var ICON_PATHS = {
|
|
4
4
|
// ---- tab bar (the four must feel like one set) ----
|
|
@@ -66,8 +66,8 @@ var ICON_PATHS = {
|
|
|
66
66
|
speaker: '<path d="M11 5 6 9H3v6h3l5 4V5Z"/><path d="M16 9a3 3 0 0 1 0 6"/><path d="M19 7a6 6 0 0 1 0 10"/>',
|
|
67
67
|
micFill: '<rect x="9" y="2.5" width="6" height="11.5" rx="3"/><path d="M5.5 11a6.5 6.5 0 0 0 13 0"/><path d="M12 17.5v3.5"/>'
|
|
68
68
|
};
|
|
69
|
-
function Icon({ name, size = 24, stroke = 1.75, color = "currentColor", fill = "none", style }) {
|
|
70
|
-
const d = ICON_PATHS[name];
|
|
69
|
+
function Icon({ name, size = 24, stroke = 1.75, color = "currentColor", fill = "none", style, svgPath }) {
|
|
70
|
+
const d = svgPath || ICON_PATHS[name];
|
|
71
71
|
if (!d)
|
|
72
72
|
return null;
|
|
73
73
|
return /* @__PURE__ */ React.createElement(
|
|
@@ -111,7 +111,10 @@ Object.assign(ICON_PATHS, {
|
|
|
111
111
|
zap: '<path d="M13 2 4 13h7l-1 9 9-11h-7l1-9Z"/>',
|
|
112
112
|
clock: '<circle cx="12" cy="12" r="9"/><path d="M12 7v5l3.5 2"/>',
|
|
113
113
|
bellOff: '<path d="M8.7 3.4A6 6 0 0 1 18 8.5c0 3 .5 5 1.1 6.3M6.1 6.1A6 6 0 0 0 6 8.5c0 6.5-2.5 8-2.5 8H16"/><path d="M13.7 20.5a2 2 0 0 1-3.4 0"/><path d="m3 3 18 18"/>',
|
|
114
|
-
plug: '<path d="M9 2v6M15 2v6"/><path d="M7 8h10v3a5 5 0 0 1-10 0V8Z"/><path d="M12 16v6"/>'
|
|
114
|
+
plug: '<path d="M9 2v6M15 2v6"/><path d="M7 8h10v3a5 5 0 0 1-10 0V8Z"/><path d="M12 16v6"/>',
|
|
115
|
+
// A form with a filled-in field: the glyph for "Fill with Beagle" and any
|
|
116
|
+
// other host app that puts your identity into someone else's page.
|
|
117
|
+
form: '<rect x="4" y="3" width="16" height="18" rx="2"/><path d="M8 8h8M8 12h5"/><path d="M8 16h3"/><path d="m14.5 17.5 1.6 1.6 3.4-3.6"/>'
|
|
115
118
|
});
|
|
116
119
|
|
|
117
120
|
// src/ui-host.jsx
|
|
@@ -121,8 +124,16 @@ var hostPrefersRtcFile = false;
|
|
|
121
124
|
var hostHasKeyBackup = false;
|
|
122
125
|
var hostEnsWrite = true;
|
|
123
126
|
var hostBrandHref = "";
|
|
127
|
+
var hostTabs = null;
|
|
128
|
+
var hostHideApps = null;
|
|
129
|
+
var hostApps = null;
|
|
130
|
+
var hostProfileSections = null;
|
|
124
131
|
function setUiHost(host) {
|
|
125
132
|
H = host || {};
|
|
133
|
+
hostTabs = Array.isArray(H.hostTabs) ? H.hostTabs : null;
|
|
134
|
+
hostHideApps = Array.isArray(H.hideApps) ? H.hideApps : null;
|
|
135
|
+
hostApps = Array.isArray(H.hostApps) ? H.hostApps : null;
|
|
136
|
+
hostProfileSections = Array.isArray(H.hostProfileSections) ? H.hostProfileSections : null;
|
|
126
137
|
hostNeedsWelcome = !!H.hostNeedsWelcome;
|
|
127
138
|
hostPrefersRtcFile = !!H.hostPrefersRtcFile;
|
|
128
139
|
hostHasKeyBackup = !!H.hostHasKeyBackup;
|
|
@@ -3032,7 +3043,7 @@ function Conversation({ T, peer, lang, peers, onOpenChat, thread: threadProp, on
|
|
|
3032
3043
|
// The internal id is not an address anyone can use and not a name
|
|
3033
3044
|
// anyone chose; saying what this row IS is more use than showing it.
|
|
3034
3045
|
/* @__PURE__ */ React.createElement("div", { style: { marginTop: 2, fontFamily: "var(--mono)", fontSize: 11.5, color: "var(--faint)" } }, T && T.assistantSub || "Local \xB7 APP")
|
|
3035
|
-
) : phone ? /* @__PURE__ */ React.createElement("div", { style: { marginTop: 2, display: "flex" } }, /* @__PURE__ */ React.createElement(RouteTag, { peer })) : /* @__PURE__ */ React.createElement("div", { style: { display: "flex", alignItems: "center", gap: 8, marginTop: 2 } }, /* @__PURE__ */ React.createElement(Mono, { size: 11.5, dim: true, copy: peer.userId, title: peer.userId }, shortKey(peer.userId, 10, 6)), /* @__PURE__ */ React.createElement("span", { style: { color: "var(--line)" } }, "\xB7"), /* @__PURE__ */ React.createElement("button", { onClick: () => onOpenNet(peer), title: T && T.openNet || "Network view", style: { background: "none", border: "none", cursor: "pointer", padding: 0, color: "var(--accent)", display: "inline-flex", alignItems: "center" } }, /* @__PURE__ */ React.createElement(Icon, { name: "network", size: 12, stroke: 2 })), /* @__PURE__ */ React.createElement(Mono, { size: 11.5, dim: true, copy: peer.ip, title: peer.ip }, peer.ip), peer.address && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("span", { style: { color: "var(--line)" } }, "\xB7"), /* @__PURE__ */ React.createElement(
|
|
3046
|
+
) : phone ? /* @__PURE__ */ React.createElement("div", { style: { marginTop: 2, display: "flex" } }, /* @__PURE__ */ React.createElement(RouteTag, { peer })) : /* @__PURE__ */ React.createElement("div", { style: { display: "flex", alignItems: "center", gap: 8, marginTop: 2 } }, /* @__PURE__ */ React.createElement(Mono, { size: 11.5, dim: true, copy: peer.userId, title: peer.userId }, shortKey(peer.userId, 10, 6)), onOpenNet && /* @__PURE__ */ React.createElement("span", { style: { color: "var(--line)" } }, "\xB7"), onOpenNet && /* @__PURE__ */ React.createElement("button", { onClick: () => onOpenNet(peer), title: T && T.openNet || "Network view", style: { background: "none", border: "none", cursor: "pointer", padding: 0, color: "var(--accent)", display: "inline-flex", alignItems: "center" } }, /* @__PURE__ */ React.createElement(Icon, { name: "network", size: 12, stroke: 2 })), /* @__PURE__ */ React.createElement(Mono, { size: 11.5, dim: true, copy: peer.ip, title: peer.ip }, peer.ip), peer.address && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("span", { style: { color: "var(--line)" } }, "\xB7"), /* @__PURE__ */ React.createElement(
|
|
3036
3047
|
Mono,
|
|
3037
3048
|
{
|
|
3038
3049
|
size: 11.5,
|
|
@@ -3067,7 +3078,7 @@ ${peer.address}`
|
|
|
3067
3078
|
} }), phone && onSendRtcFile && !peer.app && /* @__PURE__ */ React.createElement(MenuItem, { icon: "file", label: T && T.sendWebrtcFile || "Send file via WebRTC", onClick: () => {
|
|
3068
3079
|
setMenu(false);
|
|
3069
3080
|
rtcFileRef.current && rtcFileRef.current.click();
|
|
3070
|
-
} }), phone && !peer.app && /* @__PURE__ */ React.createElement(MenuItem, { icon: "network", label: T && T.openNet || "Network view", onClick: () => {
|
|
3081
|
+
} }), phone && !peer.app && onOpenNet && /* @__PURE__ */ React.createElement(MenuItem, { icon: "network", label: T && T.openNet || "Network view", onClick: () => {
|
|
3071
3082
|
setMenu(false);
|
|
3072
3083
|
onOpenNet(peer);
|
|
3073
3084
|
} }), !peer.app && /* @__PURE__ */ React.createElement(MenuItem, { icon: "hash", label: T.alias, onClick: () => {
|
|
@@ -4042,7 +4053,7 @@ function DkAvatarSheet({ T, me, zh, onSet, onClose }) {
|
|
|
4042
4053
|
return /* @__PURE__ */ React.createElement(DkPunkPicker, { T, onPick: pickPunk, onClose: () => setPicking(false) });
|
|
4043
4054
|
return /* @__PURE__ */ React.createElement("div", { onClick: onClose, style: { position: "fixed", inset: 0, zIndex: 90, background: "color-mix(in oklab, #000, transparent 38%)", display: "flex", alignItems: "center", justifyContent: "center", padding: 16 } }, /* @__PURE__ */ React.createElement("div", { onClick: (e) => e.stopPropagation(), style: { width: 360, maxWidth: "100%", background: "var(--panel)", border: "1px solid var(--line)", borderRadius: 16, padding: 16, display: "flex", flexDirection: "column", gap: 8 } }, /* @__PURE__ */ React.createElement("div", { style: { display: "flex", alignItems: "center", gap: 10, marginBottom: 4 } }, /* @__PURE__ */ React.createElement(DkAvatar, { peer: { ...me, id: me.userId, agent: false }, size: 40, radius: 10, dot: false }), /* @__PURE__ */ React.createElement("span", { style: { flex: 1, fontFamily: "var(--mono)", fontSize: 13.5, fontWeight: 700, color: "var(--text)" } }, zh ? "\u66F4\u6362\u5934\u50CF" : "Change avatar"), /* @__PURE__ */ React.createElement(Btn, { icon: "x", size: "sm", onClick: onClose })), item("sparkles", zh ? "\u9009\u4E00\u4E2A CryptoPunk" : "Choose a CryptoPunk", () => setPicking(true)), canUpload && item("image", zh ? "\u4E0A\u4F20\u7167\u7247" : "Upload a photo", () => fileRef.current && fileRef.current.click()), has && item("trash", zh ? "\u79FB\u9664\u5934\u50CF" : "Remove avatar", () => save(canUpload ? { punkId: null, avatarDataUrl: null } : { punkId: null }), true), /* @__PURE__ */ React.createElement("input", { ref: fileRef, type: "file", accept: "image/*", onChange: onFile, style: { display: "none" } }), /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--ui)", fontSize: 11.5, color: "var(--faint)", lineHeight: 1.5, marginTop: 2 } }, zh ? "\u4E0D\u9700\u8981\u6CE8\u518C beagles.eth \u540D\u5B57\u3002\u597D\u53CB\u4F1A\u5728\u4E0B\u6B21\u6536\u5230\u4F60\u7684\u8D44\u6599\u65F6\u770B\u5230\u65B0\u5934\u50CF\u3002" : "No beagles.eth name needed. Friends see it the next time your profile reaches them."), err && /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--mono)", fontSize: 11.5, color: "var(--danger)" } }, err)));
|
|
4044
4055
|
}
|
|
4045
|
-
function ProfileTab({ T, me, onEdit, t, setTweak, onSetAvatar }) {
|
|
4056
|
+
function ProfileTab({ T, me, onEdit, t, setTweak, onSetAvatar, sections, sectionProps }) {
|
|
4046
4057
|
var _a;
|
|
4047
4058
|
const [avatarSheet, setAvatarSheet] = React.useState(false);
|
|
4048
4059
|
const [qr, setQr] = React.useState(null);
|
|
@@ -4074,12 +4085,33 @@ function ProfileTab({ T, me, onEdit, t, setTweak, onSetAvatar }) {
|
|
|
4074
4085
|
},
|
|
4075
4086
|
style: { width: 16, height: 16, accentColor: "var(--accent)" }
|
|
4076
4087
|
}
|
|
4077
|
-
), /* @__PURE__ */ React.createElement("div", { style: { flex: 1 } }, /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--mono)", fontSize: 13.5, fontWeight: 600, color: "var(--text)" } }, T && T.autoAcceptLabel || "Auto-accept friend requests"), /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--ui)", fontSize: 11.5, color: "var(--dim)", marginTop: 2 } }, T && T.autoAcceptSub || "Off: requests wait in the sidebar for your approval.")))), hostHasKeyBackup && /* @__PURE__ */ React.createElement(DkKeyBackup, { t: t || {} }), t && setTweak && /* @__PURE__ */ React.createElement(DkAlertSettings, { t, setTweak }), t && setTweak && /* @__PURE__ */ React.createElement(DkDisplaySettings, { t, setTweak }), /* @__PURE__ */ React.createElement(Card, { label: T.network }, /* @__PURE__ */ React.createElement(FieldRow, { T, label: T.virtualIp, value: me.ip, copy: true }), /* @__PURE__ */ React.createElement(FieldRow, { T, label: T.wireLabel, value: `${me.wire} \xB7 lossless`, mono: false }), /* @__PURE__ */ React.createElement(DkVersionRow, { T, me }), /* @__PURE__ */ React.createElement(DkUpdateCheck, { T })), /* @__PURE__ */ React.createElement(Card, { label: T.dangerZone }, /* @__PURE__ */ React.createElement("div", { style: { display: "flex", alignItems: "center", gap: 13, padding: "14px 16px" } }, /* @__PURE__ */ React.createElement("div", { style: { width: 34, height: 34, borderRadius: 8, flexShrink: 0, background: "color-mix(in oklab, var(--danger), transparent 86%)", display: "flex", alignItems: "center", justifyContent: "center", color: "var(--danger)" } }, /* @__PURE__ */ React.createElement(Icon, { name: "trash", size: 17, stroke: 2 })), /* @__PURE__ */ React.createElement("div", { style: { flex: 1 } }, /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--mono)", fontSize: 13.5, fontWeight: 600, color: "var(--danger)" } }, T.deleteNode), /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--ui)", fontSize: 12, color: "var(--faint)", marginTop: 1 } }, T.deleteSub)), /* @__PURE__ */ React.createElement(Btn, { tone: "danger", size: "sm" }, T.delete)))), qr && /* @__PURE__ */ React.createElement(DkQrModal, { T, value: qr.value, label: qr.label, onClose: () => setQr(null) }), avatarSheet && /* @__PURE__ */ React.createElement(DkAvatarSheet, { T, me, zh: t && t.lang === "zh", onSet: onSetAvatar, onClose: () => setAvatarSheet(false) }), editing && /* @__PURE__ */ React.createElement(DkEditModal, { T, me, onClose: () => setEditing(false), onSave: (name, description) => {
|
|
4088
|
+
), /* @__PURE__ */ React.createElement("div", { style: { flex: 1 } }, /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--mono)", fontSize: 13.5, fontWeight: 600, color: "var(--text)" } }, T && T.autoAcceptLabel || "Auto-accept friend requests"), /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--ui)", fontSize: 11.5, color: "var(--dim)", marginTop: 2 } }, T && T.autoAcceptSub || "Off: requests wait in the sidebar for your approval.")))), hostHasKeyBackup && /* @__PURE__ */ React.createElement(DkKeyBackup, { t: t || {} }), t && setTweak && /* @__PURE__ */ React.createElement(DkAlertSettings, { t, setTweak }), t && setTweak && /* @__PURE__ */ React.createElement(DkDisplaySettings, { t, setTweak }), /* @__PURE__ */ React.createElement(Card, { label: T.network }, /* @__PURE__ */ React.createElement(FieldRow, { T, label: T.virtualIp, value: me.ip, copy: true }), /* @__PURE__ */ React.createElement(FieldRow, { T, label: T.wireLabel, value: `${me.wire} \xB7 lossless`, mono: false }), /* @__PURE__ */ React.createElement(DkVersionRow, { T, me }), /* @__PURE__ */ React.createElement(DkUpdateCheck, { T })), /* @__PURE__ */ React.createElement(Card, { label: T.dangerZone }, /* @__PURE__ */ React.createElement("div", { style: { display: "flex", alignItems: "center", gap: 13, padding: "14px 16px" } }, /* @__PURE__ */ React.createElement("div", { style: { width: 34, height: 34, borderRadius: 8, flexShrink: 0, background: "color-mix(in oklab, var(--danger), transparent 86%)", display: "flex", alignItems: "center", justifyContent: "center", color: "var(--danger)" } }, /* @__PURE__ */ React.createElement(Icon, { name: "trash", size: 17, stroke: 2 })), /* @__PURE__ */ React.createElement("div", { style: { flex: 1 } }, /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--mono)", fontSize: 13.5, fontWeight: 600, color: "var(--danger)" } }, T.deleteNode), /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--ui)", fontSize: 12, color: "var(--faint)", marginTop: 1 } }, T.deleteSub)), /* @__PURE__ */ React.createElement(Btn, { tone: "danger", size: "sm" }, T.delete)))), Array.isArray(sections) && sections.length > 0 && /* @__PURE__ */ React.createElement("div", { style: { maxWidth: 760, margin: "0 auto", padding: "0 20px 40px", display: "flex", flexDirection: "column", gap: 16 } }, sections.map((sec) => sec && typeof sec.render === "function" ? /* @__PURE__ */ React.createElement(DkHostSection, { key: sec.id, sec, props: sectionProps, lang: t && t.lang }) : null)), qr && /* @__PURE__ */ React.createElement(DkQrModal, { T, value: qr.value, label: qr.label, onClose: () => setQr(null) }), avatarSheet && /* @__PURE__ */ React.createElement(DkAvatarSheet, { T, me, zh: t && t.lang === "zh", onSet: onSetAvatar, onClose: () => setAvatarSheet(false) }), editing && /* @__PURE__ */ React.createElement(DkEditModal, { T, me, onClose: () => setEditing(false), onSave: (name, description) => {
|
|
4078
4089
|
if (onEdit)
|
|
4079
4090
|
onEdit(name, description);
|
|
4080
4091
|
setEditing(false);
|
|
4081
4092
|
} }));
|
|
4082
4093
|
}
|
|
4094
|
+
var DkHostSection = class extends React.Component {
|
|
4095
|
+
constructor(props) {
|
|
4096
|
+
super(props);
|
|
4097
|
+
this.state = { err: null };
|
|
4098
|
+
}
|
|
4099
|
+
static getDerivedStateFromError(err) {
|
|
4100
|
+
return { err };
|
|
4101
|
+
}
|
|
4102
|
+
render() {
|
|
4103
|
+
var _a;
|
|
4104
|
+
const { sec, props, lang } = this.props;
|
|
4105
|
+
if (this.state.err) {
|
|
4106
|
+
return /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--mono)", fontSize: 12, color: "var(--faint)" } }, lang === "zh" ? "\u8FD9\u4E2A\u9644\u52A0\u677F\u5757\u51FA\u9519\u4E86\u3002" : "This host section failed to render.");
|
|
4107
|
+
}
|
|
4108
|
+
try {
|
|
4109
|
+
return (_a = sec.render(props)) != null ? _a : null;
|
|
4110
|
+
} catch (e) {
|
|
4111
|
+
return null;
|
|
4112
|
+
}
|
|
4113
|
+
}
|
|
4114
|
+
};
|
|
4083
4115
|
Object.assign(window, { DkShareSheet, ProfileTab, DkPunkAvatar, DkEnsAvatar, DkPublicProfile });
|
|
4084
4116
|
|
|
4085
4117
|
// src/ui.jsx
|
|
@@ -4296,6 +4328,84 @@ function Section({ label, count, trailing, style }) {
|
|
|
4296
4328
|
}
|
|
4297
4329
|
Object.assign(window, { useIsPhone, DkPhoneStyles, DkIdenticon, DkBot, DkAvatar, DkImgAvatar, StatusDot, Mono, shortKey, RouteTag, Tag, Unread, Btn, Section });
|
|
4298
4330
|
|
|
4331
|
+
// src/host-tabs.js
|
|
4332
|
+
var BUILTIN_TABS = ["chat", "people", "network", "apps", "profile"];
|
|
4333
|
+
var warned = /* @__PURE__ */ new Set();
|
|
4334
|
+
function warnOnce(what) {
|
|
4335
|
+
if (warned.has(what))
|
|
4336
|
+
return;
|
|
4337
|
+
warned.add(what);
|
|
4338
|
+
try {
|
|
4339
|
+
console.warn(`[beagle-ui] ignoring unknown host tab or app: ${what}`);
|
|
4340
|
+
} catch (e) {
|
|
4341
|
+
}
|
|
4342
|
+
}
|
|
4343
|
+
function pickText(value, lang, fallback = "") {
|
|
4344
|
+
if (typeof value === "string")
|
|
4345
|
+
return value;
|
|
4346
|
+
if (value && typeof value === "object")
|
|
4347
|
+
return value[lang] || value.en || value.zh || fallback;
|
|
4348
|
+
return fallback;
|
|
4349
|
+
}
|
|
4350
|
+
function resolveTabs(hostTabs2) {
|
|
4351
|
+
if (!Array.isArray(hostTabs2) || !hostTabs2.length) {
|
|
4352
|
+
return BUILTIN_TABS.map((id) => ({ id, kind: "builtin" }));
|
|
4353
|
+
}
|
|
4354
|
+
const out = [];
|
|
4355
|
+
const seen = /* @__PURE__ */ new Set();
|
|
4356
|
+
for (const entry of hostTabs2) {
|
|
4357
|
+
if (typeof entry === "string") {
|
|
4358
|
+
if (!BUILTIN_TABS.includes(entry)) {
|
|
4359
|
+
warnOnce(entry);
|
|
4360
|
+
continue;
|
|
4361
|
+
}
|
|
4362
|
+
if (seen.has(entry))
|
|
4363
|
+
continue;
|
|
4364
|
+
seen.add(entry);
|
|
4365
|
+
out.push({ id: entry, kind: "builtin" });
|
|
4366
|
+
continue;
|
|
4367
|
+
}
|
|
4368
|
+
if (entry && typeof entry === "object" && typeof entry.id === "string" && entry.id) {
|
|
4369
|
+
if (typeof entry.render !== "function") {
|
|
4370
|
+
warnOnce(`${entry.id} (no render function)`);
|
|
4371
|
+
continue;
|
|
4372
|
+
}
|
|
4373
|
+
if (BUILTIN_TABS.includes(entry.id)) {
|
|
4374
|
+
warnOnce(`${entry.id} (a built-in id cannot be redefined)`);
|
|
4375
|
+
continue;
|
|
4376
|
+
}
|
|
4377
|
+
if (seen.has(entry.id))
|
|
4378
|
+
continue;
|
|
4379
|
+
seen.add(entry.id);
|
|
4380
|
+
out.push({
|
|
4381
|
+
id: entry.id,
|
|
4382
|
+
kind: "host",
|
|
4383
|
+
label: entry.label,
|
|
4384
|
+
icon: entry.icon,
|
|
4385
|
+
render: entry.render,
|
|
4386
|
+
badge: typeof entry.badge === "function" ? entry.badge : void 0
|
|
4387
|
+
});
|
|
4388
|
+
continue;
|
|
4389
|
+
}
|
|
4390
|
+
warnOnce(String(entry && entry.id ? entry.id : entry));
|
|
4391
|
+
}
|
|
4392
|
+
return out.length ? out : BUILTIN_TABS.map((id) => ({ id, kind: "builtin" }));
|
|
4393
|
+
}
|
|
4394
|
+
function hasTab(tabs, id) {
|
|
4395
|
+
return (tabs != null ? tabs : []).some((t) => t.id === id);
|
|
4396
|
+
}
|
|
4397
|
+
function resolveApps(builtins, hideApps, hostApps2) {
|
|
4398
|
+
const hidden = new Set(Array.isArray(hideApps) ? hideApps : []);
|
|
4399
|
+
const host = (Array.isArray(hostApps2) ? hostApps2 : []).filter((a) => {
|
|
4400
|
+
if (a && typeof a.id === "string" && a.id && typeof a.open === "function")
|
|
4401
|
+
return true;
|
|
4402
|
+
warnOnce(`app ${a && a.id ? a.id : String(a)}`);
|
|
4403
|
+
return false;
|
|
4404
|
+
}).map((a) => ({ ...a, host: true }));
|
|
4405
|
+
const kept = (builtins != null ? builtins : []).filter((a) => !hidden.has(a.id));
|
|
4406
|
+
return host.concat(kept);
|
|
4407
|
+
}
|
|
4408
|
+
|
|
4299
4409
|
// src/apps.jsx
|
|
4300
4410
|
var APPS = [
|
|
4301
4411
|
{
|
|
@@ -4336,11 +4446,24 @@ function dkB64Url(obj) {
|
|
|
4336
4446
|
const b64 = btoa(unescape(encodeURIComponent(json)));
|
|
4337
4447
|
return b64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
4338
4448
|
}
|
|
4339
|
-
function AppsTab({ T, t }) {
|
|
4449
|
+
function AppsTab({ T, t, me, peers, phone, setTab }) {
|
|
4340
4450
|
const zh = t && t.lang === "zh";
|
|
4451
|
+
const apps = React.useMemo(
|
|
4452
|
+
() => resolveApps(APPS, hostHideApps, hostApps),
|
|
4453
|
+
[]
|
|
4454
|
+
);
|
|
4341
4455
|
const [busy, setBusy] = React.useState(null);
|
|
4342
4456
|
const [err, setErr] = React.useState(null);
|
|
4343
4457
|
const open = async (app) => {
|
|
4458
|
+
if (app.host) {
|
|
4459
|
+
setErr(null);
|
|
4460
|
+
try {
|
|
4461
|
+
app.open({ T, t, me, peers, phone, setTab });
|
|
4462
|
+
} catch (e) {
|
|
4463
|
+
setErr(String(e && e.message || e));
|
|
4464
|
+
}
|
|
4465
|
+
return;
|
|
4466
|
+
}
|
|
4344
4467
|
setBusy(app.id);
|
|
4345
4468
|
setErr(null);
|
|
4346
4469
|
const win = window.open("", "_blank");
|
|
@@ -4362,7 +4485,7 @@ function AppsTab({ T, t }) {
|
|
|
4362
4485
|
setBusy(null);
|
|
4363
4486
|
}
|
|
4364
4487
|
};
|
|
4365
|
-
return /* @__PURE__ */ React.createElement("div", { style: { flex: 1, overflow: "auto", background: "var(--bg)" } }, /* @__PURE__ */ React.createElement("div", { style: { maxWidth: 760, margin: "0 auto", padding: "24px 28px 60px", display: "flex", flexDirection: "column", gap: 16 } }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--mono)", fontSize: 11, fontWeight: 700, letterSpacing: 0.6, textTransform: "uppercase", color: "var(--faint)" } }, zh ? "\u5E94\u7528" : "Apps"), /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--ui)", fontSize: 12.5, color: "var(--faint)", marginTop: 6, lineHeight: 1.6 } }, zh ? "\u8FD9\u4E9B\u5E94\u7528\u63A5\u53D7 Beagle \u8EAB\u4EFD\u3002\u4ECE\u8FD9\u91CC\u6253\u5F00\u4E0D\u9700\u8981\u518D\u767B\u5F55\u4E00\u6B21 \u2014\u2014 \u4F1A\u5E26\u4E0A\u4E00\u4E2A\u4E24\u5206\u949F\u5185\u6709\u6548\u7684\u7B7E\u540D\u3002" : "These accept a Beagle identity. Opening one from here does not ask you to sign in again \u2014 it carries a signature that is good for two minutes.")), err && /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--mono)", fontSize: 11.5, color: "#f85149" } }, err),
|
|
4488
|
+
return /* @__PURE__ */ React.createElement("div", { style: { flex: 1, overflow: "auto", background: "var(--bg)" } }, /* @__PURE__ */ React.createElement("div", { style: { maxWidth: 760, margin: "0 auto", padding: "24px 28px 60px", display: "flex", flexDirection: "column", gap: 16 } }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--mono)", fontSize: 11, fontWeight: 700, letterSpacing: 0.6, textTransform: "uppercase", color: "var(--faint)" } }, zh ? "\u5E94\u7528" : "Apps"), /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--ui)", fontSize: 12.5, color: "var(--faint)", marginTop: 6, lineHeight: 1.6 } }, zh ? "\u8FD9\u4E9B\u5E94\u7528\u63A5\u53D7 Beagle \u8EAB\u4EFD\u3002\u4ECE\u8FD9\u91CC\u6253\u5F00\u4E0D\u9700\u8981\u518D\u767B\u5F55\u4E00\u6B21 \u2014\u2014 \u4F1A\u5E26\u4E0A\u4E00\u4E2A\u4E24\u5206\u949F\u5185\u6709\u6548\u7684\u7B7E\u540D\u3002" : "These accept a Beagle identity. Opening one from here does not ask you to sign in again \u2014 it carries a signature that is good for two minutes.")), err && /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--mono)", fontSize: 11.5, color: "#f85149" } }, err), apps.map((app) => /* @__PURE__ */ React.createElement("div", { key: app.id, style: {
|
|
4366
4489
|
display: "flex",
|
|
4367
4490
|
alignItems: "center",
|
|
4368
4491
|
gap: 14,
|
|
@@ -4379,7 +4502,7 @@ function AppsTab({ T, t }) {
|
|
|
4379
4502
|
display: "flex",
|
|
4380
4503
|
alignItems: "center",
|
|
4381
4504
|
justifyContent: "center"
|
|
4382
|
-
} }, /* @__PURE__ */ React.createElement(Icon, { name: app.icon, size: 19, color: "var(--accent)", stroke: 1.8 })), /* @__PURE__ */ React.createElement("div", { style: { flex: 1, minWidth: 0 } }, /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--ui)", fontSize: 14, fontWeight: 600, color: "var(--text)" } }, app.name), /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--ui)", fontSize: 12.5, color: "var(--faint)", marginTop: 2 } },
|
|
4505
|
+
} }, /* @__PURE__ */ React.createElement(Icon, { name: app.icon, size: 19, color: "var(--accent)", stroke: 1.8 })), /* @__PURE__ */ React.createElement("div", { style: { flex: 1, minWidth: 0 } }, /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--ui)", fontSize: 14, fontWeight: 600, color: "var(--text)" } }, pickText(app.name, t && t.lang, app.id)), /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--ui)", fontSize: 12.5, color: "var(--faint)", marginTop: 2 } }, pickText(app.blurb, t && t.lang, "")), /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--mono)", fontSize: 11, color: "var(--dim)", marginTop: 3 } }, app.host ? zh ? "\u672C\u673A\u5E94\u7528" : "runs in this app" : String(app.origin || "").replace(/^https?:\/\//, ""))), /* @__PURE__ */ React.createElement(Btn, { tone: "accent", size: "sm", onClick: busy ? void 0 : () => open(app) }, busy === app.id ? zh ? "\u6253\u5F00\u4E2D\u2026" : "opening\u2026" : zh ? "\u6253\u5F00" : "Open")))));
|
|
4383
4506
|
}
|
|
4384
4507
|
|
|
4385
4508
|
// src/rtc-signaling.jsx
|
|
@@ -6384,7 +6507,7 @@ var STR = {
|
|
|
6384
6507
|
meetingDesc: "\u8DE8\u670D\u52A1\u5668\u521B\u5EFA\u97F3\u89C6\u9891\u623F\u95F4\uFF0C\u901A\u8FC7\u865A\u62DF IP \u9080\u8BF7\u597D\u53CB\u3002\u7FA4\u7EC4\u901A\u8BDD\u3001\u5C4F\u5E55\u5171\u4EAB\u4E0E\u5171\u4EAB\u51FA\u53E3\u8DEF\u7531\u5C06\u5728\u4E0B\u4E2A\u7248\u672C\u4E0A\u7EBF\u3002"
|
|
6385
6508
|
}
|
|
6386
6509
|
};
|
|
6387
|
-
function RailBtn({ icon, label, active, soon, onClick }) {
|
|
6510
|
+
function RailBtn({ icon, label, active, soon, onClick, svgPath }) {
|
|
6388
6511
|
return /* @__PURE__ */ React.createElement("button", { onClick, title: label, style: {
|
|
6389
6512
|
width: 52,
|
|
6390
6513
|
height: 52,
|
|
@@ -6399,9 +6522,9 @@ function RailBtn({ icon, label, active, soon, onClick }) {
|
|
|
6399
6522
|
alignItems: "center",
|
|
6400
6523
|
justifyContent: "center",
|
|
6401
6524
|
gap: 3
|
|
6402
|
-
} }, /* @__PURE__ */ React.createElement(Icon, { name: icon, size: 20, stroke: active ? 2.1 : 1.8, color: active ? "var(--accent)" : "var(--dim)" }), /* @__PURE__ */ React.createElement("span", { style: { fontSize: 9, fontWeight: 600, letterSpacing: 0.2, color: active ? "var(--accent)" : "var(--faint)" } }, label), soon && /* @__PURE__ */ React.createElement("span", { style: { position: "absolute", top: 5, right: 6, width: 6, height: 6, borderRadius: 999, background: "var(--warn)" } }));
|
|
6525
|
+
} }, /* @__PURE__ */ React.createElement(Icon, { name: icon, svgPath, size: 20, stroke: active ? 2.1 : 1.8, color: active ? "var(--accent)" : "var(--dim)" }), /* @__PURE__ */ React.createElement("span", { style: { fontSize: 9, fontWeight: 600, letterSpacing: 0.2, color: active ? "var(--accent)" : "var(--faint)" } }, label), soon && /* @__PURE__ */ React.createElement("span", { style: { position: "absolute", top: 5, right: 6, width: 6, height: 6, borderRadius: 999, background: "var(--warn)" } }));
|
|
6403
6526
|
}
|
|
6404
|
-
function TabBarBtn({ icon, label, active, badge, onClick }) {
|
|
6527
|
+
function TabBarBtn({ icon, label, active, badge, onClick, svgPath }) {
|
|
6405
6528
|
return /* @__PURE__ */ React.createElement("button", { onClick, style: {
|
|
6406
6529
|
flex: 1,
|
|
6407
6530
|
minWidth: 0,
|
|
@@ -6416,9 +6539,36 @@ function TabBarBtn({ icon, label, active, badge, onClick }) {
|
|
|
6416
6539
|
justifyContent: "center",
|
|
6417
6540
|
gap: 3,
|
|
6418
6541
|
fontFamily: "var(--mono)"
|
|
6419
|
-
} }, /* @__PURE__ */ React.createElement(Icon, { name: icon, size: 22, stroke: active ? 2.1 : 1.8, color: active ? "var(--accent)" : "var(--dim)" }), /* @__PURE__ */ React.createElement("span", { style: { fontSize: 10, fontWeight: 600, color: active ? "var(--accent)" : "var(--faint)", whiteSpace: "nowrap" } }, label), badge ? /* @__PURE__ */ React.createElement("span", { style: { position: "absolute", top: 4, left: "50%", marginLeft: 6 } }, /* @__PURE__ */ React.createElement(Unread, { n: badge })) : null);
|
|
6542
|
+
} }, /* @__PURE__ */ React.createElement(Icon, { name: icon, svgPath, size: 22, stroke: active ? 2.1 : 1.8, color: active ? "var(--accent)" : "var(--dim)" }), /* @__PURE__ */ React.createElement("span", { style: { fontSize: 10, fontWeight: 600, color: active ? "var(--accent)" : "var(--faint)", whiteSpace: "nowrap" } }, label), badge ? /* @__PURE__ */ React.createElement("span", { style: { position: "absolute", top: 4, left: "50%", marginLeft: 6 } }, /* @__PURE__ */ React.createElement(Unread, { n: badge })) : null);
|
|
6420
6543
|
}
|
|
6421
6544
|
var DK_PEOPLE_TABS = ["here", "recommended", "registered"];
|
|
6545
|
+
var HostTabPane = class extends React.Component {
|
|
6546
|
+
constructor(props) {
|
|
6547
|
+
super(props);
|
|
6548
|
+
this.state = { err: null };
|
|
6549
|
+
}
|
|
6550
|
+
static getDerivedStateFromError(err) {
|
|
6551
|
+
return { err };
|
|
6552
|
+
}
|
|
6553
|
+
componentDidCatch(err) {
|
|
6554
|
+
try {
|
|
6555
|
+
console.error("[beagle-ui] host tab failed", err);
|
|
6556
|
+
} catch (e) {
|
|
6557
|
+
}
|
|
6558
|
+
}
|
|
6559
|
+
render() {
|
|
6560
|
+
var _a;
|
|
6561
|
+
const { tab, props, lang } = this.props;
|
|
6562
|
+
if (this.state.err) {
|
|
6563
|
+
return /* @__PURE__ */ React.createElement("div", { style: { flex: 1, display: "flex", alignItems: "center", justifyContent: "center", padding: 24, textAlign: "center" } }, /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--mono)", fontSize: 12.5, color: "var(--faint)", maxWidth: 420 } }, lang === "zh" ? `"${pickText(tab.label, lang, tab.id)}" \u8FD9\u4E2A\u6807\u7B7E\u9875\u51FA\u9519\u4E86\u3002\u5176\u5B83\u6807\u7B7E\u9875\u4E0D\u53D7\u5F71\u54CD\u3002` : `The "${pickText(tab.label, lang, tab.id)}" tab failed to render. The rest of the app is unaffected.`));
|
|
6564
|
+
}
|
|
6565
|
+
try {
|
|
6566
|
+
return (_a = tab.render(props)) != null ? _a : null;
|
|
6567
|
+
} catch (e) {
|
|
6568
|
+
return null;
|
|
6569
|
+
}
|
|
6570
|
+
}
|
|
6571
|
+
};
|
|
6422
6572
|
function Brand({ T, children, style }) {
|
|
6423
6573
|
if (!hostBrandHref)
|
|
6424
6574
|
return /* @__PURE__ */ React.createElement("span", { style }, children);
|
|
@@ -6535,7 +6685,17 @@ function DkUpdateModal({ T, info, onClose }) {
|
|
|
6535
6685
|
}
|
|
6536
6686
|
function DkApp() {
|
|
6537
6687
|
const [t, setTweak] = useTweaks({ ...DK_DEFAULTS, lang: dkDetectLang() });
|
|
6538
|
-
const
|
|
6688
|
+
const tabs = React.useMemo(() => resolveTabs(hostTabs), []);
|
|
6689
|
+
const showPeople = hasTab(tabs, "people");
|
|
6690
|
+
const showNetwork = hasTab(tabs, "network");
|
|
6691
|
+
const showProfile = hasTab(tabs, "profile");
|
|
6692
|
+
const firstTab = tabs[0] ? tabs[0].id === "people" ? "here" : tabs[0].id : "chat";
|
|
6693
|
+
const [tab, setTab] = React.useState(() => {
|
|
6694
|
+
const want = t.startTab || "chat";
|
|
6695
|
+
if (want === "chat" && hasTab(tabs, "chat"))
|
|
6696
|
+
return "chat";
|
|
6697
|
+
return hasTab(tabs, want) || DK_PEOPLE_TABS.includes(want) && showPeople ? want : firstTab;
|
|
6698
|
+
});
|
|
6539
6699
|
const [activeId, setActiveId] = React.useState(null);
|
|
6540
6700
|
const data = useDaemonData();
|
|
6541
6701
|
const me = data.me;
|
|
@@ -6570,11 +6730,13 @@ function DkApp() {
|
|
|
6570
6730
|
});
|
|
6571
6731
|
}, []);
|
|
6572
6732
|
React.useEffect(() => {
|
|
6733
|
+
if (!showNetwork)
|
|
6734
|
+
return void 0;
|
|
6573
6735
|
refreshBackend();
|
|
6574
6736
|
const ms = backend && backend.state === "releasing" ? 1500 : 8e3;
|
|
6575
6737
|
const t2 = setInterval(refreshBackend, ms);
|
|
6576
6738
|
return () => clearInterval(t2);
|
|
6577
|
-
}, [refreshBackend, backend && backend.state]);
|
|
6739
|
+
}, [refreshBackend, backend && backend.state, showNetwork]);
|
|
6578
6740
|
const armLan = React.useCallback(async () => {
|
|
6579
6741
|
await dkPost("/api/lan-arm", {});
|
|
6580
6742
|
refreshBackend();
|
|
@@ -6843,29 +7005,61 @@ function DkApp() {
|
|
|
6843
7005
|
setTab("chat");
|
|
6844
7006
|
openConversation(id);
|
|
6845
7007
|
};
|
|
6846
|
-
const onOpenNet = () => setTab("network");
|
|
6847
|
-
const
|
|
6848
|
-
{ id: "chat", icon: "message", label: T.chat },
|
|
6849
|
-
|
|
6850
|
-
|
|
6851
|
-
|
|
6852
|
-
|
|
6853
|
-
|
|
6854
|
-
|
|
7008
|
+
const onOpenNet = showNetwork ? () => setTab("network") : null;
|
|
7009
|
+
const RAIL_FOR = {
|
|
7010
|
+
chat: [{ id: "chat", icon: "message", label: T.chat }],
|
|
7011
|
+
people: [
|
|
7012
|
+
{ id: "here", icon: "users", label: T.here },
|
|
7013
|
+
{ id: "recommended", icon: "sparkles", label: T.recommended },
|
|
7014
|
+
{ id: "registered", icon: "at", label: T.registered }
|
|
7015
|
+
],
|
|
7016
|
+
network: [{ id: "network", icon: "network", label: T.network }],
|
|
7017
|
+
apps: [{ id: "apps", icon: "grid", label: T.apps }],
|
|
7018
|
+
profile: []
|
|
7019
|
+
};
|
|
7020
|
+
const nav = tabs.flatMap((x) => x.kind === "builtin" ? RAIL_FOR[x.id] || [] : [{ id: x.id, icon: x.icon, label: pickText(x.label, t.lang, x.id) }]);
|
|
6855
7021
|
const peopleTab = DK_PEOPLE_TABS.includes(tab);
|
|
6856
7022
|
const lastPeople = React.useRef("here");
|
|
6857
7023
|
if (peopleTab)
|
|
6858
7024
|
lastPeople.current = tab;
|
|
6859
7025
|
const unreadTotal = (peers || []).reduce((n, p) => n + (Number(p.unread) || 0), 0) + (requests || []).length;
|
|
6860
|
-
const
|
|
6861
|
-
|
|
6862
|
-
|
|
6863
|
-
|
|
6864
|
-
|
|
6865
|
-
|
|
6866
|
-
|
|
7026
|
+
const NAV_FOR = {
|
|
7027
|
+
chat: { icon: "message", label: T.chat, active: tab === "chat", badge: unreadTotal, go: () => setTab("chat") },
|
|
7028
|
+
people: { icon: "users", label: T.people, active: peopleTab, go: () => setTab(lastPeople.current) },
|
|
7029
|
+
network: { icon: "network", label: T.network, active: tab === "network", go: () => setTab("network") },
|
|
7030
|
+
apps: { icon: "grid", label: T.apps, active: tab === "apps", go: () => setTab("apps") },
|
|
7031
|
+
profile: { icon: "userRound", label: T.profile, active: tab === "profile", go: () => setTab("profile") }
|
|
7032
|
+
};
|
|
7033
|
+
const phoneNav = tabs.map((x) => x.kind === "builtin" ? { id: x.id, ...NAV_FOR[x.id] } : {
|
|
7034
|
+
id: x.id,
|
|
7035
|
+
icon: typeof x.icon === "string" ? x.icon : void 0,
|
|
7036
|
+
svgPath: x.icon && typeof x.icon === "object" ? x.icon.svgPath : void 0,
|
|
7037
|
+
label: pickText(x.label, t.lang, x.id),
|
|
7038
|
+
active: tab === x.id,
|
|
7039
|
+
// A host badge is called on every render, like the unread count beside
|
|
7040
|
+
// it; a throwing one must not take the tab bar down with it.
|
|
7041
|
+
badge: (() => {
|
|
7042
|
+
try {
|
|
7043
|
+
return x.badge ? x.badge() : 0;
|
|
7044
|
+
} catch (e) {
|
|
7045
|
+
return 0;
|
|
7046
|
+
}
|
|
7047
|
+
})(),
|
|
7048
|
+
go: () => setTab(x.id)
|
|
7049
|
+
});
|
|
6867
7050
|
const inConversation = phone && tab === "chat" && !!activeId && (peers || []).some((p) => p.id === activeId);
|
|
6868
|
-
return /* @__PURE__ */ React.createElement("div", { style: { ...vars, "--row-pad": rowPad, position: "fixed", inset: 0, display: "flex", flexDirection: phone ? "column" : "row", background: "var(--bg)", color: "var(--text)", fontFamily: "var(--ui)" } }, /* @__PURE__ */ React.createElement(DkPhoneStyles, null), !phone && /* @__PURE__ */ React.createElement("div", { style: { width: 68, flexShrink: 0, borderRight: "1px solid var(--line)", background: "var(--rail)", display: "flex", flexDirection: "column", alignItems: "center", padding: "14px 0", gap: 8 } }, /* @__PURE__ */ React.createElement(Brand, { T, style: { width: 38, height: 38, borderRadius: 10, background: "var(--accent)", display: "flex", alignItems: "center", justifyContent: "center", marginBottom: 8, flexShrink: 0 } }, /* @__PURE__ */ React.createElement(Icon, { name: "terminal", size: 20, color: "#fff", stroke: 2.2 })), nav.map((n) => /* @__PURE__ */ React.createElement(
|
|
7051
|
+
return /* @__PURE__ */ React.createElement("div", { style: { ...vars, "--row-pad": rowPad, position: "fixed", inset: 0, display: "flex", flexDirection: phone ? "column" : "row", background: "var(--bg)", color: "var(--text)", fontFamily: "var(--ui)" } }, /* @__PURE__ */ React.createElement(DkPhoneStyles, null), !phone && /* @__PURE__ */ React.createElement("div", { style: { width: 68, flexShrink: 0, borderRight: "1px solid var(--line)", background: "var(--rail)", display: "flex", flexDirection: "column", alignItems: "center", padding: "14px 0", gap: 8 } }, /* @__PURE__ */ React.createElement(Brand, { T, style: { width: 38, height: 38, borderRadius: 10, background: "var(--accent)", display: "flex", alignItems: "center", justifyContent: "center", marginBottom: 8, flexShrink: 0 } }, /* @__PURE__ */ React.createElement(Icon, { name: "terminal", size: 20, color: "#fff", stroke: 2.2 })), nav.map((n) => /* @__PURE__ */ React.createElement(
|
|
7052
|
+
RailBtn,
|
|
7053
|
+
{
|
|
7054
|
+
key: n.id,
|
|
7055
|
+
icon: typeof n.icon === "string" ? n.icon : void 0,
|
|
7056
|
+
svgPath: n.icon && typeof n.icon === "object" ? n.icon.svgPath : void 0,
|
|
7057
|
+
label: n.label,
|
|
7058
|
+
active: tab === n.id,
|
|
7059
|
+
soon: n.soon,
|
|
7060
|
+
onClick: () => setTab(n.id)
|
|
7061
|
+
}
|
|
7062
|
+
)), /* @__PURE__ */ React.createElement("div", { style: { flex: 1 } }), showProfile && /* @__PURE__ */ React.createElement("button", { onClick: () => setTab("profile"), title: T.profile, style: {
|
|
6869
7063
|
padding: 4,
|
|
6870
7064
|
borderRadius: 12,
|
|
6871
7065
|
cursor: "pointer",
|
|
@@ -6886,10 +7080,22 @@ function DkApp() {
|
|
|
6886
7080
|
fontWeight: 600,
|
|
6887
7081
|
background: tab === n.id ? "var(--accent)" : "transparent",
|
|
6888
7082
|
color: tab === n.id ? "#fff" : "var(--dim)"
|
|
6889
|
-
} }, /* @__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: 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 }),
|
|
6890
|
-
|
|
6891
|
-
|
|
6892
|
-
|
|
7083
|
+
} }, /* @__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: 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(
|
|
7084
|
+
ProfileTab,
|
|
7085
|
+
{
|
|
7086
|
+
T,
|
|
7087
|
+
me,
|
|
7088
|
+
onEdit,
|
|
7089
|
+
t,
|
|
7090
|
+
setTweak,
|
|
7091
|
+
onSetAvatar: (p) => dkApi.setProfileFull(p).then((r) => {
|
|
7092
|
+
data.refresh();
|
|
7093
|
+
return r;
|
|
7094
|
+
}),
|
|
7095
|
+
sections: hostProfileSections,
|
|
7096
|
+
sectionProps: { T, t, me, peers, phone, setTab }
|
|
7097
|
+
}
|
|
7098
|
+
)), 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, svgPath: n.svgPath, label: n.label, active: n.active, badge: n.badge, onClick: n.go }))), data.locked && /* @__PURE__ */ React.createElement(
|
|
6893
7099
|
DkLockedOut,
|
|
6894
7100
|
{
|
|
6895
7101
|
compact: true,
|
package/package.json
CHANGED