@yezack/dsh-remote-mobile 1.10.0 → 1.10.2
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/CHANGELOG.md +54 -42
- package/LICENSE +21 -21
- package/README.md +203 -61
- package/README_EN.md +205 -57
- package/lib/auth/gate.js +1 -1
- package/lib/auth/token.d.ts +10 -10
- package/lib/auth/token.js +18 -15
- package/lib/bridge/compat.js +260 -260
- package/lib/bridge/directory-picker.d.ts +118 -0
- package/lib/bridge/directory-picker.js +617 -0
- package/lib/client.js +1010 -178
- package/lib/gateway/detector.d.ts +10 -12
- package/lib/gateway/detector.js +12 -25
- package/lib/gateway/server.d.ts +9 -9
- package/lib/gateway/server.js +10 -10
- package/lib/index.d.ts +1 -0
- package/lib/index.js +86 -35
- package/lib/routes/api.d.ts +15 -12
- package/lib/routes/api.js +113 -4
- package/lib/routes/login-page.js +9 -7
- package/lib/routes/register.d.ts +9 -0
- package/lib/routes/register.js +53 -0
- package/lib/startup-hint.d.ts +5 -0
- package/lib/startup-hint.js +72 -0
- package/lib/styles/style-snippets.js +639 -639
- package/package.json +3 -3
package/lib/client.js
CHANGED
|
@@ -47,10 +47,10 @@ __export(index_exports, {
|
|
|
47
47
|
inject: () => inject
|
|
48
48
|
});
|
|
49
49
|
module.exports = __toCommonJS(index_exports);
|
|
50
|
-
var
|
|
50
|
+
var import_react11 = __toESM(require("react"), 1);
|
|
51
51
|
|
|
52
52
|
// src/client/components/MainSection.jsx
|
|
53
|
-
var
|
|
53
|
+
var import_react10 = __toESM(require("react"), 1);
|
|
54
54
|
|
|
55
55
|
// src/client/api.js
|
|
56
56
|
var RM_API_BASE = (function() {
|
|
@@ -103,6 +103,13 @@ function updateAdvancedSecurityOptions(payload) {
|
|
|
103
103
|
body: JSON.stringify(payload)
|
|
104
104
|
});
|
|
105
105
|
}
|
|
106
|
+
function updateProxyConfig(payload) {
|
|
107
|
+
return safeFetchJson(RM_API_BASE + "update-options", {
|
|
108
|
+
method: "POST",
|
|
109
|
+
headers: { "Content-Type": "application/json" },
|
|
110
|
+
body: JSON.stringify(payload)
|
|
111
|
+
});
|
|
112
|
+
}
|
|
106
113
|
function updateSecret(secret) {
|
|
107
114
|
return safeFetchJson(RM_API_BASE + "set-secret", {
|
|
108
115
|
method: "POST",
|
|
@@ -172,6 +179,13 @@ function resetStylesApi() {
|
|
|
172
179
|
headers: { "Content-Type": "application/json" }
|
|
173
180
|
});
|
|
174
181
|
}
|
|
182
|
+
function toggleDirectoryPickerApi(enabled) {
|
|
183
|
+
return safeFetchJson(RM_API_BASE + "directory-picker", {
|
|
184
|
+
method: "POST",
|
|
185
|
+
headers: { "Content-Type": "application/json" },
|
|
186
|
+
body: JSON.stringify({ enabled: Boolean(enabled) })
|
|
187
|
+
});
|
|
188
|
+
}
|
|
175
189
|
|
|
176
190
|
// src/client/qrcode.js
|
|
177
191
|
var generateQrSvg = (function() {
|
|
@@ -687,6 +701,18 @@ var generateQrSvg = (function() {
|
|
|
687
701
|
};
|
|
688
702
|
})();
|
|
689
703
|
|
|
704
|
+
// src/client/utils/access.js
|
|
705
|
+
function resolveAccessPort(status) {
|
|
706
|
+
const port = Number(status?.proxy?.activePort);
|
|
707
|
+
if (!Number.isInteger(port) || port <= 0 || port > 65535) {
|
|
708
|
+
return null;
|
|
709
|
+
}
|
|
710
|
+
return port;
|
|
711
|
+
}
|
|
712
|
+
function buildDirectLink(host, port, token) {
|
|
713
|
+
return `http://${host}:${port}/auth?token=${token || ""}`;
|
|
714
|
+
}
|
|
715
|
+
|
|
690
716
|
// src/client/components/NetworkCard.jsx
|
|
691
717
|
var import_react = __toESM(require("react"), 1);
|
|
692
718
|
|
|
@@ -798,6 +824,30 @@ var translations = {
|
|
|
798
824
|
saveConfigSuccessToast: "\u9AD8\u7EA7\u5B89\u5168\u53C2\u6570\u5DF2\u6210\u529F\u4FDD\u5B58\u5E76\u540C\u6B65\u5230 settings.json\uFF01",
|
|
799
825
|
restoreDefaultsSuccessToast: "\u5DF2\u6210\u529F\u6062\u590D\u9ED8\u8BA4\u5B89\u5168\u53C2\u6570\u5E76\u7ACB\u5373\u751F\u6548\uFF01",
|
|
800
826
|
saveConfigFailTip: "\u53C2\u6570\u5FC5\u987B\u4E3A\u5927\u4E8E 0 \u7684\u6709\u6548\u6574\u6570",
|
|
827
|
+
// 卡片 9: 接入代理配置
|
|
828
|
+
proxyConfigCardTitle: "\u63A5\u5165\u4EE3\u7406\u914D\u7F6E",
|
|
829
|
+
proxyConfigCardDesc: "\u63A7\u5236\u63A5\u5165\u6A21\u5F0F\u3001\u4EE3\u7406\u76D1\u542C\u5730\u5740\u4E0E\u53D7\u4FE1\u4EFB\u57DF\u540D\u3002\u4FDD\u5B58\u540E\u9700\u91CD\u542F DSH \u751F\u6548\u3002",
|
|
830
|
+
proxyModeLabel: "\u63A5\u5165\u6A21\u5F0F",
|
|
831
|
+
proxyModeHint: "proxy\uFF1A\u6838\u5FC3\u56DE\u73AF\uFF0C\u7531\u63D2\u4EF6\u8F6C\u53D1\uFF1Bdirect\uFF1A\u4E0D\u542F\u52A8\u4EE3\u7406\uFF0C\u76F4\u63A5\u8BBF\u95EE\u6838\u5FC3",
|
|
832
|
+
proxyModeProxy: "\u5B89\u5168\u63A5\u5165\u4EE3\u7406\uFF08proxy\uFF09",
|
|
833
|
+
proxyModeDirect: "\u76F4\u8FDE\u6838\u5FC3\uFF08direct\uFF09",
|
|
834
|
+
proxyPortLabel: "\u4EE3\u7406\u7AEF\u53E3",
|
|
835
|
+
proxyPortHint: "\u9ED8\u8BA4 3081\uFF1B\u7AEF\u53E3\u5360\u7528\u65F6\u4F1A\u81EA\u52A8\u9012\u589E",
|
|
836
|
+
proxyHostLabel: "\u4EE3\u7406\u76D1\u542C\u5730\u5740",
|
|
837
|
+
proxyHostHint: "0.0.0.0 \u8868\u793A\u6240\u6709\u7F51\u5361\uFF1B127.0.0.1 \u4EC5\u672C\u673A",
|
|
838
|
+
proxyTrustedHostsLabel: "\u53D7\u4FE1\u4EFB\u57DF\u540D",
|
|
839
|
+
proxyTrustedHostsHint: "\u6BCF\u884C\u4E00\u4E2A\uFF0C\u4F8B\u5982 xxx.tailnet.ts.net\uFF1B\u81EA\u5B9A\u4E49\u53CD\u4EE3\u57DF\u540D\u5FC5\u987B\u52A0\u5165",
|
|
840
|
+
proxyRestartNote: "\u4FDD\u5B58\u540E\u9700\u91CD\u542F DSH \u624D\u4F1A\u91CD\u65B0\u7ED1\u5B9A\u76D1\u542C\u5730\u5740/\u7AEF\u53E3\u3002",
|
|
841
|
+
proxySaveBtn: "\u{1F4BE} \u4FDD\u5B58\u63A5\u5165\u914D\u7F6E",
|
|
842
|
+
proxySavingBtn: "\u6B63\u5728\u4FDD\u5B58...",
|
|
843
|
+
proxyResetBtn: "\u{1F504} \u6062\u590D\u9ED8\u8BA4",
|
|
844
|
+
proxySaveConfirm: "\u786E\u5B9A\u4FDD\u5B58\u63A5\u5165\u914D\u7F6E\u5417\uFF1F\u4FDD\u5B58\u540E\u9700\u91CD\u542F DSH \u751F\u6548\u3002",
|
|
845
|
+
proxyResetConfirm: "\u786E\u5B9A\u6062\u590D\u9ED8\u8BA4\u63A5\u5165\u914D\u7F6E\uFF08proxy\u30013081\u30010.0.0.0\u3001\u65E0\u53D7\u4FE1\u4EFB\u57DF\u540D\uFF09\u5417\uFF1F",
|
|
846
|
+
proxySavedToast: "\u63A5\u5165\u914D\u7F6E\u5DF2\u4FDD\u5B58\uFF1B\u91CD\u542F DSH \u540E\u751F\u6548\u3002",
|
|
847
|
+
proxyResetToast: "\u5DF2\u6062\u590D\u9ED8\u8BA4\u63A5\u5165\u914D\u7F6E\uFF1B\u91CD\u542F DSH \u540E\u751F\u6548\u3002",
|
|
848
|
+
proxySaveFailTip: "\u8BF7\u68C0\u67E5\u7AEF\u53E3\u3001\u76D1\u542C\u5730\u5740\u4E0E\u53D7\u4FE1\u4EFB\u57DF\u540D\u683C\u5F0F",
|
|
849
|
+
proxyCurrentRuntime: "\u5F53\u524D\u8FD0\u884C",
|
|
850
|
+
proxyNotReady: "\u5B89\u5168\u63A5\u5165\u4EE3\u7406\u672A\u5C31\u7EEA\uFF0C\u8BF7\u5148\u542F\u52A8\u4EE3\u7406",
|
|
801
851
|
// 卡片 8: 移动端样式片段(样式小插件)
|
|
802
852
|
tabAccess: "\u63A5\u5165",
|
|
803
853
|
tabDevices: "\u8BBE\u5907\u4E0E\u5B89\u5168",
|
|
@@ -841,6 +891,26 @@ var translations = {
|
|
|
841
891
|
conflictReportText: "[DSH \u63D2\u4EF6\u51B2\u7A81\u8BCA\u65AD\u62A5\u544A]\n\u73B0\u8C61\uFF1Adsh-remote-mobile \u8BBE\u7F6E\u9762\u677F\u63D0\u793A\u300C\u68C0\u6D4B\u5230\u5176\u4ED6\u8FDC\u7A0B\u63A5\u5165\u63D2\u4EF6\u300D\u3002\n\u539F\u56E0\uFF1A\u53E6\u4E00\u6B3E\u8FDC\u7A0B/Web \u63A5\u5165\u7C7B\u63D2\u4EF6\u5360\u7528\u4E86 Cordis \u5171\u4EAB\u670D\u52A1 remoteWebUiPairing\uFF0Cdsh-remote-mobile \u4E3A\u4FDD\u8BC1\u6B63\u5E38\u542F\u52A8\u5DF2\u81EA\u52A8\u8BA9\u51FA\u8BE5\u670D\u52A1\uFF0C\u5F53\u524D\u4E24\u5957\u8FDC\u7A0B\u63A5\u5165\u529F\u80FD\u5E76\u5B58\u3002\n\u5360\u7528\u65B9\u63D2\u4EF6\u5305\u540D\uFF1A{plugin}\n\u5360\u7528\u65B9 loader entry id\uFF1A{entryId}\n\u5904\u7406\u65B9\u6848\uFF08\u4E8C\u9009\u4E00\uFF09\uFF1A\n\u65B9\u6848 A\uFF08\u4FDD\u7559 dsh-remote-mobile\uFF0C\u7981\u7528\u5360\u7528\u65B9\uFF09\uFF1A\n1. \u6253\u5F00\u914D\u7F6E\u6587\u4EF6 ~/.dsh/profiles/web/cordis.patch.yml\n2. \u5728\u6587\u4EF6\u672B\u5C3E\u8FFD\u52A0\u4EE5\u4E0B\u4E24\u884C\uFF08\u6CE8\u610F YAML \u7F29\u8FDB\uFF0C\u7B2C\u4E8C\u884C\u524D\u6709\u4E24\u4E2A\u7A7A\u683C\uFF09\uFF1A\n- id: {entryId}\n disabled: true\n3. \u7ED3\u675F\u5F53\u524D\u6B63\u5728\u8FD0\u884C\u7684 dsh web \u8FDB\u7A0B\uFF0C\u91CD\u65B0\u6267\u884C dsh web --no-open\n\u65B9\u6848 B\uFF08\u4FDD\u7559\u5360\u7528\u65B9\uFF0C\u5378\u8F7D dsh-remote-mobile\uFF09\uFF1A\n\u6267\u884C\u547D\u4EE4 dsh plugin --profile web remove dsh-remote-mobile \u540E\u91CD\u542F dsh web",
|
|
842
892
|
conflictReportNoEntryIdText: "[DSH \u63D2\u4EF6\u51B2\u7A81\u8BCA\u65AD\u62A5\u544A]\n\u73B0\u8C61\uFF1Adsh-remote-mobile \u8BBE\u7F6E\u9762\u677F\u63D0\u793A\u300C\u68C0\u6D4B\u5230\u5176\u4ED6\u8FDC\u7A0B\u63A5\u5165\u63D2\u4EF6\u300D\u3002\n\u539F\u56E0\uFF1A\u53E6\u4E00\u6B3E\u8FDC\u7A0B/Web \u63A5\u5165\u7C7B\u63D2\u4EF6\u5360\u7528\u4E86 Cordis \u5171\u4EAB\u670D\u52A1 remoteWebUiPairing\uFF0Cdsh-remote-mobile \u4E3A\u4FDD\u8BC1\u6B63\u5E38\u542F\u52A8\u5DF2\u81EA\u52A8\u8BA9\u51FA\u8BE5\u670D\u52A1\uFF0C\u5F53\u524D\u4E24\u5957\u8FDC\u7A0B\u63A5\u5165\u529F\u80FD\u5E76\u5B58\u3002\n\u5360\u7528\u65B9\u63D2\u4EF6\u5305\u540D\uFF1A{plugin}\n\u5360\u7528\u65B9 loader entry id\uFF1A\u672A\u80FD\u81EA\u52A8\u8BC6\u522B\n\u5904\u7406\u65B9\u6848\uFF08\u4E8C\u9009\u4E00\uFF09\uFF1A\n\u65B9\u6848 A\uFF08\u4FDD\u7559 dsh-remote-mobile\uFF0C\u7981\u7528\u5360\u7528\u65B9\uFF09\uFF1A\n1. \u6267\u884C dsh --dump-config \u67E5\u770B\u5168\u90E8 loader entry\uFF0C\u627E\u5230\u5360\u7528\u65B9\u63D2\u4EF6\u5BF9\u5E94\u7684\u6761\u76EE id\n2. \u6253\u5F00\u914D\u7F6E\u6587\u4EF6 ~/.dsh/profiles/web/cordis.patch.yml\uFF0C\u5728\u6587\u4EF6\u672B\u5C3E\u8FFD\u52A0\uFF08\u6CE8\u610F YAML \u7F29\u8FDB\uFF09\uFF1A\n- id: <\u5360\u7528\u65B9\u6761\u76EEid>\n disabled: true\n3. \u7ED3\u675F\u5F53\u524D\u6B63\u5728\u8FD0\u884C\u7684 dsh web \u8FDB\u7A0B\uFF0C\u91CD\u65B0\u6267\u884C dsh web --no-open\n\u65B9\u6848 B\uFF08\u4FDD\u7559\u5360\u7528\u65B9\uFF0C\u5378\u8F7D dsh-remote-mobile\uFF09\uFF1A\n\u6267\u884C\u547D\u4EE4 dsh plugin --profile web remove dsh-remote-mobile \u540E\u91CD\u542F dsh web",
|
|
843
893
|
conflictBannerDismiss: "\u77E5\u9053\u4E86",
|
|
894
|
+
// 移动端目录选择器(添加工作区 / 选择文件夹)提醒与一键配置
|
|
895
|
+
dirPickerBannerTitle: "\u624B\u673A\u7AEF\u300C\u6DFB\u52A0\u5DE5\u4F5C\u533A / \u9009\u62E9\u6587\u4EF6\u5939\u300D\u53D7\u9650\u63D0\u9192",
|
|
896
|
+
dirPickerBannerBody: "\u5F53\u524D DSH \u6838\u5FC3\u7ED1\u5B9A\u5728\u672C\u5730\u56DE\u73AF\uFF08127.0.0.1\uFF09\uFF0C\u5B98\u65B9\u76EE\u5F55\u9009\u62E9\u5668\uFF08dsh-host-directory-picker-auto\uFF09\u4F1A\u5C06\u6765\u81EA 3081 \u4EE3\u7406\u7684\u624B\u673A\u8BF7\u6C42\u8BEF\u5224\u4E3A\u300C\u672C\u673A\u64CD\u4F5C\u300D\uFF0C\u4ECE\u800C\u628A\u6587\u4EF6\u5939\u9009\u62E9\u7A97\u53E3\u5F39\u5728\u7535\u8111\u5C4F\u5E55\u4E0A\uFF0C\u5BFC\u81F4\u624B\u673A\u7AEF\u4E00\u76F4\u7B49\u5F85\u3001\u65E0\u6CD5\u6DFB\u52A0\u5DE5\u4F5C\u533A\u3002\n\u53EF\u70B9\u51FB\u4E0B\u65B9\u6309\u94AE\u4E00\u952E\u5199\u5165\u7F51\u9875\u5185\u76EE\u5F55\u9009\u62E9\u5668\uFF08browse \u6A21\u5F0F\uFF0C\u5DF2\u5185\u7F6E\u9632\u91CD\u590D\u53BB\u91CD\uFF09\uFF0C\u5F00\u542F\u540E\u624B\u673A\u4E0E\u7535\u8111\u5747\u53EF\u76F4\u63A5\u5728\u7F51\u9875\u5185\u6D4F\u89C8\u5E76\u9009\u62E9\u6587\u4EF6\u5939\u3002",
|
|
897
|
+
dirPickerEnableBtn: "\u26A1 \u4E00\u952E\u5F00\u542F\u7F51\u9875\u76EE\u5F55\u9009\u62E9\u5668",
|
|
898
|
+
dirPickerEnablingBtn: "\u6B63\u5728\u5199\u5165\u914D\u7F6E...",
|
|
899
|
+
dirPickerCopyYamlBtn: "\u{1F4CB} \u590D\u5236 YAML \u914D\u7F6E",
|
|
900
|
+
dirPickerCopiedYamlTip: "\u5DF2\u590D\u5236\u76EE\u5F55\u9009\u62E9\u5668 YAML \u914D\u7F6E\uFF0C\u53EF\u7C98\u8D34\u5230 cordis.patch.yml",
|
|
901
|
+
dirPickerBannerDismiss: "\u6682\u4E0D\u5904\u7406",
|
|
902
|
+
dirPickerRestartBannerTitle: "\u7F51\u9875\u76EE\u5F55\u9009\u62E9\u5668\u914D\u7F6E\u5DF2\u5199\u5165\uFF08\u7B49\u5F85\u751F\u6548\uFF09",
|
|
903
|
+
dirPickerRestartBannerBody: "\u5DF2\u5C06\u7F51\u9875\u5185\u76EE\u5F55\u9009\u62E9\u5668\u914D\u7F6E\u5199\u5165 {path}\u3002\u82E5 DSH \u672A\u81EA\u52A8\u70ED\u91CD\u8F7D\uFF0C\u8BF7\u91CD\u542F dsh web \u5E76\u5237\u65B0\u624B\u673A\u9875\u9762\uFF0C\u5373\u53EF\u5728\u624B\u673A\u7AEF\u6B63\u5E38\u6DFB\u52A0\u5DE5\u4F5C\u533A\u3002",
|
|
904
|
+
dirPickerEnabledToast: "\u5DF2\u6210\u529F\u5199\u5165\u7F51\u9875\u76EE\u5F55\u9009\u62E9\u5668\u914D\u7F6E\uFF01\u82E5\u672A\u81EA\u52A8\u70ED\u91CD\u8F7D\uFF0C\u8BF7\u91CD\u542F dsh web \u751F\u6548\u3002",
|
|
905
|
+
dirPickerDisabledToast: "\u5DF2\u79FB\u9664\u7F51\u9875\u76EE\u5F55\u9009\u62E9\u5668\u914D\u7F6E\uFF08\u6062\u590D PC \u539F\u751F\u5F39\u7A97\uFF09\uFF0C\u91CD\u542F dsh web \u540E\u751F\u6548\u3002",
|
|
906
|
+
dirPickerDisableConfirm: "\u786E\u5B9A\u8981\u6062\u590D\u4E3A PC \u539F\u751F\u7CFB\u7EDF\u76EE\u5F55\u9009\u62E9\u5668\u5417\uFF1F\n\n\u6062\u590D\u540E\uFF0C\u7535\u8111\u7AEF\u5C06\u91CD\u65B0\u5F39\u51FA macOS / Windows \u539F\u751F\u6587\u4EF6\u5939\u7A97\u53E3\uFF0C\u4F46\u624B\u673A\u7AEF\u70B9\u51FB\u300C\u6DFB\u52A0\u5DE5\u4F5C\u533A / \u9009\u62E9\u6587\u4EF6\u5939\u300D\u65F6\u4F1A\u5F39\u5728\u7535\u8111\u684C\u9762\u4E0A\uFF0C\u5BFC\u81F4\u624B\u673A\u7AEF\u65E0\u6CD5\u72EC\u7ACB\u6DFB\u52A0\u5DE5\u4F5C\u533A\u3002",
|
|
907
|
+
dirPickerSectionTitle: "\u{1F4C1} \u79FB\u52A8\u7AEF\u6DFB\u52A0\u5DE5\u4F5C\u533A\uFF08\u76EE\u5F55\u9009\u62E9\u5668\u6A21\u5F0F\uFF09",
|
|
908
|
+
dirPickerSectionDesc: "\u63A7\u5236\u70B9\u51FB\u300C\u6DFB\u52A0\u5DE5\u4F5C\u533A / \u9009\u62E9\u6587\u4EF6\u5939\u300D\u65F6\u4F7F\u7528\u7F51\u9875\u5185\u76EE\u5F55\u6D4F\u89C8\u5668\uFF08\u624B\u673A+\u7535\u8111\u901A\u7528\uFF09\u8FD8\u662F\u7535\u8111\u7CFB\u7EDF\u539F\u751F\u5F39\u7A97\uFF08\u4EC5\u7535\u8111\u53EF\u7528\uFF09\u3002\u63D2\u4EF6\u5728\u5199\u5165 cordis.patch.yml \u65F6\u4F1A\u81EA\u52A8\u6267\u884C\u4E25\u683C\u5E42\u7B49\u53BB\u91CD\u3002",
|
|
909
|
+
dirPickerStatusActive: "\u{1F7E2} \u5DF2\u542F\u7528\u7F51\u9875\u5185\u76EE\u5F55\u9009\u62E9\u5668\uFF08\u624B\u673A\u7AEF\u53EF\u6B63\u5E38\u6DFB\u52A0\u5DE5\u4F5C\u533A\uFF09",
|
|
910
|
+
dirPickerStatusPendingRestart: "\u23F3 \u5DF2\u5199\u5165\u914D\u7F6E\uFF08\u91CD\u542F DSH \u6216\u70ED\u91CD\u8F7D\u540E\u751F\u6548\uFF09",
|
|
911
|
+
dirPickerStatusNativeWarn: "\u26A0\uFE0F \u5F53\u524D\u4E3A\u7CFB\u7EDF\u539F\u751F\u5F39\u7A97\uFF08\u624B\u673A\u7AEF\u65E0\u6CD5\u9009\u62E9\u6587\u4EF6\u5939\uFF09",
|
|
912
|
+
dirPickerRestoreNativeBtn: "\u{1F504} \u6062\u590D PC \u539F\u751F\u76EE\u5F55\u9009\u62E9\u5668",
|
|
913
|
+
dirPickerPatchFileLabel: "\u76EE\u6807\u914D\u7F6E\u6587\u4EF6\uFF1A",
|
|
844
914
|
// Toast 提示
|
|
845
915
|
toastDeviceConnected: "\u{1F389} \u65B0\u8BBE\u5907\u63A5\u5165\u6210\u529F\uFF1A{name} ({ip})",
|
|
846
916
|
toastDeviceOnline: "\u{1F4F6} \u8BBE\u5907\u91CD\u65B0\u4E0A\u7EBF\uFF1A{name} ({ip})",
|
|
@@ -952,6 +1022,30 @@ var translations = {
|
|
|
952
1022
|
saveConfigSuccessToast: "Security policy successfully saved and synced to settings.json!",
|
|
953
1023
|
restoreDefaultsSuccessToast: "Default security policies restored and applied immediately!",
|
|
954
1024
|
saveConfigFailTip: "Parameters must be valid integers greater than 0",
|
|
1025
|
+
// Card 9: Access Proxy Configuration
|
|
1026
|
+
proxyConfigCardTitle: "Access Proxy Configuration",
|
|
1027
|
+
proxyConfigCardDesc: "Configure the access mode, proxy listener, and trusted hosts. Restart DSH after saving.",
|
|
1028
|
+
proxyModeLabel: "Access mode",
|
|
1029
|
+
proxyModeHint: "proxy: core stays on loopback and the plugin forwards; direct: no proxy, access the core directly",
|
|
1030
|
+
proxyModeProxy: "Secure access proxy (proxy)",
|
|
1031
|
+
proxyModeDirect: "Direct core (direct)",
|
|
1032
|
+
proxyPortLabel: "Proxy port",
|
|
1033
|
+
proxyPortHint: "Default 3081; automatically increments if occupied",
|
|
1034
|
+
proxyHostLabel: "Proxy listen address",
|
|
1035
|
+
proxyHostHint: "0.0.0.0 means all interfaces; 127.0.0.1 means local only",
|
|
1036
|
+
proxyTrustedHostsLabel: "Trusted hosts",
|
|
1037
|
+
proxyTrustedHostsHint: "One per line, e.g. xxx.tailnet.ts.net; custom reverse-proxy domains must be listed",
|
|
1038
|
+
proxyRestartNote: "Restart DSH after saving to rebind the listen address/port.",
|
|
1039
|
+
proxySaveBtn: "\u{1F4BE} Save Access Config",
|
|
1040
|
+
proxySavingBtn: "Saving...",
|
|
1041
|
+
proxyResetBtn: "\u{1F504} Restore Defaults",
|
|
1042
|
+
proxySaveConfirm: "Save the access configuration? A DSH restart is required.",
|
|
1043
|
+
proxyResetConfirm: "Restore defaults (proxy, 3081, 0.0.0.0, no trusted hosts)?",
|
|
1044
|
+
proxySavedToast: "Access configuration saved; restart DSH to apply.",
|
|
1045
|
+
proxyResetToast: "Default access configuration restored; restart DSH to apply.",
|
|
1046
|
+
proxySaveFailTip: "Check the port, listen address, and trusted-host format",
|
|
1047
|
+
proxyCurrentRuntime: "Current runtime",
|
|
1048
|
+
proxyNotReady: "Secure access proxy is not ready. Start the proxy first.",
|
|
955
1049
|
// Card 8: Mobile Style Snippets (style mini-plugin)
|
|
956
1050
|
tabAccess: "Access",
|
|
957
1051
|
tabDevices: "Devices & Security",
|
|
@@ -995,6 +1089,26 @@ var translations = {
|
|
|
995
1089
|
conflictReportText: '[DSH plugin conflict diagnosis]\nSymptom: the dsh-remote-mobile settings panel shows "Another remote-access plugin detected".\nCause: another remote/Web access plugin registered the shared Cordis service remoteWebUiPairing first; dsh-remote-mobile yielded it to keep startup safe, so both remote features now run in parallel.\nConflicting plugin package: {plugin}\nConflicting loader entry id: {entryId}\nFix (choose ONE):\nOption A (keep dsh-remote-mobile, disable the other):\n1. Open ~/.dsh/profiles/web/cordis.patch.yml\n2. Append these two lines at the end (mind YAML indentation, two spaces before disabled):\n- id: {entryId}\n disabled: true\n3. Stop the running dsh web process, then run dsh web --no-open again\nOption B (keep the other, remove dsh-remote-mobile):\nRun dsh plugin --profile web remove dsh-remote-mobile and restart dsh web',
|
|
996
1090
|
conflictReportNoEntryIdText: '[DSH plugin conflict diagnosis]\nSymptom: the dsh-remote-mobile settings panel shows "Another remote-access plugin detected".\nCause: another remote/Web access plugin registered the shared Cordis service remoteWebUiPairing first; dsh-remote-mobile yielded it to keep startup safe, so both remote features now run in parallel.\nConflicting plugin package: {plugin}\nConflicting loader entry id: could not be detected automatically\nFix (choose ONE):\nOption A (keep dsh-remote-mobile, disable the other):\n1. Run dsh --dump-config to list all loader entries and find the entry id of the conflicting plugin\n2. Open ~/.dsh/profiles/web/cordis.patch.yml and append at the end (mind YAML indentation):\n- id: <the conflicting entry id>\n disabled: true\n3. Stop the running dsh web process, then run dsh web --no-open again\nOption B (keep the other, remove dsh-remote-mobile):\nRun dsh plugin --profile web remove dsh-remote-mobile and restart dsh web',
|
|
997
1091
|
conflictBannerDismiss: "Got it",
|
|
1092
|
+
// Mobile directory picker (Add Workspace / Select Folder) reminder & one-click patch
|
|
1093
|
+
dirPickerBannerTitle: 'Mobile "Add Workspace / Select Folder" Limitation',
|
|
1094
|
+
dirPickerBannerBody: "Because the DSH core stays on loopback (127.0.0.1), the official auto directory picker (dsh-host-directory-picker-auto) mistakes mobile requests via proxy 3081 for local desktop sessions and opens the native OS folder dialog on your PC screen \u2014 leaving your phone stuck waiting and unable to add workspaces.\nClick below to enable the in-app web directory browser (browse mode, with strict deduplication) so both mobile and PC can pick folders directly inside the web UI.",
|
|
1095
|
+
dirPickerEnableBtn: "\u26A1 Enable In-App Directory Browser",
|
|
1096
|
+
dirPickerEnablingBtn: "Applying patch...",
|
|
1097
|
+
dirPickerCopyYamlBtn: "\u{1F4CB} Copy YAML Snippet",
|
|
1098
|
+
dirPickerCopiedYamlTip: "YAML snippet copied! Paste it into cordis.patch.yml",
|
|
1099
|
+
dirPickerBannerDismiss: "Dismiss",
|
|
1100
|
+
dirPickerRestartBannerTitle: "In-App Directory Browser Configured (Pending Reload)",
|
|
1101
|
+
dirPickerRestartBannerBody: "Configuration has been written to {path}. If DSH does not hot-reload automatically, please restart dsh web and refresh your mobile browser to add workspaces on mobile.",
|
|
1102
|
+
dirPickerEnabledToast: "In-app directory browser enabled! Restart dsh web if HMR did not reload automatically.",
|
|
1103
|
+
dirPickerDisabledToast: "Restored PC native directory picker; restart dsh web to apply.",
|
|
1104
|
+
dirPickerDisableConfirm: "Restore the PC native OS folder dialog?\n\nOnce restored, PC will open the native macOS / Windows folder window again, but mobile devices will NOT be able to pick folders or add workspaces.",
|
|
1105
|
+
dirPickerSectionTitle: "\u{1F4C1} Mobile Workspace Directory Picker Mode",
|
|
1106
|
+
dirPickerSectionDesc: "Choose between the in-app web directory browser (works on both mobile and PC) and the native OS folder dialog (PC only). Writing to cordis.patch.yml automatically deduplicates entries.",
|
|
1107
|
+
dirPickerStatusActive: "\u{1F7E2} In-App Web Directory Browser Enabled (Mobile Ready)",
|
|
1108
|
+
dirPickerStatusPendingRestart: "\u23F3 Configured in patch file (Restart DSH or wait for HMR)",
|
|
1109
|
+
dirPickerStatusNativeWarn: "\u26A0\uFE0F Native OS Dialog Active (Mobile cannot add workspaces)",
|
|
1110
|
+
dirPickerRestoreNativeBtn: "\u{1F504} Restore PC Native Picker",
|
|
1111
|
+
dirPickerPatchFileLabel: "Target patch file: ",
|
|
998
1112
|
// Toast
|
|
999
1113
|
toastDeviceConnected: "\u{1F389} New device connected: {name} ({ip})",
|
|
1000
1114
|
toastDeviceOnline: "\u{1F4F6} Device reconnected: {name} ({ip})",
|
|
@@ -1065,7 +1179,10 @@ var import_jsx_runtime = require("react/jsx-runtime");
|
|
|
1065
1179
|
function NetworkCard({ status, toggleTailscale, toggleLan, copyText, lang }) {
|
|
1066
1180
|
const tsHost = status.tailscaleIp || "100.x.y.z";
|
|
1067
1181
|
const lanHost = status.lanIp || "127.0.0.1";
|
|
1068
|
-
const port = status
|
|
1182
|
+
const port = resolveAccessPort(status);
|
|
1183
|
+
const portReady = port !== null;
|
|
1184
|
+
const tailscaleAddress = portReady ? `http://${tsHost}:${port}` : null;
|
|
1185
|
+
const lanAddress = portReady ? `http://${lanHost}:${port}` : null;
|
|
1069
1186
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1070
1187
|
"div",
|
|
1071
1188
|
{
|
|
@@ -1099,7 +1216,7 @@ function NetworkCard({ status, toggleTailscale, toggleLan, copyText, lang }) {
|
|
|
1099
1216
|
children: t("netCardDesc", lang)
|
|
1100
1217
|
}
|
|
1101
1218
|
),
|
|
1102
|
-
status?.
|
|
1219
|
+
status?.proxy?.mode === "proxy" && status.proxy.running === false ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1103
1220
|
"div",
|
|
1104
1221
|
{
|
|
1105
1222
|
style: {
|
|
@@ -1116,9 +1233,9 @@ function NetworkCard({ status, toggleTailscale, toggleLan, copyText, lang }) {
|
|
|
1116
1233
|
children: [
|
|
1117
1234
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("strong", { children: [
|
|
1118
1235
|
"\u26A0\uFE0F ",
|
|
1119
|
-
lang === "en" ? "
|
|
1236
|
+
lang === "en" ? "Secure Proxy Not Ready" : "\u5B89\u5168\u63A5\u5165\u4EE3\u7406\u672A\u5C31\u7EEA"
|
|
1120
1237
|
] }),
|
|
1121
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: status.
|
|
1238
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: status.proxy.error ? `${lang === "en" ? "Failure reason: " : "\u542F\u52A8\u5931\u8D25\uFF1A"}${status.proxy.error}` : lang === "en" ? "Secure proxy is initializing or failed to bind port. External devices cannot connect currently." : "\u5B89\u5168\u63A5\u5165\u4EE3\u7406\u6B63\u5728\u542F\u52A8\u6216\u7AEF\u53E3\u7ED1\u5B9A\u5931\u8D25\uFF0C\u5916\u90E8\u624B\u673A\u8BBE\u5907\u5F53\u524D\u6682\u65F6\u65E0\u6CD5\u8FDE\u63A5\u3002" })
|
|
1122
1239
|
]
|
|
1123
1240
|
}
|
|
1124
1241
|
) : null,
|
|
@@ -1260,7 +1377,7 @@ function NetworkCard({ status, toggleTailscale, toggleLan, copyText, lang }) {
|
|
|
1260
1377
|
style: {
|
|
1261
1378
|
fontSize: "13px",
|
|
1262
1379
|
fontFamily: "monospace",
|
|
1263
|
-
color: "var(--dsw-alias-brand-primary, #3b82f6)",
|
|
1380
|
+
color: portReady ? "var(--dsw-alias-brand-primary, #3b82f6)" : "var(--dsw-alias-label-error, #ef4444)",
|
|
1264
1381
|
display: "flex",
|
|
1265
1382
|
alignItems: "center",
|
|
1266
1383
|
justifyContent: "space-between",
|
|
@@ -1281,22 +1398,24 @@ function NetworkCard({ status, toggleTailscale, toggleLan, copyText, lang }) {
|
|
|
1281
1398
|
flex: 1,
|
|
1282
1399
|
minWidth: 0
|
|
1283
1400
|
},
|
|
1284
|
-
children:
|
|
1401
|
+
children: tailscaleAddress || t("proxyNotReady", lang)
|
|
1285
1402
|
}
|
|
1286
1403
|
),
|
|
1287
1404
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1288
1405
|
"button",
|
|
1289
1406
|
{
|
|
1290
1407
|
type: "button",
|
|
1291
|
-
|
|
1408
|
+
disabled: !portReady,
|
|
1409
|
+
onClick: () => tailscaleAddress && copyText(tailscaleAddress, t("copiedTip", lang)),
|
|
1292
1410
|
style: {
|
|
1293
1411
|
padding: "3px 10px",
|
|
1294
1412
|
background: "var(--dsw-alias-bg-layer-3, rgba(255, 255, 255, 0.08))",
|
|
1295
1413
|
border: "1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.25))",
|
|
1296
1414
|
borderRadius: "4px",
|
|
1297
1415
|
fontSize: "11px",
|
|
1298
|
-
cursor: "pointer",
|
|
1416
|
+
cursor: portReady ? "pointer" : "not-allowed",
|
|
1299
1417
|
color: "var(--dsw-alias-label-secondary, inherit)",
|
|
1418
|
+
opacity: portReady ? 1 : 0.4,
|
|
1300
1419
|
whiteSpace: "nowrap",
|
|
1301
1420
|
flexShrink: 0
|
|
1302
1421
|
},
|
|
@@ -1446,7 +1565,7 @@ function NetworkCard({ status, toggleTailscale, toggleLan, copyText, lang }) {
|
|
|
1446
1565
|
style: {
|
|
1447
1566
|
fontSize: "13px",
|
|
1448
1567
|
fontFamily: "monospace",
|
|
1449
|
-
color: "var(--dsw-alias-brand-primary, #3b82f6)",
|
|
1568
|
+
color: portReady ? "var(--dsw-alias-brand-primary, #3b82f6)" : "var(--dsw-alias-label-error, #ef4444)",
|
|
1450
1569
|
display: "flex",
|
|
1451
1570
|
alignItems: "center",
|
|
1452
1571
|
justifyContent: "space-between",
|
|
@@ -1467,22 +1586,24 @@ function NetworkCard({ status, toggleTailscale, toggleLan, copyText, lang }) {
|
|
|
1467
1586
|
flex: 1,
|
|
1468
1587
|
minWidth: 0
|
|
1469
1588
|
},
|
|
1470
|
-
children:
|
|
1589
|
+
children: lanAddress || t("proxyNotReady", lang)
|
|
1471
1590
|
}
|
|
1472
1591
|
),
|
|
1473
1592
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1474
1593
|
"button",
|
|
1475
1594
|
{
|
|
1476
1595
|
type: "button",
|
|
1477
|
-
|
|
1596
|
+
disabled: !portReady,
|
|
1597
|
+
onClick: () => lanAddress && copyText(lanAddress, t("copiedTip", lang)),
|
|
1478
1598
|
style: {
|
|
1479
1599
|
padding: "3px 10px",
|
|
1480
1600
|
background: "var(--dsw-alias-bg-layer-3, rgba(255, 255, 255, 0.08))",
|
|
1481
1601
|
border: "1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.25))",
|
|
1482
1602
|
borderRadius: "4px",
|
|
1483
1603
|
fontSize: "11px",
|
|
1484
|
-
cursor: "pointer",
|
|
1604
|
+
cursor: portReady ? "pointer" : "not-allowed",
|
|
1485
1605
|
color: "var(--dsw-alias-label-secondary, inherit)",
|
|
1606
|
+
opacity: portReady ? 1 : 0.4,
|
|
1486
1607
|
whiteSpace: "nowrap",
|
|
1487
1608
|
flexShrink: 0
|
|
1488
1609
|
},
|
|
@@ -1591,10 +1712,12 @@ function QrPairingCard({
|
|
|
1591
1712
|
copyDirectLink,
|
|
1592
1713
|
lang
|
|
1593
1714
|
}) {
|
|
1594
|
-
const port = status
|
|
1715
|
+
const port = resolveAccessPort(status);
|
|
1716
|
+
const portReady = port !== null;
|
|
1717
|
+
const proxyUnavailable = status?.proxy?.mode === "proxy" && status.proxy.running === false;
|
|
1595
1718
|
const isExpired = timeLeft <= 0;
|
|
1596
1719
|
const currentHost = selectedTab === "lan" && status.lanIp ? status.lanIp : status.tailscaleIp || status.lanIp || typeof window !== "undefined" && window.location.hostname || "127.0.0.1";
|
|
1597
|
-
const directLink =
|
|
1720
|
+
const directLink = portReady ? buildDirectLink(currentHost, port, status.code || "") : "";
|
|
1598
1721
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
1599
1722
|
"div",
|
|
1600
1723
|
{
|
|
@@ -1629,7 +1752,7 @@ function QrPairingCard({
|
|
|
1629
1752
|
children: t("pairingCardDesc", lang)
|
|
1630
1753
|
}
|
|
1631
1754
|
),
|
|
1632
|
-
status?.
|
|
1755
|
+
status?.proxy?.mode === "proxy" && status.proxy.running === false ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
1633
1756
|
"div",
|
|
1634
1757
|
{
|
|
1635
1758
|
style: {
|
|
@@ -1646,14 +1769,34 @@ function QrPairingCard({
|
|
|
1646
1769
|
children: [
|
|
1647
1770
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("strong", { children: [
|
|
1648
1771
|
"\u26A0\uFE0F ",
|
|
1649
|
-
lang === "en" ? "
|
|
1772
|
+
lang === "en" ? "Secure Proxy Error" : "\u5B89\u5168\u63A5\u5165\u4EE3\u7406\u672A\u5C31\u7EEA"
|
|
1650
1773
|
] }),
|
|
1651
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { marginTop: "4px", fontSize: "12px" }, children: status.
|
|
1652
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { marginTop: "4px", fontSize: "11px", color: "var(--dsw-alias-label-tertiary, #888)" }, children: lang === "en" ? "Tip: Check
|
|
1774
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { marginTop: "4px", fontSize: "12px" }, children: status.proxy.error ? `${lang === "en" ? "Failure reason: " : "\u542F\u52A8\u5931\u8D25\uFF1A"}${status.proxy.error}` : lang === "en" ? "Secure proxy is initializing or port binding failed. External devices cannot connect currently." : "\u5B89\u5168\u63A5\u5165\u4EE3\u7406\u6B63\u5728\u542F\u52A8\u6216\u7AEF\u53E3\u7ED1\u5B9A\u5931\u8D25\uFF0C\u5916\u90E8\u624B\u673A\u8BBE\u5907\u6682\u65F6\u65E0\u6CD5\u626B\u7801\u8FDE\u63A5\u3002" }),
|
|
1775
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { marginTop: "4px", fontSize: "11px", color: "var(--dsw-alias-label-tertiary, #888)" }, children: lang === "en" ? "Tip: Check whether the secure proxy port (default 3081) is in use or inspect background logs." : "\u6392\u67E5\u5EFA\u8BAE\uFF1A\u8BF7\u68C0\u67E5\u5B89\u5168\u63A5\u5165\u4EE3\u7406\u7AEF\u53E3\uFF08\u9ED8\u8BA4 3081\uFF09\u662F\u5426\u88AB\u5176\u4ED6\u8FDB\u7A0B\u5360\u7528\uFF0C\u6216\u68C0\u67E5\u540E\u53F0\u7EC8\u7AEF\u65E5\u5FD7\u3002" })
|
|
1653
1776
|
]
|
|
1654
1777
|
}
|
|
1655
1778
|
) : null,
|
|
1656
|
-
|
|
1779
|
+
!portReady && !status.loading && !proxyUnavailable ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1780
|
+
"div",
|
|
1781
|
+
{
|
|
1782
|
+
style: {
|
|
1783
|
+
background: "rgba(245, 158, 11, 0.12)",
|
|
1784
|
+
border: "1px solid rgba(245, 158, 11, 0.35)",
|
|
1785
|
+
borderRadius: "8px",
|
|
1786
|
+
padding: "12px 14px",
|
|
1787
|
+
marginBottom: "14px",
|
|
1788
|
+
fontSize: "13px",
|
|
1789
|
+
color: "var(--dsw-alias-label-secondary, inherit)",
|
|
1790
|
+
lineHeight: "1.6",
|
|
1791
|
+
textAlign: "left"
|
|
1792
|
+
},
|
|
1793
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("strong", { children: [
|
|
1794
|
+
"\u26A0\uFE0F ",
|
|
1795
|
+
t("proxyNotReady", lang)
|
|
1796
|
+
] })
|
|
1797
|
+
}
|
|
1798
|
+
) : null,
|
|
1799
|
+
showQr && portReady && !proxyUnavailable ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
1657
1800
|
"div",
|
|
1658
1801
|
{
|
|
1659
1802
|
style: {
|
|
@@ -1814,30 +1957,30 @@ function QrPairingCard({
|
|
|
1814
1957
|
fontSize: "32px",
|
|
1815
1958
|
fontWeight: "800",
|
|
1816
1959
|
letterSpacing: showCode ? "6px" : "4px",
|
|
1817
|
-
color: status?.
|
|
1960
|
+
color: status?.proxy?.mode === "proxy" && status.proxy.running === false || isExpired ? "var(--dsw-alias-label-error, #ef4444)" : "var(--dsw-alias-brand-primary, #3b82f6)",
|
|
1818
1961
|
fontFamily: "monospace",
|
|
1819
1962
|
userSelect: "all"
|
|
1820
1963
|
},
|
|
1821
|
-
children: status?.
|
|
1964
|
+
children: status?.proxy?.mode === "proxy" && status.proxy.running === false ? lang === "en" ? "DISABLED" : "\u5DF2\u505C\u7528" : isExpired ? lang === "en" ? "EXPIRED" : "\u5DF2\u8FC7\u671F" : showCode ? status.code : "\u2022\u2022\u2022\u2022\u2022\u2022"
|
|
1822
1965
|
}
|
|
1823
1966
|
),
|
|
1824
1967
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1825
1968
|
"button",
|
|
1826
1969
|
{
|
|
1827
1970
|
type: "button",
|
|
1828
|
-
disabled: status?.
|
|
1971
|
+
disabled: status?.proxy?.mode === "proxy" && status.proxy.running === false,
|
|
1829
1972
|
onClick: () => setShowCode(!showCode),
|
|
1830
1973
|
title: showCode ? t("clickToHide", lang) : t("clickToReveal", lang),
|
|
1831
1974
|
style: {
|
|
1832
1975
|
background: "transparent",
|
|
1833
1976
|
border: "none",
|
|
1834
1977
|
color: "var(--dsw-alias-label-secondary, #888)",
|
|
1835
|
-
cursor: status?.
|
|
1978
|
+
cursor: status?.proxy?.mode === "proxy" && status.proxy.running === false ? "not-allowed" : "pointer",
|
|
1836
1979
|
display: "flex",
|
|
1837
1980
|
alignItems: "center",
|
|
1838
1981
|
justifyContent: "center",
|
|
1839
1982
|
padding: "4px",
|
|
1840
|
-
opacity: status?.
|
|
1983
|
+
opacity: status?.proxy?.mode === "proxy" && status.proxy.running === false ? 0.4 : 1
|
|
1841
1984
|
},
|
|
1842
1985
|
children: showCode ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { style: { width: "20px", height: "20px", fill: "currentColor" }, viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z" }) }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { style: { width: "20px", height: "20px", fill: "currentColor" }, viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M12 7c2.76 0 5 2.24 5 5 0 .65-.13 1.26-.36 1.83l2.92 2.92c1.51-1.26 2.7-2.89 3.43-4.75-1.73-4.39-6-7.5-11-7.5-1.4 0-2.74.25-3.98.7l2.16 2.16C10.74 7.13 11.35 7 12 7zM2 4.27l2.28 2.28.46.46C3.08 8.3 1.78 10.02 1 12c1.73 4.39 6 7.5 11 7.5 1.55 0 3.03-.3 4.38-.84l.42.42L19.73 22 21 20.73 3.27 3 2 4.27zM7.53 9.8l1.55 1.55c-.05.21-.08.43-.08.65 0 1.66 1.34 3 3 3 .22 0 .44-.03.65-.08l1.55 1.55c-.67.33-1.41.53-2.2.53-2.76 0-5-2.24-5-5 0-.79.2-1.53.53-2.2zm4.31-.78l3.15 3.15.02-.16c0-1.66-1.34-3-3-3l-.17.01z" }) })
|
|
1843
1986
|
}
|
|
@@ -1850,7 +1993,7 @@ function QrPairingCard({
|
|
|
1850
1993
|
{
|
|
1851
1994
|
style: {
|
|
1852
1995
|
fontSize: "12px",
|
|
1853
|
-
color: status?.
|
|
1996
|
+
color: status?.proxy?.mode === "proxy" && status.proxy.running === false || isExpired ? "var(--dsw-alias-label-error, #ef4444)" : "var(--dsw-alias-label-secondary, #888)",
|
|
1854
1997
|
margin: "4px 0 16px 0",
|
|
1855
1998
|
display: "flex",
|
|
1856
1999
|
alignItems: "center",
|
|
@@ -1866,11 +2009,11 @@ function QrPairingCard({
|
|
|
1866
2009
|
width: "8px",
|
|
1867
2010
|
height: "8px",
|
|
1868
2011
|
borderRadius: "50%",
|
|
1869
|
-
background: status?.
|
|
2012
|
+
background: status?.proxy?.mode === "proxy" && status.proxy.running === false || isExpired ? "#ef4444" : "#10b981"
|
|
1870
2013
|
}
|
|
1871
2014
|
}
|
|
1872
2015
|
),
|
|
1873
|
-
status?.
|
|
2016
|
+
status?.proxy?.mode === "proxy" && status.proxy.running === false ? `\u26A0\uFE0F ${lang === "en" ? "Proxy Service Error" : "\u5B89\u5168\u63A5\u5165\u4EE3\u7406\u670D\u52A1\u5F02\u5E38"}` : isExpired ? `\u26A0\uFE0F ${t("codeExpired", lang)}` : `${t("codeValidUntil", lang)}${formatCountdown(timeLeft, lang)}`
|
|
1874
2017
|
]
|
|
1875
2018
|
}
|
|
1876
2019
|
),
|
|
@@ -1888,7 +2031,7 @@ function QrPairingCard({
|
|
|
1888
2031
|
"button",
|
|
1889
2032
|
{
|
|
1890
2033
|
type: "button",
|
|
1891
|
-
disabled:
|
|
2034
|
+
disabled: proxyUnavailable || !portReady,
|
|
1892
2035
|
onClick: () => setShowQr(!showQr),
|
|
1893
2036
|
style: {
|
|
1894
2037
|
padding: "7px 16px",
|
|
@@ -1898,8 +2041,8 @@ function QrPairingCard({
|
|
|
1898
2041
|
borderRadius: "8px",
|
|
1899
2042
|
fontSize: "13px",
|
|
1900
2043
|
fontWeight: "600",
|
|
1901
|
-
cursor:
|
|
1902
|
-
opacity:
|
|
2044
|
+
cursor: proxyUnavailable || !portReady ? "not-allowed" : "pointer",
|
|
2045
|
+
opacity: proxyUnavailable || !portReady ? 0.4 : 1,
|
|
1903
2046
|
whiteSpace: "nowrap",
|
|
1904
2047
|
flexShrink: 0
|
|
1905
2048
|
},
|
|
@@ -1910,7 +2053,7 @@ function QrPairingCard({
|
|
|
1910
2053
|
"button",
|
|
1911
2054
|
{
|
|
1912
2055
|
type: "button",
|
|
1913
|
-
disabled: status?.
|
|
2056
|
+
disabled: status?.proxy?.mode === "proxy" && status.proxy.running === false,
|
|
1914
2057
|
onClick: refreshStatusAndCode,
|
|
1915
2058
|
style: {
|
|
1916
2059
|
padding: "7px 16px",
|
|
@@ -1920,8 +2063,8 @@ function QrPairingCard({
|
|
|
1920
2063
|
borderRadius: "8px",
|
|
1921
2064
|
fontSize: "13px",
|
|
1922
2065
|
fontWeight: "600",
|
|
1923
|
-
cursor: status?.
|
|
1924
|
-
opacity: status?.
|
|
2066
|
+
cursor: status?.proxy?.mode === "proxy" && status.proxy.running === false ? "not-allowed" : "pointer",
|
|
2067
|
+
opacity: status?.proxy?.mode === "proxy" && status.proxy.running === false ? 0.4 : 1,
|
|
1925
2068
|
whiteSpace: "nowrap",
|
|
1926
2069
|
flexShrink: 0
|
|
1927
2070
|
},
|
|
@@ -3090,21 +3233,365 @@ function ConfigCard({
|
|
|
3090
3233
|
);
|
|
3091
3234
|
}
|
|
3092
3235
|
|
|
3093
|
-
// src/client/components/
|
|
3236
|
+
// src/client/components/ProxyConfigCard.jsx
|
|
3094
3237
|
var import_react8 = __toESM(require("react"), 1);
|
|
3095
3238
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
3239
|
+
function ProxyConfigCard({
|
|
3240
|
+
status,
|
|
3241
|
+
modeInput,
|
|
3242
|
+
setModeInput,
|
|
3243
|
+
proxyPortInput,
|
|
3244
|
+
setProxyPortInput,
|
|
3245
|
+
proxyHostInput,
|
|
3246
|
+
setProxyHostInput,
|
|
3247
|
+
trustedHostsInput,
|
|
3248
|
+
setTrustedHostsInput,
|
|
3249
|
+
saveProxyConfig,
|
|
3250
|
+
resetProxyConfigDefaults,
|
|
3251
|
+
toggleDirectoryPicker,
|
|
3252
|
+
isPatchingDirPicker,
|
|
3253
|
+
copyText,
|
|
3254
|
+
isSaving,
|
|
3255
|
+
lang
|
|
3256
|
+
}) {
|
|
3257
|
+
const isDirect = modeInput === "direct";
|
|
3258
|
+
const dirPicker = status && status.directoryPicker || {};
|
|
3259
|
+
const isBrowseEnabled = Boolean(dirPicker.patchEnabled || dirPicker.runtimeActive);
|
|
3260
|
+
const fieldLabelStyle = {
|
|
3261
|
+
fontSize: "12px",
|
|
3262
|
+
fontWeight: "600",
|
|
3263
|
+
color: "var(--dsw-alias-label-primary, inherit)"
|
|
3264
|
+
};
|
|
3265
|
+
const fieldHintStyle = {
|
|
3266
|
+
fontSize: "11px",
|
|
3267
|
+
color: "var(--dsw-alias-label-tertiary, #888)",
|
|
3268
|
+
lineHeight: 1.5
|
|
3269
|
+
};
|
|
3270
|
+
const inputStyle = {
|
|
3271
|
+
height: "34px",
|
|
3272
|
+
background: "var(--dsw-alias-bg-layer-1, rgba(0,0,0,0.15))",
|
|
3273
|
+
border: "1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.25))",
|
|
3274
|
+
borderRadius: "6px",
|
|
3275
|
+
padding: "0 10px",
|
|
3276
|
+
color: "inherit",
|
|
3277
|
+
fontSize: "13px",
|
|
3278
|
+
outline: "none",
|
|
3279
|
+
boxSizing: "border-box",
|
|
3280
|
+
width: "100%"
|
|
3281
|
+
};
|
|
3282
|
+
const fieldBoxStyle = {
|
|
3283
|
+
display: "flex",
|
|
3284
|
+
flexDirection: "column",
|
|
3285
|
+
gap: "6px",
|
|
3286
|
+
background: "var(--dsw-alias-bg-layer-2, rgba(128,128,128,0.06))",
|
|
3287
|
+
border: "1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.12))",
|
|
3288
|
+
borderRadius: "8px",
|
|
3289
|
+
padding: "10px 12px"
|
|
3290
|
+
};
|
|
3291
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
3292
|
+
"div",
|
|
3293
|
+
{
|
|
3294
|
+
style: {
|
|
3295
|
+
background: "var(--dsw-alias-bg-layer-3, rgba(128,128,128,0.06))",
|
|
3296
|
+
border: "1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.15))",
|
|
3297
|
+
borderRadius: "12px",
|
|
3298
|
+
padding: "14px",
|
|
3299
|
+
display: "flex",
|
|
3300
|
+
flexDirection: "column",
|
|
3301
|
+
gap: "12px"
|
|
3302
|
+
},
|
|
3303
|
+
children: [
|
|
3304
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: "8px 12px", flexWrap: "wrap" }, children: [
|
|
3305
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
|
|
3306
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { fontSize: "16px" }, children: "\u{1F50C}" }),
|
|
3307
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { fontSize: "15px", fontWeight: "600", color: "var(--dsw-alias-label-primary, inherit)" }, children: t("proxyConfigCardTitle", lang) })
|
|
3308
|
+
] }),
|
|
3309
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
3310
|
+
"span",
|
|
3311
|
+
{
|
|
3312
|
+
style: {
|
|
3313
|
+
fontSize: "11px",
|
|
3314
|
+
color: "var(--dsw-alias-label-tertiary, #888)",
|
|
3315
|
+
background: "var(--dsw-alias-bg-layer-2, rgba(128,128,128,0.08))",
|
|
3316
|
+
border: "1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.15))",
|
|
3317
|
+
borderRadius: "999px",
|
|
3318
|
+
padding: "3px 8px",
|
|
3319
|
+
whiteSpace: "nowrap"
|
|
3320
|
+
},
|
|
3321
|
+
children: [
|
|
3322
|
+
t("proxyCurrentRuntime", lang),
|
|
3323
|
+
": ",
|
|
3324
|
+
status?.proxy?.mode || "-",
|
|
3325
|
+
" / ",
|
|
3326
|
+
status?.proxy?.activePort || "-"
|
|
3327
|
+
]
|
|
3328
|
+
}
|
|
3329
|
+
)
|
|
3330
|
+
] }),
|
|
3331
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { fontSize: "12px", color: "var(--dsw-alias-label-tertiary, #888)", lineHeight: 1.5 }, children: t("proxyConfigCardDesc", lang) }),
|
|
3332
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(200px, 1fr))", gap: "12px" }, children: [
|
|
3333
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: fieldBoxStyle, children: [
|
|
3334
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("label", { style: fieldLabelStyle, children: t("proxyModeLabel", lang) }),
|
|
3335
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
3336
|
+
"select",
|
|
3337
|
+
{
|
|
3338
|
+
value: modeInput,
|
|
3339
|
+
onChange: (e) => setModeInput(e.target.value),
|
|
3340
|
+
style: { ...inputStyle, cursor: "pointer" },
|
|
3341
|
+
children: [
|
|
3342
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: "proxy", children: t("proxyModeProxy", lang) }),
|
|
3343
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: "direct", children: t("proxyModeDirect", lang) })
|
|
3344
|
+
]
|
|
3345
|
+
}
|
|
3346
|
+
),
|
|
3347
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: fieldHintStyle, children: t("proxyModeHint", lang) })
|
|
3348
|
+
] }),
|
|
3349
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: fieldBoxStyle, children: [
|
|
3350
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("label", { style: fieldLabelStyle, children: t("proxyPortLabel", lang) }),
|
|
3351
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3352
|
+
"input",
|
|
3353
|
+
{
|
|
3354
|
+
type: "number",
|
|
3355
|
+
min: "1",
|
|
3356
|
+
max: "65535",
|
|
3357
|
+
value: proxyPortInput,
|
|
3358
|
+
onChange: (e) => setProxyPortInput(e.target.value),
|
|
3359
|
+
disabled: isDirect,
|
|
3360
|
+
style: { ...inputStyle, opacity: isDirect ? 0.55 : 1 }
|
|
3361
|
+
}
|
|
3362
|
+
),
|
|
3363
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: fieldHintStyle, children: t("proxyPortHint", lang) })
|
|
3364
|
+
] }),
|
|
3365
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: fieldBoxStyle, children: [
|
|
3366
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("label", { style: fieldLabelStyle, children: t("proxyHostLabel", lang) }),
|
|
3367
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3368
|
+
"input",
|
|
3369
|
+
{
|
|
3370
|
+
type: "text",
|
|
3371
|
+
value: proxyHostInput,
|
|
3372
|
+
onChange: (e) => setProxyHostInput(e.target.value),
|
|
3373
|
+
placeholder: "0.0.0.0",
|
|
3374
|
+
disabled: isDirect,
|
|
3375
|
+
style: { ...inputStyle, opacity: isDirect ? 0.55 : 1 }
|
|
3376
|
+
}
|
|
3377
|
+
),
|
|
3378
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: fieldHintStyle, children: t("proxyHostHint", lang) })
|
|
3379
|
+
] })
|
|
3380
|
+
] }),
|
|
3381
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: fieldBoxStyle, children: [
|
|
3382
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("label", { style: fieldLabelStyle, children: t("proxyTrustedHostsLabel", lang) }),
|
|
3383
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3384
|
+
"textarea",
|
|
3385
|
+
{
|
|
3386
|
+
value: trustedHostsInput,
|
|
3387
|
+
onChange: (e) => setTrustedHostsInput(e.target.value),
|
|
3388
|
+
placeholder: "xxx.tailnet.ts.net\ndsh.example.com",
|
|
3389
|
+
rows: 3,
|
|
3390
|
+
spellCheck: false,
|
|
3391
|
+
style: {
|
|
3392
|
+
...inputStyle,
|
|
3393
|
+
height: "auto",
|
|
3394
|
+
minHeight: "70px",
|
|
3395
|
+
padding: "8px 10px",
|
|
3396
|
+
resize: "vertical",
|
|
3397
|
+
fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace"
|
|
3398
|
+
}
|
|
3399
|
+
}
|
|
3400
|
+
),
|
|
3401
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: fieldHintStyle, children: t("proxyTrustedHostsHint", lang) })
|
|
3402
|
+
] }),
|
|
3403
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { fontSize: "11px", color: "#f59e0b", lineHeight: 1.5 }, children: [
|
|
3404
|
+
"\u26A0\uFE0F ",
|
|
3405
|
+
t("proxyRestartNote", lang)
|
|
3406
|
+
] }),
|
|
3407
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { display: "flex", alignItems: "center", justifyContent: "flex-end", gap: "10px", flexWrap: "wrap" }, children: [
|
|
3408
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3409
|
+
"button",
|
|
3410
|
+
{
|
|
3411
|
+
type: "button",
|
|
3412
|
+
onClick: resetProxyConfigDefaults,
|
|
3413
|
+
disabled: isSaving,
|
|
3414
|
+
style: {
|
|
3415
|
+
padding: "6px 14px",
|
|
3416
|
+
background: "transparent",
|
|
3417
|
+
border: "1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.25))",
|
|
3418
|
+
color: "var(--dsw-alias-label-secondary, inherit)",
|
|
3419
|
+
borderRadius: "6px",
|
|
3420
|
+
fontSize: "12px",
|
|
3421
|
+
cursor: isSaving ? "not-allowed" : "pointer",
|
|
3422
|
+
opacity: isSaving ? 0.6 : 1,
|
|
3423
|
+
whiteSpace: "nowrap"
|
|
3424
|
+
},
|
|
3425
|
+
children: t("proxyResetBtn", lang)
|
|
3426
|
+
}
|
|
3427
|
+
),
|
|
3428
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3429
|
+
"button",
|
|
3430
|
+
{
|
|
3431
|
+
type: "button",
|
|
3432
|
+
onClick: saveProxyConfig,
|
|
3433
|
+
disabled: isSaving,
|
|
3434
|
+
style: {
|
|
3435
|
+
padding: "6px 18px",
|
|
3436
|
+
background: "#2563eb",
|
|
3437
|
+
border: "none",
|
|
3438
|
+
color: "#ffffff",
|
|
3439
|
+
borderRadius: "6px",
|
|
3440
|
+
fontSize: "12px",
|
|
3441
|
+
fontWeight: "600",
|
|
3442
|
+
cursor: isSaving ? "not-allowed" : "pointer",
|
|
3443
|
+
opacity: isSaving ? 0.7 : 1,
|
|
3444
|
+
whiteSpace: "nowrap",
|
|
3445
|
+
boxShadow: "0 2px 6px rgba(37, 99, 235, 0.3)"
|
|
3446
|
+
},
|
|
3447
|
+
children: isSaving ? t("proxySavingBtn", lang) : t("proxySaveBtn", lang)
|
|
3448
|
+
}
|
|
3449
|
+
)
|
|
3450
|
+
] }),
|
|
3451
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
3452
|
+
"div",
|
|
3453
|
+
{
|
|
3454
|
+
style: {
|
|
3455
|
+
...fieldBoxStyle,
|
|
3456
|
+
marginTop: "4px",
|
|
3457
|
+
border: isBrowseEnabled ? "1px solid rgba(16, 185, 129, 0.3)" : "1px solid rgba(245, 158, 11, 0.35)",
|
|
3458
|
+
background: isBrowseEnabled ? "rgba(16, 185, 129, 0.06)" : "rgba(245, 158, 11, 0.08)"
|
|
3459
|
+
},
|
|
3460
|
+
children: [
|
|
3461
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
3462
|
+
"div",
|
|
3463
|
+
{
|
|
3464
|
+
style: {
|
|
3465
|
+
display: "flex",
|
|
3466
|
+
alignItems: "center",
|
|
3467
|
+
justifyContent: "space-between",
|
|
3468
|
+
gap: "8px",
|
|
3469
|
+
flexWrap: "wrap"
|
|
3470
|
+
},
|
|
3471
|
+
children: [
|
|
3472
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: fieldLabelStyle, children: t("dirPickerSectionTitle", lang) }),
|
|
3473
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3474
|
+
"span",
|
|
3475
|
+
{
|
|
3476
|
+
style: {
|
|
3477
|
+
fontSize: "11px",
|
|
3478
|
+
fontWeight: "600",
|
|
3479
|
+
color: isBrowseEnabled ? "#10b981" : "#f59e0b"
|
|
3480
|
+
},
|
|
3481
|
+
children: dirPicker.restartRequired ? t("dirPickerStatusPendingRestart", lang) : isBrowseEnabled ? t("dirPickerStatusActive", lang) : t("dirPickerStatusNativeWarn", lang)
|
|
3482
|
+
}
|
|
3483
|
+
)
|
|
3484
|
+
]
|
|
3485
|
+
}
|
|
3486
|
+
),
|
|
3487
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: fieldHintStyle, children: t("dirPickerSectionDesc", lang) }),
|
|
3488
|
+
dirPicker.patchFilePath ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
3489
|
+
"div",
|
|
3490
|
+
{
|
|
3491
|
+
style: {
|
|
3492
|
+
fontSize: "11px",
|
|
3493
|
+
color: "var(--dsw-alias-label-tertiary, #888)",
|
|
3494
|
+
fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
|
|
3495
|
+
wordBreak: "break-all"
|
|
3496
|
+
},
|
|
3497
|
+
children: [
|
|
3498
|
+
t("dirPickerPatchFileLabel", lang),
|
|
3499
|
+
dirPicker.patchFilePath
|
|
3500
|
+
]
|
|
3501
|
+
}
|
|
3502
|
+
) : null,
|
|
3503
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
3504
|
+
"div",
|
|
3505
|
+
{
|
|
3506
|
+
style: {
|
|
3507
|
+
display: "flex",
|
|
3508
|
+
alignItems: "center",
|
|
3509
|
+
gap: "8px",
|
|
3510
|
+
flexWrap: "wrap",
|
|
3511
|
+
marginTop: "4px"
|
|
3512
|
+
},
|
|
3513
|
+
children: [
|
|
3514
|
+
typeof toggleDirectoryPicker === "function" ? isBrowseEnabled ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3515
|
+
"button",
|
|
3516
|
+
{
|
|
3517
|
+
type: "button",
|
|
3518
|
+
disabled: isPatchingDirPicker,
|
|
3519
|
+
onClick: () => toggleDirectoryPicker(false),
|
|
3520
|
+
style: {
|
|
3521
|
+
padding: "5px 12px",
|
|
3522
|
+
background: "transparent",
|
|
3523
|
+
border: "1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.3))",
|
|
3524
|
+
color: "var(--dsw-alias-label-secondary, inherit)",
|
|
3525
|
+
borderRadius: "6px",
|
|
3526
|
+
fontSize: "12px",
|
|
3527
|
+
cursor: isPatchingDirPicker ? "not-allowed" : "pointer",
|
|
3528
|
+
opacity: isPatchingDirPicker ? 0.6 : 1
|
|
3529
|
+
},
|
|
3530
|
+
children: t("dirPickerRestoreNativeBtn", lang)
|
|
3531
|
+
}
|
|
3532
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3533
|
+
"button",
|
|
3534
|
+
{
|
|
3535
|
+
type: "button",
|
|
3536
|
+
disabled: isPatchingDirPicker,
|
|
3537
|
+
onClick: () => toggleDirectoryPicker(true),
|
|
3538
|
+
style: {
|
|
3539
|
+
padding: "5px 12px",
|
|
3540
|
+
background: "#2563eb",
|
|
3541
|
+
border: "none",
|
|
3542
|
+
color: "#ffffff",
|
|
3543
|
+
borderRadius: "6px",
|
|
3544
|
+
fontSize: "12px",
|
|
3545
|
+
fontWeight: "600",
|
|
3546
|
+
cursor: isPatchingDirPicker ? "not-allowed" : "pointer",
|
|
3547
|
+
opacity: isPatchingDirPicker ? 0.7 : 1
|
|
3548
|
+
},
|
|
3549
|
+
children: isPatchingDirPicker ? t("dirPickerEnablingBtn", lang) : t("dirPickerEnableBtn", lang)
|
|
3550
|
+
}
|
|
3551
|
+
) : null,
|
|
3552
|
+
typeof copyText === "function" && dirPicker.yamlSnippet ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3553
|
+
"button",
|
|
3554
|
+
{
|
|
3555
|
+
type: "button",
|
|
3556
|
+
onClick: () => copyText(dirPicker.yamlSnippet, t("dirPickerCopiedYamlTip", lang)),
|
|
3557
|
+
style: {
|
|
3558
|
+
padding: "5px 10px",
|
|
3559
|
+
background: "transparent",
|
|
3560
|
+
border: "1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.25))",
|
|
3561
|
+
color: "var(--dsw-alias-label-secondary, inherit)",
|
|
3562
|
+
borderRadius: "6px",
|
|
3563
|
+
fontSize: "12px",
|
|
3564
|
+
cursor: "pointer"
|
|
3565
|
+
},
|
|
3566
|
+
children: t("dirPickerCopyYamlBtn", lang)
|
|
3567
|
+
}
|
|
3568
|
+
) : null
|
|
3569
|
+
]
|
|
3570
|
+
}
|
|
3571
|
+
)
|
|
3572
|
+
]
|
|
3573
|
+
}
|
|
3574
|
+
)
|
|
3575
|
+
]
|
|
3576
|
+
}
|
|
3577
|
+
);
|
|
3578
|
+
}
|
|
3579
|
+
|
|
3580
|
+
// src/client/components/StylesCard.jsx
|
|
3581
|
+
var import_react9 = __toESM(require("react"), 1);
|
|
3582
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
3096
3583
|
function StylesCard({ lang, showToast }) {
|
|
3097
|
-
const [snippets, setSnippets] = (0,
|
|
3098
|
-
const [loading, setLoading] = (0,
|
|
3099
|
-
const [editingId, setEditingId] = (0,
|
|
3100
|
-
const [showForm, setShowForm] = (0,
|
|
3101
|
-
const [name, setName] = (0,
|
|
3102
|
-
const [css, setCss] = (0,
|
|
3103
|
-
const [pcEnabled, setPcEnabled] = (0,
|
|
3104
|
-
const [mobileEnabled, setMobileEnabled] = (0,
|
|
3105
|
-
const [expanded, setExpanded] = (0,
|
|
3106
|
-
const [feedback, setFeedback] = (0,
|
|
3107
|
-
const showFeedback = (0,
|
|
3584
|
+
const [snippets, setSnippets] = (0, import_react9.useState)([]);
|
|
3585
|
+
const [loading, setLoading] = (0, import_react9.useState)(true);
|
|
3586
|
+
const [editingId, setEditingId] = (0, import_react9.useState)(null);
|
|
3587
|
+
const [showForm, setShowForm] = (0, import_react9.useState)(false);
|
|
3588
|
+
const [name, setName] = (0, import_react9.useState)("");
|
|
3589
|
+
const [css, setCss] = (0, import_react9.useState)("");
|
|
3590
|
+
const [pcEnabled, setPcEnabled] = (0, import_react9.useState)(false);
|
|
3591
|
+
const [mobileEnabled, setMobileEnabled] = (0, import_react9.useState)(true);
|
|
3592
|
+
const [expanded, setExpanded] = (0, import_react9.useState)({});
|
|
3593
|
+
const [feedback, setFeedback] = (0, import_react9.useState)("");
|
|
3594
|
+
const showFeedback = (0, import_react9.useCallback)((msg, type = "success") => {
|
|
3108
3595
|
if (typeof showToast === "function") {
|
|
3109
3596
|
showToast(msg, type);
|
|
3110
3597
|
} else {
|
|
@@ -3112,7 +3599,7 @@ function StylesCard({ lang, showToast }) {
|
|
|
3112
3599
|
setTimeout(() => setFeedback(""), 3500);
|
|
3113
3600
|
}
|
|
3114
3601
|
}, [showToast]);
|
|
3115
|
-
const load = (0,
|
|
3602
|
+
const load = (0, import_react9.useCallback)(() => {
|
|
3116
3603
|
fetchStyles().then((data) => {
|
|
3117
3604
|
setSnippets(data.snippets || []);
|
|
3118
3605
|
setLoading(false);
|
|
@@ -3121,7 +3608,7 @@ function StylesCard({ lang, showToast }) {
|
|
|
3121
3608
|
showFeedback(t("stylesLoadFail", lang), "danger");
|
|
3122
3609
|
});
|
|
3123
3610
|
}, [lang, showFeedback]);
|
|
3124
|
-
(0,
|
|
3611
|
+
(0, import_react9.useEffect)(() => {
|
|
3125
3612
|
load();
|
|
3126
3613
|
}, [load]);
|
|
3127
3614
|
const toggle = (id, scope, enabled) => {
|
|
@@ -3263,7 +3750,7 @@ function StylesCard({ lang, showToast }) {
|
|
|
3263
3750
|
color: "var(--dsw-alias-brand-primary, #3b82f6)",
|
|
3264
3751
|
border: "1px solid rgba(59,130,246,0.3)"
|
|
3265
3752
|
};
|
|
3266
|
-
return /* @__PURE__ */ (0,
|
|
3753
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
3267
3754
|
"div",
|
|
3268
3755
|
{
|
|
3269
3756
|
style: {
|
|
@@ -3276,15 +3763,15 @@ function StylesCard({ lang, showToast }) {
|
|
|
3276
3763
|
gap: "14px"
|
|
3277
3764
|
},
|
|
3278
3765
|
children: [
|
|
3279
|
-
/* @__PURE__ */ (0,
|
|
3280
|
-
/* @__PURE__ */ (0,
|
|
3281
|
-
/* @__PURE__ */ (0,
|
|
3282
|
-
/* @__PURE__ */ (0,
|
|
3766
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: "10px", flexWrap: "wrap" }, children: [
|
|
3767
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
|
|
3768
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: { fontSize: "16px" }, children: "\u{1F3A8}" }),
|
|
3769
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: { fontSize: "15px", fontWeight: "600", color: "var(--dsw-alias-label-primary, inherit)" }, children: t("stylesCardTitle", lang) })
|
|
3283
3770
|
] }),
|
|
3284
|
-
/* @__PURE__ */ (0,
|
|
3771
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", onClick: resetAll, style: miniBtnStyle, children: t("stylesResetAll", lang) })
|
|
3285
3772
|
] }),
|
|
3286
|
-
/* @__PURE__ */ (0,
|
|
3287
|
-
feedback && typeof showToast !== "function" ? /* @__PURE__ */ (0,
|
|
3773
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { fontSize: "12px", color: "var(--dsw-alias-label-tertiary, #888)", lineHeight: "1.5" }, children: t("stylesCardDesc", lang) }),
|
|
3774
|
+
feedback && typeof showToast !== "function" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3288
3775
|
"div",
|
|
3289
3776
|
{
|
|
3290
3777
|
style: {
|
|
@@ -3298,15 +3785,15 @@ function StylesCard({ lang, showToast }) {
|
|
|
3298
3785
|
children: feedback
|
|
3299
3786
|
}
|
|
3300
3787
|
) : null,
|
|
3301
|
-
loading ? /* @__PURE__ */ (0,
|
|
3302
|
-
snippets.some((s) => s.builtin) ? /* @__PURE__ */ (0,
|
|
3303
|
-
/* @__PURE__ */ (0,
|
|
3304
|
-
/* @__PURE__ */ (0,
|
|
3305
|
-
/* @__PURE__ */ (0,
|
|
3306
|
-
/* @__PURE__ */ (0,
|
|
3307
|
-
/* @__PURE__ */ (0,
|
|
3308
|
-
/* @__PURE__ */ (0,
|
|
3309
|
-
/* @__PURE__ */ (0,
|
|
3788
|
+
loading ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { fontSize: "12px", color: "var(--dsw-alias-label-tertiary, #888)" }, children: lang === "en" ? "Loading style snippets..." : "\u6B63\u5728\u52A0\u8F7D\u6837\u5F0F\u7247\u6BB5..." }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
3789
|
+
snippets.some((s) => s.builtin) ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
3790
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { fontSize: "13px", fontWeight: "600", color: "var(--dsw-alias-label-secondary, inherit)" }, children: t("stylesPresetsTitle", lang) }),
|
|
3791
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: "8px" }, children: snippets.filter((s) => s.builtin).map((s) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: rowStyle, children: [
|
|
3792
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { display: "flex", alignItems: "flex-start", justifyContent: "space-between", gap: "8px", flexWrap: "wrap" }, children: [
|
|
3793
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { flex: "1 1 180px", minWidth: 0, maxWidth: "100%" }, children: [
|
|
3794
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "6px", flexWrap: "wrap" }, children: [
|
|
3795
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: { fontSize: "12px", fontWeight: "600", color: "var(--dsw-alias-label-primary, inherit)" }, children: s.name }),
|
|
3796
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3310
3797
|
"span",
|
|
3311
3798
|
{
|
|
3312
3799
|
style: {
|
|
@@ -3320,7 +3807,7 @@ function StylesCard({ lang, showToast }) {
|
|
|
3320
3807
|
children: "Preset"
|
|
3321
3808
|
}
|
|
3322
3809
|
),
|
|
3323
|
-
/* @__PURE__ */ (0,
|
|
3810
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3324
3811
|
"span",
|
|
3325
3812
|
{
|
|
3326
3813
|
style: {
|
|
@@ -3335,11 +3822,11 @@ function StylesCard({ lang, showToast }) {
|
|
|
3335
3822
|
}
|
|
3336
3823
|
)
|
|
3337
3824
|
] }),
|
|
3338
|
-
s.description ? /* @__PURE__ */ (0,
|
|
3825
|
+
s.description ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { fontSize: "11px", color: "var(--dsw-alias-label-tertiary, #888)", marginTop: "3px" }, children: s.description }) : null
|
|
3339
3826
|
] }),
|
|
3340
|
-
/* @__PURE__ */ (0,
|
|
3341
|
-
/* @__PURE__ */ (0,
|
|
3342
|
-
/* @__PURE__ */ (0,
|
|
3827
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "6px 8px", flexWrap: "wrap", maxWidth: "100%" }, children: [
|
|
3828
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { style: { display: "inline-flex", alignItems: "center", gap: "4px", fontSize: "11px", cursor: "pointer", whiteSpace: "nowrap" }, children: [
|
|
3829
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3343
3830
|
"input",
|
|
3344
3831
|
{
|
|
3345
3832
|
type: "checkbox",
|
|
@@ -3351,8 +3838,8 @@ function StylesCard({ lang, showToast }) {
|
|
|
3351
3838
|
"\u{1F5A5}\uFE0F ",
|
|
3352
3839
|
t("stylesPcShort", lang)
|
|
3353
3840
|
] }),
|
|
3354
|
-
/* @__PURE__ */ (0,
|
|
3355
|
-
/* @__PURE__ */ (0,
|
|
3841
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { style: { display: "inline-flex", alignItems: "center", gap: "4px", fontSize: "11px", cursor: "pointer", whiteSpace: "nowrap" }, children: [
|
|
3842
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3356
3843
|
"input",
|
|
3357
3844
|
{
|
|
3358
3845
|
type: "checkbox",
|
|
@@ -3364,13 +3851,13 @@ function StylesCard({ lang, showToast }) {
|
|
|
3364
3851
|
"\u{1F4F1} ",
|
|
3365
3852
|
t("stylesMobileShort", lang)
|
|
3366
3853
|
] }),
|
|
3367
|
-
/* @__PURE__ */ (0,
|
|
3368
|
-
/* @__PURE__ */ (0,
|
|
3369
|
-
/* @__PURE__ */ (0,
|
|
3854
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { display: "inline-flex", alignItems: "center", gap: "6px", flexWrap: "wrap" }, children: [
|
|
3855
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", onClick: () => toggleExpand(s.id), style: miniBtnStyle, children: expanded[s.id] ? t("stylesHideCss", lang) : t("stylesViewCss", lang) }),
|
|
3856
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", onClick: () => copyCss(s.css), style: miniBtnStyle, children: t("stylesCopyCss", lang) })
|
|
3370
3857
|
] })
|
|
3371
3858
|
] })
|
|
3372
3859
|
] }),
|
|
3373
|
-
expanded[s.id] ? /* @__PURE__ */ (0,
|
|
3860
|
+
expanded[s.id] ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3374
3861
|
"pre",
|
|
3375
3862
|
{
|
|
3376
3863
|
style: {
|
|
@@ -3393,8 +3880,8 @@ function StylesCard({ lang, showToast }) {
|
|
|
3393
3880
|
) : null
|
|
3394
3881
|
] }, s.id)) })
|
|
3395
3882
|
] }) : null,
|
|
3396
|
-
/* @__PURE__ */ (0,
|
|
3397
|
-
!showForm ? /* @__PURE__ */ (0,
|
|
3883
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { fontSize: "13px", fontWeight: "600", color: "var(--dsw-alias-label-secondary, inherit)", marginTop: "4px" }, children: t("stylesCustomTitle", lang) }),
|
|
3884
|
+
!showForm ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3398
3885
|
"button",
|
|
3399
3886
|
{
|
|
3400
3887
|
type: "button",
|
|
@@ -3412,7 +3899,7 @@ function StylesCard({ lang, showToast }) {
|
|
|
3412
3899
|
},
|
|
3413
3900
|
children: t("stylesAddNew", lang)
|
|
3414
3901
|
}
|
|
3415
|
-
) : /* @__PURE__ */ (0,
|
|
3902
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
3416
3903
|
"div",
|
|
3417
3904
|
{
|
|
3418
3905
|
style: {
|
|
@@ -3425,8 +3912,8 @@ function StylesCard({ lang, showToast }) {
|
|
|
3425
3912
|
padding: "12px"
|
|
3426
3913
|
},
|
|
3427
3914
|
children: [
|
|
3428
|
-
/* @__PURE__ */ (0,
|
|
3429
|
-
/* @__PURE__ */ (0,
|
|
3915
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { display: "flex", gap: "8px", flexWrap: "wrap" }, children: [
|
|
3916
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3430
3917
|
"input",
|
|
3431
3918
|
{
|
|
3432
3919
|
type: "text",
|
|
@@ -3446,8 +3933,8 @@ function StylesCard({ lang, showToast }) {
|
|
|
3446
3933
|
}
|
|
3447
3934
|
}
|
|
3448
3935
|
),
|
|
3449
|
-
/* @__PURE__ */ (0,
|
|
3450
|
-
/* @__PURE__ */ (0,
|
|
3936
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { style: { display: "inline-flex", alignItems: "center", gap: "4px", fontSize: "11px", cursor: "pointer", whiteSpace: "nowrap" }, children: [
|
|
3937
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3451
3938
|
"input",
|
|
3452
3939
|
{
|
|
3453
3940
|
type: "checkbox",
|
|
@@ -3459,8 +3946,8 @@ function StylesCard({ lang, showToast }) {
|
|
|
3459
3946
|
"\u{1F5A5}\uFE0F ",
|
|
3460
3947
|
t("stylesPcShort", lang)
|
|
3461
3948
|
] }),
|
|
3462
|
-
/* @__PURE__ */ (0,
|
|
3463
|
-
/* @__PURE__ */ (0,
|
|
3949
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { style: { display: "inline-flex", alignItems: "center", gap: "4px", fontSize: "11px", cursor: "pointer", whiteSpace: "nowrap" }, children: [
|
|
3950
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3464
3951
|
"input",
|
|
3465
3952
|
{
|
|
3466
3953
|
type: "checkbox",
|
|
@@ -3473,7 +3960,7 @@ function StylesCard({ lang, showToast }) {
|
|
|
3473
3960
|
t("stylesMobileShort", lang)
|
|
3474
3961
|
] })
|
|
3475
3962
|
] }),
|
|
3476
|
-
/* @__PURE__ */ (0,
|
|
3963
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3477
3964
|
"textarea",
|
|
3478
3965
|
{
|
|
3479
3966
|
value: css,
|
|
@@ -3496,20 +3983,20 @@ function StylesCard({ lang, showToast }) {
|
|
|
3496
3983
|
}
|
|
3497
3984
|
}
|
|
3498
3985
|
),
|
|
3499
|
-
/* @__PURE__ */ (0,
|
|
3500
|
-
/* @__PURE__ */ (0,
|
|
3501
|
-
editingId !== null ? /* @__PURE__ */ (0,
|
|
3502
|
-
showForm && !editingId ? /* @__PURE__ */ (0,
|
|
3986
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { display: "flex", gap: "8px", flexWrap: "wrap" }, children: [
|
|
3987
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", onClick: save, style: primaryBtnStyle, children: t("stylesSave", lang) }),
|
|
3988
|
+
editingId !== null ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", onClick: cancelEdit, style: miniBtnStyle, children: t("stylesCancelEdit", lang) }) : null,
|
|
3989
|
+
showForm && !editingId ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", onClick: cancelEdit, style: miniBtnStyle, children: t("stylesCancelEdit", lang) }) : null
|
|
3503
3990
|
] })
|
|
3504
3991
|
]
|
|
3505
3992
|
}
|
|
3506
3993
|
),
|
|
3507
|
-
snippets.filter((s) => !s.builtin).length === 0 ? /* @__PURE__ */ (0,
|
|
3508
|
-
/* @__PURE__ */ (0,
|
|
3509
|
-
/* @__PURE__ */ (0,
|
|
3510
|
-
/* @__PURE__ */ (0,
|
|
3511
|
-
/* @__PURE__ */ (0,
|
|
3512
|
-
/* @__PURE__ */ (0,
|
|
3994
|
+
snippets.filter((s) => !s.builtin).length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { fontSize: "12px", color: "var(--dsw-alias-label-tertiary, #888)" }, children: t("stylesEmptyCustom", lang) }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: "8px" }, children: snippets.filter((s) => !s.builtin).map((s) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: rowStyle, children: [
|
|
3995
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { display: "flex", alignItems: "flex-start", justifyContent: "space-between", gap: "8px", flexWrap: "wrap" }, children: [
|
|
3996
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { flex: "1 1 180px", minWidth: 0, maxWidth: "100%" }, children: [
|
|
3997
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "6px", flexWrap: "wrap" }, children: [
|
|
3998
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: { fontSize: "12px", fontWeight: "600", color: "var(--dsw-alias-label-primary, inherit)" }, children: s.name }),
|
|
3999
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3513
4000
|
"span",
|
|
3514
4001
|
{
|
|
3515
4002
|
style: {
|
|
@@ -3524,11 +4011,11 @@ function StylesCard({ lang, showToast }) {
|
|
|
3524
4011
|
}
|
|
3525
4012
|
)
|
|
3526
4013
|
] }),
|
|
3527
|
-
s.description ? /* @__PURE__ */ (0,
|
|
4014
|
+
s.description ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { fontSize: "11px", color: "var(--dsw-alias-label-tertiary, #888)", marginTop: "3px" }, children: s.description }) : null
|
|
3528
4015
|
] }),
|
|
3529
|
-
/* @__PURE__ */ (0,
|
|
3530
|
-
/* @__PURE__ */ (0,
|
|
3531
|
-
/* @__PURE__ */ (0,
|
|
4016
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "6px 8px", flexWrap: "wrap", maxWidth: "100%" }, children: [
|
|
4017
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { style: { display: "inline-flex", alignItems: "center", gap: "4px", fontSize: "11px", cursor: "pointer", whiteSpace: "nowrap" }, children: [
|
|
4018
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3532
4019
|
"input",
|
|
3533
4020
|
{
|
|
3534
4021
|
type: "checkbox",
|
|
@@ -3540,8 +4027,8 @@ function StylesCard({ lang, showToast }) {
|
|
|
3540
4027
|
"\u{1F5A5}\uFE0F ",
|
|
3541
4028
|
t("stylesPcShort", lang)
|
|
3542
4029
|
] }),
|
|
3543
|
-
/* @__PURE__ */ (0,
|
|
3544
|
-
/* @__PURE__ */ (0,
|
|
4030
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { style: { display: "inline-flex", alignItems: "center", gap: "4px", fontSize: "11px", cursor: "pointer", whiteSpace: "nowrap" }, children: [
|
|
4031
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3545
4032
|
"input",
|
|
3546
4033
|
{
|
|
3547
4034
|
type: "checkbox",
|
|
@@ -3553,15 +4040,15 @@ function StylesCard({ lang, showToast }) {
|
|
|
3553
4040
|
"\u{1F4F1} ",
|
|
3554
4041
|
t("stylesMobileShort", lang)
|
|
3555
4042
|
] }),
|
|
3556
|
-
/* @__PURE__ */ (0,
|
|
3557
|
-
/* @__PURE__ */ (0,
|
|
3558
|
-
/* @__PURE__ */ (0,
|
|
3559
|
-
/* @__PURE__ */ (0,
|
|
3560
|
-
/* @__PURE__ */ (0,
|
|
4043
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { display: "inline-flex", alignItems: "center", gap: "6px", flexWrap: "wrap" }, children: [
|
|
4044
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", onClick: () => startEdit(s), style: miniBtnStyle, children: t("stylesEditBtn", lang) }),
|
|
4045
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", onClick: () => remove(s), style: { ...miniBtnStyle, color: "#ef4444" }, children: t("stylesDeleteBtn", lang) }),
|
|
4046
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", onClick: () => toggleExpand(s.id), style: miniBtnStyle, children: expanded[s.id] ? t("stylesHideCss", lang) : t("stylesViewCss", lang) }),
|
|
4047
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", onClick: () => copyCss(s.css), style: miniBtnStyle, children: t("stylesCopyCss", lang) })
|
|
3561
4048
|
] })
|
|
3562
4049
|
] })
|
|
3563
4050
|
] }),
|
|
3564
|
-
expanded[s.id] ? /* @__PURE__ */ (0,
|
|
4051
|
+
expanded[s.id] ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3565
4052
|
"pre",
|
|
3566
4053
|
{
|
|
3567
4054
|
style: {
|
|
@@ -3583,7 +4070,7 @@ function StylesCard({ lang, showToast }) {
|
|
|
3583
4070
|
}
|
|
3584
4071
|
) : null
|
|
3585
4072
|
] }, s.id)) }),
|
|
3586
|
-
/* @__PURE__ */ (0,
|
|
4073
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { fontSize: "11px", color: "var(--dsw-alias-label-tertiary, #888)", lineHeight: "1.6" }, children: t("stylesHint", lang) })
|
|
3587
4074
|
] })
|
|
3588
4075
|
]
|
|
3589
4076
|
}
|
|
@@ -3591,14 +4078,14 @@ function StylesCard({ lang, showToast }) {
|
|
|
3591
4078
|
}
|
|
3592
4079
|
|
|
3593
4080
|
// src/client/version.js
|
|
3594
|
-
var PLUGIN_VERSION = "v1.10.
|
|
3595
|
-
var BUILD_TIME = "2026-
|
|
4081
|
+
var PLUGIN_VERSION = "v1.10.2";
|
|
4082
|
+
var BUILD_TIME = "2026-11-02 23:13:58";
|
|
3596
4083
|
|
|
3597
4084
|
// src/client/components/MainSection.jsx
|
|
3598
|
-
var
|
|
4085
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
3599
4086
|
function TailscaleMobileSection(props) {
|
|
3600
4087
|
const ctx = props && props.ctx || typeof window !== "undefined" && window.__DSH_CLIENT_CTX__ || null;
|
|
3601
|
-
const [status, setStatus] = (0,
|
|
4088
|
+
const [status, setStatus] = (0, import_react10.useState)({
|
|
3602
4089
|
tailscaleIp: "",
|
|
3603
4090
|
lanIp: "",
|
|
3604
4091
|
code: "",
|
|
@@ -3620,36 +4107,53 @@ function TailscaleMobileSection(props) {
|
|
|
3620
4107
|
locale: "zh",
|
|
3621
4108
|
pairingBridgeMode: "pending",
|
|
3622
4109
|
pairingBridgeConflict: "",
|
|
3623
|
-
pairingBridgeConflictId: ""
|
|
4110
|
+
pairingBridgeConflictId: "",
|
|
4111
|
+
directoryPicker: {
|
|
4112
|
+
patchEnabled: false,
|
|
4113
|
+
patchPartial: false,
|
|
4114
|
+
runtimeActive: false,
|
|
4115
|
+
restartRequired: false,
|
|
4116
|
+
needsWarning: false,
|
|
4117
|
+
patchFilePath: "",
|
|
4118
|
+
yamlSnippet: ""
|
|
4119
|
+
},
|
|
4120
|
+
proxy: null
|
|
3624
4121
|
});
|
|
3625
|
-
const [secretInput, setSecretInput] = (0,
|
|
3626
|
-
const [showSecret, setShowSecret] = (0,
|
|
3627
|
-
const [showCode, setShowCode] = (0,
|
|
3628
|
-
const [showQr, setShowQr] = (0,
|
|
3629
|
-
const [selectedTab, setSelectedTab] = (0,
|
|
3630
|
-
const [timeLeft, setTimeLeft] = (0,
|
|
3631
|
-
const [toast, setToast] = (0,
|
|
3632
|
-
const [maxVisitsInput, setMaxVisitsInput] = (0,
|
|
3633
|
-
const [maxFailedInput, setMaxFailedInput] = (0,
|
|
3634
|
-
const [lockDurationMinsInput, setLockDurationMinsInput] = (0,
|
|
3635
|
-
const [
|
|
3636
|
-
const [
|
|
3637
|
-
const [
|
|
3638
|
-
const [
|
|
3639
|
-
const
|
|
3640
|
-
const [
|
|
3641
|
-
const
|
|
3642
|
-
const
|
|
3643
|
-
const
|
|
4122
|
+
const [secretInput, setSecretInput] = (0, import_react10.useState)("");
|
|
4123
|
+
const [showSecret, setShowSecret] = (0, import_react10.useState)(false);
|
|
4124
|
+
const [showCode, setShowCode] = (0, import_react10.useState)(false);
|
|
4125
|
+
const [showQr, setShowQr] = (0, import_react10.useState)(false);
|
|
4126
|
+
const [selectedTab, setSelectedTab] = (0, import_react10.useState)("lan");
|
|
4127
|
+
const [timeLeft, setTimeLeft] = (0, import_react10.useState)(300);
|
|
4128
|
+
const [toast, setToast] = (0, import_react10.useState)(null);
|
|
4129
|
+
const [maxVisitsInput, setMaxVisitsInput] = (0, import_react10.useState)("60");
|
|
4130
|
+
const [maxFailedInput, setMaxFailedInput] = (0, import_react10.useState)("5");
|
|
4131
|
+
const [lockDurationMinsInput, setLockDurationMinsInput] = (0, import_react10.useState)("15");
|
|
4132
|
+
const [modeInput, setModeInput] = (0, import_react10.useState)("proxy");
|
|
4133
|
+
const [proxyPortInput, setProxyPortInput] = (0, import_react10.useState)("3081");
|
|
4134
|
+
const [proxyHostInput, setProxyHostInput] = (0, import_react10.useState)("0.0.0.0");
|
|
4135
|
+
const [trustedHostsInput, setTrustedHostsInput] = (0, import_react10.useState)("");
|
|
4136
|
+
const proxyConfigLoadedRef = (0, import_react10.useRef)(false);
|
|
4137
|
+
const [isSaving, setIsSaving] = (0, import_react10.useState)(false);
|
|
4138
|
+
const [showVersionTip, setShowVersionTip] = (0, import_react10.useState)(false);
|
|
4139
|
+
const [currentLang, setCurrentLang] = (0, import_react10.useState)(resolveLocale(ctx, status));
|
|
4140
|
+
const [npmLatestVersion, setNpmLatestVersion] = (0, import_react10.useState)("");
|
|
4141
|
+
const [hasUpdate, setHasUpdate] = (0, import_react10.useState)(false);
|
|
4142
|
+
const [conflictBannerDismissed, setConflictBannerDismissed] = (0, import_react10.useState)(false);
|
|
4143
|
+
const [dirPickerBannerDismissed, setDirPickerBannerDismissed] = (0, import_react10.useState)(false);
|
|
4144
|
+
const [isPatchingDirPicker, setIsPatchingDirPicker] = (0, import_react10.useState)(false);
|
|
4145
|
+
const qrTabTouchedRef = (0, import_react10.useRef)(false);
|
|
4146
|
+
const toastTimerRef = (0, import_react10.useRef)(null);
|
|
4147
|
+
const showToast = (0, import_react10.useCallback)((message, type = "success", duration = 2500) => {
|
|
3644
4148
|
if (toastTimerRef.current) clearTimeout(toastTimerRef.current);
|
|
3645
4149
|
setToast({ message, type });
|
|
3646
4150
|
toastTimerRef.current = setTimeout(() => setToast(null), duration);
|
|
3647
4151
|
}, []);
|
|
3648
|
-
const updateQrTab = (0,
|
|
4152
|
+
const updateQrTab = (0, import_react10.useCallback)((tab) => {
|
|
3649
4153
|
qrTabTouchedRef.current = true;
|
|
3650
4154
|
setSelectedTab(tab);
|
|
3651
4155
|
}, []);
|
|
3652
|
-
const [activeTab, setActiveTab] = (0,
|
|
4156
|
+
const [activeTab, setActiveTab] = (0, import_react10.useState)(() => {
|
|
3653
4157
|
try {
|
|
3654
4158
|
const saved = localStorage.getItem("dsh-rm-settings-tab");
|
|
3655
4159
|
if (saved === "access" || saved === "devices" || saved === "style" || saved === "storage") return saved;
|
|
@@ -3664,7 +4168,7 @@ function TailscaleMobileSection(props) {
|
|
|
3664
4168
|
} catch (e) {
|
|
3665
4169
|
}
|
|
3666
4170
|
};
|
|
3667
|
-
const refreshStatusOnly = (0,
|
|
4171
|
+
const refreshStatusOnly = (0, import_react10.useCallback)(() => {
|
|
3668
4172
|
fetchStatus().then((data) => {
|
|
3669
4173
|
if (data.tailscaleIp && !qrTabTouchedRef.current) {
|
|
3670
4174
|
setSelectedTab("tailscale");
|
|
@@ -3676,6 +4180,14 @@ function TailscaleMobileSection(props) {
|
|
|
3676
4180
|
if (data.locale) {
|
|
3677
4181
|
setCurrentLang(resolveLocale(ctx, data));
|
|
3678
4182
|
}
|
|
4183
|
+
if (!proxyConfigLoadedRef.current && data.proxy) {
|
|
4184
|
+
setModeInput(data.proxy.configuredMode === "direct" ? "direct" : "proxy");
|
|
4185
|
+
setProxyPortInput(String(data.proxy.proxyPort || 3081));
|
|
4186
|
+
setProxyHostInput(data.proxy.proxyHost || "0.0.0.0");
|
|
4187
|
+
setTrustedHostsInput(Array.isArray(data.proxy.trustedHosts) ? data.proxy.trustedHosts.join("\n") : "");
|
|
4188
|
+
proxyConfigLoadedRef.current = true;
|
|
4189
|
+
}
|
|
4190
|
+
const dp = data.directoryPicker || {};
|
|
3679
4191
|
setStatus((prev) => ({
|
|
3680
4192
|
...prev,
|
|
3681
4193
|
tailscaleIp: data.tailscaleIp || "",
|
|
@@ -3696,12 +4208,22 @@ function TailscaleMobileSection(props) {
|
|
|
3696
4208
|
pairingBridgeMode: data.pairingBridgeMode || "pending",
|
|
3697
4209
|
pairingBridgeConflict: data.pairingBridgeConflict || "",
|
|
3698
4210
|
pairingBridgeConflictId: data.pairingBridgeConflictId || "",
|
|
4211
|
+
directoryPicker: {
|
|
4212
|
+
patchEnabled: Boolean(dp.patchEnabled),
|
|
4213
|
+
patchPartial: Boolean(dp.patchPartial),
|
|
4214
|
+
runtimeActive: Boolean(dp.runtimeActive),
|
|
4215
|
+
restartRequired: Boolean(dp.restartRequired),
|
|
4216
|
+
needsWarning: Boolean(dp.needsWarning),
|
|
4217
|
+
patchFilePath: dp.patchFilePath || "",
|
|
4218
|
+
yamlSnippet: dp.yamlSnippet || ""
|
|
4219
|
+
},
|
|
4220
|
+
proxy: data.proxy || null,
|
|
3699
4221
|
loading: false
|
|
3700
4222
|
}));
|
|
3701
4223
|
}).catch(() => {
|
|
3702
4224
|
});
|
|
3703
4225
|
}, [ctx]);
|
|
3704
|
-
const refreshStatusAndCode = (0,
|
|
4226
|
+
const refreshStatusAndCode = (0, import_react10.useCallback)(() => {
|
|
3705
4227
|
refreshStatusOnly();
|
|
3706
4228
|
generatePairCode().then((data) => {
|
|
3707
4229
|
if (data.success) {
|
|
@@ -3716,7 +4238,7 @@ function TailscaleMobileSection(props) {
|
|
|
3716
4238
|
}).catch(() => {
|
|
3717
4239
|
});
|
|
3718
4240
|
}, [refreshStatusOnly]);
|
|
3719
|
-
(0,
|
|
4241
|
+
(0, import_react10.useEffect)(() => {
|
|
3720
4242
|
let cancelled = false;
|
|
3721
4243
|
fetch("https://registry.npmjs.org/dsh-remote-mobile/latest", { cache: "no-store" }).then((res) => res.ok ? res.json() : Promise.reject(new Error("npm registry error"))).then((data) => {
|
|
3722
4244
|
if (cancelled) return;
|
|
@@ -3744,7 +4266,7 @@ function TailscaleMobileSection(props) {
|
|
|
3744
4266
|
}
|
|
3745
4267
|
return 0;
|
|
3746
4268
|
};
|
|
3747
|
-
(0,
|
|
4269
|
+
(0, import_react10.useEffect)(() => {
|
|
3748
4270
|
refreshStatusAndCode();
|
|
3749
4271
|
const localeUnsubs = [];
|
|
3750
4272
|
try {
|
|
@@ -3812,7 +4334,7 @@ function TailscaleMobileSection(props) {
|
|
|
3812
4334
|
}
|
|
3813
4335
|
};
|
|
3814
4336
|
}, [refreshStatusAndCode, refreshStatusOnly, currentLang, ctx]);
|
|
3815
|
-
(0,
|
|
4337
|
+
(0, import_react10.useEffect)(() => {
|
|
3816
4338
|
if (timeLeft <= 0) return;
|
|
3817
4339
|
const timer = setInterval(() => {
|
|
3818
4340
|
setTimeLeft((prev) => {
|
|
@@ -3998,14 +4520,118 @@ function TailscaleMobileSection(props) {
|
|
|
3998
4520
|
showToast((currentLang === "en" ? "Reset failed: " : "\u91CD\u7F6E\u5931\u8D25\uFF1A") + (err?.message || err), "danger", 3500);
|
|
3999
4521
|
});
|
|
4000
4522
|
};
|
|
4523
|
+
const persistProxyConfig = (mode, port, host, hosts) => {
|
|
4524
|
+
setIsSaving(true);
|
|
4525
|
+
updateProxyConfig({
|
|
4526
|
+
mode,
|
|
4527
|
+
proxyPort: port,
|
|
4528
|
+
proxyHost: host,
|
|
4529
|
+
trustedHosts: hosts
|
|
4530
|
+
}).then((data) => {
|
|
4531
|
+
setIsSaving(false);
|
|
4532
|
+
if (data.success) {
|
|
4533
|
+
setStatus((prev) => ({
|
|
4534
|
+
...prev,
|
|
4535
|
+
proxy: prev.proxy ? {
|
|
4536
|
+
...prev.proxy,
|
|
4537
|
+
configuredMode: data.mode,
|
|
4538
|
+
proxyPort: data.proxyPort,
|
|
4539
|
+
proxyHost: data.proxyHost,
|
|
4540
|
+
trustedHosts: data.trustedHosts || [],
|
|
4541
|
+
mode: data.activeMode || prev.proxy.mode,
|
|
4542
|
+
activePort: data.activePort || prev.proxy.activePort
|
|
4543
|
+
} : prev.proxy
|
|
4544
|
+
}));
|
|
4545
|
+
refreshStatusOnly();
|
|
4546
|
+
showToast(t("proxySavedToast", currentLang), "success", 5e3);
|
|
4547
|
+
} else {
|
|
4548
|
+
showToast((currentLang === "en" ? "Save failed: " : "\u4FDD\u5B58\u5931\u8D25\uFF1A") + (data.reason || ""), "danger", 3500);
|
|
4549
|
+
}
|
|
4550
|
+
}).catch((err) => {
|
|
4551
|
+
setIsSaving(false);
|
|
4552
|
+
showToast((currentLang === "en" ? "Save failed: " : "\u4FDD\u5B58\u5931\u8D25\uFF1A") + (err?.message || err), "danger", 3500);
|
|
4553
|
+
});
|
|
4554
|
+
};
|
|
4555
|
+
const saveProxyConfig = () => {
|
|
4556
|
+
const port = parseInt(proxyPortInput, 10);
|
|
4557
|
+
const host = proxyHostInput.trim();
|
|
4558
|
+
const hosts = trustedHostsInput.split(/\r?\n/).map((h) => h.trim()).filter(Boolean);
|
|
4559
|
+
if (!Number.isInteger(port) || port < 1 || port > 65535 || !host) {
|
|
4560
|
+
alert(t("proxySaveFailTip", currentLang));
|
|
4561
|
+
return;
|
|
4562
|
+
}
|
|
4563
|
+
if (!confirm(t("proxySaveConfirm", currentLang))) {
|
|
4564
|
+
return;
|
|
4565
|
+
}
|
|
4566
|
+
persistProxyConfig(modeInput === "direct" ? "direct" : "proxy", port, host, hosts);
|
|
4567
|
+
};
|
|
4568
|
+
const resetProxyConfigDefaults = () => {
|
|
4569
|
+
if (!confirm(t("proxyResetConfirm", currentLang))) {
|
|
4570
|
+
return;
|
|
4571
|
+
}
|
|
4572
|
+
setModeInput("proxy");
|
|
4573
|
+
setProxyPortInput("3081");
|
|
4574
|
+
setProxyHostInput("0.0.0.0");
|
|
4575
|
+
setTrustedHostsInput("");
|
|
4576
|
+
persistProxyConfig("proxy", 3081, "0.0.0.0", []);
|
|
4577
|
+
};
|
|
4578
|
+
const toggleDirectoryPicker = (enable) => {
|
|
4579
|
+
if (!enable) {
|
|
4580
|
+
if (!confirm(t("dirPickerDisableConfirm", currentLang))) {
|
|
4581
|
+
return;
|
|
4582
|
+
}
|
|
4583
|
+
}
|
|
4584
|
+
setIsPatchingDirPicker(true);
|
|
4585
|
+
toggleDirectoryPickerApi(enable).then((res) => {
|
|
4586
|
+
setIsPatchingDirPicker(false);
|
|
4587
|
+
if (res && res.success) {
|
|
4588
|
+
const dp = res.directoryPicker || {};
|
|
4589
|
+
setStatus((prev) => ({
|
|
4590
|
+
...prev,
|
|
4591
|
+
directoryPicker: {
|
|
4592
|
+
patchEnabled: Boolean(dp.patchEnabled),
|
|
4593
|
+
patchPartial: Boolean(dp.patchPartial),
|
|
4594
|
+
runtimeActive: Boolean(dp.runtimeActive),
|
|
4595
|
+
restartRequired: Boolean(dp.restartRequired),
|
|
4596
|
+
needsWarning: Boolean(dp.needsWarning),
|
|
4597
|
+
patchFilePath: dp.patchFilePath || "",
|
|
4598
|
+
yamlSnippet: dp.yamlSnippet || ""
|
|
4599
|
+
}
|
|
4600
|
+
}));
|
|
4601
|
+
refreshStatusOnly();
|
|
4602
|
+
showToast(
|
|
4603
|
+
t(enable ? "dirPickerEnabledToast" : "dirPickerDisabledToast", currentLang),
|
|
4604
|
+
"success",
|
|
4605
|
+
4500
|
|
4606
|
+
);
|
|
4607
|
+
} else {
|
|
4608
|
+
showToast(
|
|
4609
|
+
(currentLang === "en" ? "Operation failed: " : "\u64CD\u4F5C\u5931\u8D25\uFF1A") + (res && res.reason || ""),
|
|
4610
|
+
"danger",
|
|
4611
|
+
3500
|
|
4612
|
+
);
|
|
4613
|
+
}
|
|
4614
|
+
}).catch((err) => {
|
|
4615
|
+
setIsPatchingDirPicker(false);
|
|
4616
|
+
showToast(
|
|
4617
|
+
(currentLang === "en" ? "Operation failed: " : "\u64CD\u4F5C\u5931\u8D25\uFF1A") + (err?.message || err),
|
|
4618
|
+
"danger",
|
|
4619
|
+
3500
|
|
4620
|
+
);
|
|
4621
|
+
});
|
|
4622
|
+
};
|
|
4001
4623
|
const copyDirectLink = () => {
|
|
4002
4624
|
if (timeLeft <= 0) {
|
|
4003
4625
|
alert(t("codeExpired", currentLang));
|
|
4004
4626
|
return;
|
|
4005
4627
|
}
|
|
4006
4628
|
const effectiveQrIp = selectedTab === "tailscale" && status.tailscaleIp ? status.tailscaleIp : status.lanIp || "127.0.0.1";
|
|
4007
|
-
const port =
|
|
4008
|
-
|
|
4629
|
+
const port = resolveAccessPort(status);
|
|
4630
|
+
if (port === null) {
|
|
4631
|
+
showToast(t("proxyNotReady", currentLang), "danger", 3e3);
|
|
4632
|
+
return;
|
|
4633
|
+
}
|
|
4634
|
+
const directLink = buildDirectLink(effectiveQrIp, port, status.code || "");
|
|
4009
4635
|
copyText(directLink, t("copiedTip", currentLang));
|
|
4010
4636
|
setStatus((prev) => ({ ...prev, copied: true }));
|
|
4011
4637
|
setTimeout(() => {
|
|
@@ -4050,7 +4676,7 @@ function TailscaleMobileSection(props) {
|
|
|
4050
4676
|
}
|
|
4051
4677
|
}
|
|
4052
4678
|
};
|
|
4053
|
-
return /* @__PURE__ */ (0,
|
|
4679
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
4054
4680
|
"div",
|
|
4055
4681
|
{
|
|
4056
4682
|
style: {
|
|
@@ -4062,7 +4688,7 @@ function TailscaleMobileSection(props) {
|
|
|
4062
4688
|
position: "relative"
|
|
4063
4689
|
},
|
|
4064
4690
|
children: [
|
|
4065
|
-
toast ? /* @__PURE__ */ (0,
|
|
4691
|
+
toast ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
4066
4692
|
"div",
|
|
4067
4693
|
{
|
|
4068
4694
|
style: {
|
|
@@ -4087,12 +4713,12 @@ function TailscaleMobileSection(props) {
|
|
|
4087
4713
|
pointerEvents: "none"
|
|
4088
4714
|
},
|
|
4089
4715
|
children: [
|
|
4090
|
-
/* @__PURE__ */ (0,
|
|
4091
|
-
/* @__PURE__ */ (0,
|
|
4716
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: toast.type === "danger" ? "\u{1F6A8}" : toast.type === "success" ? "\u2705" : "\u2139\uFE0F" }),
|
|
4717
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: toast.message })
|
|
4092
4718
|
]
|
|
4093
4719
|
}
|
|
4094
4720
|
) : null,
|
|
4095
|
-
/* @__PURE__ */ (0,
|
|
4721
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
4096
4722
|
"div",
|
|
4097
4723
|
{
|
|
4098
4724
|
style: {
|
|
@@ -4104,8 +4730,8 @@ function TailscaleMobileSection(props) {
|
|
|
4104
4730
|
marginBottom: "4px"
|
|
4105
4731
|
},
|
|
4106
4732
|
children: [
|
|
4107
|
-
/* @__PURE__ */ (0,
|
|
4108
|
-
/* @__PURE__ */ (0,
|
|
4733
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: { minWidth: "220px", flex: 1 }, children: [
|
|
4734
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
4109
4735
|
"div",
|
|
4110
4736
|
{
|
|
4111
4737
|
style: {
|
|
@@ -4116,7 +4742,7 @@ function TailscaleMobileSection(props) {
|
|
|
4116
4742
|
margin: "0 0 6px 0"
|
|
4117
4743
|
},
|
|
4118
4744
|
children: [
|
|
4119
|
-
/* @__PURE__ */ (0,
|
|
4745
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4120
4746
|
"h3",
|
|
4121
4747
|
{
|
|
4122
4748
|
style: {
|
|
@@ -4128,7 +4754,7 @@ function TailscaleMobileSection(props) {
|
|
|
4128
4754
|
children: t("title", currentLang)
|
|
4129
4755
|
}
|
|
4130
4756
|
),
|
|
4131
|
-
/* @__PURE__ */ (0,
|
|
4757
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
4132
4758
|
"div",
|
|
4133
4759
|
{
|
|
4134
4760
|
style: { position: "relative", display: "inline-flex", alignItems: "center" },
|
|
@@ -4142,7 +4768,7 @@ function TailscaleMobileSection(props) {
|
|
|
4142
4768
|
);
|
|
4143
4769
|
},
|
|
4144
4770
|
children: [
|
|
4145
|
-
/* @__PURE__ */ (0,
|
|
4771
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4146
4772
|
"span",
|
|
4147
4773
|
{
|
|
4148
4774
|
style: {
|
|
@@ -4159,7 +4785,7 @@ function TailscaleMobileSection(props) {
|
|
|
4159
4785
|
children: PLUGIN_VERSION
|
|
4160
4786
|
}
|
|
4161
4787
|
),
|
|
4162
|
-
showVersionTip ? /* @__PURE__ */ (0,
|
|
4788
|
+
showVersionTip ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4163
4789
|
"div",
|
|
4164
4790
|
{
|
|
4165
4791
|
style: {
|
|
@@ -4187,7 +4813,7 @@ function TailscaleMobileSection(props) {
|
|
|
4187
4813
|
]
|
|
4188
4814
|
}
|
|
4189
4815
|
),
|
|
4190
|
-
hasUpdate && npmLatestVersion ? /* @__PURE__ */ (0,
|
|
4816
|
+
hasUpdate && npmLatestVersion ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
4191
4817
|
"a",
|
|
4192
4818
|
{
|
|
4193
4819
|
href: `https://www.npmjs.com/package/dsh-remote-mobile/v/${npmLatestVersion}`,
|
|
@@ -4217,7 +4843,7 @@ function TailscaleMobileSection(props) {
|
|
|
4217
4843
|
]
|
|
4218
4844
|
}
|
|
4219
4845
|
),
|
|
4220
|
-
/* @__PURE__ */ (0,
|
|
4846
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4221
4847
|
"div",
|
|
4222
4848
|
{
|
|
4223
4849
|
style: {
|
|
@@ -4228,7 +4854,7 @@ function TailscaleMobileSection(props) {
|
|
|
4228
4854
|
}
|
|
4229
4855
|
)
|
|
4230
4856
|
] }),
|
|
4231
|
-
/* @__PURE__ */ (0,
|
|
4857
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
4232
4858
|
"a",
|
|
4233
4859
|
{
|
|
4234
4860
|
href: "https://github.com/IceApriler/dsh-remote-mobile",
|
|
@@ -4250,15 +4876,15 @@ function TailscaleMobileSection(props) {
|
|
|
4250
4876
|
cursor: "pointer"
|
|
4251
4877
|
},
|
|
4252
4878
|
children: [
|
|
4253
|
-
/* @__PURE__ */ (0,
|
|
4254
|
-
/* @__PURE__ */ (0,
|
|
4879
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("svg", { style: { width: "16px", height: "16px", fill: "currentColor" }, viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z" }) }),
|
|
4880
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: "dsh-remote-mobile" })
|
|
4255
4881
|
]
|
|
4256
4882
|
}
|
|
4257
4883
|
)
|
|
4258
4884
|
]
|
|
4259
4885
|
}
|
|
4260
4886
|
),
|
|
4261
|
-
status.pairingBridgeConflict && !conflictBannerDismissed ? /* @__PURE__ */ (0,
|
|
4887
|
+
status.pairingBridgeConflict && !conflictBannerDismissed ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
4262
4888
|
"div",
|
|
4263
4889
|
{
|
|
4264
4890
|
style: {
|
|
@@ -4271,9 +4897,9 @@ function TailscaleMobileSection(props) {
|
|
|
4271
4897
|
background: "rgba(245, 158, 11, 0.12)"
|
|
4272
4898
|
},
|
|
4273
4899
|
children: [
|
|
4274
|
-
/* @__PURE__ */ (0,
|
|
4275
|
-
/* @__PURE__ */ (0,
|
|
4276
|
-
/* @__PURE__ */ (0,
|
|
4900
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { style: { fontSize: "16px", lineHeight: "20px" }, children: "\u26A0\uFE0F" }),
|
|
4901
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
|
|
4902
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4277
4903
|
"div",
|
|
4278
4904
|
{
|
|
4279
4905
|
style: {
|
|
@@ -4285,7 +4911,7 @@ function TailscaleMobileSection(props) {
|
|
|
4285
4911
|
children: t("conflictBannerTitle", currentLang)
|
|
4286
4912
|
}
|
|
4287
4913
|
),
|
|
4288
|
-
/* @__PURE__ */ (0,
|
|
4914
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4289
4915
|
"div",
|
|
4290
4916
|
{
|
|
4291
4917
|
style: {
|
|
@@ -4299,7 +4925,7 @@ function TailscaleMobileSection(props) {
|
|
|
4299
4925
|
})
|
|
4300
4926
|
}
|
|
4301
4927
|
),
|
|
4302
|
-
/* @__PURE__ */ (0,
|
|
4928
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4303
4929
|
"button",
|
|
4304
4930
|
{
|
|
4305
4931
|
type: "button",
|
|
@@ -4331,7 +4957,7 @@ function TailscaleMobileSection(props) {
|
|
|
4331
4957
|
}
|
|
4332
4958
|
)
|
|
4333
4959
|
] }),
|
|
4334
|
-
/* @__PURE__ */ (0,
|
|
4960
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4335
4961
|
"button",
|
|
4336
4962
|
{
|
|
4337
4963
|
type: "button",
|
|
@@ -4357,7 +4983,192 @@ function TailscaleMobileSection(props) {
|
|
|
4357
4983
|
]
|
|
4358
4984
|
}
|
|
4359
4985
|
) : null,
|
|
4360
|
-
/* @__PURE__ */ (0,
|
|
4986
|
+
!status.loading && status.directoryPicker.needsWarning && !dirPickerBannerDismissed ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
4987
|
+
"div",
|
|
4988
|
+
{
|
|
4989
|
+
style: {
|
|
4990
|
+
display: "flex",
|
|
4991
|
+
alignItems: "flex-start",
|
|
4992
|
+
gap: "10px",
|
|
4993
|
+
padding: "12px 14px",
|
|
4994
|
+
borderRadius: "10px",
|
|
4995
|
+
border: "1px solid rgba(245, 158, 11, 0.45)",
|
|
4996
|
+
background: "rgba(245, 158, 11, 0.12)"
|
|
4997
|
+
},
|
|
4998
|
+
children: [
|
|
4999
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { style: { fontSize: "16px", lineHeight: "20px" }, children: "\u{1F4C1}" }),
|
|
5000
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
|
|
5001
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
5002
|
+
"div",
|
|
5003
|
+
{
|
|
5004
|
+
style: {
|
|
5005
|
+
fontSize: "13px",
|
|
5006
|
+
fontWeight: "700",
|
|
5007
|
+
marginBottom: "4px",
|
|
5008
|
+
color: "var(--dsw-alias-label-primary, inherit)"
|
|
5009
|
+
},
|
|
5010
|
+
children: t("dirPickerBannerTitle", currentLang)
|
|
5011
|
+
}
|
|
5012
|
+
),
|
|
5013
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
5014
|
+
"div",
|
|
5015
|
+
{
|
|
5016
|
+
style: {
|
|
5017
|
+
fontSize: "12px",
|
|
5018
|
+
lineHeight: 1.6,
|
|
5019
|
+
whiteSpace: "pre-line",
|
|
5020
|
+
color: "var(--dsw-alias-label-secondary, inherit)"
|
|
5021
|
+
},
|
|
5022
|
+
children: t("dirPickerBannerBody", currentLang)
|
|
5023
|
+
}
|
|
5024
|
+
),
|
|
5025
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: { marginTop: "10px", display: "flex", alignItems: "center", gap: "8px", flexWrap: "wrap" }, children: [
|
|
5026
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
5027
|
+
"button",
|
|
5028
|
+
{
|
|
5029
|
+
type: "button",
|
|
5030
|
+
disabled: isPatchingDirPicker,
|
|
5031
|
+
onClick: () => toggleDirectoryPicker(true),
|
|
5032
|
+
style: {
|
|
5033
|
+
display: "inline-flex",
|
|
5034
|
+
alignItems: "center",
|
|
5035
|
+
gap: "6px",
|
|
5036
|
+
padding: "6px 12px",
|
|
5037
|
+
fontSize: "12px",
|
|
5038
|
+
fontWeight: "600",
|
|
5039
|
+
borderRadius: "7px",
|
|
5040
|
+
cursor: isPatchingDirPicker ? "not-allowed" : "pointer",
|
|
5041
|
+
opacity: isPatchingDirPicker ? 0.7 : 1,
|
|
5042
|
+
border: "none",
|
|
5043
|
+
background: "#2563eb",
|
|
5044
|
+
color: "#ffffff",
|
|
5045
|
+
boxShadow: "0 2px 6px rgba(37, 99, 235, 0.3)"
|
|
5046
|
+
},
|
|
5047
|
+
children: isPatchingDirPicker ? t("dirPickerEnablingBtn", currentLang) : t("dirPickerEnableBtn", currentLang)
|
|
5048
|
+
}
|
|
5049
|
+
),
|
|
5050
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
5051
|
+
"button",
|
|
5052
|
+
{
|
|
5053
|
+
type: "button",
|
|
5054
|
+
onClick: () => {
|
|
5055
|
+
const yaml = status.directoryPicker.yamlSnippet || "";
|
|
5056
|
+
if (yaml) {
|
|
5057
|
+
copyText(yaml, t("dirPickerCopiedYamlTip", currentLang));
|
|
5058
|
+
}
|
|
5059
|
+
},
|
|
5060
|
+
style: {
|
|
5061
|
+
display: "inline-flex",
|
|
5062
|
+
alignItems: "center",
|
|
5063
|
+
gap: "6px",
|
|
5064
|
+
padding: "5px 10px",
|
|
5065
|
+
fontSize: "12px",
|
|
5066
|
+
fontWeight: "600",
|
|
5067
|
+
borderRadius: "7px",
|
|
5068
|
+
cursor: "pointer",
|
|
5069
|
+
border: "1px solid rgba(245, 158, 11, 0.55)",
|
|
5070
|
+
background: "rgba(245, 158, 11, 0.18)",
|
|
5071
|
+
color: "var(--dsw-alias-label-primary, inherit)"
|
|
5072
|
+
},
|
|
5073
|
+
children: t("dirPickerCopyYamlBtn", currentLang)
|
|
5074
|
+
}
|
|
5075
|
+
)
|
|
5076
|
+
] })
|
|
5077
|
+
] }),
|
|
5078
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
5079
|
+
"button",
|
|
5080
|
+
{
|
|
5081
|
+
type: "button",
|
|
5082
|
+
onClick: () => setDirPickerBannerDismissed(true),
|
|
5083
|
+
title: t("dirPickerBannerDismiss", currentLang),
|
|
5084
|
+
style: {
|
|
5085
|
+
flexShrink: 0,
|
|
5086
|
+
width: "24px",
|
|
5087
|
+
height: "24px",
|
|
5088
|
+
display: "inline-flex",
|
|
5089
|
+
alignItems: "center",
|
|
5090
|
+
justifyContent: "center",
|
|
5091
|
+
border: "none",
|
|
5092
|
+
borderRadius: "6px",
|
|
5093
|
+
cursor: "pointer",
|
|
5094
|
+
fontSize: "12px",
|
|
5095
|
+
background: "rgba(128, 128, 128, 0.15)",
|
|
5096
|
+
color: "var(--dsw-alias-label-secondary, inherit)"
|
|
5097
|
+
},
|
|
5098
|
+
children: "\u2715"
|
|
5099
|
+
}
|
|
5100
|
+
)
|
|
5101
|
+
]
|
|
5102
|
+
}
|
|
5103
|
+
) : null,
|
|
5104
|
+
!status.loading && status.directoryPicker.patchEnabled && status.directoryPicker.restartRequired && !dirPickerBannerDismissed ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
5105
|
+
"div",
|
|
5106
|
+
{
|
|
5107
|
+
style: {
|
|
5108
|
+
display: "flex",
|
|
5109
|
+
alignItems: "flex-start",
|
|
5110
|
+
gap: "10px",
|
|
5111
|
+
padding: "12px 14px",
|
|
5112
|
+
borderRadius: "10px",
|
|
5113
|
+
border: "1px solid rgba(59, 130, 246, 0.45)",
|
|
5114
|
+
background: "rgba(59, 130, 246, 0.1)"
|
|
5115
|
+
},
|
|
5116
|
+
children: [
|
|
5117
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { style: { fontSize: "16px", lineHeight: "20px" }, children: "\u2705" }),
|
|
5118
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
|
|
5119
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
5120
|
+
"div",
|
|
5121
|
+
{
|
|
5122
|
+
style: {
|
|
5123
|
+
fontSize: "13px",
|
|
5124
|
+
fontWeight: "700",
|
|
5125
|
+
marginBottom: "4px",
|
|
5126
|
+
color: "var(--dsw-alias-label-primary, inherit)"
|
|
5127
|
+
},
|
|
5128
|
+
children: t("dirPickerRestartBannerTitle", currentLang)
|
|
5129
|
+
}
|
|
5130
|
+
),
|
|
5131
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
5132
|
+
"div",
|
|
5133
|
+
{
|
|
5134
|
+
style: {
|
|
5135
|
+
fontSize: "12px",
|
|
5136
|
+
lineHeight: 1.6,
|
|
5137
|
+
color: "var(--dsw-alias-label-secondary, inherit)"
|
|
5138
|
+
},
|
|
5139
|
+
children: t("dirPickerRestartBannerBody", currentLang, {
|
|
5140
|
+
path: status.directoryPicker.patchFilePath || "~/.dsh/profiles/web/cordis.patch.yml"
|
|
5141
|
+
})
|
|
5142
|
+
}
|
|
5143
|
+
)
|
|
5144
|
+
] }),
|
|
5145
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
5146
|
+
"button",
|
|
5147
|
+
{
|
|
5148
|
+
type: "button",
|
|
5149
|
+
onClick: () => setDirPickerBannerDismissed(true),
|
|
5150
|
+
title: t("dirPickerBannerDismiss", currentLang),
|
|
5151
|
+
style: {
|
|
5152
|
+
flexShrink: 0,
|
|
5153
|
+
width: "24px",
|
|
5154
|
+
height: "24px",
|
|
5155
|
+
display: "inline-flex",
|
|
5156
|
+
alignItems: "center",
|
|
5157
|
+
justifyContent: "center",
|
|
5158
|
+
border: "none",
|
|
5159
|
+
borderRadius: "6px",
|
|
5160
|
+
cursor: "pointer",
|
|
5161
|
+
fontSize: "12px",
|
|
5162
|
+
background: "rgba(128, 128, 128, 0.15)",
|
|
5163
|
+
color: "var(--dsw-alias-label-secondary, inherit)"
|
|
5164
|
+
},
|
|
5165
|
+
children: "\u2715"
|
|
5166
|
+
}
|
|
5167
|
+
)
|
|
5168
|
+
]
|
|
5169
|
+
}
|
|
5170
|
+
) : null,
|
|
5171
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4361
5172
|
"div",
|
|
4362
5173
|
{
|
|
4363
5174
|
style: {
|
|
@@ -4378,7 +5189,7 @@ function TailscaleMobileSection(props) {
|
|
|
4378
5189
|
{ id: "storage", label: t("tabStorage", currentLang) }
|
|
4379
5190
|
].map((item) => {
|
|
4380
5191
|
const isActive = activeTab === item.id;
|
|
4381
|
-
return /* @__PURE__ */ (0,
|
|
5192
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4382
5193
|
"button",
|
|
4383
5194
|
{
|
|
4384
5195
|
type: "button",
|
|
@@ -4405,8 +5216,8 @@ function TailscaleMobileSection(props) {
|
|
|
4405
5216
|
})
|
|
4406
5217
|
}
|
|
4407
5218
|
),
|
|
4408
|
-
/* @__PURE__ */ (0,
|
|
4409
|
-
/* @__PURE__ */ (0,
|
|
5219
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: { display: activeTab === "access" ? "flex" : "none", flexDirection: "column", gap: "16px" }, children: [
|
|
5220
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4410
5221
|
NetworkCard,
|
|
4411
5222
|
{
|
|
4412
5223
|
status,
|
|
@@ -4416,7 +5227,28 @@ function TailscaleMobileSection(props) {
|
|
|
4416
5227
|
lang: currentLang
|
|
4417
5228
|
}
|
|
4418
5229
|
),
|
|
4419
|
-
/* @__PURE__ */ (0,
|
|
5230
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
5231
|
+
ProxyConfigCard,
|
|
5232
|
+
{
|
|
5233
|
+
status,
|
|
5234
|
+
modeInput,
|
|
5235
|
+
setModeInput,
|
|
5236
|
+
proxyPortInput,
|
|
5237
|
+
setProxyPortInput,
|
|
5238
|
+
proxyHostInput,
|
|
5239
|
+
setProxyHostInput,
|
|
5240
|
+
trustedHostsInput,
|
|
5241
|
+
setTrustedHostsInput,
|
|
5242
|
+
saveProxyConfig,
|
|
5243
|
+
resetProxyConfigDefaults,
|
|
5244
|
+
toggleDirectoryPicker,
|
|
5245
|
+
isPatchingDirPicker,
|
|
5246
|
+
copyText,
|
|
5247
|
+
isSaving,
|
|
5248
|
+
lang: currentLang
|
|
5249
|
+
}
|
|
5250
|
+
),
|
|
5251
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4420
5252
|
QrPairingCard,
|
|
4421
5253
|
{
|
|
4422
5254
|
status,
|
|
@@ -4433,7 +5265,7 @@ function TailscaleMobileSection(props) {
|
|
|
4433
5265
|
lang: currentLang
|
|
4434
5266
|
}
|
|
4435
5267
|
),
|
|
4436
|
-
/* @__PURE__ */ (0,
|
|
5268
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4437
5269
|
SecretCard,
|
|
4438
5270
|
{
|
|
4439
5271
|
status,
|
|
@@ -4447,8 +5279,8 @@ function TailscaleMobileSection(props) {
|
|
|
4447
5279
|
}
|
|
4448
5280
|
)
|
|
4449
5281
|
] }),
|
|
4450
|
-
/* @__PURE__ */ (0,
|
|
4451
|
-
/* @__PURE__ */ (0,
|
|
5282
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: { display: activeTab === "devices" ? "flex" : "none", flexDirection: "column", gap: "16px" }, children: [
|
|
5283
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4452
5284
|
DeviceListCard,
|
|
4453
5285
|
{
|
|
4454
5286
|
status,
|
|
@@ -4457,7 +5289,7 @@ function TailscaleMobileSection(props) {
|
|
|
4457
5289
|
lang: currentLang
|
|
4458
5290
|
}
|
|
4459
5291
|
),
|
|
4460
|
-
/* @__PURE__ */ (0,
|
|
5292
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4461
5293
|
SecurityCard,
|
|
4462
5294
|
{
|
|
4463
5295
|
status,
|
|
@@ -4466,7 +5298,7 @@ function TailscaleMobileSection(props) {
|
|
|
4466
5298
|
lang: currentLang
|
|
4467
5299
|
}
|
|
4468
5300
|
),
|
|
4469
|
-
/* @__PURE__ */ (0,
|
|
5301
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4470
5302
|
ConfigCard,
|
|
4471
5303
|
{
|
|
4472
5304
|
maxVisitsInput,
|
|
@@ -4483,8 +5315,8 @@ function TailscaleMobileSection(props) {
|
|
|
4483
5315
|
}
|
|
4484
5316
|
)
|
|
4485
5317
|
] }),
|
|
4486
|
-
/* @__PURE__ */ (0,
|
|
4487
|
-
/* @__PURE__ */ (0,
|
|
5318
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: { display: activeTab === "style" ? "flex" : "none", flexDirection: "column", gap: "16px" }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(StylesCard, { lang: currentLang, showToast }) }),
|
|
5319
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: { display: activeTab === "storage" ? "flex" : "none", flexDirection: "column", gap: "16px" }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(StorageCard, { status, lang: currentLang, copyText }) })
|
|
4488
5320
|
]
|
|
4489
5321
|
}
|
|
4490
5322
|
);
|