zcode-pro 1.3.1 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +57 -30
- package/README.md +57 -30
- package/dist/inject.js +1195 -66
- package/dist/zcode_pro-1.4.0-py3-none-any.whl +0 -0
- package/dist/zcode_pro-1.4.0.tar.gz +0 -0
- package/package.json +1 -1
- package/src/host/helper.mjs +492 -57
- package/src/host/webdav.mjs +19 -11
- package/src/inject/core.js +132 -20
- package/src/inject/features/settings-dialog.js +400 -44
- package/src/inject/features/status-bar.js +17 -4
- package/src/inject/features/theme.js +500 -0
- package/src/inject/index.js +2 -0
- package/src/inject/ui.js +33 -2
package/dist/inject.js
CHANGED
|
@@ -17,15 +17,24 @@
|
|
|
17
17
|
}).then((r) => r.json()).catch((err) => ({ ok: false, error: String(err && err.message || err) }));
|
|
18
18
|
}
|
|
19
19
|
var configCache = { value: null, at: 0 };
|
|
20
|
+
var configInflight = null;
|
|
20
21
|
async function getConfig(force = false) {
|
|
21
22
|
const now = Date.now();
|
|
22
23
|
if (!force && configCache.value && now - configCache.at < 3e3) return configCache.value;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
if (configInflight) return configInflight;
|
|
25
|
+
configInflight = (async () => {
|
|
26
|
+
try {
|
|
27
|
+
const res = await rpc("/config");
|
|
28
|
+
if (res.ok && res.config) {
|
|
29
|
+
configCache = { value: res.config, at: Date.now() };
|
|
30
|
+
return res.config;
|
|
31
|
+
}
|
|
32
|
+
return configCache.value || { features: {} };
|
|
33
|
+
} finally {
|
|
34
|
+
configInflight = null;
|
|
35
|
+
}
|
|
36
|
+
})();
|
|
37
|
+
return configInflight;
|
|
29
38
|
}
|
|
30
39
|
function clearConfigCache() {
|
|
31
40
|
configCache = { value: null, at: 0 };
|
|
@@ -96,7 +105,7 @@
|
|
|
96
105
|
var zh = {
|
|
97
106
|
settingsTitle: "ZCode Pro",
|
|
98
107
|
tabFeatures: "\u529F\u80FD",
|
|
99
|
-
tabStyles: "\
|
|
108
|
+
tabStyles: "\u5916\u89C2",
|
|
100
109
|
tabProxy: "\u4EE3\u7406",
|
|
101
110
|
tabBehavior: "\u884C\u4E3A",
|
|
102
111
|
tabAgents: "\u5168\u5C40\u63D0\u793A\u8BCD",
|
|
@@ -177,8 +186,6 @@
|
|
|
177
186
|
syncVerDeleteDesc: "\u5C06\u5220\u9664\u4E91\u7AEF\u7684\u8FD9\u4EFD\u5907\u4EFD\uFF0C\u4E0D\u53EF\u6062\u590D\uFF1A",
|
|
178
187
|
syncVerDeleted: "\u5DF2\u5220\u9664\u4E91\u7AEF\u5907\u4EFD",
|
|
179
188
|
syncVerSaved: "\u5DF2\u4FDD\u5B58\u5230",
|
|
180
|
-
devMode: "\u5F00\u53D1\u6A21\u5F0F",
|
|
181
|
-
devModeRowDesc: "\u5F00\u542F\u540E\u51FA\u73B0\u201C\u91CD\u8F7D ZCode Pro\u201D\u6309\u94AE\uFF1B\u4E5F\u53EF\u7ED9\u542F\u52A8\u5668\u8BBE\u73AF\u5883\u53D8\u91CF ZCODEPRO_DEV=1 \u542F\u7528\u3002\u6B64\u6807\u7B7E\u9875\u4EC5\u5728\u5F00\u53D1\u6A21\u5F0F\u751F\u6548\u65F6\u663E\u793A\u3002",
|
|
182
189
|
devModeDesc: "\u5F00\u53D1\u8C03\u8BD5\u7528\uFF1A\u6539\u5B8C zcode-pro \u4EE3\u7801\u540E\u4E0D\u5FC5\u91CD\u542F ZCode\uFF0C\u70B9\u201C\u91CD\u8F7D ZCode Pro\u201D\u5373\u53EF\u52A0\u8F7D\u65B0\u4EE3\u7801\u3002\u6D41\u7A0B\u4E3A\u81EA\u52A8\u6784\u5EFA\uFF08\u9700\u5728\u6E90\u7801\u76EE\u5F55\u8FD0\u884C\uFF09\u2192 \u4EE5\u65B0\u8FDB\u7A0B\u91CD\u542F ZCode Pro\uFF08\u672C\u5730\u52A9\u624B\u4E0E\u6CE8\u5165\u811A\u672C\u90FD\u6362\u65B0\uFF09\u2192 \u6240\u6709 ZCode \u7A97\u53E3\u81EA\u52A8\u5237\u65B0\u5E76\u91CD\u65B0\u6CE8\u5165\uFF1BZCode \u672C\u4F53\u4E0E\u5DF2\u6253\u5F00\u7684\u4F1A\u8BDD\u4E0D\u53D7\u5F71\u54CD\u3002",
|
|
183
190
|
devReload: "\u91CD\u8F7D ZCode Pro",
|
|
184
191
|
devReloading: "\u91CD\u8F7D\u4E2D\u2026",
|
|
@@ -286,13 +293,65 @@
|
|
|
286
293
|
featureNewtabPanelsDesc: "\u5B98\u65B9\u201C\u65B0\u6807\u7B7E\u9875\u201D\u53EA\u5217\u5B98\u65B9\u9762\u677F\u4E0E\u63A8\u8350\u7684\u5B98\u65B9\u63D2\u4EF6\uFF0C\u6B64\u529F\u80FD\u628A\u7B2C\u4E09\u65B9\u5E02\u573A\u63D2\u4EF6\uFF08headroom\u3001rtk \u7B49\uFF09\u7684\u9762\u677F\u5361\u7247\u52A0\u8FDB\u53BB\uFF0C\u70B9\u51FB\u5728\u4FA7\u8FB9\u9762\u677F\u6253\u5F00\u3002",
|
|
287
294
|
ntpDescSuffix: "\u63D2\u4EF6\u9762\u677F",
|
|
288
295
|
ntpNeedSession: "\u5148\u6253\u5F00\u4E00\u4E2A\u4EFB\u52A1\u4F1A\u8BDD\uFF0C\u518D\u4ECE\u65B0\u6807\u7B7E\u9875\u6253\u5F00\u63D2\u4EF6\u9762\u677F",
|
|
289
|
-
featureStatusBarDesc: "\
|
|
290
|
-
tabStylesPane: "\u6837\u5F0F
|
|
296
|
+
featureStatusBarDesc: "\u63D0\u95EE\u8F93\u5165\u6846\u53F3\u4E0B\u89D2\u548C\u6BCF\u8F6E\u56DE\u7B54\u6700\u540E\u663E\u793A\u7EDF\u8BA1\u9879\u3002",
|
|
297
|
+
tabStylesPane: "\u6837\u5F0F",
|
|
291
298
|
tabStatusPane: "\u72B6\u6001\u680F",
|
|
299
|
+
themeColorsPane: "\u4E3B\u9898",
|
|
300
|
+
themeBgRegions: "\u5206\u533A\u80CC\u666F",
|
|
301
|
+
themeBgRegionFollow: "\u65E0\u80CC\u666F",
|
|
302
|
+
themeBgRegionLeft: "\u5DE6\u4FA7\u8FB9\u680F",
|
|
303
|
+
themeBgRegionCenter: "\u4E2D\u95F4\u533A\u57DF",
|
|
304
|
+
themeBgRegionRight: "\u53F3\u4FA7\u8FB9\u680F",
|
|
305
|
+
themeBgPane: "\u80CC\u666F\u56FE",
|
|
306
|
+
themeSkinTitle: "\u76AE\u80A4",
|
|
307
|
+
themeSkinDesc: "\u77E5\u540D\u7F16\u8F91\u5668\u4E3B\u9898\u914D\u8272\uFF0C\u81EA\u52A8\u5339\u914D ZCode \u7684\u6D45\u8272 / \u6DF1\u8272\u6A21\u5F0F\uFF1B\u9ED8\u8BA4\u4FDD\u6301 ZCode \u539F\u6837\uFF0C\u81EA\u5B9A\u4E49\u5728\u4E0B\u65B9\u81EA\u884C\u8C03\u8272\u3002",
|
|
308
|
+
themeSkinCustom: "\u81EA\u5B9A\u4E49",
|
|
309
|
+
themeCustomTitle: "\u81EA\u5B9A\u4E49\u4E3B\u9898",
|
|
310
|
+
themeCustomHint: "\u6539\u989C\u8272\u5373\u5B9E\u65F6\u751F\u6548\uFF08\u81EA\u52A8\u5207\u5230\u81EA\u5B9A\u4E49\u76AE\u80A4\uFF09\uFF1B\u6D45\u8272\u3001\u6DF1\u8272\u5404\u914D\u4E00\u6B21\uFF0C\u9009\u597D 5 \u4E2A\u989C\u8272\u5373\u53EF\u751F\u6210\u6574\u5957\u754C\u9762\u914D\u8272\u3002",
|
|
311
|
+
themeCustomLight: "\u6D45\u8272",
|
|
312
|
+
themeCustomDark: "\u6DF1\u8272",
|
|
313
|
+
themeCustomBg: "\u80CC\u666F",
|
|
314
|
+
themeCustomCard: "\u5361\u7247",
|
|
315
|
+
themeCustomFg: "\u6B63\u6587",
|
|
316
|
+
themeCustomMuted: "\u6B21\u7EA7\u6587\u5B57",
|
|
317
|
+
themeCustomAccent: "\u5F3A\u8C03\u8272",
|
|
318
|
+
themeBgDesc: "\u80CC\u666F\u6765\u6E90\u53EF\u9009\u672C\u5730\u56FE\u5E93\u3001\u6587\u4EF6\u5939\uFF08\u5B9A\u65F6\u8F6E\u6362\uFF09\u6216\u7F51\u5740\uFF08\u5B9A\u65F6\u5237\u65B0\uFF09\uFF0C\u5DE6\u680F / \u4E2D\u680F / \u53F3\u680F\u53EF\u5206\u533A\u72EC\u7ACB\u8BBE\u7F6E\uFF1B\u4FA7\u680F\u3001\u4F1A\u8BDD\u6D41\u3001\u8F93\u5165\u6846\u900F\u51FA\u80CC\u666F\uFF0C\u5F39\u7A97\u83DC\u5355\u4FDD\u6301\u4E0D\u900F\u660E\u4FDD\u53EF\u8BFB\u3002\u672C\u5730\u56FE\u5E93\u968F WebDAV \u540C\u6B65\u4E0A\u4F20\uFF08\u8986\u76D6\u5F0F\uFF0C\u4E0D\u7559\u5386\u53F2\u7248\u672C\uFF09\u3002",
|
|
319
|
+
themeBgModeNone: "\u65E0\u80CC\u666F",
|
|
320
|
+
themeBgModeLibrary: "\u672C\u5730\u56FE\u5E93",
|
|
321
|
+
themeBgModeFolder: "\u6587\u4EF6\u5939",
|
|
322
|
+
themeBgModeUrl: "\u7F51\u5740",
|
|
323
|
+
themeBgLibrary: "\u6211\u7684\u56FE\u5E93",
|
|
324
|
+
themeBgUpload: "\u4E0A\u4F20\u56FE\u7247",
|
|
325
|
+
themeBgEmpty: "\u8FD8\u6CA1\u6709\u4E0A\u4F20\u56FE\u7247\uFF0C\u652F\u6301 png / jpg / webp / gif / bmp / avif\uFF0C\u5355\u5F20 10MB \u4EE5\u5185",
|
|
326
|
+
themeBgDelete: "\u5220\u9664",
|
|
327
|
+
themeBgNoneHint: "\u9009\u62E9\u4E00\u79CD\u80CC\u666F\u6765\u6E90\uFF1B\u6587\u4EF6\u5939\u53EF\u5B9A\u65F6\u8F6E\u6362\uFF0C\u7F51\u5740\u53EF\u914D\u5408\u968F\u673A\u56FE API \u5B9A\u65F6\u5237\u65B0\u3002",
|
|
328
|
+
themeBgFolderPick: "\u6D4F\u89C8",
|
|
329
|
+
themeBgFolderPickTitle: "\u9009\u62E9\u80CC\u666F\u56FE\u6587\u4EF6\u5939",
|
|
330
|
+
themeBgFolderHint: "\u9009\u62E9\u4E00\u4E2A\u88C5\u58C1\u7EB8\u7684\u6587\u4EF6\u5939\uFF0C\u56FE\u7247\u539F\u5730\u8BFB\u53D6\u4E0D\u590D\u5236\u3002",
|
|
331
|
+
themeBgFolderRandom: "\u968F\u673A\u987A\u5E8F",
|
|
332
|
+
themeBgIntervalHint: "\u5207\u6362\u95F4\u9694\uFF08\u5206\u949F\uFF09",
|
|
333
|
+
themeBgIntervalUnit: "\u5206\u949F\uFF0C0 = \u4E0D\u5207\u6362",
|
|
334
|
+
themeBgFolderCount: "\u6587\u4EF6\u5939\u91CC\u6709 {n} \u5F20\u56FE\u7247\uFF0C\u5B9A\u65F6\u8F6E\u6362\u4E2D\u3002",
|
|
335
|
+
themeBgFolderMissing: "\u6587\u4EF6\u5939\u4E0D\u5B58\u5728\u6216\u91CC\u9762\u6CA1\u6709\u56FE\u7247\u3002",
|
|
336
|
+
themeBgUrlHint: "\u5B9A\u65F6\u5237\u65B0\u9002\u5408\u968F\u673A\u56FE API\uFF08\u6BCF\u6B21\u8BF7\u6C42\u8FD4\u56DE\u4E0D\u540C\u56FE\uFF09\uFF1B\u5237\u65B0\u65F6\u5E26\u7F13\u5B58\u53C2\u6570\u907F\u514D\u547D\u4E2D\u7F13\u5B58\u3002",
|
|
337
|
+
themeBgUrlIntervalHint: "\u5237\u65B0\u95F4\u9694\uFF08\u5206\u949F\uFF09",
|
|
338
|
+
themeBgUrlInvalid: "\u7F51\u5740\u9700\u4EE5 http(s):// \u5F00\u5934",
|
|
339
|
+
themeBgFit: "\u7F29\u653E\u65B9\u5F0F",
|
|
340
|
+
themeBgFitCover: "\u586B\u6EE1",
|
|
341
|
+
themeBgFitContain: "\u9002\u5E94",
|
|
342
|
+
themeBgFitFill: "\u62C9\u4F38",
|
|
343
|
+
themeBgFitTile: "\u5E73\u94FA",
|
|
344
|
+
themeBgMask: "\u906E\u7F69\u4E0D\u900F\u660E\u5EA6",
|
|
345
|
+
themeBgMaskHint: "\u6570\u503C\u8D8A\u9AD8\uFF0C\u56FE\u7247\u8D8A\u5411\u4E3B\u9898\u80CC\u666F\u8272\u6DE1\u5316\uFF0C\u6587\u5B57\u5BF9\u6BD4\u8D8A\u6E05\u6670",
|
|
346
|
+
themeBgMaskHint2: "\u56FE\u7247\u5411\u4E3B\u9898\u80CC\u666F\u8272\u6DE1\u5316\u7684\u7A0B\u5EA6",
|
|
347
|
+
themeBgBlur: "\u56FE\u7247\u6A21\u7CCA",
|
|
348
|
+
themeBgPanel: "\u9762\u677F\u4E0D\u900F\u660E\u5EA6",
|
|
349
|
+
themeBgPanelHint: "\u4FA7\u680F\u3001\u9762\u677F\u4E0E\u6807\u7B7E\u680F\u7684\u4E0D\u900F\u660E\u7A0B\u5EA6\u3002\u8D8A\u4F4E\uFF0C\u900F\u51FA\u7684\u56FE\u7247\u8D8A\u591A\u3002",
|
|
350
|
+
themeBgDeletedActive: "\u5F53\u524D\u80CC\u666F\u5DF2\u5220\u9664\uFF0C\u5DF2\u81EA\u52A8\u505C\u7528\u80CC\u666F",
|
|
292
351
|
sbItemCtx: "\u4E0A\u4E0B\u6587\u5360\u7528",
|
|
293
352
|
sbItemQuestions: "\u63D0\u95EE\u6B21\u6570",
|
|
294
353
|
sbMaster: "\u542F\u7528\u7EDF\u8BA1",
|
|
295
|
-
sbMasterDesc: "\u603B\u5F00\u5173\uFF1A\u5173\u95ED\u540E\
|
|
354
|
+
sbMasterDesc: "\u603B\u5F00\u5173\uFF1A\u5173\u95ED\u540E\u8F93\u5165\u6846\u53F3\u4E0B\u89D2\u7684\u7EDF\u8BA1\u884C\u4E0E\u6BCF\u8F6E\u56DE\u7B54\u7684\u7528\u91CF\u6807\u6CE8\u4E00\u8D77\u505C\u7528\u3002",
|
|
296
355
|
sbGroupSession: "\u4F1A\u8BDD\u7EDF\u8BA1\uFF08\u8DDF\u968F\u5F53\u524D\u4F1A\u8BDD\uFF09",
|
|
297
356
|
sbGroupGlobal: "\u603B\u7EDF\u8BA1",
|
|
298
357
|
sbGroupTurn: "\u6BCF\u8F6E\u7EDF\u8BA1\uFF08\u56DE\u7B54\u672B\u5C3E\uFF09",
|
|
@@ -505,7 +564,7 @@
|
|
|
505
564
|
aliasMigrateDesc: "\u5F53\u524D ZCode \u5DF2\u652F\u6301\u4FEE\u6539\u9879\u76EE\u540D\u79F0\uFF08\u9879\u76EE\u201C\u66F4\u591A\u201D\u83DC\u5355 \u2192 \u7F16\u8F91\u9879\u76EE\uFF09\uFF0C\u81EA\u5B9A\u4E49\u522B\u540D\u529F\u80FD\u5DF2\u505C\u7528\u3002\u53EF\u628A\u5DF2\u4FDD\u5B58\u7684\u522B\u540D\u5199\u5165\u5B98\u65B9\u9879\u76EE\u540D\u79F0\uFF0C\u52FE\u9009\u8981\u8FC1\u79FB\u7684\u9879\u76EE\uFF1B\u8FC1\u79FB\u53EA\u6539\u9879\u76EE\u540D\u79F0\uFF0C\u78C1\u76D8\u76EE\u5F55\u4E0D\u53D7\u5F71\u54CD\u3002",
|
|
506
565
|
aliasMigrateItemHint: "\u8FC1\u79FB\u540E\u5C06\u4F5C\u4E3A\u9879\u76EE\u540D\u79F0\u4FDD\u5B58\uFF08\u53EF\u968F\u65F6\u5728\u201C\u7F16\u8F91\u9879\u76EE\u201D\u4E2D\u518D\u6539\uFF09\u3002\u4EC5\u65E0\u6807\u8BB0\u7684\u6761\u76EE\u53EF\u52FE\u9009\uFF1B\u5DF2\u8FC1\u79FB\u3001\u5DF2\u5E76\u5165\u3001\u9879\u76EE\u5DF2\u5220\u9664\u3001\u672C\u673A\u4E0D\u5B58\u5728\uFF08\u65E7\u673A\u5668\u8DEF\u5F84\uFF09\u4EE5\u53CA\u9879\u76EE\u5DF2\u91CD\u547D\u540D\u7684\u90FD\u4E0D\u53EF\u52FE\u9009\u2014\u2014\u8981\u6539\u8FD9\u4E9B\u9879\u76EE\u7684\u540D\u5B57\uFF0C\u76F4\u63A5\u7528\u9879\u76EE\u201C\u66F4\u591A\u201D\u83DC\u5355\u91CC\u7684\u201C\u7F16\u8F91\u9879\u76EE\u201D\u3002",
|
|
507
566
|
aliasMigrateStateDone: "\u5DF2\u8FC1\u79FB",
|
|
508
|
-
aliasMigrateStateMerged: "\u5DF2\u5E76\u5165\
|
|
567
|
+
aliasMigrateStateMerged: "\u5DF2\u5E76\u5165\u201C{name}\u201D",
|
|
509
568
|
aliasMigrateStateDeleted: "\u9879\u76EE\u5DF2\u5220\u9664",
|
|
510
569
|
aliasMigrateStateMissing: "\u672C\u673A\u4E0D\u5B58\u5728",
|
|
511
570
|
aliasMigrateStateRenamed: "\u9879\u76EE\u5DF2\u91CD\u547D\u540D",
|
|
@@ -552,7 +611,7 @@
|
|
|
552
611
|
var en = {
|
|
553
612
|
settingsTitle: "ZCode Pro",
|
|
554
613
|
tabFeatures: "Features",
|
|
555
|
-
tabStyles: "
|
|
614
|
+
tabStyles: "Appearance",
|
|
556
615
|
tabProxy: "Proxy",
|
|
557
616
|
tabBehavior: "Behavior",
|
|
558
617
|
tabAgents: "Global Prompt",
|
|
@@ -633,8 +692,6 @@
|
|
|
633
692
|
syncVerDeleteDesc: "This backup will be deleted from the server and cannot be recovered: ",
|
|
634
693
|
syncVerDeleted: "Backup deleted from the server.",
|
|
635
694
|
syncVerSaved: "Saved to",
|
|
636
|
-
devMode: "Developer mode",
|
|
637
|
-
devModeRowDesc: 'Shows the "Reload ZCode Pro" button; can also be enabled with the ZCODEPRO_DEV=1 environment variable. This tab is visible only while developer mode is active.',
|
|
638
695
|
devModeDesc: 'For development: after changing zcode-pro code, click "Reload ZCode Pro" instead of restarting ZCode. It builds automatically (when running from the source repo), restarts the ZCode Pro launcher process (fresh helper and injected script), and every ZCode window refreshes and re-injects. The ZCode app itself and all sessions stay untouched.',
|
|
639
696
|
devReload: "Reload ZCode Pro",
|
|
640
697
|
devReloading: "Reloading\u2026",
|
|
@@ -742,13 +799,65 @@
|
|
|
742
799
|
featureNewtabPanelsDesc: 'The built-in "new tab page" only lists built-in panels and recommended official plugins; this adds cards for third-party marketplace plugin panels (headroom, rtk, \u2026) that open in the side pane.',
|
|
743
800
|
ntpDescSuffix: "plugin panel",
|
|
744
801
|
ntpNeedSession: "Open a task session first, then open plugin panels from the new tab page",
|
|
745
|
-
featureStatusBarDesc:
|
|
802
|
+
featureStatusBarDesc: "Shows statistics at the bottom-right of the input box and at the end of each answer.",
|
|
746
803
|
tabStylesPane: "Styles",
|
|
747
804
|
tabStatusPane: "Status bar",
|
|
805
|
+
themeColorsPane: "Theme",
|
|
806
|
+
themeBgRegions: "Regional backgrounds",
|
|
807
|
+
themeBgRegionFollow: "None",
|
|
808
|
+
themeBgRegionLeft: "Left sidebar",
|
|
809
|
+
themeBgRegionCenter: "Center area",
|
|
810
|
+
themeBgRegionRight: "Right sidebar",
|
|
811
|
+
themeBgPane: "Background",
|
|
812
|
+
themeSkinTitle: "Skins",
|
|
813
|
+
themeSkinDesc: 'Famous editor theme palettes, auto-matching ZCode\u2019s light / dark mode; "Default" keeps ZCode as-is, "Custom" is tuned below.',
|
|
814
|
+
themeSkinCustom: "Custom",
|
|
815
|
+
themeCustomTitle: "Custom theme",
|
|
816
|
+
themeCustomHint: "Color changes apply live (auto-switches to the custom skin); set light and dark separately \u2014 pick 5 colors and the whole palette is derived.",
|
|
817
|
+
themeCustomLight: "Light",
|
|
818
|
+
themeCustomDark: "Dark",
|
|
819
|
+
themeCustomBg: "Background",
|
|
820
|
+
themeCustomCard: "Card",
|
|
821
|
+
themeCustomFg: "Text",
|
|
822
|
+
themeCustomMuted: "Muted text",
|
|
823
|
+
themeCustomAccent: "Accent",
|
|
824
|
+
themeBgDesc: "Sources: local library, folder (rotate on a timer) or URL (refresh on a timer); left / center / right regions can each have their own. Sidebar, chat and composer reveal the background while menus and dialogs stay opaque. The library uploads with the zcode-pro sync group (overwrite, no history versions).",
|
|
825
|
+
themeBgModeNone: "None",
|
|
826
|
+
themeBgModeLibrary: "Library",
|
|
827
|
+
themeBgModeFolder: "Folder",
|
|
828
|
+
themeBgModeUrl: "URL",
|
|
829
|
+
themeBgLibrary: "My library",
|
|
830
|
+
themeBgUpload: "Upload",
|
|
831
|
+
themeBgEmpty: "No images yet. png / jpg / webp / gif / bmp / avif, up to 10MB each",
|
|
832
|
+
themeBgDelete: "Delete",
|
|
833
|
+
themeBgNoneHint: "Pick a background source; folders rotate on a timer, URLs refresh on a timer for random-image APIs.",
|
|
834
|
+
themeBgFolderPick: "Browse",
|
|
835
|
+
themeBgFolderPickTitle: "Choose a wallpaper folder",
|
|
836
|
+
themeBgFolderHint: "Pick a folder of wallpapers; images are read in place, not copied.",
|
|
837
|
+
themeBgFolderRandom: "Random order",
|
|
838
|
+
themeBgIntervalHint: "Switch interval (minutes)",
|
|
839
|
+
themeBgIntervalUnit: "min, 0 = off",
|
|
840
|
+
themeBgFolderCount: "{n} images in the folder, rotating on the timer.",
|
|
841
|
+
themeBgFolderMissing: "Folder missing or contains no images.",
|
|
842
|
+
themeBgUrlHint: "Timed refresh suits random-image APIs (each request returns a new image); a cache-buster is appended on refresh.",
|
|
843
|
+
themeBgUrlIntervalHint: "Refresh interval (minutes)",
|
|
844
|
+
themeBgUrlInvalid: "URL must start with http(s)://",
|
|
845
|
+
themeBgFit: "Fit",
|
|
846
|
+
themeBgFitCover: "Fill",
|
|
847
|
+
themeBgFitContain: "Fit",
|
|
848
|
+
themeBgFitFill: "Stretch",
|
|
849
|
+
themeBgFitTile: "Tile",
|
|
850
|
+
themeBgMask: "Mask opacity",
|
|
851
|
+
themeBgMaskHint: "Higher values fade the image toward the theme background color for clearer text",
|
|
852
|
+
themeBgMaskHint2: "How much the image fades toward the theme background color",
|
|
853
|
+
themeBgBlur: "Image blur",
|
|
854
|
+
themeBgPanel: "Panel opacity",
|
|
855
|
+
themeBgPanelHint: "Opacity of sidebar, panels and tab bar. Lower reveals more of the image.",
|
|
856
|
+
themeBgDeletedActive: "Active background was deleted; background disabled",
|
|
748
857
|
sbItemCtx: "Context usage",
|
|
749
858
|
sbItemQuestions: "Questions asked",
|
|
750
859
|
sbMaster: "Enable statistics",
|
|
751
|
-
sbMasterDesc: "Master switch: turning this off disables both the
|
|
860
|
+
sbMasterDesc: "Master switch: turning this off disables both the input-box statistics and per-turn labels.",
|
|
752
861
|
sbGroupSession: "Session statistics (follows current session)",
|
|
753
862
|
sbGroupGlobal: "Global statistics",
|
|
754
863
|
sbGroupTurn: "Per-turn statistics (answer rows)",
|
|
@@ -1159,8 +1268,8 @@
|
|
|
1159
1268
|
clearTimeout(toastTimer);
|
|
1160
1269
|
toastTimer = setTimeout(() => el.remove(), kind === "error" ? 5e3 : 2600);
|
|
1161
1270
|
}
|
|
1162
|
-
var overlayClass = "fixed inset-0 isolate z-50 flex items-
|
|
1163
|
-
var overlayClassBare = "fixed inset-0 isolate z-50 flex items-
|
|
1271
|
+
var overlayClass = "fixed inset-0 isolate z-50 flex items-start justify-center bg-black/60 supports-backdrop-filter:backdrop-blur-xs duration-100 p-4 platform-linux-desktop:top-12";
|
|
1272
|
+
var overlayClassBare = "fixed inset-0 isolate z-50 flex items-start justify-center duration-100 p-4 platform-linux-desktop:top-12";
|
|
1164
1273
|
var contentClass = "w-full sm:max-w-md rounded-2xl border-none bg-popover/98 p-5 text-ui-base/relaxed text-foreground ring-border shadow-2xl";
|
|
1165
1274
|
var dialogStack = [];
|
|
1166
1275
|
function openDialog({ title, description, onMount, onClose, width = "sm:max-w-md", overlay = "dim", draggable = false, posKey = "", dismissOnOutside = true, bodyClass = "", closable = false }) {
|
|
@@ -1188,7 +1297,8 @@
|
|
|
1188
1297
|
const content = h("div", {
|
|
1189
1298
|
role: "dialog",
|
|
1190
1299
|
"aria-modal": "true",
|
|
1191
|
-
class: contentClass.replace("sm:max-w-md", width) + " zcodepro-card"
|
|
1300
|
+
class: contentClass.replace("sm:max-w-md", width) + " zcodepro-card",
|
|
1301
|
+
style: "margin-top:12vh;max-height:calc(88vh - 3rem);overflow-y:auto;"
|
|
1192
1302
|
});
|
|
1193
1303
|
const overlayEl = h("div", {
|
|
1194
1304
|
"data-overlay": overlay,
|
|
@@ -1604,6 +1714,32 @@
|
|
|
1604
1714
|
color: var(--color-foreground, #111);
|
|
1605
1715
|
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12);
|
|
1606
1716
|
}
|
|
1717
|
+
/* \u4E3B\u9898\uFF08\u6837\u5F0F \u2192 \u4E3B\u9898\uFF09\uFF1A\u76AE\u80A4\u5361\u7247\uFF08\u8272\u5757\u9884\u89C8 + \u540D\u79F0\uFF09\u4E0E\u80CC\u666F\u7F29\u7565\u56FE */
|
|
1718
|
+
.zcodepro-skin-card {
|
|
1719
|
+
display: flex; flex-direction: column; gap: 6px;
|
|
1720
|
+
padding: 8px; border: 1px solid var(--color-card-border, #8883);
|
|
1721
|
+
border-radius: 10px; background: transparent; cursor: pointer; text-align: left;
|
|
1722
|
+
transition: border-color 0.15s ease, background-color 0.15s ease;
|
|
1723
|
+
}
|
|
1724
|
+
.zcodepro-skin-card:hover { background-color: color-mix(in oklab, var(--color-foreground, #888) 6%, transparent); }
|
|
1725
|
+
.zcodepro-skin-card[data-state="active"] { border-color: var(--color-primary, #333); }
|
|
1726
|
+
.zcodepro-skin-swatches { display: flex; height: 18px; border-radius: 5px; overflow: hidden; }
|
|
1727
|
+
.zcodepro-skin-swatches > span { flex: 1; }
|
|
1728
|
+
.zcodepro-bg-card {
|
|
1729
|
+
position: relative; width: 100%; aspect-ratio: 16 / 9;
|
|
1730
|
+
border-radius: 8px; border: 2px solid transparent; padding: 0;
|
|
1731
|
+
background-size: cover; background-position: center; cursor: pointer; overflow: hidden;
|
|
1732
|
+
}
|
|
1733
|
+
.zcodepro-bg-card:hover { filter: brightness(1.15); }
|
|
1734
|
+
.zcodepro-bg-card[data-state="active"] { border-color: var(--color-primary, #333); }
|
|
1735
|
+
.zcodepro-bg-card img { width: 100%; height: 100%; object-fit: cover; display: block; }
|
|
1736
|
+
.zcodepro-bg-del {
|
|
1737
|
+
position: absolute; top: 4px; right: 4px; width: 20px; height: 20px;
|
|
1738
|
+
border-radius: 6px; border: none; cursor: pointer; font-size: 11px; line-height: 1;
|
|
1739
|
+
color: #fff; background: rgba(0, 0, 0, 0.55);
|
|
1740
|
+
display: flex; align-items: center; justify-content: center;
|
|
1741
|
+
}
|
|
1742
|
+
.zcodepro-bg-del:hover { background: rgba(220, 38, 38, 0.85); }
|
|
1607
1743
|
/* \u7D27\u51D1\u5C0F\u6309\u94AE\uFF1A\u51E0\u4F55/\u914D\u8272\u5199\u5165\u81EA\u6709\u89C4\u5219\u5E76\u53D6\u4E3B\u9898\u53D8\u91CF\uFF08\u9AD8\u5EA6=24px\uFF0C\u4E0E\u6807\u7B7E\u9875\u4E00\u81F4\uFF09 */
|
|
1608
1744
|
.zcodepro-btn-sm {
|
|
1609
1745
|
display: inline-flex;
|
|
@@ -1691,6 +1827,8 @@
|
|
|
1691
1827
|
-webkit-appearance: none;
|
|
1692
1828
|
appearance: none;
|
|
1693
1829
|
width: 100%;
|
|
1830
|
+
/* \u4E0D\u7ED9 padding\uFF1Apadding \u4F1A\u7F29\u5C0F thumb \u7684\u53EF\u6ED1\u533A\u95F4\uFF08\u62D6\u4E0D\u5230\u6700\u5DE6/\u6700\u53F3\uFF09\u3002
|
|
1831
|
+
\u8F68\u9053\u8D77\u70B9\u5BF9\u9F50\u7531\u5F39\u7A97\u91CC\u7684\u56FA\u5B9A\u6807\u7B7E\u5217\u5BBD\u8D1F\u8D23 */
|
|
1694
1832
|
height: 4px;
|
|
1695
1833
|
border-radius: 9999px;
|
|
1696
1834
|
background: color-mix(in oklab, var(--color-foreground, #888) 18%, transparent);
|
|
@@ -3806,6 +3944,478 @@
|
|
|
3806
3944
|
if (hlEl) hlEl.textContent = "";
|
|
3807
3945
|
}
|
|
3808
3946
|
|
|
3947
|
+
// src/inject/features/theme.js
|
|
3948
|
+
var SC = (light, dark, lightA, darkA) => ({ light, dark, lightA, darkA });
|
|
3949
|
+
var SCALES = {
|
|
3950
|
+
dracula: SC(
|
|
3951
|
+
["#fefeff", "#f5f4f9", "#f1f0f6", "#edebf4", "#dedee4", "#c4c3cb", "#aaa9b3", "#885cdb", "#9a6ff0", "#af85ff", "#5f5c77", "#2b2a3a"],
|
|
3952
|
+
["#21222c", "#282a36", "#2d303d", "#343746", "#484b59", "#656873", "#80828a", "#aa80e5", "#bd93f9", "#d3a9ff", "#7b89b3", "#f8f8f2"],
|
|
3953
|
+
["#2b2a3a03", "#2b2a3a06", "#2b2a3a0f", "#2b2a3a17", "#2b2a3a1f", "#2b2a3a26", "#2b2a3a31", "#2b2a3a44", "#2b2a3a72", "#2b2a3a7c", "#2b2a3a9b", "#2b2a3adf"],
|
|
3954
|
+
["#f8f8f203", "#f8f8f206", "#f8f8f20f", "#f8f8f217", "#f8f8f21f", "#f8f8f226", "#f8f8f231", "#f8f8f244", "#f8f8f272", "#f8f8f27c", "#f8f8f29b", "#f8f8f2df"]
|
|
3955
|
+
),
|
|
3956
|
+
nord: SC(
|
|
3957
|
+
["#fbfcfe", "#f2f5f9", "#eef2f7", "#eaeff5", "#dce0e5", "#c3c7cd", "#aaaeb6", "#4d6f99", "#5e81ac", "#7296c2", "#576377", "#2e3440"],
|
|
3958
|
+
["#272c36", "#2e3440", "#343a48", "#3b4252", "#4e5564", "#686e7c", "#808692", "#75adbd", "#88c0d0", "#9ed7e7", "#8e9ab0", "#eceff4"],
|
|
3959
|
+
["#2e344003", "#2e344006", "#2e34400f", "#2e344017", "#2e34401f", "#2e344026", "#2e344031", "#2e344044", "#2e344072", "#2e34407c", "#2e34409b", "#2e3440df"],
|
|
3960
|
+
["#eceff403", "#eceff406", "#eceff40f", "#eceff417", "#eceff41f", "#eceff426", "#eceff431", "#eceff444", "#eceff472", "#eceff47c", "#eceff49b", "#eceff4df"]
|
|
3961
|
+
),
|
|
3962
|
+
tokyonight: SC(
|
|
3963
|
+
["#fafbfe", "#eef0f6", "#e9ebf2", "#e3e6ef", "#d9dce5", "#c0c5d1", "#a8aebd", "#2d488e", "#3d59a1", "#506eb8", "#5a6684", "#2f3a55"],
|
|
3964
|
+
["#13141d", "#1a1b26", "#1e212f", "#24283b", "#34394f", "#4b516a", "#606784", "#688fe3", "#7aa2f7", "#8fb8ff", "#8893c3", "#c0caf5"],
|
|
3965
|
+
["#2f3a5503", "#2f3a5506", "#2f3a550f", "#2f3a5517", "#2f3a551f", "#2f3a5526", "#2f3a5531", "#2f3a5544", "#2f3a5572", "#2f3a557c", "#2f3a559b", "#2f3a55df"],
|
|
3966
|
+
["#c0caf503", "#c0caf506", "#c0caf50f", "#c0caf517", "#c0caf51f", "#c0caf526", "#c0caf531", "#c0caf544", "#c0caf572", "#c0caf57c", "#c0caf59b", "#c0caf5df"]
|
|
3967
|
+
),
|
|
3968
|
+
catppuccin: SC(
|
|
3969
|
+
["#fbfcfe", "#eff1f5", "#eaecf1", "#e4e7ed", "#dde0e6", "#c8cbd5", "#b4b7c3", "#6174e8", "#7287fd", "#869dff", "#73768c", "#4c4f69"],
|
|
3970
|
+
["#181825", "#1e1e2e", "#262738", "#313244", "#424357", "#595c71", "#6e7289", "#a1abea", "#b4befe", "#cad5ff", "#979cb5", "#cdd6f4"],
|
|
3971
|
+
["#4c4f6903", "#4c4f6906", "#4c4f690f", "#4c4f6917", "#4c4f691f", "#4c4f6926", "#4c4f6931", "#4c4f6944", "#4c4f6972", "#4c4f697c", "#4c4f699b", "#4c4f69df"],
|
|
3972
|
+
["#cdd6f403", "#cdd6f406", "#cdd6f40f", "#cdd6f417", "#cdd6f41f", "#cdd6f426", "#cdd6f431", "#cdd6f444", "#cdd6f472", "#cdd6f47c", "#cdd6f49b", "#cdd6f4df"]
|
|
3973
|
+
),
|
|
3974
|
+
gruvbox: SC(
|
|
3975
|
+
["#fefbf0", "#f8f2dd", "#f5eed4", "#f3eacc", "#e3decb", "#cbc5b5", "#b3aea0", "#8e6b00", "#a07d0a", "#b6922e", "#706558", "#3c3836"],
|
|
3976
|
+
["#1d2021", "#282828", "#312f2e", "#3c3836", "#4f4944", "#696256", "#807867", "#c38600", "#d79921", "#eeaf40", "#a1927f", "#ebdbb2"],
|
|
3977
|
+
["#3c383603", "#3c383606", "#3c38360f", "#3c383617", "#3c38361f", "#3c383626", "#3c383631", "#3c383644", "#3c383672", "#3c38367c", "#3c38369b", "#3c3836df"],
|
|
3978
|
+
["#ebdbb203", "#ebdbb206", "#ebdbb20f", "#ebdbb217", "#ebdbb21f", "#ebdbb226", "#ebdbb231", "#ebdbb244", "#ebdbb272", "#ebdbb27c", "#ebdbb29b", "#ebdbb2df"]
|
|
3979
|
+
),
|
|
3980
|
+
onedark: SC(
|
|
3981
|
+
["#fcfdff", "#f4f6fa", "#f0f3f8", "#edf0f6", "#dfe1e6", "#c6c8ce", "#adb0b7", "#3870c4", "#4a82d8", "#5f98f0", "#606774", "#333842"],
|
|
3982
|
+
["#21252b", "#282c34", "#2d313a", "#333842", "#404550", "#525863", "#626874", "#4e9cdb", "#61afef", "#77c6ff", "#6a717e", "#abb2bf"],
|
|
3983
|
+
["#33384203", "#33384206", "#3338420f", "#33384217", "#3338421f", "#33384226", "#33384231", "#33384244", "#33384272", "#3338427c", "#3338429b", "#333842df"],
|
|
3984
|
+
["#abb2bf03", "#abb2bf06", "#abb2bf0f", "#abb2bf17", "#abb2bf1f", "#abb2bf26", "#abb2bf31", "#abb2bf44", "#abb2bf72", "#abb2bf7c", "#abb2bf9b", "#abb2bfdf"]
|
|
3985
|
+
),
|
|
3986
|
+
solarized: SC(
|
|
3987
|
+
["#fffbf0", "#fdf6e3", "#fcf4dd", "#fbf1d7", "#ebe8d8", "#d7d7ca", "#c2c6bc", "#0078be", "#268bd2", "#41a1ea", "#889899", "#586e75"],
|
|
3988
|
+
["#00212b", "#002b36", "#03303b", "#073642", "#1b424d", "#31525b", "#446168", "#008e86", "#2aa198", "#47b7ae", "#62777d", "#93a1a1"],
|
|
3989
|
+
["#586e7503", "#586e7506", "#586e750f", "#586e7517", "#586e751f", "#586e7526", "#586e7531", "#586e7544", "#586e7572", "#586e757c", "#586e759b", "#586e75df"],
|
|
3990
|
+
["#93a1a103", "#93a1a106", "#93a1a10f", "#93a1a117", "#93a1a11f", "#93a1a126", "#93a1a131", "#93a1a144", "#93a1a172", "#93a1a17c", "#93a1a19b", "#93a1a1df"]
|
|
3991
|
+
),
|
|
3992
|
+
rosepine: SC(
|
|
3993
|
+
["#fffaf3", "#faf4ed", "#f8f1ea", "#f6efe8", "#e8e3e1", "#d3ced3", "#bfbac5", "#7e6896", "#907aa9", "#a58fbf", "#837d93", "#575279"],
|
|
3994
|
+
["#141220", "#191724", "#1c1a28", "#1f1d2e", "#323143", "#4e4d60", "#69677b", "#b194d3", "#c4a7e7", "#dbbdff", "#817e99", "#e0def4"],
|
|
3995
|
+
["#57527903", "#57527906", "#5752790f", "#57527917", "#5752791f", "#57527926", "#57527931", "#57527944", "#57527972", "#5752797c", "#5752799b", "#575279df"],
|
|
3996
|
+
["#e0def403", "#e0def406", "#e0def40f", "#e0def417", "#e0def41f", "#e0def426", "#e0def431", "#e0def444", "#e0def472", "#e0def47c", "#e0def49b", "#e0def4df"]
|
|
3997
|
+
),
|
|
3998
|
+
everforest: SC(
|
|
3999
|
+
["#fefdf5", "#faf7ec", "#f8f4e8", "#f6f2e4", "#e7e6dd", "#d2d2cb", "#bcbeb9", "#588c47", "#6a9e59", "#7fb46e", "#76827b", "#4f585e"],
|
|
4000
|
+
["#272e33", "#2d353b", "#30393f", "#343f44", "#454e50", "#5d625f", "#73756d", "#95ad6e", "#a7c080", "#bdd796", "#a7aea2", "#d3c6aa"],
|
|
4001
|
+
["#4f585e03", "#4f585e06", "#4f585e0f", "#4f585e17", "#4f585e1f", "#4f585e26", "#4f585e31", "#4f585e44", "#4f585e72", "#4f585e7c", "#4f585e9b", "#4f585edf"],
|
|
4002
|
+
["#d3c6aa03", "#d3c6aa06", "#d3c6aa0f", "#d3c6aa17", "#d3c6aa1f", "#d3c6aa26", "#d3c6aa31", "#d3c6aa44", "#d3c6aa72", "#d3c6aa7c", "#d3c6aa9b", "#d3c6aadf"]
|
|
4003
|
+
),
|
|
4004
|
+
nightowl: SC(
|
|
4005
|
+
["#fdfdfe", "#f6f7f9", "#f3f4f7", "#f0f2f5", "#e2e3e7", "#cbcbd2", "#b3b4bd", "#2253c2", "#3366d6", "#477cee", "#64667c", "#403f53"],
|
|
4006
|
+
["#010e1c", "#011627", "#072033", "#122d42", "#284054", "#445a6e", "#5f7285", "#7097ea", "#82aaff", "#97c1ff", "#778ea7", "#d6deeb"],
|
|
4007
|
+
["#403f5303", "#403f5306", "#403f530f", "#403f5317", "#403f531f", "#403f5326", "#403f5331", "#403f5344", "#403f5372", "#403f537c", "#403f539b", "#403f53df"],
|
|
4008
|
+
["#d6deeb03", "#d6deeb06", "#d6deeb0f", "#d6deeb17", "#d6deeb1f", "#d6deeb26", "#d6deeb31", "#d6deeb44", "#d6deeb72", "#d6deeb7c", "#d6deeb9b", "#d6deebdf"]
|
|
4009
|
+
),
|
|
4010
|
+
kanagawa: SC(
|
|
4011
|
+
["#fcf9f0", "#f4f1e8", "#f0ede4", "#edeae1", "#e1ded5", "#cac8c0", "#b4b2aa", "#2d4d95", "#3d5fa8", "#5074bf", "#72726a", "#43443e"],
|
|
4012
|
+
["#16161d", "#1f1f28", "#24242f", "#2a2a37", "#3c3c46", "#57565a", "#6f6d6c", "#6c8ac4", "#7e9cd8", "#93b2ef", "#848277", "#dcd7ba"],
|
|
4013
|
+
["#43443e03", "#43443e06", "#43443e0f", "#43443e17", "#43443e1f", "#43443e26", "#43443e31", "#43443e44", "#43443e72", "#43443e7c", "#43443e9b", "#43443edf"],
|
|
4014
|
+
["#dcd7ba03", "#dcd7ba06", "#dcd7ba0f", "#dcd7ba17", "#dcd7ba1f", "#dcd7ba26", "#dcd7ba31", "#dcd7ba44", "#dcd7ba72", "#dcd7ba7c", "#dcd7ba9b", "#dcd7badf"]
|
|
4015
|
+
)
|
|
4016
|
+
};
|
|
4017
|
+
var THEME_SKINS = [
|
|
4018
|
+
{
|
|
4019
|
+
id: "default",
|
|
4020
|
+
zh: "\u9ED8\u8BA4",
|
|
4021
|
+
en: "Default",
|
|
4022
|
+
preview: ["#f8f8f8", "#ffffff", "#ececee", "#dfdfdf", "#8b8b8b", "#18181b", "#9a9a9a", "#18181b"]
|
|
4023
|
+
},
|
|
4024
|
+
{ id: "dracula", hue: "dracula", zh: "\u5FB7\u53E4\u62C9", en: "Dracula" },
|
|
4025
|
+
{ id: "nord", hue: "nord", zh: "\u6781\u591C", en: "Nord" },
|
|
4026
|
+
{ id: "tokyonight", hue: "tokyonight", zh: "\u4E1C\u4EAC\u591C", en: "Tokyo Night" },
|
|
4027
|
+
{ id: "catppuccin", hue: "catppuccin", zh: "\u5976\u5496", en: "Catppuccin" },
|
|
4028
|
+
{ id: "gruvbox", hue: "gruvbox", zh: "\u6696\u5CA9", en: "Gruvbox" },
|
|
4029
|
+
{ id: "onedark", hue: "onedark", zh: "One Dark", en: "One Dark" },
|
|
4030
|
+
{ id: "solarized", hue: "solarized", zh: "\u65E5\u6652", en: "Solarized" },
|
|
4031
|
+
{ id: "rosepine", hue: "rosepine", zh: "\u73AB\u7470\u677E", en: "Ros\xE9 Pine" },
|
|
4032
|
+
{ id: "everforest", hue: "everforest", zh: "\u5E38\u7EFF", en: "Everforest" },
|
|
4033
|
+
{ id: "nightowl", hue: "nightowl", zh: "\u591C\u67AD", en: "Night Owl" },
|
|
4034
|
+
{ id: "kanagawa", hue: "kanagawa", zh: "\u795E\u5948\u5DDD", en: "Kanagawa" }
|
|
4035
|
+
];
|
|
4036
|
+
for (const s of THEME_SKINS) {
|
|
4037
|
+
if (!s.hue) continue;
|
|
4038
|
+
const L = SCALES[s.hue].light;
|
|
4039
|
+
s.preview = [L[1], L[0], L[3], L[5], L[8], L[9], L[10], L[11]];
|
|
4040
|
+
}
|
|
4041
|
+
var THEME_SKIN_IDS = THEME_SKINS.map((s) => s.id);
|
|
4042
|
+
var hexA = (hex, alphaHex) => `#${hex.slice(1)}${alphaHex}`;
|
|
4043
|
+
function skinVars(s, isDark) {
|
|
4044
|
+
if (!s) return null;
|
|
4045
|
+
const fg = s[11];
|
|
4046
|
+
return {
|
|
4047
|
+
"--color-background": s[1],
|
|
4048
|
+
"--color-background-win-alt": s[3],
|
|
4049
|
+
"--color-background-alt": `color-mix(in oklab, ${s[1]} ${isDark ? 60 : 70}%, transparent)`,
|
|
4050
|
+
"--color-sidebar": s[isDark ? 1 : 2],
|
|
4051
|
+
"--color-header": s[isDark ? 2 : 0],
|
|
4052
|
+
"--color-panel": s[isDark ? 2 : 0],
|
|
4053
|
+
"--color-card": s[isDark ? 3 : 0],
|
|
4054
|
+
"--color-card-selected": s[isDark ? 4 : 1],
|
|
4055
|
+
"--color-input": s[isDark ? 3 : 0],
|
|
4056
|
+
"--color-input-focused": s[isDark ? 3 : 0],
|
|
4057
|
+
"--color-menu": s[isDark ? 3 : 0],
|
|
4058
|
+
"--color-menu-hover": s[isDark ? 4 : 2],
|
|
4059
|
+
"--color-popover": s[isDark ? 3 : 0],
|
|
4060
|
+
"--color-popover-header": s[isDark ? 2 : 1],
|
|
4061
|
+
"--color-highspeed-composer-surface": s[isDark ? 0 : 1],
|
|
4062
|
+
"--color-tab-active": s[isDark ? 1 : 0],
|
|
4063
|
+
"--color-foreground": fg,
|
|
4064
|
+
"--color-foreground-subtle": s[10],
|
|
4065
|
+
"--color-foreground-subtlest": `color-mix(in oklab, ${s[10]} 60%, transparent)`,
|
|
4066
|
+
"--color-foreground-inverse": isDark ? "#101010" : "#ffffff",
|
|
4067
|
+
"--color-popover-foreground": fg,
|
|
4068
|
+
"--color-tooltip-foreground": fg,
|
|
4069
|
+
"--color-brand": fg,
|
|
4070
|
+
"--color-primary": fg,
|
|
4071
|
+
"--color-primary-foreground": isDark ? "#101010" : "#ffffff",
|
|
4072
|
+
"--color-accent": s[2],
|
|
4073
|
+
"--color-highspeed-accent": s[8],
|
|
4074
|
+
"--highspeed-sidebar-model-icon": s[8],
|
|
4075
|
+
"--highspeed-sidebar-model-gradient": `linear-gradient(90deg,${s[7]} 0%,${s[8]} 50%,${s[9]} 100%)`,
|
|
4076
|
+
"--color-hover": hexA(fg, isDark ? "12" : "0f"),
|
|
4077
|
+
"--color-surface-hover": hexA(fg, isDark ? "12" : "0f"),
|
|
4078
|
+
"--color-border": hexA(fg, "1a"),
|
|
4079
|
+
"--color-border-hover": hexA(fg, "26"),
|
|
4080
|
+
"--color-card-border": hexA(fg, "1a"),
|
|
4081
|
+
"--color-input-border": hexA(fg, "1a"),
|
|
4082
|
+
"--color-input-border-hover": hexA(fg, "26"),
|
|
4083
|
+
"--color-input-border-focused": hexA(fg, "26"),
|
|
4084
|
+
"--color-popover-border": hexA(fg, "1a"),
|
|
4085
|
+
"--color-tab-border": hexA(fg, "1a"),
|
|
4086
|
+
"--color-highspeed-composer-border-pre-animation": hexA(fg, "1a")
|
|
4087
|
+
};
|
|
4088
|
+
}
|
|
4089
|
+
var CUSTOM_DEFAULTS = {
|
|
4090
|
+
light: { bg: "#f7f8fa", card: "#ffffff", fg: "#24262b", muted: "#6b7280", accent: "#6366f1" },
|
|
4091
|
+
dark: { bg: "#18181d", card: "#232329", fg: "#e8e8ec", muted: "#9494a0", accent: "#8b8ff5" }
|
|
4092
|
+
};
|
|
4093
|
+
var mixOf = (x, t2, y) => `color-mix(in oklab, ${x} ${Math.round((1 - t2) * 100)}%, ${y} ${Math.round(t2 * 100)}%)`;
|
|
4094
|
+
function anchorsScale(a, isDark) {
|
|
4095
|
+
const { bg, card, fg, muted, accent } = a;
|
|
4096
|
+
return isDark ? [
|
|
4097
|
+
mixOf(bg, 0.12, "#000"),
|
|
4098
|
+
// 0 最深(输入区)
|
|
4099
|
+
bg,
|
|
4100
|
+
// 1 背景
|
|
4101
|
+
mixOf(bg, 0.45, card),
|
|
4102
|
+
// 2 顶栏/面板
|
|
4103
|
+
card,
|
|
4104
|
+
// 3 卡片/输入
|
|
4105
|
+
mixOf(card, 0.12, fg),
|
|
4106
|
+
// 4 选中/悬停
|
|
4107
|
+
mixOf(card, 0.28, fg),
|
|
4108
|
+
// 5
|
|
4109
|
+
mixOf(card, 0.42, fg),
|
|
4110
|
+
// 6
|
|
4111
|
+
mixOf(accent, 0.14, "#000"),
|
|
4112
|
+
// 7
|
|
4113
|
+
accent,
|
|
4114
|
+
// 8 品牌级
|
|
4115
|
+
mixOf(accent, 0.18, "#fff"),
|
|
4116
|
+
// 9
|
|
4117
|
+
mixOf(muted, 0.18, fg),
|
|
4118
|
+
// 10 次级文字
|
|
4119
|
+
fg
|
|
4120
|
+
// 11 主文字
|
|
4121
|
+
] : [
|
|
4122
|
+
card,
|
|
4123
|
+
// 0 最浅(顶栏/卡片)
|
|
4124
|
+
bg,
|
|
4125
|
+
// 1 背景
|
|
4126
|
+
mixOf(bg, 0.05, fg),
|
|
4127
|
+
// 2 侧栏
|
|
4128
|
+
mixOf(bg, 0.11, fg),
|
|
4129
|
+
// 3 winAlt
|
|
4130
|
+
mixOf(bg, 0.17, fg),
|
|
4131
|
+
// 4 悬停
|
|
4132
|
+
mixOf(bg, 0.26, fg),
|
|
4133
|
+
// 5
|
|
4134
|
+
mixOf(bg, 0.36, fg),
|
|
4135
|
+
// 6
|
|
4136
|
+
mixOf(accent, 0.14, "#000"),
|
|
4137
|
+
accent,
|
|
4138
|
+
mixOf(accent, 0.18, "#fff"),
|
|
4139
|
+
mixOf(muted, 0.18, fg),
|
|
4140
|
+
fg
|
|
4141
|
+
];
|
|
4142
|
+
}
|
|
4143
|
+
var skinStyleEl = null;
|
|
4144
|
+
var bgStyleEl = null;
|
|
4145
|
+
var injectedKeys = /* @__PURE__ */ new Set();
|
|
4146
|
+
var classObserver = null;
|
|
4147
|
+
var currentTheme = { skin: "default", custom: null, bg: { mode: "none", maskOpacity: 0.82, blurPx: 0, panelOpacity: 0.3 } };
|
|
4148
|
+
var lastModeSig = "";
|
|
4149
|
+
var bgTimer = null;
|
|
4150
|
+
var regionStyleEl = null;
|
|
4151
|
+
var regionTimers = [];
|
|
4152
|
+
var regionFolderIdx = { left: -1, center: -1, right: -1 };
|
|
4153
|
+
var REGION_SELECTORS = {
|
|
4154
|
+
left: 'div[class*="workspace-sidebar-panel-width"]',
|
|
4155
|
+
center: '[data-testid="conversation-column"]',
|
|
4156
|
+
right: '[data-testid="conversation-column"] ~ [data-testid="browser"]'
|
|
4157
|
+
};
|
|
4158
|
+
var folderIdx = -1;
|
|
4159
|
+
var urlTick = 0;
|
|
4160
|
+
var applySeq = 0;
|
|
4161
|
+
var SURFACE_TOKENS = [
|
|
4162
|
+
"--color-background",
|
|
4163
|
+
"--color-background-win-alt",
|
|
4164
|
+
"--color-sidebar",
|
|
4165
|
+
"--color-header",
|
|
4166
|
+
"--color-panel",
|
|
4167
|
+
"--color-card",
|
|
4168
|
+
"--color-card-selected",
|
|
4169
|
+
"--color-input",
|
|
4170
|
+
"--color-input-focused",
|
|
4171
|
+
"--color-highspeed-composer-surface"
|
|
4172
|
+
];
|
|
4173
|
+
var isDarkMode = () => document.documentElement.classList.contains("theme-zai-dark") || document.documentElement.classList.contains("dark");
|
|
4174
|
+
var probeEl = null;
|
|
4175
|
+
function resolvedColor(token) {
|
|
4176
|
+
try {
|
|
4177
|
+
if (!probeEl || !probeEl.isConnected) {
|
|
4178
|
+
probeEl = document.createElement("div");
|
|
4179
|
+
probeEl.style.display = "none";
|
|
4180
|
+
(document.body || document.documentElement).append(probeEl);
|
|
4181
|
+
}
|
|
4182
|
+
probeEl.style.color = "";
|
|
4183
|
+
probeEl.style.color = `var(${token})`;
|
|
4184
|
+
const v = getComputedStyle(probeEl).color;
|
|
4185
|
+
return /^rgba?\(/.test(v) ? v : "";
|
|
4186
|
+
} catch {
|
|
4187
|
+
return "";
|
|
4188
|
+
}
|
|
4189
|
+
}
|
|
4190
|
+
function ensureEl(id) {
|
|
4191
|
+
let el = document.getElementById(id);
|
|
4192
|
+
if (!el || !el.isConnected) {
|
|
4193
|
+
el = document.createElement("style");
|
|
4194
|
+
el.id = id;
|
|
4195
|
+
(document.head || document.documentElement).append(el);
|
|
4196
|
+
}
|
|
4197
|
+
return el;
|
|
4198
|
+
}
|
|
4199
|
+
function applySkin(skinId, custom) {
|
|
4200
|
+
skinStyleEl = ensureEl("__zcodepro_skin__");
|
|
4201
|
+
const root = document.documentElement;
|
|
4202
|
+
for (const id of [...THEME_SKIN_IDS, "custom"]) root.classList.remove("zcodepro-skin-" + id);
|
|
4203
|
+
const preset = THEME_SKINS.find((s) => s.id === skinId && s.hue);
|
|
4204
|
+
const isCustom = skinId === "custom";
|
|
4205
|
+
if (!preset && !isCustom) {
|
|
4206
|
+
skinStyleEl.textContent = "";
|
|
4207
|
+
return;
|
|
4208
|
+
}
|
|
4209
|
+
const cls = preset ? preset.id : "custom";
|
|
4210
|
+
root.classList.add("zcodepro-skin-" + cls);
|
|
4211
|
+
const scaleOf = (isDark) => {
|
|
4212
|
+
if (isCustom) {
|
|
4213
|
+
const dflt = CUSTOM_DEFAULTS[isDark ? "dark" : "light"];
|
|
4214
|
+
const src = custom && custom[isDark ? "dark" : "light"] || {};
|
|
4215
|
+
const a = {};
|
|
4216
|
+
for (const k of ["bg", "card", "fg", "muted", "accent"]) {
|
|
4217
|
+
a[k] = /^#[0-9a-f]{6}$/i.test(src[k]) ? src[k] : dflt[k];
|
|
4218
|
+
}
|
|
4219
|
+
return anchorsScale(a, isDark);
|
|
4220
|
+
}
|
|
4221
|
+
const sc = SCALES[preset.hue];
|
|
4222
|
+
return isDark ? sc.dark : sc.light;
|
|
4223
|
+
};
|
|
4224
|
+
const rules = (isDark) => {
|
|
4225
|
+
const vars = skinVars(scaleOf(isDark), isDark);
|
|
4226
|
+
return vars ? Object.entries(vars).map(([k, v]) => `${k}:${v};`).join("") : "";
|
|
4227
|
+
};
|
|
4228
|
+
const sb = (isDark) => {
|
|
4229
|
+
const fg = scaleOf(isDark)[11];
|
|
4230
|
+
return `::-webkit-scrollbar-thumb{background-color:${hexA(fg, "59")} !important;}::-webkit-scrollbar-thumb:hover{background-color:${hexA(fg, "8c")} !important;}`;
|
|
4231
|
+
};
|
|
4232
|
+
skinStyleEl.textContent = `html.theme-zai-light.zcodepro-skin-${cls}{${rules(false)}}html.theme-zai-dark.zcodepro-skin-${cls},html.dark.zcodepro-skin-${cls}{${rules(true)}}html.theme-zai-light.zcodepro-skin-${cls}{${sb(false)}}html.theme-zai-dark.zcodepro-skin-${cls},html.dark.zcodepro-skin-${cls}{${sb(true)}}`;
|
|
4233
|
+
}
|
|
4234
|
+
function clearBgOverrides() {
|
|
4235
|
+
const root = document.documentElement;
|
|
4236
|
+
for (const k of injectedKeys) root.style.removeProperty(k);
|
|
4237
|
+
injectedKeys = /* @__PURE__ */ new Set();
|
|
4238
|
+
}
|
|
4239
|
+
async function applyBackground(bg) {
|
|
4240
|
+
const seq = ++applySeq;
|
|
4241
|
+
bgStyleEl = ensureEl("__zcodepro_bg__");
|
|
4242
|
+
const root = document.documentElement;
|
|
4243
|
+
if (bgTimer) {
|
|
4244
|
+
clearInterval(bgTimer);
|
|
4245
|
+
bgTimer = null;
|
|
4246
|
+
}
|
|
4247
|
+
root.classList.remove("zcodepro-bg-on");
|
|
4248
|
+
clearBgOverrides();
|
|
4249
|
+
const bgActive = !!(bg && bg.mode && bg.mode !== "none");
|
|
4250
|
+
const anyRegion = !!(bg && bg.regions && (bg.regions.left || bg.regions.center || bg.regions.right));
|
|
4251
|
+
if (!bgActive) bgStyleEl.textContent = "";
|
|
4252
|
+
if (!bgActive && !anyRegion) {
|
|
4253
|
+
await applyRegionBackgrounds(bg);
|
|
4254
|
+
return;
|
|
4255
|
+
}
|
|
4256
|
+
const num01 = (v, dflt) => typeof v === "number" && Number.isFinite(v) ? Math.min(1, Math.max(0, v)) : dflt;
|
|
4257
|
+
const maskOpacity = num01(bg.maskOpacity, 0.82);
|
|
4258
|
+
const alpha = Math.min(0.99, maskOpacity);
|
|
4259
|
+
const blurPx = typeof bg.blurPx === "number" && Number.isFinite(bg.blurPx) ? Math.min(24, Math.max(0, Math.round(bg.blurPx))) : 0;
|
|
4260
|
+
const panelOpacity = num01(bg.panelOpacity, 0.3);
|
|
4261
|
+
const resolvedBg = resolvedColor("--color-background");
|
|
4262
|
+
const mHex = resolvedBg.match(/^rgba?\(([\d.]+),\s*([\d.]+),\s*([\d.]+)/);
|
|
4263
|
+
const rgb = mHex ? [Math.round(+mHex[1]), Math.round(+mHex[2]), Math.round(+mHex[3])].join(",") : isDarkMode() ? "13,13,13" : "248,248,248";
|
|
4264
|
+
const panelMix = Math.round(panelOpacity * 100);
|
|
4265
|
+
if (panelMix < 100) {
|
|
4266
|
+
for (const t2 of SURFACE_TOKENS) {
|
|
4267
|
+
const v = resolvedColor(t2);
|
|
4268
|
+
if (v) {
|
|
4269
|
+
root.style.setProperty(t2, `color-mix(in srgb, ${v} ${panelMix}%, transparent)`);
|
|
4270
|
+
injectedKeys.add(t2);
|
|
4271
|
+
}
|
|
4272
|
+
}
|
|
4273
|
+
}
|
|
4274
|
+
await applyRegionBackgrounds(bg, { rgb, alpha, fit: bg.fit, seq });
|
|
4275
|
+
if (seq !== applySeq) return;
|
|
4276
|
+
if (!bgActive) return;
|
|
4277
|
+
const FIT_CSS = {
|
|
4278
|
+
cover: "background-size:100% 100%,cover !important;background-repeat:no-repeat !important;",
|
|
4279
|
+
contain: "background-size:100% 100%,contain !important;background-repeat:no-repeat !important;",
|
|
4280
|
+
fill: "background-size:100% 100%,100% 100% !important;background-repeat:no-repeat !important;",
|
|
4281
|
+
tile: "background-size:100% 100%,auto !important;background-repeat:no-repeat,repeat !important;"
|
|
4282
|
+
};
|
|
4283
|
+
const fitCss = FIT_CSS[bg.fit] || FIT_CSS.cover;
|
|
4284
|
+
const blurCss = blurPx > 0 ? `filter:blur(${blurPx}px);` : "";
|
|
4285
|
+
const spread = blurPx > 0 ? Math.max(20, blurPx * 2) : 0;
|
|
4286
|
+
const setImage = (image) => {
|
|
4287
|
+
bgStyleEl.textContent = `html.zcodepro-bg-on{background-color:rgb(${rgb}) !important;}html.zcodepro-bg-on::before{content:'' !important;position:fixed;inset:-${spread}px;z-index:-1;pointer-events:none;background-image:linear-gradient(rgba(${rgb},${alpha}),rgba(${rgb},${alpha})),${image} !important;${fitCss}background-position:center !important;${blurCss}}`;
|
|
4288
|
+
root.classList.add("zcodepro-bg-on");
|
|
4289
|
+
};
|
|
4290
|
+
const helperUrl = liveBoot().helperUrl || HELPER_URL;
|
|
4291
|
+
if (bg.mode === "library") {
|
|
4292
|
+
if (!bg.file) {
|
|
4293
|
+
bgStyleEl.textContent = "";
|
|
4294
|
+
return;
|
|
4295
|
+
}
|
|
4296
|
+
setImage(`url("${helperUrl}/bg/file/${encodeURIComponent(bg.file)}")`);
|
|
4297
|
+
return;
|
|
4298
|
+
}
|
|
4299
|
+
if (bg.mode === "folder") {
|
|
4300
|
+
const res = await rpc("/bg/folder/list");
|
|
4301
|
+
if (seq !== applySeq) return;
|
|
4302
|
+
const files = res.ok && Array.isArray(res.files) ? res.files.filter((f) => f && f.name) : [];
|
|
4303
|
+
if (!files.length) {
|
|
4304
|
+
bgStyleEl.textContent = "";
|
|
4305
|
+
root.classList.remove("zcodepro-bg-on");
|
|
4306
|
+
return;
|
|
4307
|
+
}
|
|
4308
|
+
const pick = () => {
|
|
4309
|
+
let idx = 0;
|
|
4310
|
+
if (bg.folderRandom) idx = files.length > 1 ? Math.floor(Math.random() * files.length) : 0;
|
|
4311
|
+
else {
|
|
4312
|
+
folderIdx = (folderIdx + 1) % files.length;
|
|
4313
|
+
idx = folderIdx;
|
|
4314
|
+
}
|
|
4315
|
+
setImage(`url("${helperUrl}/bg/folder/file/${encodeURIComponent(files[idx].name)}")`);
|
|
4316
|
+
};
|
|
4317
|
+
pick();
|
|
4318
|
+
const ms = Math.max(0, Number(bg.intervalMin) || 0) * 6e4;
|
|
4319
|
+
if (ms >= 3e4) bgTimer = setInterval(pick, ms);
|
|
4320
|
+
return;
|
|
4321
|
+
}
|
|
4322
|
+
if (bg.mode === "url") {
|
|
4323
|
+
const u0 = /^https?:\/\/\S+$/i.test(bg.url || "") && !/[<>"'\\]/.test(bg.url) ? bg.url : "";
|
|
4324
|
+
if (!u0) {
|
|
4325
|
+
bgStyleEl.textContent = "";
|
|
4326
|
+
return;
|
|
4327
|
+
}
|
|
4328
|
+
const bust = () => {
|
|
4329
|
+
urlTick += 1;
|
|
4330
|
+
const sep = u0.includes("?") ? "&" : "?";
|
|
4331
|
+
setImage(`url("${u0}${sep}_zcp=${urlTick}")`);
|
|
4332
|
+
};
|
|
4333
|
+
bust();
|
|
4334
|
+
const ms = Math.max(0, Number(bg.intervalMin) || 0) * 6e4;
|
|
4335
|
+
if (ms >= 3e4) bgTimer = setInterval(bust, ms);
|
|
4336
|
+
}
|
|
4337
|
+
}
|
|
4338
|
+
async function applyRegionBackgrounds(bg, pre) {
|
|
4339
|
+
regionStyleEl = ensureEl("__zcodepro_bg_regions__");
|
|
4340
|
+
for (const t2 of regionTimers) clearInterval(t2);
|
|
4341
|
+
regionTimers = [];
|
|
4342
|
+
const rules = /* @__PURE__ */ new Map();
|
|
4343
|
+
const flush = () => {
|
|
4344
|
+
regionStyleEl.textContent = [...rules.values()].join("");
|
|
4345
|
+
};
|
|
4346
|
+
const alpha = pre ? pre.alpha : 0.82;
|
|
4347
|
+
const rgb = pre ? pre.rgb : "13,13,13";
|
|
4348
|
+
const FIT_CSS = {
|
|
4349
|
+
cover: "100% 100%,cover",
|
|
4350
|
+
contain: "100% 100%,contain",
|
|
4351
|
+
fill: "100% 100%,100% 100%",
|
|
4352
|
+
tile: "100% 100%,auto"
|
|
4353
|
+
};
|
|
4354
|
+
const sizeVal = FIT_CSS[bg && bg.fit] || FIT_CSS.cover;
|
|
4355
|
+
const repeatVal = bg && bg.fit === "tile" ? "no-repeat,repeat" : "no-repeat";
|
|
4356
|
+
const helperUrl = liveBoot().helperUrl || HELPER_URL;
|
|
4357
|
+
const safeUrl = (u) => /^https?:\/\/\S+$/i.test(u || "") && !/[<>"'\\]/.test(u) ? u : "";
|
|
4358
|
+
const addRule = (region, image) => {
|
|
4359
|
+
if (!image) return;
|
|
4360
|
+
rules.set(region, `${REGION_SELECTORS[region]}{background-image:linear-gradient(rgba(${rgb},${alpha}),rgba(${rgb},${alpha})),${image} !important;background-size:${sizeVal} !important;background-position:center !important;background-repeat:${repeatVal} !important;}`);
|
|
4361
|
+
};
|
|
4362
|
+
const seq = applySeq;
|
|
4363
|
+
for (const region of ["left", "center", "right"]) {
|
|
4364
|
+
const r = bg && bg.regions && bg.regions[region];
|
|
4365
|
+
if (!r) continue;
|
|
4366
|
+
if (r.mode === "library") {
|
|
4367
|
+
if (r.file) addRule(region, `url("${helperUrl}/bg/file/${encodeURIComponent(r.file)}")`);
|
|
4368
|
+
} else if (r.mode === "url") {
|
|
4369
|
+
const u = safeUrl(r.url);
|
|
4370
|
+
if (u) addRule(region, `url("${u}")`);
|
|
4371
|
+
} else if (r.mode === "folder" && r.folder) {
|
|
4372
|
+
const res = await rpc("/bg/folder/list?dir=" + encodeURIComponent(r.folder));
|
|
4373
|
+
if (seq !== applySeq) return;
|
|
4374
|
+
const files = res.ok && !res.missing && Array.isArray(res.files) ? res.files.filter((f) => f && f.name) : [];
|
|
4375
|
+
if (!files.length) continue;
|
|
4376
|
+
const pick = () => {
|
|
4377
|
+
let idx = 0;
|
|
4378
|
+
if (bg.folderRandom !== false) idx = files.length > 1 ? Math.floor(Math.random() * files.length) : 0;
|
|
4379
|
+
else {
|
|
4380
|
+
regionFolderIdx[region] = (regionFolderIdx[region] + 1) % files.length;
|
|
4381
|
+
idx = regionFolderIdx[region];
|
|
4382
|
+
}
|
|
4383
|
+
addRule(region, `url("${helperUrl}/bg/folder/file/${encodeURIComponent(files[idx].name)}")`);
|
|
4384
|
+
flush();
|
|
4385
|
+
};
|
|
4386
|
+
pick();
|
|
4387
|
+
const ms = Math.max(0, Number(bg.intervalMin) || 0) * 6e4;
|
|
4388
|
+
if (ms >= 3e4) regionTimers.push(setInterval(pick, ms));
|
|
4389
|
+
}
|
|
4390
|
+
}
|
|
4391
|
+
flush();
|
|
4392
|
+
}
|
|
4393
|
+
function applyAll(theme) {
|
|
4394
|
+
if (theme && typeof theme === "object") currentTheme = theme;
|
|
4395
|
+
applySkin(currentTheme.skin || "default", currentTheme.custom);
|
|
4396
|
+
void applyBackground(currentTheme.bg);
|
|
4397
|
+
}
|
|
4398
|
+
function startTheme() {
|
|
4399
|
+
if (!document.head && !document.documentElement) return;
|
|
4400
|
+
applyAll({ skin: "default", custom: null, bg: { mode: "none", maskOpacity: 0.82, blurPx: 0, panelOpacity: 0.3 } });
|
|
4401
|
+
void getConfig().then((cfg) => applyAll(cfg.theme)).catch(() => {
|
|
4402
|
+
});
|
|
4403
|
+
window.addEventListener("zcodepro:config-changed", () => {
|
|
4404
|
+
void getConfig(true).then((cfg) => applyAll(cfg.theme)).catch(() => {
|
|
4405
|
+
});
|
|
4406
|
+
});
|
|
4407
|
+
if (!classObserver) {
|
|
4408
|
+
lastModeSig = isDarkMode() ? "d" : "l";
|
|
4409
|
+
classObserver = new MutationObserver(() => {
|
|
4410
|
+
const sig = isDarkMode() ? "d" : "l";
|
|
4411
|
+
if (sig === lastModeSig) return;
|
|
4412
|
+
lastModeSig = sig;
|
|
4413
|
+
applyAll(currentTheme);
|
|
4414
|
+
});
|
|
4415
|
+
classObserver.observe(document.documentElement, { attributes: true, attributeFilter: ["class"] });
|
|
4416
|
+
}
|
|
4417
|
+
}
|
|
4418
|
+
|
|
3809
4419
|
// src/inject/features/settings-dialog.js
|
|
3810
4420
|
function openExternal(url) {
|
|
3811
4421
|
try {
|
|
@@ -4009,15 +4619,17 @@
|
|
|
4009
4619
|
}, "\u2715");
|
|
4010
4620
|
titleEl.replaceChildren(titleLeft, closeX);
|
|
4011
4621
|
}
|
|
4012
|
-
const health = await
|
|
4013
|
-
|
|
4014
|
-
|
|
4015
|
-
|
|
4016
|
-
|
|
4017
|
-
|
|
4622
|
+
const [health, config, agentsRes, visionRes, titleGenRes, titleGenProvidersRes, rtkRes, headroomRes] = await Promise.all([
|
|
4623
|
+
rpc("/health"),
|
|
4624
|
+
getConfig(true),
|
|
4625
|
+
rpc("/agents"),
|
|
4626
|
+
rpc("/vision"),
|
|
4627
|
+
rpc("/title-gen"),
|
|
4628
|
+
rpc("/title-gen/providers"),
|
|
4629
|
+
rpc("/rtk"),
|
|
4630
|
+
rpc("/headroom")
|
|
4631
|
+
]);
|
|
4018
4632
|
const titleGenProviders = titleGenProvidersRes.ok && Array.isArray(titleGenProvidersRes.providers) ? titleGenProvidersRes.providers : [];
|
|
4019
|
-
const rtkRes = await rpc("/rtk");
|
|
4020
|
-
const headroomRes = await rpc("/headroom");
|
|
4021
4633
|
const setFeature = async (key, value) => {
|
|
4022
4634
|
const res = await rpc("/config", { method: "POST", body: { features: { [key]: value } } });
|
|
4023
4635
|
clearConfigCache();
|
|
@@ -4581,6 +5193,8 @@
|
|
|
4581
5193
|
renderToolbarSwitch();
|
|
4582
5194
|
const paneStylesSub1 = h("div", { class: "mt-4" });
|
|
4583
5195
|
const paneStylesSub2 = h("div", { class: "mt-4", style: "display:none" });
|
|
5196
|
+
const paneStylesSub3 = h("div", { class: "mt-4", style: "display:none" });
|
|
5197
|
+
const paneStylesSub4 = h("div", { class: "mt-4", style: "display:none" });
|
|
4584
5198
|
const ITEM_NAMES = {
|
|
4585
5199
|
ctx: "sbItemCtx",
|
|
4586
5200
|
questions: "sbItemQuestions",
|
|
@@ -4736,11 +5350,521 @@
|
|
|
4736
5350
|
h("div", { class: "mt-3 mb-1 text-ui-sm font-medium" }, L.sbGroupTurn),
|
|
4737
5351
|
turnList
|
|
4738
5352
|
);
|
|
5353
|
+
let themeCfg = structuredClone(config.theme || {});
|
|
5354
|
+
const numOrBg = (v, d) => typeof v === "number" && Number.isFinite(v) ? v : d;
|
|
5355
|
+
themeCfg.skin = themeCfg.skin || "default";
|
|
5356
|
+
themeCfg.custom = {
|
|
5357
|
+
light: themeCfg.custom && themeCfg.custom.light || {},
|
|
5358
|
+
dark: themeCfg.custom && themeCfg.custom.dark || {}
|
|
5359
|
+
};
|
|
5360
|
+
themeCfg.bg = {
|
|
5361
|
+
...themeCfg.bg || {},
|
|
5362
|
+
mode: themeCfg.bg?.mode || "none",
|
|
5363
|
+
maskOpacity: numOrBg(themeCfg.bg?.maskOpacity, 0.82),
|
|
5364
|
+
blurPx: numOrBg(themeCfg.bg?.blurPx, 0),
|
|
5365
|
+
panelOpacity: numOrBg(themeCfg.bg?.panelOpacity, 0.3)
|
|
5366
|
+
};
|
|
5367
|
+
themeCfg.bg.regions = themeCfg.bg.regions && typeof themeCfg.bg.regions === "object" ? themeCfg.bg.regions : {};
|
|
5368
|
+
let bgFiles = [];
|
|
5369
|
+
let bgLoading = false;
|
|
5370
|
+
let folderInfo = { count: 0, dir: "" };
|
|
5371
|
+
const themeInputCls = "h-8 w-full rounded-lg border border-border bg-input px-2.5 text-ui-sm text-foreground outline-none transition-shadow placeholder:text-foreground-subtle focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/40";
|
|
5372
|
+
const numField = (val, min, max, commit, title) => {
|
|
5373
|
+
const n = h("input", {
|
|
5374
|
+
type: "number",
|
|
5375
|
+
min: String(min),
|
|
5376
|
+
max: String(max),
|
|
5377
|
+
step: "1",
|
|
5378
|
+
title,
|
|
5379
|
+
class: "h-7 w-24 rounded-lg border border-border bg-input px-2 text-right text-ui-xs tabular-nums text-foreground outline-none focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/40"
|
|
5380
|
+
});
|
|
5381
|
+
n.value = String(val);
|
|
5382
|
+
n.addEventListener("change", () => {
|
|
5383
|
+
const v = Math.max(min, Math.min(max, Math.round(Number(n.value) || 0)));
|
|
5384
|
+
n.value = String(v);
|
|
5385
|
+
commit(v);
|
|
5386
|
+
});
|
|
5387
|
+
return n;
|
|
5388
|
+
};
|
|
5389
|
+
const bgUrl = (name) => `${HELPER_URL}/bg/file/${encodeURIComponent(name)}`;
|
|
5390
|
+
const saveTheme = async (patch) => {
|
|
5391
|
+
themeCfg = {
|
|
5392
|
+
skin: patch.skin !== void 0 ? patch.skin : themeCfg.skin,
|
|
5393
|
+
custom: patch.custom !== void 0 ? patch.custom : themeCfg.custom,
|
|
5394
|
+
bg: { ...themeCfg.bg, ...patch.bg || {} }
|
|
5395
|
+
};
|
|
5396
|
+
const res = await rpc("/config", { method: "POST", body: { theme: themeCfg } });
|
|
5397
|
+
clearConfigCache();
|
|
5398
|
+
window.dispatchEvent(new CustomEvent("zcodepro:config-changed"));
|
|
5399
|
+
if (!res.ok) showToast(L.failed + ": " + errText(res), "error");
|
|
5400
|
+
renderThemeColors();
|
|
5401
|
+
renderThemeBg();
|
|
5402
|
+
};
|
|
5403
|
+
const refreshBgFiles = async () => {
|
|
5404
|
+
bgLoading = true;
|
|
5405
|
+
renderThemeBg();
|
|
5406
|
+
const res = await rpc("/bg");
|
|
5407
|
+
bgLoading = false;
|
|
5408
|
+
if (res.ok && Array.isArray(res.files)) bgFiles = res.files;
|
|
5409
|
+
if (themeCfg.bg.mode === "library" && themeCfg.bg.file && !bgFiles.some((f) => f.name === themeCfg.bg.file)) {
|
|
5410
|
+
themeCfg = { ...themeCfg, bg: { ...themeCfg.bg, file: "" } };
|
|
5411
|
+
await saveTheme({ bg: { file: "" } });
|
|
5412
|
+
showToast(L.themeBgDeletedActive, "success");
|
|
5413
|
+
return;
|
|
5414
|
+
}
|
|
5415
|
+
renderThemeBg();
|
|
5416
|
+
};
|
|
5417
|
+
const refreshFolderInfo = async () => {
|
|
5418
|
+
if (!themeCfg.bg.folder) {
|
|
5419
|
+
folderInfo = { count: 0, dir: "" };
|
|
5420
|
+
renderThemeBg();
|
|
5421
|
+
return;
|
|
5422
|
+
}
|
|
5423
|
+
const res = await rpc("/bg/folder/list");
|
|
5424
|
+
folderInfo = res.ok && !res.missing && Array.isArray(res.files) ? { count: res.files.length, dir: res.dir || themeCfg.bg.folder } : { count: 0, dir: themeCfg.bg.folder };
|
|
5425
|
+
renderThemeBg();
|
|
5426
|
+
};
|
|
5427
|
+
const bgInput = h("input", { type: "file", accept: ".png,.jpg,.jpeg,.webp,.gif,.bmp,.avif", multiple: "", style: "display:none" });
|
|
5428
|
+
bgInput.addEventListener("change", () => {
|
|
5429
|
+
const files = [...bgInput.files || []];
|
|
5430
|
+
bgInput.value = "";
|
|
5431
|
+
if (!files.length) return;
|
|
5432
|
+
void (async () => {
|
|
5433
|
+
let first = themeCfg.bg.file;
|
|
5434
|
+
for (const f of files) {
|
|
5435
|
+
const dataUrl = await new Promise((resolve) => {
|
|
5436
|
+
const r = new FileReader();
|
|
5437
|
+
r.onload = () => resolve(String(r.result || ""));
|
|
5438
|
+
r.onerror = () => resolve("");
|
|
5439
|
+
r.readAsDataURL(f);
|
|
5440
|
+
});
|
|
5441
|
+
if (!dataUrl) continue;
|
|
5442
|
+
const res = await rpc("/bg", { method: "POST", body: { name: f.name, data: dataUrl } });
|
|
5443
|
+
if (!res.ok) {
|
|
5444
|
+
showToast(L.failed + ": " + errText(res), "error");
|
|
5445
|
+
continue;
|
|
5446
|
+
}
|
|
5447
|
+
if (Array.isArray(res.files)) bgFiles = res.files;
|
|
5448
|
+
if (!first) first = f.name;
|
|
5449
|
+
}
|
|
5450
|
+
if (first && first !== themeCfg.bg.file) await saveTheme({ bg: { file: first } });
|
|
5451
|
+
else renderThemeBg();
|
|
5452
|
+
})();
|
|
5453
|
+
});
|
|
5454
|
+
let customSaveTimer = null;
|
|
5455
|
+
const CUSTOM_FIELDS = [
|
|
5456
|
+
["bg", "themeCustomBg"],
|
|
5457
|
+
["card", "themeCustomCard"],
|
|
5458
|
+
["fg", "themeCustomFg"],
|
|
5459
|
+
["muted", "themeCustomMuted"],
|
|
5460
|
+
["accent", "themeCustomAccent"]
|
|
5461
|
+
];
|
|
5462
|
+
const customVal = (mode, k) => themeCfg.custom[mode] && /^#[0-9a-f]{6}$/i.test(themeCfg.custom[mode][k] || "") ? themeCfg.custom[mode][k] : CUSTOM_DEFAULTS[mode][k];
|
|
5463
|
+
const customInput = (mode, k, label) => {
|
|
5464
|
+
const inp = h("input", {
|
|
5465
|
+
type: "color",
|
|
5466
|
+
value: customVal(mode, k),
|
|
5467
|
+
title: label,
|
|
5468
|
+
style: "width:30px;height:22px;padding:0;border:1px solid var(--color-card-border);border-radius:5px;background:transparent;cursor:pointer"
|
|
5469
|
+
});
|
|
5470
|
+
inp.addEventListener("input", () => {
|
|
5471
|
+
const next = {
|
|
5472
|
+
light: { ...themeCfg.custom.light },
|
|
5473
|
+
dark: { ...themeCfg.custom.dark }
|
|
5474
|
+
};
|
|
5475
|
+
next[mode][k] = inp.value.toLowerCase();
|
|
5476
|
+
clearTimeout(customSaveTimer);
|
|
5477
|
+
customSaveTimer = setTimeout(() => {
|
|
5478
|
+
void saveTheme({ skin: "custom", custom: next });
|
|
5479
|
+
}, 250);
|
|
5480
|
+
});
|
|
5481
|
+
return h("label", { class: "flex items-center gap-1.5 text-ui-xs text-foreground-subtle" }, inp, label);
|
|
5482
|
+
};
|
|
5483
|
+
const customSwatch = (mode) => [
|
|
5484
|
+
customVal(mode, "bg"),
|
|
5485
|
+
customVal(mode, "card"),
|
|
5486
|
+
customVal(mode, "fg"),
|
|
5487
|
+
customVal(mode, "muted"),
|
|
5488
|
+
customVal(mode, "accent")
|
|
5489
|
+
];
|
|
5490
|
+
const renderThemeColors = () => {
|
|
5491
|
+
paneStylesSub3.replaceChildren(
|
|
5492
|
+
h("div", { class: "mb-1 text-ui-sm font-medium" }, L.themeSkinTitle),
|
|
5493
|
+
h("p", { class: "mb-2 text-ui-xs/relaxed text-foreground-subtle" }, L.themeSkinDesc),
|
|
5494
|
+
// 4 列 × 3 行可视,超出滚动;色条 8 块(底/卡片/加深面/边框/强调×2/次级文字/正文)
|
|
5495
|
+
h(
|
|
5496
|
+
"div",
|
|
5497
|
+
{ class: "grid grid-cols-4 gap-2", style: "max-height:13.5rem;overflow-y:auto;" },
|
|
5498
|
+
...THEME_SKINS.map((skin) => h(
|
|
5499
|
+
"button",
|
|
5500
|
+
{
|
|
5501
|
+
type: "button",
|
|
5502
|
+
class: "zcodepro-skin-card",
|
|
5503
|
+
"data-state": themeCfg.skin === skin.id ? "active" : "inactive",
|
|
5504
|
+
onClick: () => void saveTheme({ skin: skin.id })
|
|
5505
|
+
},
|
|
5506
|
+
h(
|
|
5507
|
+
"div",
|
|
5508
|
+
{ class: "zcodepro-skin-swatches" },
|
|
5509
|
+
...skin.preview.map((c) => h("span", { style: `background:${c}` }))
|
|
5510
|
+
),
|
|
5511
|
+
h("span", { class: "text-ui-xs text-foreground" }, isZhLocale() ? skin.zh : skin.en)
|
|
5512
|
+
)),
|
|
5513
|
+
h(
|
|
5514
|
+
"button",
|
|
5515
|
+
{
|
|
5516
|
+
type: "button",
|
|
5517
|
+
class: "zcodepro-skin-card",
|
|
5518
|
+
"data-state": themeCfg.skin === "custom" ? "active" : "inactive",
|
|
5519
|
+
onClick: () => void saveTheme({ skin: "custom" })
|
|
5520
|
+
},
|
|
5521
|
+
h(
|
|
5522
|
+
"div",
|
|
5523
|
+
{ class: "zcodepro-skin-swatches" },
|
|
5524
|
+
...customSwatch("light").map((c) => h("span", { style: `background:${c}` })),
|
|
5525
|
+
...customSwatch("dark").map((c) => h("span", { style: `background:${c}` }))
|
|
5526
|
+
),
|
|
5527
|
+
h("span", { class: "text-ui-xs text-foreground" }, L.themeSkinCustom)
|
|
5528
|
+
)
|
|
5529
|
+
),
|
|
5530
|
+
h("div", { class: "mt-3 mb-1 text-ui-sm font-medium" }, L.themeCustomTitle),
|
|
5531
|
+
h("p", { class: "mb-2 text-ui-xs/relaxed text-foreground-subtle" }, L.themeCustomHint),
|
|
5532
|
+
h(
|
|
5533
|
+
"div",
|
|
5534
|
+
{ class: "grid grid-cols-2 gap-3" },
|
|
5535
|
+
...["light", "dark"].map((mode) => h(
|
|
5536
|
+
"div",
|
|
5537
|
+
{ class: "rounded-xl border border-border p-2" },
|
|
5538
|
+
h(
|
|
5539
|
+
"div",
|
|
5540
|
+
{ class: "mb-1.5 text-ui-xs font-medium text-foreground-subtle" },
|
|
5541
|
+
mode === "light" ? L.themeCustomLight : L.themeCustomDark
|
|
5542
|
+
),
|
|
5543
|
+
h(
|
|
5544
|
+
"div",
|
|
5545
|
+
{ class: "flex flex-col gap-1.5" },
|
|
5546
|
+
...CUSTOM_FIELDS.map(([k, key]) => customInput(mode, k, L[key]))
|
|
5547
|
+
)
|
|
5548
|
+
))
|
|
5549
|
+
)
|
|
5550
|
+
);
|
|
5551
|
+
};
|
|
5552
|
+
const setRegion = (region, value) => {
|
|
5553
|
+
void saveTheme({ bg: { regions: { ...themeCfg.bg.regions, [region]: value } } });
|
|
5554
|
+
};
|
|
5555
|
+
const regionRow = (region, label) => {
|
|
5556
|
+
const cur = themeCfg.bg.regions[region] || null;
|
|
5557
|
+
const mode = cur ? cur.mode : null;
|
|
5558
|
+
const rBtn = (id, text) => h("button", {
|
|
5559
|
+
type: "button",
|
|
5560
|
+
class: "zcodepro-tab",
|
|
5561
|
+
"data-state": mode === id ? "active" : "inactive",
|
|
5562
|
+
onClick: () => {
|
|
5563
|
+
if (id === null) {
|
|
5564
|
+
setRegion(region, null);
|
|
5565
|
+
return;
|
|
5566
|
+
}
|
|
5567
|
+
const keep = themeCfg.bg.regions[region];
|
|
5568
|
+
setRegion(region, { mode: id, file: keep && keep.file || "", folder: keep && keep.folder || "", url: keep && keep.url || "" });
|
|
5569
|
+
}
|
|
5570
|
+
}, text);
|
|
5571
|
+
let valueCtrl = null;
|
|
5572
|
+
if (mode === "library") {
|
|
5573
|
+
const sel = h("select", { class: "h-7 max-w-40 rounded-lg border border-border bg-input px-1.5 text-ui-xs text-foreground outline-none" });
|
|
5574
|
+
sel.append(h("option", { value: "" }, "\u2014"));
|
|
5575
|
+
for (const f of bgFiles) sel.append(h("option", { value: f.name }, f.name));
|
|
5576
|
+
sel.value = cur && cur.file || "";
|
|
5577
|
+
sel.addEventListener("change", () => setRegion(region, { ...cur, file: sel.value }));
|
|
5578
|
+
valueCtrl = sel;
|
|
5579
|
+
} else if (mode === "folder") {
|
|
5580
|
+
const inp = h("input", { type: "text", value: cur && cur.folder || "", class: themeInputCls.replace("h-8", "h-7"), placeholder: "/path/to/wallpapers" });
|
|
5581
|
+
inp.addEventListener("change", () => {
|
|
5582
|
+
if (inp.value.trim()) setRegion(region, { ...cur, folder: inp.value.trim() });
|
|
5583
|
+
});
|
|
5584
|
+
valueCtrl = inp;
|
|
5585
|
+
} else if (mode === "url") {
|
|
5586
|
+
const inp = h("input", { type: "url", value: cur && cur.url || "", class: themeInputCls.replace("h-8", "h-7"), placeholder: "https://..." });
|
|
5587
|
+
inp.addEventListener("change", () => {
|
|
5588
|
+
if (/^https?:\/\/\S+$/.test(inp.value.trim())) setRegion(region, { ...cur, url: inp.value.trim() });
|
|
5589
|
+
});
|
|
5590
|
+
valueCtrl = inp;
|
|
5591
|
+
}
|
|
5592
|
+
return h(
|
|
5593
|
+
"div",
|
|
5594
|
+
{ class: "flex flex-wrap items-center gap-2" },
|
|
5595
|
+
h("span", { class: "w-16 shrink-0 text-ui-xs text-foreground" }, label),
|
|
5596
|
+
h(
|
|
5597
|
+
"div",
|
|
5598
|
+
{ class: "flex flex-wrap gap-1" },
|
|
5599
|
+
rBtn(null, L.themeBgRegionFollow),
|
|
5600
|
+
rBtn("library", L.themeBgModeLibrary),
|
|
5601
|
+
rBtn("folder", L.themeBgModeFolder),
|
|
5602
|
+
rBtn("url", L.themeBgModeUrl)
|
|
5603
|
+
),
|
|
5604
|
+
valueCtrl || h("span", { class: "text-ui-xs text-foreground-subtle" }, "")
|
|
5605
|
+
);
|
|
5606
|
+
};
|
|
5607
|
+
const renderThemeBg = () => {
|
|
5608
|
+
const sliderRow = (label, title, min, max, step, val, unit, commit, hint) => {
|
|
5609
|
+
const lab = h("span", { class: "shrink-0 whitespace-nowrap text-ui-xs font-medium text-foreground-subtle", title, style: "width:72px" }, label);
|
|
5610
|
+
const valLabel = h("span", { class: "w-12 text-right text-ui-xs tabular-nums text-foreground-subtle" }, val + unit);
|
|
5611
|
+
const range = h("input", {
|
|
5612
|
+
type: "range",
|
|
5613
|
+
min: String(min),
|
|
5614
|
+
max: String(max),
|
|
5615
|
+
step: String(step),
|
|
5616
|
+
value: String(val),
|
|
5617
|
+
class: "zcodepro-range",
|
|
5618
|
+
"aria-label": label,
|
|
5619
|
+
style: "flex:1"
|
|
5620
|
+
});
|
|
5621
|
+
let timer = null;
|
|
5622
|
+
range.addEventListener("input", () => {
|
|
5623
|
+
const v = Number(range.value);
|
|
5624
|
+
valLabel.textContent = v + unit;
|
|
5625
|
+
clearTimeout(timer);
|
|
5626
|
+
timer = setTimeout(() => commit(v), 300);
|
|
5627
|
+
});
|
|
5628
|
+
return h(
|
|
5629
|
+
"div",
|
|
5630
|
+
{ class: "flex flex-col gap-0.5" },
|
|
5631
|
+
h("div", { class: "flex items-center gap-3" }, lab, range, valLabel),
|
|
5632
|
+
hint ? h("span", { class: "text-ui-xs/relaxed text-foreground-subtle" }, hint) : null
|
|
5633
|
+
);
|
|
5634
|
+
};
|
|
5635
|
+
const numOr = (v, d) => typeof v === "number" && Number.isFinite(v) ? v : d;
|
|
5636
|
+
const maskRow = () => sliderRow(
|
|
5637
|
+
L.themeBgMask,
|
|
5638
|
+
L.themeBgMaskHint,
|
|
5639
|
+
0,
|
|
5640
|
+
99,
|
|
5641
|
+
1,
|
|
5642
|
+
Math.round(numOr(themeCfg.bg.maskOpacity, 0.82) * 100),
|
|
5643
|
+
"%",
|
|
5644
|
+
(v) => {
|
|
5645
|
+
void saveTheme({ bg: { maskOpacity: v / 100 } });
|
|
5646
|
+
},
|
|
5647
|
+
L.themeBgMaskHint2
|
|
5648
|
+
);
|
|
5649
|
+
const blurRow = () => sliderRow(
|
|
5650
|
+
L.themeBgBlur,
|
|
5651
|
+
"",
|
|
5652
|
+
0,
|
|
5653
|
+
24,
|
|
5654
|
+
1,
|
|
5655
|
+
numOr(themeCfg.bg.blurPx, 0),
|
|
5656
|
+
"px",
|
|
5657
|
+
(v) => {
|
|
5658
|
+
void saveTheme({ bg: { blurPx: v } });
|
|
5659
|
+
},
|
|
5660
|
+
""
|
|
5661
|
+
);
|
|
5662
|
+
const panelRow = () => sliderRow(
|
|
5663
|
+
L.themeBgPanel,
|
|
5664
|
+
"",
|
|
5665
|
+
0,
|
|
5666
|
+
100,
|
|
5667
|
+
1,
|
|
5668
|
+
Math.round(numOr(themeCfg.bg.panelOpacity, 0.3) * 100),
|
|
5669
|
+
"%",
|
|
5670
|
+
(v) => {
|
|
5671
|
+
void saveTheme({ bg: { panelOpacity: v / 100 } });
|
|
5672
|
+
},
|
|
5673
|
+
L.themeBgPanelHint
|
|
5674
|
+
);
|
|
5675
|
+
const modeBtn = (id, label) => h("button", {
|
|
5676
|
+
type: "button",
|
|
5677
|
+
class: "zcodepro-tab",
|
|
5678
|
+
"data-state": themeCfg.bg.mode === id ? "active" : "inactive",
|
|
5679
|
+
onClick: () => void saveTheme({ bg: { mode: id } })
|
|
5680
|
+
}, label);
|
|
5681
|
+
const folderInput = h("input", { type: "text", value: themeCfg.bg.folder, class: themeInputCls, placeholder: "/path/to/wallpapers" });
|
|
5682
|
+
const applyFolder = async (dir) => {
|
|
5683
|
+
const v = (dir || "").trim();
|
|
5684
|
+
if (!v) return;
|
|
5685
|
+
const res = await rpc("/bg/folder", { method: "POST", body: { dir: v } });
|
|
5686
|
+
if (!res.ok) {
|
|
5687
|
+
showToast(L.failed + ": " + errText(res), "error");
|
|
5688
|
+
renderThemeBg();
|
|
5689
|
+
return;
|
|
5690
|
+
}
|
|
5691
|
+
folderInfo = { count: (res.files || []).length, dir: res.dir || v };
|
|
5692
|
+
await saveTheme({ bg: { mode: "folder", folder: v } });
|
|
5693
|
+
};
|
|
5694
|
+
folderInput.addEventListener("change", () => {
|
|
5695
|
+
void applyFolder(folderInput.value);
|
|
5696
|
+
});
|
|
5697
|
+
const browseBtn = btnSmall(L.themeBgFolderPick, () => {
|
|
5698
|
+
void (async () => {
|
|
5699
|
+
browseBtn.disabled = true;
|
|
5700
|
+
try {
|
|
5701
|
+
const res = await rpc("/pick-folder?start=" + encodeURIComponent(themeCfg.bg.folder || "") + "&title=" + encodeURIComponent(L.themeBgFolderPickTitle));
|
|
5702
|
+
if (res && res.ok && res.path) {
|
|
5703
|
+
folderInput.value = res.path;
|
|
5704
|
+
await applyFolder(res.path);
|
|
5705
|
+
}
|
|
5706
|
+
} finally {
|
|
5707
|
+
browseBtn.disabled = false;
|
|
5708
|
+
}
|
|
5709
|
+
})();
|
|
5710
|
+
});
|
|
5711
|
+
const randomCheck = h("input", { type: "checkbox" });
|
|
5712
|
+
randomCheck.checked = themeCfg.bg.folderRandom !== false;
|
|
5713
|
+
randomCheck.addEventListener("change", () => {
|
|
5714
|
+
void saveTheme({ bg: { folderRandom: randomCheck.checked } });
|
|
5715
|
+
});
|
|
5716
|
+
const urlInput = h("input", { type: "url", value: themeCfg.bg.url, class: themeInputCls, placeholder: "https://..." });
|
|
5717
|
+
urlInput.addEventListener("change", () => {
|
|
5718
|
+
const v = urlInput.value.trim();
|
|
5719
|
+
if (!v) {
|
|
5720
|
+
void saveTheme({ bg: { mode: "none", url: "" } });
|
|
5721
|
+
return;
|
|
5722
|
+
}
|
|
5723
|
+
if (!/^https?:\/\/\S+$/.test(v)) {
|
|
5724
|
+
showToast(L.themeBgUrlInvalid, "error");
|
|
5725
|
+
renderThemeBg();
|
|
5726
|
+
return;
|
|
5727
|
+
}
|
|
5728
|
+
void saveTheme({ bg: { mode: "url", url: v } });
|
|
5729
|
+
});
|
|
5730
|
+
const libCard = (f) => {
|
|
5731
|
+
const del = h("button", {
|
|
5732
|
+
type: "button",
|
|
5733
|
+
class: "zcodepro-bg-del",
|
|
5734
|
+
title: L.themeBgDelete,
|
|
5735
|
+
onClick: (ev) => {
|
|
5736
|
+
ev.stopPropagation();
|
|
5737
|
+
void (async () => {
|
|
5738
|
+
const res = await rpc("/bg/delete", { method: "POST", body: { name: f.name } });
|
|
5739
|
+
if (!res.ok) {
|
|
5740
|
+
showToast(L.failed + ": " + errText(res), "error");
|
|
5741
|
+
return;
|
|
5742
|
+
}
|
|
5743
|
+
if (Array.isArray(res.files)) bgFiles = res.files;
|
|
5744
|
+
await refreshBgFiles();
|
|
5745
|
+
})();
|
|
5746
|
+
}
|
|
5747
|
+
}, "\u2715");
|
|
5748
|
+
return h("button", {
|
|
5749
|
+
type: "button",
|
|
5750
|
+
class: "zcodepro-bg-card",
|
|
5751
|
+
"data-state": themeCfg.bg.mode === "library" && themeCfg.bg.file === f.name ? "active" : "inactive",
|
|
5752
|
+
title: f.name,
|
|
5753
|
+
onClick: () => void saveTheme({ bg: { mode: "library", file: themeCfg.bg.file === f.name ? "" : f.name } })
|
|
5754
|
+
}, h("img", { src: bgUrl(f.name), alt: "", loading: "lazy" }), del);
|
|
5755
|
+
};
|
|
5756
|
+
const section = (titleText, body2) => h(
|
|
5757
|
+
"div",
|
|
5758
|
+
{ class: "mt-3" },
|
|
5759
|
+
h("div", { class: "mb-1.5 text-ui-xs font-medium text-foreground-subtle" }, titleText),
|
|
5760
|
+
body2
|
|
5761
|
+
);
|
|
5762
|
+
const modeArea = themeCfg.bg.mode === "library" ? [
|
|
5763
|
+
section(L.themeBgLibrary + (bgFiles.length ? `\uFF08${bgFiles.length}\uFF09` : ""), h(
|
|
5764
|
+
"div",
|
|
5765
|
+
{ class: "flex flex-col gap-2" },
|
|
5766
|
+
h(
|
|
5767
|
+
"div",
|
|
5768
|
+
{ class: "flex items-center justify-between gap-2" },
|
|
5769
|
+
h("span", { class: "text-ui-xs/relaxed text-foreground-subtle" }, bgLoading ? "\u2026" : bgFiles.length ? "" : L.themeBgEmpty),
|
|
5770
|
+
btnSmall(L.themeBgUpload, () => bgInput.click())
|
|
5771
|
+
),
|
|
5772
|
+
bgFiles.length ? h(
|
|
5773
|
+
"div",
|
|
5774
|
+
{ class: "grid grid-cols-4 gap-2", style: "max-height:13.5rem;overflow-y:auto;" },
|
|
5775
|
+
...bgFiles.map(libCard)
|
|
5776
|
+
) : null
|
|
5777
|
+
))
|
|
5778
|
+
] : themeCfg.bg.mode === "folder" ? [
|
|
5779
|
+
section(L.themeBgModeFolder, h(
|
|
5780
|
+
"div",
|
|
5781
|
+
{ class: "flex flex-col gap-2" },
|
|
5782
|
+
h("div", { class: "flex items-center gap-2" }, folderInput, browseBtn),
|
|
5783
|
+
h(
|
|
5784
|
+
"div",
|
|
5785
|
+
{ class: "flex items-center gap-2" },
|
|
5786
|
+
h("label", { class: "flex items-center gap-1.5 text-ui-xs text-foreground-subtle" }, randomCheck, L.themeBgFolderRandom),
|
|
5787
|
+
numField(themeCfg.bg.intervalMin, 0, 1440, (v) => {
|
|
5788
|
+
void saveTheme({ bg: { intervalMin: v } });
|
|
5789
|
+
}, L.themeBgIntervalHint),
|
|
5790
|
+
h("span", { class: "text-ui-xs text-foreground-subtle" }, L.themeBgIntervalUnit)
|
|
5791
|
+
),
|
|
5792
|
+
h(
|
|
5793
|
+
"p",
|
|
5794
|
+
{ class: "text-ui-xs/relaxed text-foreground-subtle" },
|
|
5795
|
+
themeCfg.bg.folder ? folderInfo.count > 0 ? L.themeBgFolderCount.replaceAll("{n}", String(folderInfo.count)) : L.themeBgFolderMissing : L.themeBgFolderHint
|
|
5796
|
+
)
|
|
5797
|
+
))
|
|
5798
|
+
] : themeCfg.bg.mode === "url" ? [
|
|
5799
|
+
section(L.themeBgModeUrl, h(
|
|
5800
|
+
"div",
|
|
5801
|
+
{ class: "flex flex-col gap-2" },
|
|
5802
|
+
urlInput,
|
|
5803
|
+
h(
|
|
5804
|
+
"div",
|
|
5805
|
+
{ class: "flex items-center gap-2" },
|
|
5806
|
+
numField(themeCfg.bg.intervalMin, 0, 1440, (v) => {
|
|
5807
|
+
void saveTheme({ bg: { intervalMin: v } });
|
|
5808
|
+
}, L.themeBgUrlIntervalHint),
|
|
5809
|
+
h("span", { class: "text-ui-xs text-foreground-subtle" }, L.themeBgIntervalUnit)
|
|
5810
|
+
),
|
|
5811
|
+
h("p", { class: "text-ui-xs/relaxed text-foreground-subtle" }, L.themeBgUrlHint)
|
|
5812
|
+
))
|
|
5813
|
+
] : [h("p", { class: "mt-3 text-ui-xs/relaxed text-foreground-subtle" }, L.themeBgNoneHint)];
|
|
5814
|
+
const fitBtn = (id, label) => h("button", {
|
|
5815
|
+
type: "button",
|
|
5816
|
+
class: "zcodepro-tab",
|
|
5817
|
+
"data-state": (themeCfg.bg.fit || "cover") === id ? "active" : "inactive",
|
|
5818
|
+
onClick: () => void saveTheme({ bg: { fit: id } })
|
|
5819
|
+
}, label);
|
|
5820
|
+
paneStylesSub4.replaceChildren(
|
|
5821
|
+
h("p", { class: "text-ui-sm/relaxed text-foreground-subtle" }, L.themeBgDesc),
|
|
5822
|
+
h(
|
|
5823
|
+
"div",
|
|
5824
|
+
{ class: "mt-2 flex flex-wrap gap-1" },
|
|
5825
|
+
modeBtn("none", L.themeBgModeNone),
|
|
5826
|
+
modeBtn("library", L.themeBgModeLibrary),
|
|
5827
|
+
modeBtn("folder", L.themeBgModeFolder),
|
|
5828
|
+
modeBtn("url", L.themeBgModeUrl)
|
|
5829
|
+
),
|
|
5830
|
+
...modeArea,
|
|
5831
|
+
section(L.themeBgRegions, h(
|
|
5832
|
+
"div",
|
|
5833
|
+
{ class: "flex flex-col gap-2" },
|
|
5834
|
+
regionRow("left", L.themeBgRegionLeft),
|
|
5835
|
+
regionRow("center", L.themeBgRegionCenter),
|
|
5836
|
+
regionRow("right", L.themeBgRegionRight)
|
|
5837
|
+
)),
|
|
5838
|
+
h(
|
|
5839
|
+
"div",
|
|
5840
|
+
{ class: "mt-3 flex flex-wrap items-center gap-2" },
|
|
5841
|
+
h("span", { class: "text-ui-xs font-medium text-foreground-subtle" }, L.themeBgFit),
|
|
5842
|
+
fitBtn("cover", L.themeBgFitCover),
|
|
5843
|
+
fitBtn("contain", L.themeBgFitContain),
|
|
5844
|
+
fitBtn("fill", L.themeBgFitFill),
|
|
5845
|
+
fitBtn("tile", L.themeBgFitTile)
|
|
5846
|
+
),
|
|
5847
|
+
h(
|
|
5848
|
+
"div",
|
|
5849
|
+
{ class: "mt-3 flex flex-col gap-2" },
|
|
5850
|
+
maskRow(),
|
|
5851
|
+
blurRow(),
|
|
5852
|
+
panelRow()
|
|
5853
|
+
),
|
|
5854
|
+
bgInput
|
|
5855
|
+
);
|
|
5856
|
+
};
|
|
5857
|
+
renderThemeColors();
|
|
5858
|
+
renderThemeBg();
|
|
5859
|
+
void refreshBgFiles();
|
|
5860
|
+
void refreshFolderInfo();
|
|
4739
5861
|
let stylesSubTab = "styles";
|
|
4740
5862
|
const stylesSubTablist = h("div", { role: "tablist", "aria-orientation": "horizontal", class: "zcodepro-tablist" });
|
|
4741
5863
|
const renderStylesSubTabs = () => stylesSubTablist.replaceChildren(...[
|
|
4742
5864
|
["styles", L.tabStylesPane],
|
|
4743
|
-
["status", L.tabStatusPane]
|
|
5865
|
+
["status", L.tabStatusPane],
|
|
5866
|
+
["colors", L.themeColorsPane],
|
|
5867
|
+
["bgimg", L.themeBgPane]
|
|
4744
5868
|
].map(([id, label]) => h("button", {
|
|
4745
5869
|
type: "button",
|
|
4746
5870
|
role: "tab",
|
|
@@ -4751,11 +5875,13 @@
|
|
|
4751
5875
|
stylesSubTab = id;
|
|
4752
5876
|
paneStylesSub1.style.display = id === "styles" ? "" : "none";
|
|
4753
5877
|
paneStylesSub2.style.display = id === "status" ? "" : "none";
|
|
5878
|
+
paneStylesSub3.style.display = id === "colors" ? "" : "none";
|
|
5879
|
+
paneStylesSub4.style.display = id === "bgimg" ? "" : "none";
|
|
4754
5880
|
renderStylesSubTabs();
|
|
4755
5881
|
}
|
|
4756
5882
|
}, label)));
|
|
4757
5883
|
renderStylesSubTabs();
|
|
4758
|
-
paneStyles.append(stylesSubTablist, paneStylesSub1, paneStylesSub2);
|
|
5884
|
+
paneStyles.append(stylesSubTablist, paneStylesSub1, paneStylesSub2, paneStylesSub3, paneStylesSub4);
|
|
4759
5885
|
paneStylesSub1.append(
|
|
4760
5886
|
toolbarSwitchWrap,
|
|
4761
5887
|
h(
|
|
@@ -5399,15 +6525,6 @@
|
|
|
5399
6525
|
),
|
|
5400
6526
|
h("p", { class: "mt-2 text-ui-xs/relaxed text-foreground-subtle" }, L.syncHint)
|
|
5401
6527
|
);
|
|
5402
|
-
const persistDevMode = async (v) => {
|
|
5403
|
-
const res = await rpc("/config", { method: "POST", body: { devMode: v } });
|
|
5404
|
-
if (!res.ok) {
|
|
5405
|
-
showToast(L.failed + ": " + errText(res), "error");
|
|
5406
|
-
return false;
|
|
5407
|
-
}
|
|
5408
|
-
if (res.config) config.devMode = res.config.devMode;
|
|
5409
|
-
return true;
|
|
5410
|
-
};
|
|
5411
6528
|
const devReloadBtn = btnSmall(L.devReload, () => {
|
|
5412
6529
|
void runDevReload();
|
|
5413
6530
|
}, "shrink-0", "primary");
|
|
@@ -5425,33 +6542,24 @@
|
|
|
5425
6542
|
}
|
|
5426
6543
|
}, 2e3);
|
|
5427
6544
|
};
|
|
5428
|
-
|
|
5429
|
-
|
|
5430
|
-
|
|
5431
|
-
|
|
5432
|
-
|
|
6545
|
+
paneDebug.append(
|
|
6546
|
+
h("p", { class: "text-ui-sm/relaxed text-foreground-subtle" }, L.devModeDesc),
|
|
6547
|
+
h(
|
|
6548
|
+
"div",
|
|
6549
|
+
{ class: "mt-3 rounded-xl border border-border" },
|
|
5433
6550
|
h(
|
|
5434
6551
|
"div",
|
|
5435
|
-
{ class: "
|
|
5436
|
-
|
|
5437
|
-
if (await persistDevMode(!dev)) renderDevPane();
|
|
5438
|
-
}),
|
|
5439
|
-
...dev ? [h(
|
|
6552
|
+
{ class: "flex items-center justify-between gap-2 px-2 py-1.5" },
|
|
6553
|
+
h(
|
|
5440
6554
|
"div",
|
|
5441
|
-
{ class: "
|
|
5442
|
-
h(
|
|
5443
|
-
|
|
5444
|
-
|
|
5445
|
-
|
|
5446
|
-
h("div", { class: "mt-0.5 text-ui-xs/relaxed text-foreground-subtle" }, L.devReloadDesc)
|
|
5447
|
-
),
|
|
5448
|
-
devReloadBtn
|
|
5449
|
-
)] : []
|
|
6555
|
+
{ class: "min-w-0" },
|
|
6556
|
+
h("div", { class: "text-ui-sm font-medium text-foreground" }, L.devReload),
|
|
6557
|
+
h("div", { class: "mt-0.5 text-ui-xs/relaxed text-foreground-subtle" }, L.devReloadDesc)
|
|
6558
|
+
),
|
|
6559
|
+
devReloadBtn
|
|
5450
6560
|
)
|
|
5451
|
-
)
|
|
5452
|
-
|
|
5453
|
-
renderDevPane();
|
|
5454
|
-
paneDebug.append(devModeWrap);
|
|
6561
|
+
)
|
|
6562
|
+
);
|
|
5455
6563
|
const VISION_DEFAULT_PROMPT = "\u8BF7\u8BE6\u7EC6\u63CF\u8FF0\u8FD9\u5F20\u56FE\u7247\u7684\u5168\u90E8\u5185\u5BB9\u3002\u82E5\u662F\u754C\u9762\u6216\u56FE\u8868\u622A\u56FE\uFF0C\u8BF7\u5148\u628A\u6240\u6709\u9519\u8BEF\u3001\u8B66\u544A\u3001\u5F02\u5E38\u72B6\u6001\u9010\u5B57\u5F15\u7528\u51FA\u6765\uFF08\u542B\u5B8C\u6574\u539F\u6587\uFF09\uFF0C\u518D\u63CF\u8FF0\u6574\u4F53\u5E03\u5C40\u3001\u6587\u5B57\u4E0E\u5173\u952E\u6570\u636E\u3002";
|
|
5456
6564
|
const VISION_DEFAULT_CFG = {
|
|
5457
6565
|
enabled: true,
|
|
@@ -5469,6 +6577,7 @@
|
|
|
5469
6577
|
forceIntercept: true
|
|
5470
6578
|
};
|
|
5471
6579
|
let visionCfg = visionRes.ok && visionRes.config && typeof visionRes.config === "object" ? structuredClone(visionRes.config) : null;
|
|
6580
|
+
let visionAutoInitTried = false;
|
|
5472
6581
|
let visionSaveTimer = null;
|
|
5473
6582
|
const persistVision = async () => {
|
|
5474
6583
|
visionCfg.chain = visionCfg.proxies.map((p) => (p.name || "").trim()).filter(Boolean);
|
|
@@ -5539,6 +6648,14 @@
|
|
|
5539
6648
|
return;
|
|
5540
6649
|
}
|
|
5541
6650
|
if (!visionCfg) {
|
|
6651
|
+
if (!visionAutoInitTried && visionRes.hook) {
|
|
6652
|
+
visionAutoInitTried = true;
|
|
6653
|
+
void (async () => {
|
|
6654
|
+
const res = await rpc("/vision", { method: "POST", body: { config: VISION_DEFAULT_CFG } });
|
|
6655
|
+
if (res.ok) visionCfg = structuredClone(res.config);
|
|
6656
|
+
renderVision();
|
|
6657
|
+
})();
|
|
6658
|
+
}
|
|
5542
6659
|
const initBtn = btnSmall(L.visionAddProxy, async () => {
|
|
5543
6660
|
const res = await rpc("/vision", { method: "POST", body: { config: VISION_DEFAULT_CFG } });
|
|
5544
6661
|
if (res.ok) {
|
|
@@ -7970,6 +9087,7 @@
|
|
|
7970
9087
|
var items = DEFAULT_STATUS_ITEMS.map((x) => ({ ...x }));
|
|
7971
9088
|
var barEl = null;
|
|
7972
9089
|
var lastStats = null;
|
|
9090
|
+
var lastRenderedHtml = null;
|
|
7973
9091
|
function readCtx() {
|
|
7974
9092
|
for (const el of document.querySelectorAll("[title], [aria-label]")) {
|
|
7975
9093
|
if (el.closest(".zcodepro-statusbar")) continue;
|
|
@@ -8120,12 +9238,14 @@
|
|
|
8120
9238
|
if (!enabled4 || !host || !host.parentElement) {
|
|
8121
9239
|
if (barEl) barEl.remove();
|
|
8122
9240
|
barEl = null;
|
|
9241
|
+
lastRenderedHtml = null;
|
|
8123
9242
|
return;
|
|
8124
9243
|
}
|
|
8125
9244
|
if (!barEl || !barEl.isConnected) {
|
|
8126
9245
|
if (!barEl) {
|
|
8127
9246
|
barEl = document.createElement("div");
|
|
8128
9247
|
barEl.className = "zcodepro-statusbar";
|
|
9248
|
+
lastRenderedHtml = null;
|
|
8129
9249
|
}
|
|
8130
9250
|
host.parentElement.insertBefore(barEl, host.nextSibling);
|
|
8131
9251
|
}
|
|
@@ -8146,18 +9266,23 @@
|
|
|
8146
9266
|
}
|
|
8147
9267
|
const SEP = '<span class="zcodepro-statusbar-sep">\xB7</span>';
|
|
8148
9268
|
const GROUPSEP = '<span class="zcodepro-statusbar-groupsep"></span>';
|
|
8149
|
-
|
|
9269
|
+
const html = parts.reduce((acc, p, i) => {
|
|
8150
9270
|
if (i === 0) return p;
|
|
8151
9271
|
if (p === GROUPSEP || parts[i - 1] === GROUPSEP) return acc + p;
|
|
8152
9272
|
return acc + SEP + p;
|
|
8153
9273
|
}, "");
|
|
8154
9274
|
barEl.style.display = parts.length ? "" : "none";
|
|
9275
|
+
if (html === lastRenderedHtml) return;
|
|
9276
|
+
lastRenderedHtml = html;
|
|
9277
|
+
barEl.innerHTML = html;
|
|
8155
9278
|
}
|
|
8156
9279
|
async function tick() {
|
|
8157
9280
|
if (!enabled4 || document.hidden) return;
|
|
8158
9281
|
refreshOfficial();
|
|
8159
|
-
|
|
8160
|
-
|
|
9282
|
+
if (!official) {
|
|
9283
|
+
const res = await rpc("/stats/usage").catch(() => null);
|
|
9284
|
+
if (res && res.ok) lastStats = res;
|
|
9285
|
+
}
|
|
8161
9286
|
renderBar();
|
|
8162
9287
|
}
|
|
8163
9288
|
function startStatusBar() {
|
|
@@ -9580,6 +10705,10 @@
|
|
|
9580
10705
|
startStyleAdjustments();
|
|
9581
10706
|
} catch {
|
|
9582
10707
|
}
|
|
10708
|
+
try {
|
|
10709
|
+
startTheme();
|
|
10710
|
+
} catch {
|
|
10711
|
+
}
|
|
9583
10712
|
try {
|
|
9584
10713
|
startSettingsEntry();
|
|
9585
10714
|
} catch {
|