dsh-webdav-sync 1.0.0 → 1.0.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/lib/client.js +24 -51
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -51,7 +51,7 @@ window.__ModuleLoader__.load({
|
|
|
51
51
|
];
|
|
52
52
|
//#endregion
|
|
53
53
|
//#region \0webdav-sync-css:/home/runner/work/dsh-webdav/dsh-webdav/src/client/WebdavSyncCard.module.css?inline
|
|
54
|
-
const css = ".summary_318697645 {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n font-size: 13px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.summaryText_318697645 {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.page_318697645 {\n display: flex;\n flex-direction: column;\n gap: 20px;\n padding: 4px 0 8px;\n font-size: 13px;\n color: var(--dsw-alias-label-primary);\n}\n\n.legend_318697645 {\n display: flex;\n align-items: baseline;\n gap: 8px;\n margin: 0 0 8px;\n font-size: 12px;\n font-weight: 600;\n letter-spacing: 0.02em;\n color: var(--dsw-alias-label-secondary);\n}\n\n.hint_318697645 {\n margin: 0;\n font-size: 12px;\n line-height: 1.6;\n color: var(--dsw-alias-label-tertiary);\n}\n\n.field_318697645 {\n display: flex;\n flex-direction: column;\n gap: 4px;\n margin-bottom: 10px;\n}\n\n.fieldLabel_318697645 {\n font-size: 12px;\n color: var(--dsw-alias-label-secondary);\n}\n\n/*\n * The line of explanation belonging to one field: it sits between that field's\n * label and its input, so a reader gets the rule before typing, and the gap\n * between two fields (10px) still reads as the bigger break.\n */\n.fieldHint_318697645 {\n margin: 0;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-label-tertiary);\n}\n\n.grid_318697645 {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));\n gap: 10px 14px;\n}\n\n
|
|
54
|
+
const css = ".summary_318697645 {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n font-size: 13px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.summaryText_318697645 {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.page_318697645 {\n display: flex;\n flex-direction: column;\n gap: 20px;\n padding: 4px 0 8px;\n font-size: 13px;\n color: var(--dsw-alias-label-primary);\n}\n\n.legend_318697645 {\n display: flex;\n align-items: baseline;\n gap: 8px;\n margin: 0 0 8px;\n font-size: 12px;\n font-weight: 600;\n letter-spacing: 0.02em;\n color: var(--dsw-alias-label-secondary);\n}\n\n.hint_318697645 {\n margin: 0;\n font-size: 12px;\n line-height: 1.6;\n color: var(--dsw-alias-label-tertiary);\n}\n\n.field_318697645 {\n display: flex;\n flex-direction: column;\n gap: 4px;\n margin-bottom: 10px;\n}\n\n.fieldLabel_318697645 {\n font-size: 12px;\n color: var(--dsw-alias-label-secondary);\n}\n\n/*\n * The line of explanation belonging to one field: it sits between that field's\n * label and its input, so a reader gets the rule before typing, and the gap\n * between two fields (10px) still reads as the bigger break.\n */\n.fieldHint_318697645 {\n margin: 0;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-label-tertiary);\n}\n\n.grid_318697645 {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));\n gap: 10px 14px;\n}\n\n/*\n * A field's label line when the field also carries an option of its own: the\n * label and the saved-password checkbox share the line, so the option reads as\n * part of the field it governs instead of as a setting of its own further down\n * the card. They sit at the two ends of that line (`space-between`): the label\n * keeps the field column's left edge, the checkbox lines up with its right edge\n * — packed together they read as one long word. The checkbox is brought down to\n * the field label's 12px and its colour for the same reason as the part rows\n * (see `.partRow_318697645 label`): a control inside a label line should not outrank the\n * line it sits in.\n */\n.labelRow_318697645 {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 10px;\n}\n\n.labelRow_318697645 label {\n gap: 6px;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.labelRow_318697645 label input {\n width: 14px;\n height: 14px;\n}\n\n/*\n * The auto-sync choice: every tab in one row, all the same width, so six\n * options read as one strip instead of a dropdown hiding five of them.\n */\n/* Doubled class: the control's own rule also sets a display, and this wins. */\n.autoControl_318697645.autoControl_318697645 {\n display: grid;\n width: 100%;\n box-sizing: border-box;\n}\n\n/* Six tabs have to share the row, so each keeps its padding modest. */\n.autoControl_318697645 button {\n padding: 0 6px;\n font-size: 12px;\n}\n\n.partRow_318697645 {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 7px 0;\n border-bottom: 1px solid var(--dsw-alias-border-l2);\n}\n\n/* No trailing border when the rows stand alone (a host with no view yet). */\n.partRow_318697645:last-child {\n border-bottom: none;\n}\n\n/* The checkbox with its one-line description under it. */\n.partText_318697645 {\n display: flex;\n flex: 1;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n/*\n * The checkbox component sets its own label at 14px, which is bigger than this\n * card's section headings (12px) — the rows read as if they outranked the\n * heading above them. Its class name is internal to the component, so the\n * element selector is the way in; the box shrinks with the text to match.\n */\n.partRow_318697645 label {\n gap: 6px;\n font-size: 12px;\n line-height: 18px;\n}\n\n.partRow_318697645 label input {\n width: 14px;\n height: 14px;\n}\n\n.partHint_318697645 {\n font-size: 11px;\n line-height: 1.4;\n color: var(--dsw-alias-label-tertiary);\n}\n\n.partState_318697645 {\n margin-left: auto;\n flex: none;\n padding-top: 2px;\n font-size: 11px;\n color: var(--dsw-alias-label-tertiary);\n}\n\n.partStateBoth_318697645 {\n color: var(--dsw-alias-label-warning, var(--dsw-alias-label-secondary));\n}\n\n.notice_318697645 {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 10px 12px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 10px;\n background: var(--dsw-alias-bg-layer-2);\n font-size: 12px;\n}\n\n.noticeTitle_318697645 {\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n}\n\n/*\n * The sync actions. Six short labels have to sit on one row, so the buttons\n * keep their own padding down; wrapping stays on only as a narrow-card escape.\n */\n.footer_318697645 {\n display: flex;\n align-items: center;\n gap: 6px;\n flex-wrap: wrap;\n padding-top: 4px;\n}\n\n.footer_318697645 button {\n padding: 0 8px;\n}\n\n.spacer_318697645 {\n flex: 1;\n}\n\n/* The card's own actions: WebDAV settings, kept apart from the sync ones. */\n.cardFooter_318697645 {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-wrap: wrap;\n margin-top: 4px;\n padding-top: 12px;\n border-top: 1px solid var(--dsw-alias-border-l2);\n}\n\n.failed_318697645 {\n font-size: 12px;\n color: var(--dsw-alias-label-error);\n}\n\n.note_318697645 {\n font-size: 12px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.confirm_318697645 {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-wrap: wrap;\n padding: 10px 12px;\n border: 1px solid var(--dsw-alias-border-l4);\n border-radius: 10px;\n font-size: 12px;\n color: var(--dsw-alias-label-primary);\n}\n\n.previewList_318697645 {\n display: flex;\n flex-direction: column;\n gap: 4px;\n font-size: 12px;\n}\n\n.previewRow_318697645 {\n display: flex;\n gap: 8px;\n}\n\n.previewPart_318697645 {\n min-width: 90px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.output_318697645 {\n max-height: 180px;\n margin: 0;\n overflow: auto;\n padding: 8px 10px;\n border-radius: 8px;\n background: var(--dsw-alias-bg-layer-3);\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n font-size: 11px;\n line-height: 1.5;\n white-space: pre-wrap;\n color: var(--dsw-alias-label-secondary);\n}\n\n.spin_318697645 {\n animation: webdavSyncSpin 0.9s linear infinite;\n}\n\n@keyframes webdavSyncSpin {\n to {\n transform: rotate(360deg);\n }\n}\n";
|
|
55
55
|
const tagId = "dsh-webdav-sync/WebdavSyncCard.module.css";
|
|
56
56
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=\"" + tagId + "\"]") === null) {
|
|
57
57
|
const tag = document.createElement("style");
|
|
@@ -71,7 +71,7 @@ window.__ModuleLoader__.load({
|
|
|
71
71
|
"fieldHint": "fieldHint_318697645",
|
|
72
72
|
"grid": "grid_318697645",
|
|
73
73
|
"partRow": "partRow_318697645",
|
|
74
|
-
"
|
|
74
|
+
"labelRow": "labelRow_318697645",
|
|
75
75
|
"autoControl": "autoControl_318697645",
|
|
76
76
|
"partText": "partText_318697645",
|
|
77
77
|
"partHint": "partHint_318697645",
|
|
@@ -216,10 +216,6 @@ window.__ModuleLoader__.load({
|
|
|
216
216
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
217
217
|
className: WebdavSyncCard_module_default.page,
|
|
218
218
|
children: [
|
|
219
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
220
|
-
className: WebdavSyncCard_module_default.hint,
|
|
221
|
-
children: t("sectionSubtitle")
|
|
222
|
-
}),
|
|
223
219
|
state.error !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
224
220
|
className: WebdavSyncCard_module_default.failed,
|
|
225
221
|
role: "alert",
|
|
@@ -232,24 +228,17 @@ window.__ModuleLoader__.load({
|
|
|
232
228
|
}),
|
|
233
229
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
234
230
|
className: WebdavSyncCard_module_default.field,
|
|
235
|
-
children: [
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
id: "webdav-sync-url",
|
|
247
|
-
value: state.url,
|
|
248
|
-
spellCheck: false,
|
|
249
|
-
placeholder: "https://dav.jianguoyun.com/dav/",
|
|
250
|
-
onChange: (event) => props.edit("url", event.target.value)
|
|
251
|
-
})
|
|
252
|
-
]
|
|
231
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
232
|
+
className: WebdavSyncCard_module_default.fieldLabel,
|
|
233
|
+
htmlFor: "webdav-sync-url",
|
|
234
|
+
children: t("urlLabel")
|
|
235
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
|
|
236
|
+
id: "webdav-sync-url",
|
|
237
|
+
value: state.url,
|
|
238
|
+
spellCheck: false,
|
|
239
|
+
placeholder: "https://dav.jianguoyun.com/dav/",
|
|
240
|
+
onChange: (event) => props.edit("url", event.target.value)
|
|
241
|
+
})]
|
|
253
242
|
}),
|
|
254
243
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
255
244
|
className: WebdavSyncCard_module_default.grid,
|
|
@@ -268,10 +257,17 @@ window.__ModuleLoader__.load({
|
|
|
268
257
|
})]
|
|
269
258
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
270
259
|
className: WebdavSyncCard_module_default.field,
|
|
271
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.
|
|
272
|
-
className: WebdavSyncCard_module_default.
|
|
273
|
-
|
|
274
|
-
|
|
260
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
261
|
+
className: WebdavSyncCard_module_default.labelRow,
|
|
262
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
263
|
+
className: WebdavSyncCard_module_default.fieldLabel,
|
|
264
|
+
htmlFor: "webdav-sync-password",
|
|
265
|
+
children: t("passwordLabel")
|
|
266
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Checkbox, {
|
|
267
|
+
checked: state.rememberPassword,
|
|
268
|
+
label: t("rememberPassword"),
|
|
269
|
+
onChange: (next) => props.toggle("rememberPassword", next)
|
|
270
|
+
})]
|
|
275
271
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
|
|
276
272
|
id: "webdav-sync-password",
|
|
277
273
|
type: "password",
|
|
@@ -303,17 +299,6 @@ window.__ModuleLoader__.load({
|
|
|
303
299
|
onChange: (event) => props.edit("passphrase", event.target.value)
|
|
304
300
|
})
|
|
305
301
|
]
|
|
306
|
-
}),
|
|
307
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
308
|
-
className: WebdavSyncCard_module_default.toggleRow,
|
|
309
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Checkbox, {
|
|
310
|
-
checked: state.rememberPassword,
|
|
311
|
-
label: t("rememberPassword"),
|
|
312
|
-
onChange: (next) => props.toggle("rememberPassword", next)
|
|
313
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
314
|
-
className: WebdavSyncCard_module_default.fieldHint,
|
|
315
|
-
children: t("rememberPasswordHint")
|
|
316
|
-
})]
|
|
317
302
|
})
|
|
318
303
|
] }),
|
|
319
304
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h4", {
|
|
@@ -336,10 +321,6 @@ window.__ModuleLoader__.load({
|
|
|
336
321
|
className: WebdavSyncCard_module_default.legend,
|
|
337
322
|
children: t("partsLegend")
|
|
338
323
|
}),
|
|
339
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
340
|
-
className: WebdavSyncCard_module_default.hint,
|
|
341
|
-
children: t("partsHint")
|
|
342
|
-
}),
|
|
343
324
|
(state.view?.parts ?? []).map((part) => {
|
|
344
325
|
const stateKey = part.synced ? partStateKey(part) : "partOff";
|
|
345
326
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -909,26 +890,22 @@ window.__ModuleLoader__.load({
|
|
|
909
890
|
/** Chinese copy — the source dictionary. */
|
|
910
891
|
const zh = {
|
|
911
892
|
sectionTitle: "WebDAV 同步",
|
|
912
|
-
sectionSubtitle: "把本机的模型配置与已装插件同步到 WebDAV,多台机器保持一致。",
|
|
913
893
|
cardSummaryOff: "WebDAV 同步:未开启",
|
|
914
894
|
cardSummaryOn: "WebDAV 同步:{url}",
|
|
915
895
|
cardSummaryUnset: "WebDAV 同步:已开启,地址待填写",
|
|
916
896
|
addressLegend: "服务器",
|
|
917
897
|
urlLabel: "WebDAV 地址",
|
|
918
|
-
urlHint: "地址填到文件夹这一层,例如坚果云 https://dav.jianguoyun.com/dav/。",
|
|
919
898
|
userLabel: "用户名",
|
|
920
899
|
passwordLabel: "密码",
|
|
921
900
|
passphraseLabel: "口令",
|
|
922
901
|
passphraseHint: "口令在文件离开本机前用来加密,服务器看不到内容;不要与 WebDAV 密码用同一个。",
|
|
923
902
|
rememberPassword: "保存密码",
|
|
924
|
-
rememberPasswordHint: "「保存密码」关掉后,密码只在本次运行内使用,不写入本机。",
|
|
925
903
|
autoLegend: "自动同步",
|
|
926
904
|
autoManual: "手动同步",
|
|
927
905
|
autoEvery: "{n} 分钟",
|
|
928
906
|
autoHour: "{n} 小时",
|
|
929
907
|
autoOff: "关闭同步",
|
|
930
908
|
partsLegend: "同步内容",
|
|
931
|
-
partsHint: "按份合并:只在本机改动的推送出去,只在服务器改动的取回来,两边都改过的保留较新的一份,被替换的那份存到 sync 目录。",
|
|
932
909
|
partModels: "模型供应商与模型",
|
|
933
910
|
partModelsHint: "有哪些供应商、各自提供哪些模型、API key 从哪里读。",
|
|
934
911
|
partDefaults: "默认模型",
|
|
@@ -984,26 +961,22 @@ window.__ModuleLoader__.load({
|
|
|
984
961
|
/** English copy, complete by construction. */
|
|
985
962
|
const en = {
|
|
986
963
|
sectionTitle: "WebDAV sync",
|
|
987
|
-
sectionSubtitle: "Keep the model setup and installed plugins the same on every computer through a WebDAV folder.",
|
|
988
964
|
cardSummaryOff: "WebDAV sync: off",
|
|
989
965
|
cardSummaryOn: "WebDAV sync: {url}",
|
|
990
966
|
cardSummaryUnset: "WebDAV sync: on, no address yet",
|
|
991
967
|
addressLegend: "Server",
|
|
992
968
|
urlLabel: "WebDAV address",
|
|
993
|
-
urlHint: "The folder itself, e.g. Nutstore https://dav.jianguoyun.com/dav/.",
|
|
994
969
|
userLabel: "User name",
|
|
995
970
|
passwordLabel: "Password",
|
|
996
971
|
passphraseLabel: "Passphrase",
|
|
997
972
|
passphraseHint: "It seals the file before it leaves this computer, so the server cannot read it. Do not reuse the password above.",
|
|
998
973
|
rememberPassword: "Remember the password",
|
|
999
|
-
rememberPasswordHint: "With “Remember the password” off, the password is used for this run only and is not written here.",
|
|
1000
974
|
autoLegend: "Sync by itself",
|
|
1001
975
|
autoManual: "By hand",
|
|
1002
976
|
autoEvery: "Every {n} min",
|
|
1003
977
|
autoHour: "Every {n} h",
|
|
1004
978
|
autoOff: "Off",
|
|
1005
979
|
partsLegend: "What is synced",
|
|
1006
|
-
partsHint: "Merged a part at a time: a part changed only here is pushed, one changed only on the server is brought in, one changed on both keeps the newer, and the replaced copy is kept in the sync folder.",
|
|
1007
980
|
partModels: "Model providers and models",
|
|
1008
981
|
partModelsHint: "Which providers there are, what models each offers, and where their API keys come from.",
|
|
1009
982
|
partDefaults: "Default model",
|