dsh-pocket 2.6.1 → 2.6.3
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/README.en.md +1 -1
- package/README.md +2 -2
- package/client/api.js +0 -3
- package/client/client.js +194 -320
- package/client/index.jsx +0 -125
- package/client/mobile/mobile-apply.tsx +1 -0
- package/client/pocket-locales.js +0 -38
- package/lib/index.js +1 -8
- package/lib/proxy.mjs +2 -2
- package/lib/settings.mjs +0 -75
- package/lib/tunnel.mjs +11 -5
- package/lib/web-rpc.js +1 -20
- package/package.json +1 -1
package/client/client.js
CHANGED
|
@@ -37,7 +37,7 @@ __export(index_exports, {
|
|
|
37
37
|
redactStatus: () => redactStatus
|
|
38
38
|
});
|
|
39
39
|
module.exports = __toCommonJS(index_exports);
|
|
40
|
-
var
|
|
40
|
+
var import_react3 = require("react");
|
|
41
41
|
|
|
42
42
|
// client/api.js
|
|
43
43
|
var POCKET_RPC_CHANNEL = "/dsh-pocket";
|
|
@@ -54,10 +54,7 @@ var POCKET_ENDPOINTS = Object.freeze({
|
|
|
54
54
|
lanSetOverride: "lan.setOverride",
|
|
55
55
|
lanSetEnabled: "lan.setEnabled",
|
|
56
56
|
pinSetCustom: "pin.setCustom",
|
|
57
|
-
pocketReset: "pocket.reset"
|
|
58
|
-
tempPinCreate: "tempPin.create",
|
|
59
|
-
tempPinList: "tempPin.list",
|
|
60
|
-
tempPinRevoke: "tempPin.revoke"
|
|
57
|
+
pocketReset: "pocket.reset"
|
|
61
58
|
});
|
|
62
59
|
function compareVersions(a, b) {
|
|
63
60
|
const pa = String(a).replace(/^[vV]/, "").split(".");
|
|
@@ -340,6 +337,59 @@ function MobileDrawerFooter({ useSessions, downloadSessionLog, toggleSidebar, t
|
|
|
340
337
|
));
|
|
341
338
|
}
|
|
342
339
|
|
|
340
|
+
// client/mobile/MobileComposerFullscreen.tsx
|
|
341
|
+
var import_react2 = require("react");
|
|
342
|
+
var FULLSCREEN_ATTR = "data-dsh-pocket-composer-fullscreen";
|
|
343
|
+
function isFullscreen() {
|
|
344
|
+
return typeof document !== "undefined" && document.body?.getAttribute(FULLSCREEN_ATTR) === "1";
|
|
345
|
+
}
|
|
346
|
+
function setFullscreen(on) {
|
|
347
|
+
if (typeof document === "undefined") return;
|
|
348
|
+
if (on) document.body.setAttribute(FULLSCREEN_ATTR, "1");
|
|
349
|
+
else document.body.removeAttribute(FULLSCREEN_ATTR);
|
|
350
|
+
}
|
|
351
|
+
function MobileComposerFullscreen() {
|
|
352
|
+
const [on, setOn] = (0, import_react2.useState)(isFullscreen);
|
|
353
|
+
(0, import_react2.useEffect)(() => {
|
|
354
|
+
const update = () => setOn(isFullscreen());
|
|
355
|
+
const observer = new MutationObserver(update);
|
|
356
|
+
observer.observe(document.body, { attributes: true, attributeFilter: [FULLSCREEN_ATTR] });
|
|
357
|
+
return () => observer.disconnect();
|
|
358
|
+
}, []);
|
|
359
|
+
return (0, import_react2.createElement)("button", {
|
|
360
|
+
type: "button",
|
|
361
|
+
"aria-label": on ? "\u6536\u8D77\u8F93\u5165" : "\u653E\u5927\u8F93\u5165",
|
|
362
|
+
"aria-pressed": on,
|
|
363
|
+
title: on ? "\u6536\u8D77\u8F93\u5165" : "\u653E\u5927\u8F93\u5165",
|
|
364
|
+
"data-mobile-nav": "composer-fullscreen",
|
|
365
|
+
"data-mobile-nav-keep": "1",
|
|
366
|
+
// 自己的按钮不该被 #23 的 slot 通用隐藏规则误伤
|
|
367
|
+
onClick: () => {
|
|
368
|
+
const next = !isFullscreen();
|
|
369
|
+
setFullscreen(next);
|
|
370
|
+
setOn(next);
|
|
371
|
+
},
|
|
372
|
+
style: {
|
|
373
|
+
appearance: "none",
|
|
374
|
+
WebkitAppearance: "none",
|
|
375
|
+
border: "none",
|
|
376
|
+
background: "transparent",
|
|
377
|
+
color: "inherit",
|
|
378
|
+
cursor: "pointer",
|
|
379
|
+
padding: "0 8px",
|
|
380
|
+
height: 32,
|
|
381
|
+
minWidth: 32,
|
|
382
|
+
borderRadius: 6,
|
|
383
|
+
display: "inline-flex",
|
|
384
|
+
alignItems: "center",
|
|
385
|
+
justifyContent: "center",
|
|
386
|
+
font: "inherit",
|
|
387
|
+
fontSize: 16,
|
|
388
|
+
lineHeight: 1
|
|
389
|
+
}
|
|
390
|
+
}, on ? "\u2921" : "\u2922");
|
|
391
|
+
}
|
|
392
|
+
|
|
343
393
|
// client/mobile/mobile.css.ts
|
|
344
394
|
var MOBILE_CSS = `
|
|
345
395
|
/* ---------- base control styles (rendered at any width, hidden where unused) ---------- */
|
|
@@ -1606,26 +1656,7 @@ var zh2 = {
|
|
|
1606
1656
|
"slowHint": " \u2014 \u6709\u70B9\u4E45\uFF1F\u68C0\u67E5\u662F\u5426\u5F00\u7740\u4EE3\u7406/VPN\uFF08Clash TUN \u7B49\uFF09",
|
|
1607
1657
|
"error": "\u274C \u5F00\u542F\u5931\u8D25\uFF1A{detail}\uFF08\u53EF\u91CD\u8BD5\uFF1B\u82E5\u662F\u4EE3\u7406/VPN \u95EE\u9898\u89C1 README \u6392\u969C\uFF09",
|
|
1608
1658
|
"unknownError": "\u672A\u77E5\u9519\u8BEF",
|
|
1609
|
-
"feedback": "\u6709\u95EE\u9898\uFF1F\u6B22\u8FCE\u5230 GitHub Issues \u53CD\u9988 \u{1F64F}"
|
|
1610
|
-
// 临时 PIN(issue #69)
|
|
1611
|
-
"tempPinTitle": "\u4E34\u65F6\u8BBF\u95EE PIN\uFF08\u5E26\u8D85\u65F6\uFF09",
|
|
1612
|
-
"tempPinSubtitle": "\u7ED9\u8BBF\u5BA2\u5F00\u4E00\u4E2A\u6709\u5BFF\u547D\u7684 8 \u4F4D PIN\uFF0C\u8FC7\u671F\u81EA\u52A8\u4F5C\u5E9F\uFF1B\u4E0E\u4E3B PIN \u5171\u7528\u901F\u7387\u9650\u5236\u3002",
|
|
1613
|
-
"tempPinKindPublic": "\u516C\u7F51",
|
|
1614
|
-
"tempPinKindLan": "\u5C40\u57DF\u7F51",
|
|
1615
|
-
"tempPinDuration": "\u6709\u6548\u65F6\u957F",
|
|
1616
|
-
"tempPinDuration1h": "1 \u5C0F\u65F6",
|
|
1617
|
-
"tempPinDuration24h": "24 \u5C0F\u65F6",
|
|
1618
|
-
"tempPinDuration7d": "7 \u5929",
|
|
1619
|
-
"tempPinLabel": "\u5907\u6CE8\uFF08\u53EF\u9009\uFF0C\u7ED9\u8C01\u7528\uFF09",
|
|
1620
|
-
"tempPinLabelPh": "\u670B\u53CB\u5C0F\u738B",
|
|
1621
|
-
"tempPinCreate": "\u751F\u6210",
|
|
1622
|
-
"tempPinCreated": "\u5DF2\u751F\u6210\uFF08\u4EC5\u663E\u793A\u4E00\u6B21\uFF09",
|
|
1623
|
-
"tempPinCopied": "\u5DF2\u590D\u5236",
|
|
1624
|
-
"tempPinCopy": "\u590D\u5236",
|
|
1625
|
-
"tempPinEmpty": "\u6682\u65E0\u4E34\u65F6 PIN",
|
|
1626
|
-
"tempPinExpiresIn": "\u8FC7\u671F",
|
|
1627
|
-
"tempPinRevoke": "\u64A4\u9500",
|
|
1628
|
-
"tempPinRevoked": "\u5DF2\u64A4\u9500"
|
|
1659
|
+
"feedback": "\u6709\u95EE\u9898\uFF1F\u6B22\u8FCE\u5230 GitHub Issues \u53CD\u9988 \u{1F64F}"
|
|
1629
1660
|
};
|
|
1630
1661
|
var en2 = {
|
|
1631
1662
|
"section": "Phone access",
|
|
@@ -1720,26 +1751,7 @@ var en2 = {
|
|
|
1720
1751
|
"slowHint": " \u2014 taking long? Check for a proxy/VPN (e.g., Clash TUN)",
|
|
1721
1752
|
"error": "\u274C Failed to enable: {detail} (you can retry; for proxy/VPN issues see the README)",
|
|
1722
1753
|
"unknownError": "unknown error",
|
|
1723
|
-
"feedback": "\u{1F64F} Questions? Open an issue on GitHub"
|
|
1724
|
-
// Temp PIN (issue #69)
|
|
1725
|
-
"tempPinTitle": "Temporary access PINs (auto-expire)",
|
|
1726
|
-
"tempPinSubtitle": "Issue a time-limited 8-char PIN to a guest; expires automatically. Shares the main PIN rate limit.",
|
|
1727
|
-
"tempPinKindPublic": "Public",
|
|
1728
|
-
"tempPinKindLan": "LAN",
|
|
1729
|
-
"tempPinDuration": "Valid for",
|
|
1730
|
-
"tempPinDuration1h": "1 hour",
|
|
1731
|
-
"tempPinDuration24h": "24 hours",
|
|
1732
|
-
"tempPinDuration7d": "7 days",
|
|
1733
|
-
"tempPinLabel": "Note (optional, who is this for)",
|
|
1734
|
-
"tempPinLabelPh": "Friend Alice",
|
|
1735
|
-
"tempPinCreate": "Create",
|
|
1736
|
-
"tempPinCreated": "Created (shown once)",
|
|
1737
|
-
"tempPinCopied": "Copied",
|
|
1738
|
-
"tempPinCopy": "Copy",
|
|
1739
|
-
"tempPinEmpty": "No temporary PINs yet",
|
|
1740
|
-
"tempPinExpiresIn": "expires",
|
|
1741
|
-
"tempPinRevoke": "Revoke",
|
|
1742
|
-
"tempPinRevoked": "Revoked"
|
|
1754
|
+
"feedback": "\u{1F64F} Questions? Open an issue on GitHub"
|
|
1743
1755
|
};
|
|
1744
1756
|
|
|
1745
1757
|
// client/index.jsx
|
|
@@ -1767,15 +1779,15 @@ var styles = {
|
|
|
1767
1779
|
warn: { color: "var(--dsw-alias-state-warn-primary,#b45309)", fontSize: 12, lineHeight: 1.5 }
|
|
1768
1780
|
};
|
|
1769
1781
|
function PocketSettingsTab({ rpcCall, t }) {
|
|
1770
|
-
const [status, setStatus] = (0,
|
|
1771
|
-
const [busy, setBusy] = (0,
|
|
1772
|
-
const [error, setError] = (0,
|
|
1773
|
-
const [tunnelState, setTunnelState] = (0,
|
|
1774
|
-
const [restartNotice, setRestartNotice] = (0,
|
|
1775
|
-
const [updateInfo, setUpdateInfo] = (0,
|
|
1776
|
-
const [isDesktop, setIsDesktop] = (0,
|
|
1777
|
-
const [now, setNow] = (0,
|
|
1778
|
-
(0,
|
|
1782
|
+
const [status, setStatus] = (0, import_react3.useState)(null);
|
|
1783
|
+
const [busy, setBusy] = (0, import_react3.useState)(false);
|
|
1784
|
+
const [error, setError] = (0, import_react3.useState)(null);
|
|
1785
|
+
const [tunnelState, setTunnelState] = (0, import_react3.useState)(null);
|
|
1786
|
+
const [restartNotice, setRestartNotice] = (0, import_react3.useState)(false);
|
|
1787
|
+
const [updateInfo, setUpdateInfo] = (0, import_react3.useState)(null);
|
|
1788
|
+
const [isDesktop, setIsDesktop] = (0, import_react3.useState)(false);
|
|
1789
|
+
const [now, setNow] = (0, import_react3.useState)(Date.now());
|
|
1790
|
+
(0, import_react3.useEffect)(() => {
|
|
1779
1791
|
const t2 = setInterval(() => setNow(Date.now()), 1e3);
|
|
1780
1792
|
return () => clearInterval(t2);
|
|
1781
1793
|
}, []);
|
|
@@ -1807,18 +1819,18 @@ function PocketSettingsTab({ rpcCall, t }) {
|
|
|
1807
1819
|
} catch {
|
|
1808
1820
|
}
|
|
1809
1821
|
};
|
|
1810
|
-
(0,
|
|
1822
|
+
(0, import_react3.useEffect)(() => {
|
|
1811
1823
|
load();
|
|
1812
1824
|
const t2 = setInterval(load, 3e3);
|
|
1813
1825
|
return () => clearInterval(t2);
|
|
1814
1826
|
}, []);
|
|
1815
|
-
(0,
|
|
1827
|
+
(0, import_react3.useEffect)(() => {
|
|
1816
1828
|
try {
|
|
1817
1829
|
sessionStorage.removeItem("dshp-auto-reloaded");
|
|
1818
1830
|
} catch {
|
|
1819
1831
|
}
|
|
1820
1832
|
}, []);
|
|
1821
|
-
(0,
|
|
1833
|
+
(0, import_react3.useEffect)(() => {
|
|
1822
1834
|
if (isDesktop) return;
|
|
1823
1835
|
let alive = true;
|
|
1824
1836
|
const check = async () => {
|
|
@@ -1874,75 +1886,8 @@ function PocketSettingsTab({ rpcCall, t }) {
|
|
|
1874
1886
|
setUpdateInfo((u) => ({ ...u, updating: false, result: "fail", output: err.message }));
|
|
1875
1887
|
}
|
|
1876
1888
|
};
|
|
1877
|
-
const [
|
|
1878
|
-
const [
|
|
1879
|
-
const [tempPinLast, setTempPinLast] = (0, import_react2.useState)(null);
|
|
1880
|
-
const [tempPinBusy, setTempPinBusy] = (0, import_react2.useState)(false);
|
|
1881
|
-
const [tempPinError, setTempPinError] = (0, import_react2.useState)(null);
|
|
1882
|
-
const loadTempPins = async () => {
|
|
1883
|
-
try {
|
|
1884
|
-
const r = await call(POCKET_ENDPOINTS.tempPinList, {});
|
|
1885
|
-
setTempPinsList(Array.isArray(r?.tempPins) ? r.tempPins : []);
|
|
1886
|
-
} catch {
|
|
1887
|
-
}
|
|
1888
|
-
};
|
|
1889
|
-
(0, import_react2.useEffect)(() => {
|
|
1890
|
-
loadTempPins();
|
|
1891
|
-
}, []);
|
|
1892
|
-
(0, import_react2.useEffect)(() => {
|
|
1893
|
-
if (tempPinsList.length === 0 && !tempPinLast) return;
|
|
1894
|
-
const t2 = setInterval(() => {
|
|
1895
|
-
loadTempPins();
|
|
1896
|
-
}, 3e4);
|
|
1897
|
-
return () => clearInterval(t2);
|
|
1898
|
-
}, [tempPinsList.length, tempPinLast]);
|
|
1899
|
-
const createTempPinNow = async () => {
|
|
1900
|
-
setTempPinBusy(true);
|
|
1901
|
-
setTempPinError(null);
|
|
1902
|
-
try {
|
|
1903
|
-
const r = await call(POCKET_ENDPOINTS.tempPinCreate, { kind: tempPinForm.kind, expiresInSec: tempPinForm.expiresInSec, label: tempPinForm.label });
|
|
1904
|
-
setTempPinLast(r);
|
|
1905
|
-
setTempPinForm((f) => ({ ...f, label: "" }));
|
|
1906
|
-
await loadTempPins();
|
|
1907
|
-
} catch (err) {
|
|
1908
|
-
setTempPinError(err.message);
|
|
1909
|
-
} finally {
|
|
1910
|
-
setTempPinBusy(false);
|
|
1911
|
-
}
|
|
1912
|
-
};
|
|
1913
|
-
const revokeTempPinNow = async (p) => {
|
|
1914
|
-
try {
|
|
1915
|
-
await call(POCKET_ENDPOINTS.tempPinRevoke, { value: p.value, kind: p.kind });
|
|
1916
|
-
showToast(t("tempPinRevoked"));
|
|
1917
|
-
if (tempPinLast?.value === p.value) setTempPinLast(null);
|
|
1918
|
-
await loadTempPins();
|
|
1919
|
-
} catch (err) {
|
|
1920
|
-
setError(err.message);
|
|
1921
|
-
}
|
|
1922
|
-
};
|
|
1923
|
-
const copyTempPin = async (value) => {
|
|
1924
|
-
try {
|
|
1925
|
-
if (navigator.clipboard?.writeText) {
|
|
1926
|
-
await navigator.clipboard.writeText(value);
|
|
1927
|
-
showToast(t("tempPinCopied"));
|
|
1928
|
-
}
|
|
1929
|
-
} catch {
|
|
1930
|
-
}
|
|
1931
|
-
};
|
|
1932
|
-
const formatRemaining = (expiresAt) => {
|
|
1933
|
-
const ms = expiresAt - Date.now();
|
|
1934
|
-
if (ms <= 0) return "0s";
|
|
1935
|
-
const s = Math.floor(ms / 1e3);
|
|
1936
|
-
if (s < 60) return `${s}s`;
|
|
1937
|
-
const m = Math.floor(s / 60);
|
|
1938
|
-
if (m < 60) return `${m}m`;
|
|
1939
|
-
const h2 = Math.floor(m / 60);
|
|
1940
|
-
if (h2 < 24) return `${h2}h`;
|
|
1941
|
-
const d = Math.floor(h2 / 24);
|
|
1942
|
-
return `${d}d`;
|
|
1943
|
-
};
|
|
1944
|
-
const [disclaimerOpen, setDisclaimerOpen] = (0, import_react2.useState)(false);
|
|
1945
|
-
const [disclaimerChecked, setDisclaimerChecked] = (0, import_react2.useState)(false);
|
|
1889
|
+
const [disclaimerOpen, setDisclaimerOpen] = (0, import_react3.useState)(false);
|
|
1890
|
+
const [disclaimerChecked, setDisclaimerChecked] = (0, import_react3.useState)(false);
|
|
1946
1891
|
const doStartTunnel = async () => {
|
|
1947
1892
|
const cfg = status?.tunnelConfig;
|
|
1948
1893
|
if (cfg?.mode === "named" && (!cfg.hostname || !cfg.tokenSet)) {
|
|
@@ -1975,7 +1920,7 @@ function PocketSettingsTab({ rpcCall, t }) {
|
|
|
1975
1920
|
} catch {
|
|
1976
1921
|
}
|
|
1977
1922
|
};
|
|
1978
|
-
const [tunnelCfg, setTunnelCfg] = (0,
|
|
1923
|
+
const [tunnelCfg, setTunnelCfg] = (0, import_react3.useState)(null);
|
|
1979
1924
|
const switchToQuick = async () => {
|
|
1980
1925
|
try {
|
|
1981
1926
|
setStatus(await call(POCKET_ENDPOINTS.tunnelSetConfig, { mode: "quick" }));
|
|
@@ -1996,7 +1941,7 @@ function PocketSettingsTab({ rpcCall, t }) {
|
|
|
1996
1941
|
setTunnelCfg((c) => ({ ...c, err: err.message }));
|
|
1997
1942
|
}
|
|
1998
1943
|
};
|
|
1999
|
-
const [resetOpen, setResetOpen] = (0,
|
|
1944
|
+
const [resetOpen, setResetOpen] = (0, import_react3.useState)(false);
|
|
2000
1945
|
const doFactoryReset = async () => {
|
|
2001
1946
|
setResetOpen(false);
|
|
2002
1947
|
setBusy(true);
|
|
@@ -2028,7 +1973,7 @@ function PocketSettingsTab({ rpcCall, t }) {
|
|
|
2028
1973
|
} catch {
|
|
2029
1974
|
}
|
|
2030
1975
|
};
|
|
2031
|
-
const [lanToggleOpen, setLanToggleOpen] = (0,
|
|
1976
|
+
const [lanToggleOpen, setLanToggleOpen] = (0, import_react3.useState)(null);
|
|
2032
1977
|
const requestLanToggle = (on) => setLanToggleOpen(on);
|
|
2033
1978
|
const confirmLanToggle = async () => {
|
|
2034
1979
|
const on = lanToggleOpen;
|
|
@@ -2048,7 +1993,7 @@ function PocketSettingsTab({ rpcCall, t }) {
|
|
|
2048
1993
|
setError(err.message);
|
|
2049
1994
|
}
|
|
2050
1995
|
};
|
|
2051
|
-
const [customPin, setCustomPin] = (0,
|
|
1996
|
+
const [customPin, setCustomPin] = (0, import_react3.useState)(null);
|
|
2052
1997
|
const saveCustomPin = async (which) => {
|
|
2053
1998
|
try {
|
|
2054
1999
|
const r = await call(POCKET_ENDPOINTS.pinSetCustom, { which, value: customPin?.value ?? "" });
|
|
@@ -2064,11 +2009,11 @@ function PocketSettingsTab({ rpcCall, t }) {
|
|
|
2064
2009
|
setCustomPin((c) => ({ ...c, err: err.message }));
|
|
2065
2010
|
}
|
|
2066
2011
|
};
|
|
2067
|
-
const customPinRow = (which) => (0,
|
|
2012
|
+
const customPinRow = (which) => (0, import_react3.createElement)(
|
|
2068
2013
|
"div",
|
|
2069
2014
|
{ style: { marginTop: 6, fontSize: 12, color: "var(--dsw-alias-label-secondary,#6b7280)", lineHeight: 1.5 } },
|
|
2070
2015
|
t("customizing"),
|
|
2071
|
-
(0,
|
|
2016
|
+
(0, import_react3.createElement)("input", {
|
|
2072
2017
|
style: { width: 130, margin: "0 6px", padding: "4px 8px", fontSize: 14, letterSpacing: 1, textAlign: "center", border: "1px solid var(--dsw-alias-border-l2,#d1d5db)", borderRadius: 6, outline: "none" },
|
|
2073
2018
|
type: "password",
|
|
2074
2019
|
maxLength: 8,
|
|
@@ -2080,11 +2025,11 @@ function PocketSettingsTab({ rpcCall, t }) {
|
|
|
2080
2025
|
if (e.key === "Escape") setCustomPin(null);
|
|
2081
2026
|
}
|
|
2082
2027
|
}),
|
|
2083
|
-
(0,
|
|
2084
|
-
(0,
|
|
2085
|
-
customPin?.err ? (0,
|
|
2028
|
+
(0, import_react3.createElement)("button", { style: { ...styles.btn, height: 26, padding: "0 10px", fontSize: 12, marginLeft: 2 }, onClick: () => saveCustomPin(which) }, t("save")),
|
|
2029
|
+
(0, import_react3.createElement)("button", { style: { ...styles.btn, height: 26, padding: "0 10px", fontSize: 12 }, onClick: () => setCustomPin(null) }, t("cancel")),
|
|
2030
|
+
customPin?.err ? (0, import_react3.createElement)("div", { style: { color: "var(--dsw-alias-state-error-primary,#dc2626)", marginTop: 4 } }, errText(customPin.err)) : null
|
|
2086
2031
|
);
|
|
2087
|
-
const customBtn = (which) => (0,
|
|
2032
|
+
const customBtn = (which) => (0, import_react3.createElement)("button", { style: { ...styles.btn, height: 26, padding: "0 10px", fontSize: 12, marginLeft: 8 }, onClick: () => setCustomPin({ which, value: "", err: null }) }, t("customize"));
|
|
2088
2033
|
const lanUrl = status?.lanUrl;
|
|
2089
2034
|
const tunnelUrl = status?.tunnelUrl;
|
|
2090
2035
|
const tunnelPhase = tunnelState?.phase ?? "idle";
|
|
@@ -2100,14 +2045,14 @@ function PocketSettingsTab({ rpcCall, t }) {
|
|
|
2100
2045
|
if (i < 0) return s;
|
|
2101
2046
|
return (t("ok") === zh2.ok ? s.slice(0, i) : s.slice(i + 3)).trim();
|
|
2102
2047
|
};
|
|
2103
|
-
const [toast, setToast] = (0,
|
|
2104
|
-
const toastTimer = (0,
|
|
2048
|
+
const [toast, setToast] = (0, import_react3.useState)(null);
|
|
2049
|
+
const toastTimer = (0, import_react3.useRef)(null);
|
|
2105
2050
|
const showToast = (text) => {
|
|
2106
2051
|
setToast(text);
|
|
2107
2052
|
clearTimeout(toastTimer.current);
|
|
2108
2053
|
toastTimer.current = setTimeout(() => setToast(null), 2600);
|
|
2109
2054
|
};
|
|
2110
|
-
(0,
|
|
2055
|
+
(0, import_react3.useEffect)(() => () => clearTimeout(toastTimer.current), []);
|
|
2111
2056
|
const modeBtnStyle = (active) => ({
|
|
2112
2057
|
...styles.btn,
|
|
2113
2058
|
height: 28,
|
|
@@ -2117,49 +2062,49 @@ function PocketSettingsTab({ rpcCall, t }) {
|
|
|
2117
2062
|
background: active ? "var(--dsw-alias-button-primary-fill, var(--dsw-alias-brand-primary,#4f6ef7))" : "var(--dsw-alias-bg-layer-1,#fff)",
|
|
2118
2063
|
color: active ? "var(--dsw-alias-label-primary-foreground, #fff)" : "var(--dsw-alias-label-primary,inherit)"
|
|
2119
2064
|
});
|
|
2120
|
-
const Switch = (on, onClick) => (0,
|
|
2065
|
+
const Switch = (on, onClick) => (0, import_react3.createElement)("button", {
|
|
2121
2066
|
role: "switch",
|
|
2122
2067
|
"aria-checked": !!on,
|
|
2123
2068
|
style: { flexShrink: 0, width: 40, height: 22, borderRadius: 11, border: "none", padding: 0, position: "relative", cursor: "pointer", font: "inherit", background: on ? "var(--dsw-alias-button-primary-fill, var(--dsw-alias-brand-primary,#4f6ef7))" : "var(--dsw-alias-border-l2,#d1d5db)" },
|
|
2124
2069
|
onClick
|
|
2125
|
-
}, (0,
|
|
2126
|
-
const qrArea = (src, url, hint) => (0,
|
|
2070
|
+
}, (0, import_react3.createElement)("span", { style: { position: "absolute", top: 2, left: on ? 20 : 2, width: 18, height: 18, borderRadius: "50%", background: "#fff" } }));
|
|
2071
|
+
const qrArea = (src, url, hint) => (0, import_react3.createElement)(
|
|
2127
2072
|
"div",
|
|
2128
2073
|
{ style: { background: "var(--dsw-alias-bg-layer-2,#f3f4f6)", borderRadius: 10, padding: "10px 12px", textAlign: "center", margin: "10px 0" } },
|
|
2129
|
-
(0,
|
|
2130
|
-
(0,
|
|
2131
|
-
(0,
|
|
2074
|
+
(0, import_react3.createElement)("img", { src, alt: "QR", style: styles.qr }),
|
|
2075
|
+
(0, import_react3.createElement)("div", { style: styles.code }, url),
|
|
2076
|
+
(0, import_react3.createElement)("div", { style: styles.muted }, hint)
|
|
2132
2077
|
);
|
|
2133
|
-
const row = (label, control, extra) => (0,
|
|
2078
|
+
const row = (label, control, extra) => (0, import_react3.createElement)(
|
|
2134
2079
|
"div",
|
|
2135
2080
|
{ style: { borderTop: "1px solid var(--dsw-alias-border-l2,#e5e7eb)", paddingTop: 9, marginTop: 9 } },
|
|
2136
|
-
(0,
|
|
2081
|
+
(0, import_react3.createElement)(
|
|
2137
2082
|
"div",
|
|
2138
2083
|
{ style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 8 } },
|
|
2139
|
-
(0,
|
|
2084
|
+
(0, import_react3.createElement)("span", { style: { fontSize: 13 } }, label),
|
|
2140
2085
|
control
|
|
2141
2086
|
),
|
|
2142
2087
|
extra ?? null
|
|
2143
2088
|
);
|
|
2144
|
-
const [advOpen, setAdvOpen] = (0,
|
|
2145
|
-
return (0,
|
|
2089
|
+
const [advOpen, setAdvOpen] = (0, import_react3.useState)(false);
|
|
2090
|
+
return (0, import_react3.createElement)(
|
|
2146
2091
|
"div",
|
|
2147
2092
|
{ style: styles.card },
|
|
2148
|
-
(0,
|
|
2093
|
+
(0, import_react3.createElement)(
|
|
2149
2094
|
"div",
|
|
2150
2095
|
{ style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 8 } },
|
|
2151
|
-
(0,
|
|
2096
|
+
(0, import_react3.createElement)(
|
|
2152
2097
|
"div",
|
|
2153
2098
|
null,
|
|
2154
|
-
(0,
|
|
2155
|
-
(0,
|
|
2099
|
+
(0, import_react3.createElement)("strong", null, t("title")),
|
|
2100
|
+
(0, import_react3.createElement)("div", { style: styles.muted }, t("subtitle"))
|
|
2156
2101
|
),
|
|
2157
|
-
(0,
|
|
2102
|
+
(0, import_react3.createElement)(
|
|
2158
2103
|
"div",
|
|
2159
2104
|
{ style: { fontSize: 12, color: "var(--dsw-alias-label-tertiary,#8b93a1)", textAlign: "right" } },
|
|
2160
|
-
(0,
|
|
2161
|
-
(0,
|
|
2162
|
-
(0,
|
|
2105
|
+
(0, import_react3.createElement)("div", { style: { whiteSpace: "nowrap" } }, t("developer")),
|
|
2106
|
+
(0, import_react3.createElement)("div", { style: { whiteSpace: "nowrap" } }, t("starAsk")),
|
|
2107
|
+
(0, import_react3.createElement)(
|
|
2163
2108
|
"a",
|
|
2164
2109
|
{ href: "https://github.com/shaobeichen/dsh-pocket", target: "_blank", rel: "noreferrer", style: { color: "var(--dsw-alias-brand-primary,#4f6ef7)", fontSize: 12, lineHeight: 1.6, textDecoration: "underline" } },
|
|
2165
2110
|
t("starCta")
|
|
@@ -2168,49 +2113,49 @@ function PocketSettingsTab({ rpcCall, t }) {
|
|
|
2168
2113
|
),
|
|
2169
2114
|
// 桌面端不显示更新/重启横幅(更新由 DSH Desktop 管理),也不需要额外提示
|
|
2170
2115
|
// 重启后提示(进程在后台运行,停止方法)——左侧蓝色色条(桌面端不会触发本插件的自重启)
|
|
2171
|
-
!isDesktop && restartNotice ? (0,
|
|
2116
|
+
!isDesktop && restartNotice ? (0, import_react3.createElement)(
|
|
2172
2117
|
"div",
|
|
2173
2118
|
{ style: { ...styles.block, borderLeft: "4px solid var(--dsw-alias-brand-primary,#4f6ef7)", borderRadius: 8, background: "var(--dsw-alias-bg-layer-2,#f3f4f6)", padding: "10px 12px" } },
|
|
2174
|
-
(0,
|
|
2119
|
+
(0, import_react3.createElement)(
|
|
2175
2120
|
"div",
|
|
2176
2121
|
{ style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 8 } },
|
|
2177
|
-
(0,
|
|
2178
|
-
(0,
|
|
2122
|
+
(0, import_react3.createElement)("div", { style: { fontWeight: 600, fontSize: 13 } }, t("restarted")),
|
|
2123
|
+
(0, import_react3.createElement)("button", { style: styles.btn, onClick: () => setRestartNotice(false) }, t("ok"))
|
|
2179
2124
|
),
|
|
2180
|
-
(0,
|
|
2125
|
+
(0, import_react3.createElement)("div", { style: styles.muted, marginTop: 4, wordBreak: "break-all" }, fmt(t, "bgHint", { cmd: status?.killHint ?? `lsof -ti :${status?.dshPort ?? 3080} | xargs kill -9` }))
|
|
2181
2126
|
) : null,
|
|
2182
2127
|
// 更新提示——左侧黄色色条(提示有新版本);单状态:有更新/更新中/已更新自动重启,不并存
|
|
2183
2128
|
// 桌面端不渲染(更新由 DSH Desktop 管理)
|
|
2184
|
-
!isDesktop && updateInfo ? (0,
|
|
2129
|
+
!isDesktop && updateInfo ? (0, import_react3.createElement)(
|
|
2185
2130
|
"div",
|
|
2186
2131
|
{ style: { ...styles.block, borderLeft: "4px solid var(--dsw-alias-state-warn-primary,#b45309)", borderRadius: 8, background: "var(--dsw-alias-bg-layer-2,#f3f4f6)", padding: "10px 12px" } },
|
|
2187
|
-
(0,
|
|
2132
|
+
(0, import_react3.createElement)(
|
|
2188
2133
|
"div",
|
|
2189
2134
|
{ style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 8 } },
|
|
2190
|
-
(0,
|
|
2135
|
+
(0, import_react3.createElement)(
|
|
2191
2136
|
"div",
|
|
2192
2137
|
{ style: { fontWeight: 600, fontSize: 13 } },
|
|
2193
2138
|
updateInfo.updated ? fmt(t, "updatedRestart", { ver: updateInfo.current }) : updateInfo.result === "ok" ? updateInfo.autoRestart ? fmt(t, "updateAutoRestarting", { ver: updateInfo.latest }) : fmt(t, "updatedOk", { ver: updateInfo.latest }) : fmt(t, "updateAvailable", { ver: updateInfo.latest })
|
|
2194
2139
|
),
|
|
2195
|
-
updateInfo.result !== "ok" ? (0,
|
|
2140
|
+
updateInfo.result !== "ok" ? (0, import_react3.createElement)("button", { style: styles.primary, onClick: runUpdate, disabled: updateInfo.updating }, updateInfo.updating ? t("updating") : fmt(t, "updateTo", { ver: updateInfo.latest })) : updateInfo.autoRestart ? (0, import_react3.createElement)("button", { style: styles.btn, disabled: true }, t("restartingNow")) : (0, import_react3.createElement)("button", { style: styles.primary, onClick: restartPocket, disabled: updateInfo.restarting }, updateInfo.restarting ? t("restarting") : t("restartNow"))
|
|
2196
2141
|
),
|
|
2197
|
-
(0,
|
|
2142
|
+
(0, import_react3.createElement)(
|
|
2198
2143
|
"div",
|
|
2199
2144
|
{ style: styles.muted, marginTop: 4 },
|
|
2200
2145
|
updateInfo.updating ? fmt(t, "updatingDetail", { s: elapsed(updateInfo.startedAt) }) : updateInfo.restarting ? fmt(t, "restartingDetail", { s: elapsed(updateInfo.startedAt) }) : updateInfo.result === "ok" ? updateInfo.autoRestart ? t("updatedAutoDetail") : t("updatedRestartDetail") : updateInfo.result === "fail" ? fmt(t, "updateFailed", { err: errText(updateInfo.output) || t("unknownError") }) : fmt(t, "versionRange", { cur: updateInfo.current, latest: updateInfo.latest })
|
|
2201
2146
|
)
|
|
2202
2147
|
) : null,
|
|
2203
2148
|
// 局域网:标题行自带总开关 → 二维码+地址 → 设置行(访问密码 / 高级·手动选地址)
|
|
2204
|
-
(0,
|
|
2149
|
+
(0, import_react3.createElement)(
|
|
2205
2150
|
"div",
|
|
2206
2151
|
{ style: styles.block },
|
|
2207
|
-
(0,
|
|
2152
|
+
(0, import_react3.createElement)(
|
|
2208
2153
|
"div",
|
|
2209
2154
|
{ style: { display: "flex", alignItems: "center", justifyContent: "space-between" } },
|
|
2210
|
-
(0,
|
|
2155
|
+
(0, import_react3.createElement)("span", { style: { fontWeight: 600, fontSize: 13 } }, t("lanAccess")),
|
|
2211
2156
|
Switch(status?.lanEnabled !== false, () => requestLanToggle(status?.lanEnabled === false))
|
|
2212
2157
|
),
|
|
2213
|
-
status?.lanEnabled === false ? (0,
|
|
2158
|
+
status?.lanEnabled === false ? (0, import_react3.createElement)("div", { style: { marginTop: 8, fontSize: 12, color: "var(--dsw-alias-state-warn-primary,#b45309)", lineHeight: 1.5 } }, t("lanDisabledHint")) : lanUrl ? (0, import_react3.createElement)(
|
|
2214
2159
|
"div",
|
|
2215
2160
|
null,
|
|
2216
2161
|
qrArea(status.lanQr, lanUrl, t("lanHint")),
|
|
@@ -2218,100 +2163,100 @@ function PocketSettingsTab({ rpcCall, t }) {
|
|
|
2218
2163
|
row(
|
|
2219
2164
|
t("lanPin"),
|
|
2220
2165
|
Switch(status?.lanAuthEnabled !== false, () => setLanAuth(status?.lanAuthEnabled === false)),
|
|
2221
|
-
status?.lanAuthEnabled === false ? (0,
|
|
2166
|
+
status?.lanAuthEnabled === false ? (0, import_react3.createElement)("div", { style: { ...styles.muted, marginTop: 6 } }, t("lanPinOff")) : customPin?.which === "lan" ? customPinRow("lan") : (0, import_react3.createElement)(
|
|
2222
2167
|
"div",
|
|
2223
2168
|
{ style: { marginTop: 6, display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap" } },
|
|
2224
|
-
(0,
|
|
2225
|
-
(0,
|
|
2169
|
+
(0, import_react3.createElement)("span", { style: { fontFamily: "ui-monospace,Menlo,monospace", fontSize: 13, letterSpacing: 1 } }, status.lanToken),
|
|
2170
|
+
(0, import_react3.createElement)("button", { style: { ...styles.btn, height: 26, padding: "0 10px", fontSize: 12 }, onClick: refreshLanPin }, t("refresh")),
|
|
2226
2171
|
customBtn("lan"),
|
|
2227
|
-
status?.lanPinCustom ? (0,
|
|
2172
|
+
status?.lanPinCustom ? (0, import_react3.createElement)("span", { style: { fontSize: 11, color: "var(--dsw-alias-state-warn-primary,#b45309)" } }, t("pinCustomHint")) : null
|
|
2228
2173
|
)
|
|
2229
2174
|
),
|
|
2230
2175
|
// 高级:手动选地址(默认收起)
|
|
2231
2176
|
row(
|
|
2232
2177
|
t("advAddress"),
|
|
2233
|
-
(0,
|
|
2178
|
+
(0, import_react3.createElement)(
|
|
2234
2179
|
"button",
|
|
2235
2180
|
{ style: { border: "none", background: "none", font: "inherit", cursor: "pointer", fontSize: 12, color: "var(--dsw-alias-label-tertiary,#8b93a1)", padding: 0 }, onClick: () => setAdvOpen((v) => !v) },
|
|
2236
2181
|
(status?.lanIpOverride || t("lanAddressAuto")) + " \u203A"
|
|
2237
2182
|
),
|
|
2238
|
-
advOpen ? (0,
|
|
2183
|
+
advOpen ? (0, import_react3.createElement)(
|
|
2239
2184
|
"div",
|
|
2240
2185
|
{ style: { marginTop: 8 } },
|
|
2241
|
-
(0,
|
|
2186
|
+
(0, import_react3.createElement)(
|
|
2242
2187
|
"label",
|
|
2243
2188
|
{ style: { display: "flex", alignItems: "center", gap: 8, fontSize: 12, color: "var(--dsw-alias-label-secondary,#6b7280)" } },
|
|
2244
2189
|
t("lanAddress"),
|
|
2245
|
-
(0,
|
|
2190
|
+
(0, import_react3.createElement)(
|
|
2246
2191
|
"select",
|
|
2247
2192
|
{
|
|
2248
2193
|
value: status?.lanIpOverride || "",
|
|
2249
2194
|
onChange: (e) => setLanAddress(e.target.value),
|
|
2250
2195
|
style: { font: "inherit", height: 30, padding: "0 8px", borderRadius: 8, border: "1px solid var(--dsw-alias-border-l2,#d1d5db)", background: "var(--dsw-alias-bg-layer-1,#fff)", color: "var(--dsw-alias-label-primary,inherit)" }
|
|
2251
2196
|
},
|
|
2252
|
-
(0,
|
|
2253
|
-
(status?.lanCandidates || []).map((ip) => (0,
|
|
2197
|
+
(0, import_react3.createElement)("option", { value: "" }, t("lanAddressAuto")),
|
|
2198
|
+
(status?.lanCandidates || []).map((ip) => (0, import_react3.createElement)("option", { key: ip, value: ip }, ip))
|
|
2254
2199
|
)
|
|
2255
2200
|
)
|
|
2256
2201
|
) : null
|
|
2257
2202
|
)
|
|
2258
|
-
) : (0,
|
|
2203
|
+
) : (0, import_react3.createElement)("div", { style: styles.muted }, t("lanStarting"))
|
|
2259
2204
|
),
|
|
2260
2205
|
// 公网:标题行自带 开启/关闭 → 开启后:二维码+地址、地址模式行、访问密码行
|
|
2261
|
-
(0,
|
|
2206
|
+
(0, import_react3.createElement)(
|
|
2262
2207
|
"div",
|
|
2263
2208
|
{ style: styles.block },
|
|
2264
|
-
(0,
|
|
2209
|
+
(0, import_react3.createElement)(
|
|
2265
2210
|
"div",
|
|
2266
2211
|
{ style: { display: "flex", alignItems: "center", justifyContent: "space-between" } },
|
|
2267
|
-
(0,
|
|
2268
|
-
tunnelUrl ? (0,
|
|
2212
|
+
(0, import_react3.createElement)("span", { style: { fontWeight: 600, fontSize: 13 } }, t("wanAccess")),
|
|
2213
|
+
tunnelUrl ? (0, import_react3.createElement)("button", { style: { ...styles.btn, height: 28, padding: "0 12px", fontSize: 12, color: "var(--dsw-alias-state-error-primary,#dc2626)" }, onClick: stopTunnel }, t("stopTunnel")) : (0, import_react3.createElement)("button", { style: { ...styles.primary, height: 28, padding: "0 14px", fontSize: 12 }, onClick: startTunnel, disabled: busy || tunnelStarting }, busy || tunnelStarting ? t("opening") : t("enable"))
|
|
2269
2214
|
),
|
|
2270
|
-
tunnelStarting ? (0,
|
|
2215
|
+
tunnelStarting ? (0, import_react3.createElement)(
|
|
2271
2216
|
"div",
|
|
2272
2217
|
{ style: { marginTop: 8, fontSize: 12, color: "var(--dsw-alias-label-secondary,#6b7280)" } },
|
|
2273
2218
|
tunnelPhase === "downloading" ? fmt(t, "downloading", { s: elapsed(tunnelStateStarted) }) : fmt(t, "connecting", { s: elapsed(tunnelStateStarted), suffix: elapsed(tunnelStateStarted) > 30 ? t("slowHint") : "" })
|
|
2274
|
-
) : tunnelPhase === "error" ? (0,
|
|
2219
|
+
) : tunnelPhase === "error" ? (0, import_react3.createElement)(
|
|
2275
2220
|
"div",
|
|
2276
2221
|
{ style: { marginTop: 8, fontSize: 12, color: "var(--dsw-alias-state-error-primary,#dc2626)" } },
|
|
2277
2222
|
fmt(t, "error", { detail: errText(tunnelStateDetail) || t("unknownError") })
|
|
2278
|
-
) : !tunnelUrl && !isDesktop ? (0,
|
|
2279
|
-
tunnelUrl ? (0,
|
|
2223
|
+
) : !tunnelUrl && !isDesktop ? (0, import_react3.createElement)("div", { style: { ...styles.muted, marginTop: 8 } }, t("wanOffHint")) : null,
|
|
2224
|
+
tunnelUrl ? (0, import_react3.createElement)(
|
|
2280
2225
|
"div",
|
|
2281
2226
|
null,
|
|
2282
2227
|
qrArea(status.tunnelQr, tunnelUrl, namedMode ? t("namedRunningHint") : t("wanHint")),
|
|
2283
2228
|
// 地址模式行(随机/固定;固定域名选中或编辑时高亮)
|
|
2284
2229
|
row(
|
|
2285
2230
|
t("modeLabel"),
|
|
2286
|
-
(0,
|
|
2231
|
+
(0, import_react3.createElement)(
|
|
2287
2232
|
"span",
|
|
2288
2233
|
{ style: { display: "inline-flex", gap: 6 } },
|
|
2289
|
-
(0,
|
|
2290
|
-
(0,
|
|
2234
|
+
(0, import_react3.createElement)("button", { style: modeBtnStyle(!namedActive), onClick: namedMode ? switchToQuick : tunnelCfg ? () => setTunnelCfg(null) : void 0 }, t("modeQuick")),
|
|
2235
|
+
(0, import_react3.createElement)("button", { style: modeBtnStyle(namedActive), onClick: () => setTunnelCfg(tunnelCfg ? null : { hostname: tunnelModeView.hostname ?? "", token: "", err: null }) }, t("modeNamed"))
|
|
2291
2236
|
),
|
|
2292
|
-
(0,
|
|
2237
|
+
(0, import_react3.createElement)(
|
|
2293
2238
|
"div",
|
|
2294
2239
|
{ style: { marginTop: 6 } },
|
|
2295
2240
|
// 刚保存固定域名但当前连接仍是随机域名:需关闭后重新开启才生效
|
|
2296
|
-
namedMode && /trycloudflare\.com/i.test(tunnelUrl ?? "") ? (0,
|
|
2241
|
+
namedMode && /trycloudflare\.com/i.test(tunnelUrl ?? "") ? (0, import_react3.createElement)("div", { style: { ...styles.warn } }, t("namedTakeEffect")) : null,
|
|
2297
2242
|
// 固定域名:已保存摘要 + 修改入口(非编辑态)
|
|
2298
|
-
namedMode && !tunnelCfg ? (0,
|
|
2243
|
+
namedMode && !tunnelCfg ? (0, import_react3.createElement)(
|
|
2299
2244
|
"div",
|
|
2300
2245
|
{ style: { ...styles.muted } },
|
|
2301
2246
|
fmt(t, "namedSummary", { host: tunnelModeView.hostname || "\u2014", token: tunnelModeView.tokenSet ? t("namedTokenSet") : t("namedTokenMissing") }),
|
|
2302
|
-
(0,
|
|
2303
|
-
(0,
|
|
2304
|
-
!tunnelModeView.tokenSet || !tunnelModeView.hostname ? (0,
|
|
2247
|
+
(0, import_react3.createElement)("button", { style: { ...styles.btn, height: 26, padding: "0 10px", fontSize: 12, marginLeft: 8 }, onClick: () => setTunnelCfg({ hostname: tunnelModeView.hostname ?? "", token: "", err: null }) }, t("namedEdit")),
|
|
2248
|
+
(0, import_react3.createElement)("div", { style: { ...styles.muted, marginTop: 4 } }, t("namedHow")),
|
|
2249
|
+
!tunnelModeView.tokenSet || !tunnelModeView.hostname ? (0, import_react3.createElement)("div", { style: { marginTop: 2, color: "var(--dsw-alias-state-error-primary,#dc2626)" } }, t("namedNeedCfg")) : null
|
|
2305
2250
|
) : null,
|
|
2306
2251
|
// 固定域名:编辑表单(域名 + Tunnel Token,Token 留空保持不变)
|
|
2307
|
-
tunnelCfg ? (0,
|
|
2252
|
+
tunnelCfg ? (0, import_react3.createElement)(
|
|
2308
2253
|
"div",
|
|
2309
2254
|
{ style: { marginTop: 6, fontSize: 12, color: "var(--dsw-alias-label-secondary,#6b7280)", lineHeight: 1.6 } },
|
|
2310
|
-
(0,
|
|
2255
|
+
(0, import_react3.createElement)(
|
|
2311
2256
|
"div",
|
|
2312
2257
|
null,
|
|
2313
2258
|
t("namedHostnameLabel"),
|
|
2314
|
-
(0,
|
|
2259
|
+
(0, import_react3.createElement)("input", {
|
|
2315
2260
|
style: { margin: "4px 0 0 6px", padding: "4px 8px", fontSize: 13, border: "1px solid var(--dsw-alias-border-l2,#d1d5db)", borderRadius: 6, outline: "none", width: 200 },
|
|
2316
2261
|
placeholder: "pocket.example.com",
|
|
2317
2262
|
value: tunnelCfg.hostname ?? "",
|
|
@@ -2323,11 +2268,11 @@ function PocketSettingsTab({ rpcCall, t }) {
|
|
|
2323
2268
|
}
|
|
2324
2269
|
})
|
|
2325
2270
|
),
|
|
2326
|
-
(0,
|
|
2271
|
+
(0, import_react3.createElement)(
|
|
2327
2272
|
"div",
|
|
2328
2273
|
{ style: { marginTop: 6 } },
|
|
2329
2274
|
t("namedTokenLabel"),
|
|
2330
|
-
(0,
|
|
2275
|
+
(0, import_react3.createElement)("input", {
|
|
2331
2276
|
style: { margin: "4px 0 0 6px", padding: "4px 8px", fontSize: 13, border: "1px solid var(--dsw-alias-border-l2,#d1d5db)", borderRadius: 6, outline: "none", width: 240, fontFamily: "ui-monospace,Menlo,monospace" },
|
|
2332
2277
|
type: "password",
|
|
2333
2278
|
value: tunnelCfg.token ?? "",
|
|
@@ -2338,192 +2283,121 @@ function PocketSettingsTab({ rpcCall, t }) {
|
|
|
2338
2283
|
}
|
|
2339
2284
|
})
|
|
2340
2285
|
),
|
|
2341
|
-
(0,
|
|
2286
|
+
(0, import_react3.createElement)(
|
|
2342
2287
|
"div",
|
|
2343
2288
|
{ style: { marginTop: 6, display: "flex", gap: 8 } },
|
|
2344
|
-
(0,
|
|
2345
|
-
(0,
|
|
2289
|
+
(0, import_react3.createElement)("button", { style: { ...styles.btn, height: 26, padding: "0 10px", fontSize: 12 }, onClick: saveNamedTunnel }, t("save")),
|
|
2290
|
+
(0, import_react3.createElement)("button", { style: { ...styles.btn, height: 26, padding: "0 10px", fontSize: 12 }, onClick: () => setTunnelCfg(null) }, t("cancel"))
|
|
2346
2291
|
),
|
|
2347
|
-
(0,
|
|
2348
|
-
(0,
|
|
2349
|
-
tunnelCfg.err ? (0,
|
|
2292
|
+
(0, import_react3.createElement)("div", { style: { ...styles.muted, marginTop: 6 } }, t("namedHow")),
|
|
2293
|
+
(0, import_react3.createElement)("div", { style: { marginTop: 2, fontSize: 11, color: "var(--dsw-alias-state-warn-primary,#b45309)", lineHeight: 1.5 } }, t("namedSecurity")),
|
|
2294
|
+
tunnelCfg.err ? (0, import_react3.createElement)("div", { style: { color: "var(--dsw-alias-state-error-primary,#dc2626)", marginTop: 4 } }, errText(tunnelCfg.err)) : null
|
|
2350
2295
|
) : null
|
|
2351
2296
|
)
|
|
2352
2297
|
),
|
|
2353
2298
|
// 访问密码行:值 + 自定义(自定义输入态整体替换)
|
|
2354
2299
|
status.accessToken ? row(
|
|
2355
2300
|
t("pinLabel"),
|
|
2356
|
-
customPin?.which === "public" ? null : (0,
|
|
2301
|
+
customPin?.which === "public" ? null : (0, import_react3.createElement)(
|
|
2357
2302
|
"span",
|
|
2358
2303
|
{ style: { display: "inline-flex", alignItems: "center", gap: 8 } },
|
|
2359
|
-
(0,
|
|
2304
|
+
(0, import_react3.createElement)("span", { style: { fontFamily: "ui-monospace,Menlo,monospace", fontSize: 13, letterSpacing: 1 } }, status.accessToken),
|
|
2360
2305
|
customBtn("public")
|
|
2361
2306
|
),
|
|
2362
|
-
(0,
|
|
2307
|
+
(0, import_react3.createElement)(
|
|
2363
2308
|
"div",
|
|
2364
2309
|
{ style: { marginTop: 6 } },
|
|
2365
2310
|
customPin?.which === "public" ? customPinRow("public") : null,
|
|
2366
|
-
status?.publicPinCustom ? (0,
|
|
2367
|
-
namedMode ? (0,
|
|
2311
|
+
status?.publicPinCustom ? (0, import_react3.createElement)("div", { style: { ...styles.warn } }, t("pinCustomHint")) : null,
|
|
2312
|
+
namedMode ? (0, import_react3.createElement)("div", { style: { ...styles.warn } }, t("namedSecurity")) : null
|
|
2368
2313
|
)
|
|
2369
2314
|
) : null
|
|
2370
2315
|
) : null
|
|
2371
2316
|
),
|
|
2372
|
-
error ? (0,
|
|
2373
|
-
// 临时 PIN(issue #69):带过期的访问密码,给访客用
|
|
2374
|
-
(0, import_react2.createElement)(
|
|
2375
|
-
"div",
|
|
2376
|
-
{ style: styles.block },
|
|
2377
|
-
(0, import_react2.createElement)("div", { style: { fontWeight: 600, fontSize: 13, marginBottom: 4 } }, t("tempPinTitle")),
|
|
2378
|
-
(0, import_react2.createElement)("div", { style: { ...styles.muted, marginBottom: 10 } }, t("tempPinSubtitle")),
|
|
2379
|
-
// 生成表单:分类 + 时长 + 备注 + 生成
|
|
2380
|
-
(0, import_react2.createElement)(
|
|
2381
|
-
"div",
|
|
2382
|
-
{ style: { display: "flex", flexWrap: "wrap", gap: 8, alignItems: "center" } },
|
|
2383
|
-
(0, import_react2.createElement)(
|
|
2384
|
-
"select",
|
|
2385
|
-
{
|
|
2386
|
-
value: tempPinForm.kind,
|
|
2387
|
-
onChange: (e) => setTempPinForm((f) => ({ ...f, kind: e.target.value })),
|
|
2388
|
-
style: { font: "inherit", height: 30, padding: "0 8px", borderRadius: 8, border: "1px solid var(--dsw-alias-border-l2,#d1d5db)", background: "var(--dsw-alias-bg-layer-1,#fff)", color: "var(--dsw-alias-label-primary,inherit)" }
|
|
2389
|
-
},
|
|
2390
|
-
(0, import_react2.createElement)("option", { value: "public" }, t("tempPinKindPublic")),
|
|
2391
|
-
(0, import_react2.createElement)("option", { value: "lan" }, t("tempPinKindLan"))
|
|
2392
|
-
),
|
|
2393
|
-
(0, import_react2.createElement)(
|
|
2394
|
-
"select",
|
|
2395
|
-
{
|
|
2396
|
-
value: String(tempPinForm.expiresInSec),
|
|
2397
|
-
onChange: (e) => setTempPinForm((f) => ({ ...f, expiresInSec: Number(e.target.value) })),
|
|
2398
|
-
style: { font: "inherit", height: 30, padding: "0 8px", borderRadius: 8, border: "1px solid var(--dsw-alias-border-l2,#d1d5db)", background: "var(--dsw-alias-bg-layer-1,#fff)", color: "var(--dsw-alias-label-primary,inherit)" }
|
|
2399
|
-
},
|
|
2400
|
-
(0, import_react2.createElement)("option", { value: "3600" }, t("tempPinDuration1h")),
|
|
2401
|
-
(0, import_react2.createElement)("option", { value: "86400" }, t("tempPinDuration24h")),
|
|
2402
|
-
(0, import_react2.createElement)("option", { value: "604800" }, t("tempPinDuration7d"))
|
|
2403
|
-
),
|
|
2404
|
-
(0, import_react2.createElement)("input", {
|
|
2405
|
-
style: { flex: 1, minWidth: 120, height: 30, padding: "0 10px", borderRadius: 8, border: "1px solid var(--dsw-alias-border-l2,#d1d5db)", fontSize: 13, outline: "none" },
|
|
2406
|
-
placeholder: t("tempPinLabelPh"),
|
|
2407
|
-
value: tempPinForm.label,
|
|
2408
|
-
onChange: (e) => setTempPinForm((f) => ({ ...f, label: e.target.value })),
|
|
2409
|
-
onKeyDown: (e) => {
|
|
2410
|
-
if (e.key === "Enter") createTempPinNow();
|
|
2411
|
-
}
|
|
2412
|
-
}),
|
|
2413
|
-
(0, import_react2.createElement)("button", { style: { ...styles.btn, height: 30 }, onClick: createTempPinNow, disabled: tempPinBusy }, t("tempPinCreate"))
|
|
2414
|
-
),
|
|
2415
|
-
// 错误展示
|
|
2416
|
-
tempPinError ? (0, import_react2.createElement)("div", { style: { color: "var(--dsw-alias-state-error-primary,#dc2626)", fontSize: 12, marginTop: 6 } }, errText(tempPinError)) : null,
|
|
2417
|
-
// 刚生成的那一个(高亮,下一秒会消失提示用户立刻复制)
|
|
2418
|
-
tempPinLast ? (0, import_react2.createElement)(
|
|
2419
|
-
"div",
|
|
2420
|
-
{ style: { marginTop: 10, padding: "8px 10px", borderRadius: 8, background: "var(--dsw-alias-bg-layer-2,#f3f4f6)", display: "flex", alignItems: "center", justifyContent: "space-between", gap: 8, flexWrap: "wrap" } },
|
|
2421
|
-
(0, import_react2.createElement)(
|
|
2422
|
-
"div",
|
|
2423
|
-
null,
|
|
2424
|
-
(0, import_react2.createElement)("div", { style: { fontSize: 11, color: "var(--dsw-alias-state-success-primary,#16a34a)", fontWeight: 600, marginBottom: 2 } }, `${t("tempPinCreated")} \xB7 ${tempPinLast.kind === "public" ? t("tempPinKindPublic") : t("tempPinKindLan")} \xB7 ${formatRemaining(tempPinLast.expiresAt)}`),
|
|
2425
|
-
(0, import_react2.createElement)("span", { style: { fontFamily: "ui-monospace,Menlo,monospace", fontSize: 16, letterSpacing: 2, fontWeight: 600 } }, tempPinLast.value)
|
|
2426
|
-
),
|
|
2427
|
-
(0, import_react2.createElement)("button", { style: { ...styles.btn, height: 28, padding: "0 12px", fontSize: 12 }, onClick: () => copyTempPin(tempPinLast.value) }, t("tempPinCopy"))
|
|
2428
|
-
) : null,
|
|
2429
|
-
// 列表
|
|
2430
|
-
(0, import_react2.createElement)(
|
|
2431
|
-
"div",
|
|
2432
|
-
{ style: { marginTop: 12, borderTop: "1px solid var(--dsw-alias-border-l2,#e5e7eb)", paddingTop: 8 } },
|
|
2433
|
-
tempPinsList.length === 0 ? (0, import_react2.createElement)("div", { style: { ...styles.muted, padding: "6px 0" } }, t("tempPinEmpty")) : tempPinsList.map((p) => (0, import_react2.createElement)(
|
|
2434
|
-
"div",
|
|
2435
|
-
{ key: p.value, style: { display: "flex", alignItems: "center", gap: 8, padding: "6px 0", borderBottom: "1px solid var(--dsw-alias-border-l2,#e5e7eb)" } },
|
|
2436
|
-
(0, import_react2.createElement)("span", { style: { fontSize: 11, color: "var(--dsw-alias-label-tertiary,#8b93a1)", minWidth: 50 } }, p.kind === "public" ? t("tempPinKindPublic") : t("tempPinKindLan")),
|
|
2437
|
-
(0, import_react2.createElement)("span", { style: { fontFamily: "ui-monospace,Menlo,monospace", fontSize: 13, letterSpacing: 1, flexShrink: 0 } }, p.value),
|
|
2438
|
-
(0, import_react2.createElement)("span", { style: { ...styles.muted, flex: 1, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" } }, p.label || "\u2014"),
|
|
2439
|
-
(0, import_react2.createElement)("span", { style: { fontSize: 11, color: "var(--dsw-alias-label-tertiary,#8b93a1)" } }, `${t("tempPinExpiresIn")} ${formatRemaining(p.expiresAt)}`),
|
|
2440
|
-
(0, import_react2.createElement)("button", { style: { ...styles.btn, height: 24, padding: "0 10px", fontSize: 11 }, onClick: () => revokeTempPinNow(p) }, t("tempPinRevoke"))
|
|
2441
|
-
))
|
|
2442
|
-
)
|
|
2443
|
-
),
|
|
2317
|
+
error ? (0, import_react3.createElement)("div", { style: { color: "var(--dsw-alias-state-error-primary,#dc2626)", fontSize: 12, marginTop: 8 } }, `\u274C ${errText(error)}`) : null,
|
|
2444
2318
|
// 恢复出厂设置:设置出问题时的临时兜底(最底部,避免误触)
|
|
2445
|
-
(0,
|
|
2319
|
+
(0, import_react3.createElement)(
|
|
2446
2320
|
"div",
|
|
2447
2321
|
{ style: styles.block },
|
|
2448
|
-
(0,
|
|
2322
|
+
(0, import_react3.createElement)(
|
|
2449
2323
|
"div",
|
|
2450
2324
|
{ style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 8 } },
|
|
2451
|
-
(0,
|
|
2452
|
-
(0,
|
|
2325
|
+
(0, import_react3.createElement)("span", { style: { fontWeight: 600, fontSize: 13 } }, t("resetFactory")),
|
|
2326
|
+
(0, import_react3.createElement)("button", { style: { ...styles.btn, height: 28, padding: "0 12px", fontSize: 12, color: "var(--dsw-alias-state-error-primary,#dc2626)" }, onClick: () => setResetOpen(true) }, t("resetGo"))
|
|
2453
2327
|
),
|
|
2454
|
-
(0,
|
|
2328
|
+
(0, import_react3.createElement)("div", { style: { ...styles.muted, marginTop: 6 } }, t("resetIntro"))
|
|
2455
2329
|
),
|
|
2456
2330
|
// 恢复出厂设置确认弹框
|
|
2457
|
-
resetOpen ? (0,
|
|
2331
|
+
resetOpen ? (0, import_react3.createElement)(
|
|
2458
2332
|
"div",
|
|
2459
2333
|
{ style: { position: "fixed", inset: 0, zIndex: 1e4, background: "rgba(0,0,0,.5)", display: "flex", alignItems: "center", justifyContent: "center", padding: 20 } },
|
|
2460
|
-
(0,
|
|
2334
|
+
(0, import_react3.createElement)(
|
|
2461
2335
|
"div",
|
|
2462
2336
|
{ style: { background: "var(--dsw-alias-bg-layer-1,#fff)", borderRadius: 12, maxWidth: 440, width: "100%", padding: "20px 22px", boxShadow: "0 8px 32px rgba(0,0,0,.18)" } },
|
|
2463
|
-
(0,
|
|
2464
|
-
(0,
|
|
2465
|
-
(0,
|
|
2337
|
+
(0, import_react3.createElement)("div", { style: { fontWeight: 600, fontSize: 15, color: "var(--dsw-alias-state-warn-primary,#b45309)", marginBottom: 10 } }, t("resetTitle")),
|
|
2338
|
+
(0, import_react3.createElement)("div", { style: { fontSize: 13, lineHeight: 1.7, color: "var(--dsw-alias-label-primary,inherit)", whiteSpace: "pre-line" } }, t("resetBody")),
|
|
2339
|
+
(0, import_react3.createElement)(
|
|
2466
2340
|
"div",
|
|
2467
2341
|
{ style: { display: "flex", gap: 8, marginTop: 16 } },
|
|
2468
|
-
(0,
|
|
2469
|
-
(0,
|
|
2342
|
+
(0, import_react3.createElement)("button", { style: { ...styles.btn, flex: 1 }, onClick: () => setResetOpen(false) }, t("cancel")),
|
|
2343
|
+
(0, import_react3.createElement)("button", { style: { ...styles.primary, flex: 1, background: "var(--dsw-alias-state-error-primary,#dc2626)" }, onClick: doFactoryReset }, t("resetConfirm"))
|
|
2470
2344
|
)
|
|
2471
2345
|
)
|
|
2472
2346
|
) : null,
|
|
2473
2347
|
// Toast:重置等操作的即时反馈(固定屏幕正中央,2.6s 自动消失)
|
|
2474
|
-
toast ? (0,
|
|
2348
|
+
toast ? (0, import_react3.createElement)("div", {
|
|
2475
2349
|
style: { position: "fixed", left: "50%", top: "50%", transform: "translate(-50%, -50%)", zIndex: 10001, width: "auto", maxWidth: 280, background: "rgba(17,24,39,.92)", color: "#fff", border: "none", borderRadius: 10, padding: "10px 16px", fontSize: 13, lineHeight: 1.5, textAlign: "center", boxShadow: "0 8px 24px rgba(0,0,0,.22)" }
|
|
2476
2350
|
}, toast) : null,
|
|
2477
2351
|
// 局域网访问开关确认弹框(关闭/打开时弹窗提醒)
|
|
2478
|
-
lanToggleOpen !== null ? (0,
|
|
2352
|
+
lanToggleOpen !== null ? (0, import_react3.createElement)(
|
|
2479
2353
|
"div",
|
|
2480
2354
|
{ style: { position: "fixed", inset: 0, zIndex: 1e4, background: "rgba(0,0,0,.5)", display: "flex", alignItems: "center", justifyContent: "center", padding: 20 } },
|
|
2481
|
-
(0,
|
|
2355
|
+
(0, import_react3.createElement)(
|
|
2482
2356
|
"div",
|
|
2483
2357
|
{ style: { background: "var(--dsw-alias-bg-layer-1,#fff)", borderRadius: 12, maxWidth: 420, width: "100%", padding: "20px 22px", boxShadow: "0 8px 32px rgba(0,0,0,.18)" } },
|
|
2484
|
-
(0,
|
|
2485
|
-
(0,
|
|
2486
|
-
(0,
|
|
2358
|
+
(0, import_react3.createElement)("div", { style: { fontWeight: 600, fontSize: 15, color: lanToggleOpen ? "var(--dsw-alias-brand-primary,#4f6ef7)" : "var(--dsw-alias-state-warn-primary,#b45309)", marginBottom: 10 } }, t(lanToggleOpen ? "lanToggleTitleOn" : "lanToggleTitleOff")),
|
|
2359
|
+
(0, import_react3.createElement)("div", { style: { fontSize: 13, lineHeight: 1.7, color: "var(--dsw-alias-label-primary,inherit)" } }, t(lanToggleOpen ? "lanToggleBodyOn" : "lanToggleBodyOff")),
|
|
2360
|
+
(0, import_react3.createElement)(
|
|
2487
2361
|
"div",
|
|
2488
2362
|
{ style: { display: "flex", gap: 8, marginTop: 16 } },
|
|
2489
|
-
(0,
|
|
2490
|
-
(0,
|
|
2363
|
+
(0, import_react3.createElement)("button", { style: { ...styles.btn, flex: 1 }, onClick: () => setLanToggleOpen(null) }, t("cancel")),
|
|
2364
|
+
(0, import_react3.createElement)("button", { style: { ...styles.primary, flex: 1 }, onClick: confirmLanToggle }, t("confirm"))
|
|
2491
2365
|
)
|
|
2492
2366
|
)
|
|
2493
2367
|
) : null,
|
|
2494
2368
|
// 安全免责声明弹框(issue #31):每次开启公网访问前确认
|
|
2495
|
-
disclaimerOpen ? (0,
|
|
2369
|
+
disclaimerOpen ? (0, import_react3.createElement)(
|
|
2496
2370
|
"div",
|
|
2497
2371
|
{ style: { position: "fixed", inset: 0, zIndex: 1e4, background: "rgba(0,0,0,.5)", display: "flex", alignItems: "center", justifyContent: "center", padding: 20 } },
|
|
2498
|
-
(0,
|
|
2372
|
+
(0, import_react3.createElement)(
|
|
2499
2373
|
"div",
|
|
2500
2374
|
{ style: { background: "var(--dsw-alias-bg-layer-1,#fff)", borderRadius: 12, maxWidth: 420, width: "100%", padding: "20px 22px", boxShadow: "0 8px 32px rgba(0,0,0,.18)" } },
|
|
2501
|
-
(0,
|
|
2502
|
-
(0,
|
|
2503
|
-
(0,
|
|
2375
|
+
(0, import_react3.createElement)("div", { style: { fontWeight: 600, fontSize: 15, color: "var(--dsw-alias-state-warn-primary,#b45309)", marginBottom: 10 } }, t("disclaimerTitle")),
|
|
2376
|
+
(0, import_react3.createElement)("div", { style: { fontSize: 13, lineHeight: 1.7, color: "var(--dsw-alias-label-primary,inherit)" } }, t("disclaimerBody")),
|
|
2377
|
+
(0, import_react3.createElement)(
|
|
2504
2378
|
"label",
|
|
2505
2379
|
{ style: { display: "flex", alignItems: "center", gap: 8, marginTop: 14, fontSize: 13, cursor: "pointer" } },
|
|
2506
|
-
(0,
|
|
2380
|
+
(0, import_react3.createElement)("input", { type: "checkbox", checked: disclaimerChecked, onChange: (e) => setDisclaimerChecked(e.target.checked), style: { width: 16, height: 16 } }),
|
|
2507
2381
|
t("disclaimerAgree")
|
|
2508
2382
|
),
|
|
2509
|
-
(0,
|
|
2383
|
+
(0, import_react3.createElement)(
|
|
2510
2384
|
"div",
|
|
2511
2385
|
{ style: { display: "flex", gap: 8, marginTop: 16 } },
|
|
2512
|
-
(0,
|
|
2513
|
-
(0,
|
|
2386
|
+
(0, import_react3.createElement)("button", { style: { ...styles.btn, flex: 1 }, onClick: () => setDisclaimerOpen(false) }, t("cancel")),
|
|
2387
|
+
(0, import_react3.createElement)("button", {
|
|
2514
2388
|
style: { ...styles.primary, flex: 1, opacity: disclaimerChecked ? 1 : 0.5 },
|
|
2515
2389
|
disabled: !disclaimerChecked,
|
|
2516
2390
|
onClick: confirmDisclaimer
|
|
2517
2391
|
}, t("disclaimerAgree"))
|
|
2518
2392
|
),
|
|
2519
|
-
!disclaimerChecked ? (0,
|
|
2393
|
+
!disclaimerChecked ? (0, import_react3.createElement)("div", { style: { marginTop: 8, fontSize: 12, color: "var(--dsw-alias-state-error-primary,#dc2626)" } }, t("disclaimerHint")) : null
|
|
2520
2394
|
)
|
|
2521
2395
|
) : null,
|
|
2522
2396
|
// 页面最底部:反馈入口
|
|
2523
|
-
(0,
|
|
2397
|
+
(0, import_react3.createElement)(
|
|
2524
2398
|
"div",
|
|
2525
2399
|
{ style: { ...styles.block, textAlign: "center" } },
|
|
2526
|
-
(0,
|
|
2400
|
+
(0, import_react3.createElement)(
|
|
2527
2401
|
"a",
|
|
2528
2402
|
{ href: "https://github.com/shaobeichen/dsh-pocket/issues", target: "_blank", rel: "noreferrer", style: { fontSize: 12, color: "var(--dsw-alias-label-secondary,#6b7280)", textDecoration: "none" } },
|
|
2529
2403
|
t("feedback")
|