dsh-dock 0.13.0 → 0.14.0
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.md +25 -6
- package/client.js +1234 -596
- package/features/animation/view.jsx +2 -2
- package/features/balance/view.js +1 -1
- package/features/games/view.jsx +1 -1
- package/features/mobile/host.js +320 -0
- package/features/mobile/view.js +375 -153
- package/features/mobile-relay/host.js +5 -245
- package/features/mobile-relay/view.jsx +9 -330
- package/features/modelconfig/host.js +195 -1
- package/features/modelconfig/view.js +762 -92
- package/features/notify/view.jsx +2 -2
- package/features/runstate/view.jsx +2 -2
- package/features/tokenlog/view.jsx +2 -2
- package/index.js +15 -1
- package/package.json +9 -3
- package/screenshots/dock-modelconfig-provider-create.png +0 -0
- package/screenshots/dock-modelconfig-provider-edit.png +0 -0
- package/screenshots/dock-modelconfig-providers.png +0 -0
- package/screenshots/dock-modelconfig.png +0 -0
- package/src/client.jsx +1 -1
- package/src/shared.js +6 -3
- package/src/welcome-ack.js +69 -0
package/client.js
CHANGED
|
@@ -2187,7 +2187,7 @@ function initFeatureState(defs) {
|
|
|
2187
2187
|
}
|
|
2188
2188
|
function syncFeatureStateFromHost(defs) {
|
|
2189
2189
|
if (typeof fetch !== "function") return;
|
|
2190
|
-
fetch("
|
|
2190
|
+
fetch("dsh-dock/features").then(async (res) => {
|
|
2191
2191
|
if (!res.ok) return;
|
|
2192
2192
|
const data = await res.json().catch(() => null);
|
|
2193
2193
|
const persisted = data && data.ok && data.data && data.data.persisted;
|
|
@@ -2214,7 +2214,7 @@ function syncFeatureStateFromHost(defs) {
|
|
|
2214
2214
|
}
|
|
2215
2215
|
function pushFeatureEnabledToHost(id, enabled) {
|
|
2216
2216
|
if (typeof fetch !== "function") return;
|
|
2217
|
-
fetch("
|
|
2217
|
+
fetch("dsh-dock/features", {
|
|
2218
2218
|
method: "POST",
|
|
2219
2219
|
headers: { "content-type": "application/json" },
|
|
2220
2220
|
body: JSON.stringify({ id, enabled })
|
|
@@ -2300,7 +2300,7 @@ function subscribePanel(fn) {
|
|
|
2300
2300
|
var import_react2 = __toESM(require("react"), 1);
|
|
2301
2301
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
2302
2302
|
function rpcCall(method, args) {
|
|
2303
|
-
return fetch("
|
|
2303
|
+
return fetch("dsh-dock/tokenlog/" + method, {
|
|
2304
2304
|
method: "POST",
|
|
2305
2305
|
headers: { "content-type": "application/json" },
|
|
2306
2306
|
body: JSON.stringify(args === void 0 ? {} : args)
|
|
@@ -3731,7 +3731,7 @@ var modelsStore = {
|
|
|
3731
3731
|
load() {
|
|
3732
3732
|
if (this.snap.loading) return;
|
|
3733
3733
|
this.set({ loading: true, error: null });
|
|
3734
|
-
fetch("
|
|
3734
|
+
fetch("dsh-dock/models", { cache: "no-store", signal: AbortSignal.timeout(2e4) }).then((res) => res.ok ? res.json() : Promise.reject(new Error("\u6A21\u578B\u76EE\u5F55\u63A5\u53E3 HTTP " + res.status))).then((data) => this.set({ data, loading: false, error: null })).catch((e) => this.set({ loading: false, error: e && e.message || String(e) }));
|
|
3735
3735
|
}
|
|
3736
3736
|
};
|
|
3737
3737
|
function useModels() {
|
|
@@ -3748,35 +3748,190 @@ var DKM_TAGS = [["video", "\u89C6\u9891"], ["audio", "\u97F3\u9891"], ["document
|
|
|
3748
3748
|
var DKM_PI_LEVELS = ["off", "minimal", "low", "medium", "high", "xhigh", "max"];
|
|
3749
3749
|
var DKM_DS_LEVELS = ["off", "low", "high", "max"];
|
|
3750
3750
|
var DKM_EFFORT_NAMES = { off: "\u5173\u95ED", minimal: "\u6781\u4F4E", low: "\u4F4E", medium: "\u4E2D", high: "\u9AD8", xhigh: "\u8D85\u9AD8", max: "\u6700\u9AD8" };
|
|
3751
|
+
var DKM_APIS = [
|
|
3752
|
+
["openai-completions", "OpenAI \u517C\u5BB9\uFF08chat/completions\uFF09"],
|
|
3753
|
+
["openai-responses", "OpenAI Responses"],
|
|
3754
|
+
["anthropic-messages", "Anthropic Messages"]
|
|
3755
|
+
];
|
|
3756
|
+
var DKM_ROUTE_KEY_RE = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
|
|
3757
|
+
function dkmEnvFromRoute(route) {
|
|
3758
|
+
const s = String(route || "").toUpperCase().replace(/[^A-Z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
3759
|
+
if (!s) return "";
|
|
3760
|
+
return (/^[0-9]/.test(s) ? "KEY_" + s : s) + "_API_KEY";
|
|
3761
|
+
}
|
|
3762
|
+
var DKM_ALL_INPUT = DKM_MODALITIES.map((x) => x[0]);
|
|
3763
|
+
var DKM_ALL_TAGS = DKM_TAGS.map((x) => x[0]);
|
|
3764
|
+
function dkmToggleIn(list, v) {
|
|
3765
|
+
return list.indexOf(v) >= 0 ? list.filter((x) => x !== v) : list.concat([v]);
|
|
3766
|
+
}
|
|
3767
|
+
function dkmAllInputs(on) {
|
|
3768
|
+
return { input: on ? DKM_ALL_INPUT.slice() : [], tags: on ? DKM_ALL_TAGS.slice() : [] };
|
|
3769
|
+
}
|
|
3770
|
+
function dkmAllLevels(on) {
|
|
3771
|
+
const lv = {};
|
|
3772
|
+
for (const k of DKM_PI_LEVELS) lv[k] = !!on;
|
|
3773
|
+
return { effortsMode: "custom", effortLevels: lv };
|
|
3774
|
+
}
|
|
3775
|
+
function draftFromModel(m) {
|
|
3776
|
+
const levels = {};
|
|
3777
|
+
if (m.efforts === "custom" && m.effortMap && typeof m.effortMap === "object") {
|
|
3778
|
+
for (const lv of DKM_PI_LEVELS) levels[lv] = m.effortMap[lv] !== void 0;
|
|
3779
|
+
}
|
|
3780
|
+
return {
|
|
3781
|
+
id: m.id || "",
|
|
3782
|
+
name: m.name || "",
|
|
3783
|
+
contextWindow: m.contextWindow != null ? String(m.contextWindow) : "",
|
|
3784
|
+
maxTokens: m.maxTokens != null ? String(m.maxTokens) : "",
|
|
3785
|
+
input: m.input && m.input.length ? m.input.slice() : ["text"],
|
|
3786
|
+
tags: (m.tags || []).slice(),
|
|
3787
|
+
effortsMode: m.efforts === "custom" ? "custom" : m.efforts === "off" ? "off" : "inherit",
|
|
3788
|
+
effortLevels: levels,
|
|
3789
|
+
raw: m.raw && typeof m.raw === "object" ? m.raw : null
|
|
3790
|
+
};
|
|
3791
|
+
}
|
|
3792
|
+
function emptyModelDraft() {
|
|
3793
|
+
return { id: "", name: "", contextWindow: "", maxTokens: "", input: ["text"], tags: [], effortsMode: "inherit", effortLevels: {}, raw: null };
|
|
3794
|
+
}
|
|
3795
|
+
function emptyProviderForm() {
|
|
3796
|
+
return {
|
|
3797
|
+
route: "",
|
|
3798
|
+
displayName: "",
|
|
3799
|
+
api: "openai-completions",
|
|
3800
|
+
baseURL: "",
|
|
3801
|
+
apiKeyEnv: "",
|
|
3802
|
+
apiKey: "",
|
|
3803
|
+
defaultInput: ["text"],
|
|
3804
|
+
models: [],
|
|
3805
|
+
extra: {}
|
|
3806
|
+
};
|
|
3807
|
+
}
|
|
3808
|
+
function providerFormFromProvider(p) {
|
|
3809
|
+
const raw = p.rawProfile && typeof p.rawProfile === "object" && !Array.isArray(p.rawProfile) ? p.rawProfile : {};
|
|
3810
|
+
const extra = Object.assign({}, raw);
|
|
3811
|
+
delete extra.displayName;
|
|
3812
|
+
delete extra.api;
|
|
3813
|
+
delete extra.baseURL;
|
|
3814
|
+
delete extra.apiKeyEnv;
|
|
3815
|
+
delete extra.defaultInput;
|
|
3816
|
+
delete extra.models;
|
|
3817
|
+
const models = draftFromProvider(p).models;
|
|
3818
|
+
return {
|
|
3819
|
+
route: p.route || p.id || "",
|
|
3820
|
+
displayName: typeof raw.displayName === "string" ? raw.displayName : p.displayName || "",
|
|
3821
|
+
api: typeof raw.api === "string" && raw.api ? raw.api : p.api || "openai-completions",
|
|
3822
|
+
baseURL: typeof raw.baseURL === "string" ? raw.baseURL : p.baseURL || "",
|
|
3823
|
+
apiKeyEnv: typeof raw.apiKeyEnv === "string" ? raw.apiKeyEnv : p.apiKeyEnv || "",
|
|
3824
|
+
apiKey: "",
|
|
3825
|
+
defaultInput: Array.isArray(raw.defaultInput) && raw.defaultInput.length ? raw.defaultInput.slice() : Array.isArray(p.defaultInput) && p.defaultInput.length ? p.defaultInput.slice() : ["text"],
|
|
3826
|
+
models: models.length ? models : [emptyModelDraft()],
|
|
3827
|
+
extra
|
|
3828
|
+
};
|
|
3829
|
+
}
|
|
3751
3830
|
function draftFromProvider(p) {
|
|
3752
3831
|
return {
|
|
3753
3832
|
id: p.id,
|
|
3754
3833
|
kind: p.kind,
|
|
3755
3834
|
thinking: p.thinking === "disabled" ? "disabled" : "enabled",
|
|
3756
3835
|
defaultEffort: DKM_DS_LEVELS.indexOf(p.defaultEffort) >= 0 ? p.defaultEffort : "high",
|
|
3757
|
-
models: (p.models || []).map(
|
|
3758
|
-
const levels = {};
|
|
3759
|
-
if (m.efforts === "custom" && m.effortMap && typeof m.effortMap === "object") {
|
|
3760
|
-
for (const lv of DKM_PI_LEVELS) levels[lv] = m.effortMap[lv] !== void 0;
|
|
3761
|
-
}
|
|
3762
|
-
return {
|
|
3763
|
-
id: m.id || "",
|
|
3764
|
-
name: m.name || "",
|
|
3765
|
-
contextWindow: m.contextWindow != null ? String(m.contextWindow) : "",
|
|
3766
|
-
maxTokens: m.maxTokens != null ? String(m.maxTokens) : "",
|
|
3767
|
-
input: m.input && m.input.length ? m.input.slice() : ["text"],
|
|
3768
|
-
tags: (m.tags || []).slice(),
|
|
3769
|
-
effortsMode: m.efforts === "custom" ? "custom" : m.efforts === "off" ? "off" : "inherit",
|
|
3770
|
-
effortLevels: levels,
|
|
3771
|
-
raw: m.raw && typeof m.raw === "object" ? m.raw : null
|
|
3772
|
-
};
|
|
3773
|
-
})
|
|
3836
|
+
models: (p.models || []).map(draftFromModel)
|
|
3774
3837
|
};
|
|
3775
3838
|
}
|
|
3776
|
-
function
|
|
3839
|
+
function ModelRow(props) {
|
|
3840
|
+
const m = props.m, i = props.i, kind = props.kind, onPatch = props.onPatch, onDel = props.onDel;
|
|
3841
|
+
return import_react3.default.createElement(
|
|
3842
|
+
"div",
|
|
3843
|
+
{ key: i, className: "dkm-model" },
|
|
3844
|
+
import_react3.default.createElement(
|
|
3845
|
+
"div",
|
|
3846
|
+
{ className: "dkm-model-head" },
|
|
3847
|
+
import_react3.default.createElement("span", { className: "dkm-model-idx" }, "#" + (i + 1)),
|
|
3848
|
+
import_react3.default.createElement("button", { type: "button", className: "dkm-del", onClick: () => onDel(i) }, "\u5220\u9664")
|
|
3849
|
+
),
|
|
3850
|
+
import_react3.default.createElement(
|
|
3851
|
+
"div",
|
|
3852
|
+
{ className: "dkm-grid" },
|
|
3853
|
+
import_react3.default.createElement("input", { className: "dkm-input", placeholder: "\u6A21\u578B id\uFF08\u5FC5\u586B\uFF0C\u5982 deepseek-v4-pro\uFF09", value: m.id, onChange: (e) => onPatch(i, { id: e.target.value }) }),
|
|
3854
|
+
import_react3.default.createElement("input", { className: "dkm-input", placeholder: "\u663E\u793A\u540D\u79F0\uFF08\u53EF\u9009\uFF09", value: m.name, onChange: (e) => onPatch(i, { name: e.target.value }) }),
|
|
3855
|
+
import_react3.default.createElement("input", { className: "dkm-input", placeholder: "\u4E0A\u4E0B\u6587\u7A97\u53E3", inputMode: "numeric", value: m.contextWindow, onChange: (e) => onPatch(i, { contextWindow: e.target.value }) }),
|
|
3856
|
+
import_react3.default.createElement("input", { className: "dkm-input", placeholder: "\u6700\u5927\u8F93\u51FA", inputMode: "numeric", value: m.maxTokens, onChange: (e) => onPatch(i, { maxTokens: e.target.value }) })
|
|
3857
|
+
),
|
|
3858
|
+
import_react3.default.createElement(
|
|
3859
|
+
"div",
|
|
3860
|
+
{ className: "dkm-checks" },
|
|
3861
|
+
import_react3.default.createElement("span", { className: "dkm-label" }, "\u8F93\u5165\u7C7B\u578B\uFF1A"),
|
|
3862
|
+
DKM_MODALITIES.map(([v, label]) => import_react3.default.createElement(
|
|
3863
|
+
"label",
|
|
3864
|
+
{
|
|
3865
|
+
key: v,
|
|
3866
|
+
className: "dkm-check",
|
|
3867
|
+
title: v === "image" ? "\u7531\u4F60\u58F0\u660E\u8BE5\u7AEF\u70B9\u652F\u6301\u56FE\u7247\uFF1A\u4FDD\u5B58\u540E\u539F\u56FE\u76F4\u53D1\uFF0C\u5E76\u53EF\u4F5C\u4E3A\u89C6\u89C9\u6A21\u578B\u5019\u9009\u3002\u7CFB\u7EDF\u4E0D\u4F1A\u66FF\u4F60\u731C\u6D4B\uFF1B\u7AEF\u70B9\u5B9E\u9645\u4E0D\u652F\u6301\u65F6\u53D6\u6D88\u52FE\u9009\u5373\u53EF\u6062\u590D\u8D70\u56FE\u7247\u7406\u89E3\u4EE3\u7406" : null
|
|
3868
|
+
},
|
|
3869
|
+
import_react3.default.createElement("input", {
|
|
3870
|
+
type: "checkbox",
|
|
3871
|
+
checked: m.input.indexOf(v) >= 0,
|
|
3872
|
+
onChange: () => {
|
|
3873
|
+
const next = dkmToggleIn(m.input, v);
|
|
3874
|
+
onPatch(i, { input: next.length > 0 ? next : ["text"] });
|
|
3875
|
+
}
|
|
3876
|
+
}),
|
|
3877
|
+
label
|
|
3878
|
+
)),
|
|
3879
|
+
import_react3.default.createElement("span", { className: "dkm-label dkm-tag", title: "\u6807\u6CE8\u4EC5\u5728\u672C\u9762\u677F\u5C55\u793A\u4E0E\u6301\u4E45\u5316\uFF0C\u4E0D\u53C2\u4E0E\u8BF7\u6C42\u8DEF\u7531\uFF08\u5B98\u65B9 schema \u53EA\u63A5\u53D7\u6587\u672C/\u56FE\u7247\uFF09" }, "\u6807\u6CE8\uFF1A"),
|
|
3880
|
+
DKM_TAGS.map(([v, label]) => import_react3.default.createElement(
|
|
3881
|
+
"label",
|
|
3882
|
+
{ key: v, className: "dkm-check dkm-tag" },
|
|
3883
|
+
import_react3.default.createElement("input", { type: "checkbox", checked: m.tags.indexOf(v) >= 0, onChange: () => onPatch(i, { tags: dkmToggleIn(m.tags, v) }) }),
|
|
3884
|
+
label
|
|
3885
|
+
)),
|
|
3886
|
+
import_react3.default.createElement("button", { type: "button", className: "dkm-mini", title: "\u4E00\u952E\u52FE\u9009\u5168\u90E8\u8F93\u5165\u7C7B\u578B\u4E0E\u6807\u6CE8", onClick: () => onPatch(i, dkmAllInputs(true)) }, "\u5168\u9009"),
|
|
3887
|
+
import_react3.default.createElement("button", { type: "button", className: "dkm-mini", title: "\u4E00\u952E\u53D6\u6D88\u5168\u90E8\u52FE\u9009\uFF08\u8F93\u5165\u7559\u7A7A = \u7EE7\u627F\u76EE\u5F55\u9ED8\u8BA4\uFF09", onClick: () => onPatch(i, dkmAllInputs(false)) }, "\u53D6\u6D88\u5168\u9009")
|
|
3888
|
+
),
|
|
3889
|
+
import_react3.default.createElement(
|
|
3890
|
+
"div",
|
|
3891
|
+
{ className: "dkm-efforts" },
|
|
3892
|
+
import_react3.default.createElement("span", { className: "dkm-label" }, "\u601D\u8003\u5F3A\u5EA6\uFF1A"),
|
|
3893
|
+
kind === "deepseek" ? import_react3.default.createElement("span", { className: "dkm-sub" }, "\u968F Provider \u8BBE\u7F6E\uFF08Off/Low/High/Max\uFF0C\u5168\u6A21\u578B\u5171\u4EAB\uFF09") : import_react3.default.createElement(
|
|
3894
|
+
"span",
|
|
3895
|
+
null,
|
|
3896
|
+
import_react3.default.createElement(
|
|
3897
|
+
"select",
|
|
3898
|
+
{
|
|
3899
|
+
className: "dkm-select",
|
|
3900
|
+
value: m.effortsMode,
|
|
3901
|
+
onChange: (e) => onPatch(i, {
|
|
3902
|
+
effortsMode: e.target.value,
|
|
3903
|
+
effortLevels: e.target.value === "custom" && m.effortsMode !== "custom" ? { off: true, low: true, high: true } : m.effortLevels
|
|
3904
|
+
})
|
|
3905
|
+
},
|
|
3906
|
+
import_react3.default.createElement("option", { value: "inherit" }, "\u8DDF\u968F\u76EE\u5F55\u9ED8\u8BA4"),
|
|
3907
|
+
import_react3.default.createElement("option", { value: "off" }, "\u4E0D\u652F\u6301\u601D\u8003"),
|
|
3908
|
+
import_react3.default.createElement("option", { value: "custom" }, "\u81EA\u5B9A\u4E49\u6863\u4F4D")
|
|
3909
|
+
),
|
|
3910
|
+
m.effortsMode === "custom" ? DKM_PI_LEVELS.map((lv) => import_react3.default.createElement(
|
|
3911
|
+
"label",
|
|
3912
|
+
{ key: lv, className: "dkm-check" },
|
|
3913
|
+
import_react3.default.createElement("input", {
|
|
3914
|
+
type: "checkbox",
|
|
3915
|
+
checked: !!m.effortLevels[lv],
|
|
3916
|
+
onChange: () => {
|
|
3917
|
+
const nl = Object.assign({}, m.effortLevels);
|
|
3918
|
+
nl[lv] = !nl[lv];
|
|
3919
|
+
onPatch(i, { effortLevels: nl });
|
|
3920
|
+
}
|
|
3921
|
+
}),
|
|
3922
|
+
DKM_EFFORT_NAMES[lv] || lv
|
|
3923
|
+
)) : null,
|
|
3924
|
+
import_react3.default.createElement("button", { type: "button", className: "dkm-mini", title: "\u4E00\u952E\u52FE\u9009\u5168\u90E8\u5F3A\u5EA6\u6863\uFF08\u5207\u4E3A\u81EA\u5B9A\u4E49\uFF09", onClick: () => onPatch(i, dkmAllLevels(true)) }, "\u5168\u9009"),
|
|
3925
|
+
import_react3.default.createElement("button", { type: "button", className: "dkm-mini", title: "\u4E00\u952E\u53D6\u6D88\u5168\u90E8\u5F3A\u5EA6\u6863", onClick: () => onPatch(i, dkmAllLevels(false)) }, "\u53D6\u6D88\u5168\u9009")
|
|
3926
|
+
)
|
|
3927
|
+
)
|
|
3928
|
+
);
|
|
3929
|
+
}
|
|
3930
|
+
function ModelsView(props) {
|
|
3777
3931
|
const snap = useModels();
|
|
3778
3932
|
const data = snap.data;
|
|
3779
3933
|
const providers = data && Array.isArray(data.providers) ? data.providers : [];
|
|
3934
|
+
const params = props && props.params;
|
|
3780
3935
|
const [selId, setSelId] = import_react3.default.useState(null);
|
|
3781
3936
|
const [draft, setDraft] = import_react3.default.useState(null);
|
|
3782
3937
|
const [builtKey, setBuiltKey] = import_react3.default.useState(null);
|
|
@@ -3789,6 +3944,8 @@ function ModelsView() {
|
|
|
3789
3944
|
const [vpSaving, setVpSaving] = import_react3.default.useState(false);
|
|
3790
3945
|
const [vpMsg, setVpMsg] = import_react3.default.useState(null);
|
|
3791
3946
|
const [vpDirectExpanded, setVpDirectExpanded] = import_react3.default.useState(false);
|
|
3947
|
+
const [page, setPage] = import_react3.default.useState("settings");
|
|
3948
|
+
const [pageOpenCreate, setPageOpenCreate] = import_react3.default.useState(false);
|
|
3792
3949
|
import_react3.default.useEffect(() => {
|
|
3793
3950
|
modelsStore.load();
|
|
3794
3951
|
}, []);
|
|
@@ -3813,7 +3970,7 @@ function ModelsView() {
|
|
|
3813
3970
|
const saveVp = () => {
|
|
3814
3971
|
if (!vpDraft || vpSaving) return;
|
|
3815
3972
|
setVpSaving(true);
|
|
3816
|
-
fetch("
|
|
3973
|
+
fetch("dsh-dock/models", {
|
|
3817
3974
|
method: "POST",
|
|
3818
3975
|
headers: { "content-type": "application/json" },
|
|
3819
3976
|
body: JSON.stringify({ visionProxy: vpDraft, revisions: data && data.revisions || {} }),
|
|
@@ -3851,6 +4008,13 @@ function ModelsView() {
|
|
|
3851
4008
|
setSelId(id);
|
|
3852
4009
|
setMsg(null);
|
|
3853
4010
|
};
|
|
4011
|
+
import_react3.default.useEffect(() => {
|
|
4012
|
+
if (params && params.page === "providers") setPage("providers");
|
|
4013
|
+
if (params && params.openProviderForm) {
|
|
4014
|
+
setPage("providers");
|
|
4015
|
+
setPageOpenCreate(true);
|
|
4016
|
+
}
|
|
4017
|
+
}, []);
|
|
3854
4018
|
const save = () => {
|
|
3855
4019
|
if (!draft || !cur || !dirty || saving) return;
|
|
3856
4020
|
const models = draft.models.map((m) => ({
|
|
@@ -3870,7 +4034,7 @@ function ModelsView() {
|
|
|
3870
4034
|
payload.defaultEffort = draft.defaultEffort;
|
|
3871
4035
|
}
|
|
3872
4036
|
setSaving(true);
|
|
3873
|
-
fetch("
|
|
4037
|
+
fetch("dsh-dock/models", {
|
|
3874
4038
|
method: "POST",
|
|
3875
4039
|
headers: { "content-type": "application/json" },
|
|
3876
4040
|
body: JSON.stringify(payload),
|
|
@@ -3884,98 +4048,28 @@ function ModelsView() {
|
|
|
3884
4048
|
}
|
|
3885
4049
|
}).catch((e) => setMsg({ ok: false, text: e && e.message || String(e) })).then(() => setSaving(false));
|
|
3886
4050
|
};
|
|
3887
|
-
const modelRow = (m, i) =>
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
|
|
3907
|
-
)
|
|
3908
|
-
|
|
3909
|
-
"div",
|
|
3910
|
-
{ className: "dkm-checks" },
|
|
3911
|
-
import_react3.default.createElement("span", { className: "dkm-label" }, "\u8F93\u5165\u7C7B\u578B\uFF1A"),
|
|
3912
|
-
DKM_MODALITIES.map(([v, label]) => import_react3.default.createElement(
|
|
3913
|
-
"label",
|
|
3914
|
-
{
|
|
3915
|
-
key: v,
|
|
3916
|
-
className: "dkm-check",
|
|
3917
|
-
title: v === "image" ? "\u7531\u4F60\u58F0\u660E\u8BE5\u7AEF\u70B9\u652F\u6301\u56FE\u7247\uFF1A\u4FDD\u5B58\u540E\u539F\u56FE\u76F4\u53D1\uFF0C\u5E76\u53EF\u4F5C\u4E3A\u89C6\u89C9\u6A21\u578B\u5019\u9009\u3002\u7CFB\u7EDF\u4E0D\u4F1A\u66FF\u4F60\u731C\u6D4B\uFF1B\u7AEF\u70B9\u5B9E\u9645\u4E0D\u652F\u6301\u65F6\u53D6\u6D88\u52FE\u9009\u5373\u53EF\u6062\u590D\u8D70\u56FE\u7247\u7406\u89E3\u4EE3\u7406" : null
|
|
3918
|
-
},
|
|
3919
|
-
import_react3.default.createElement("input", {
|
|
3920
|
-
type: "checkbox",
|
|
3921
|
-
checked: m.input.indexOf(v) >= 0,
|
|
3922
|
-
onChange: () => {
|
|
3923
|
-
const next = toggleIn(m.input, v);
|
|
3924
|
-
patchModel(i, { input: next.length > 0 ? next : ["text"] });
|
|
3925
|
-
}
|
|
3926
|
-
}),
|
|
3927
|
-
label
|
|
3928
|
-
)),
|
|
3929
|
-
import_react3.default.createElement("span", { className: "dkm-label dkm-tag", title: "\u6807\u6CE8\u4EC5\u5728\u672C\u9762\u677F\u5C55\u793A\u4E0E\u6301\u4E45\u5316\uFF0C\u4E0D\u53C2\u4E0E\u8BF7\u6C42\u8DEF\u7531\uFF08\u5B98\u65B9 schema \u53EA\u63A5\u53D7\u6587\u672C/\u56FE\u7247\uFF09" }, "\u6807\u6CE8\uFF1A"),
|
|
3930
|
-
DKM_TAGS.map(([v, label]) => import_react3.default.createElement(
|
|
3931
|
-
"label",
|
|
3932
|
-
{ key: v, className: "dkm-check dkm-tag" },
|
|
3933
|
-
import_react3.default.createElement("input", { type: "checkbox", checked: m.tags.indexOf(v) >= 0, onChange: () => patchModel(i, { tags: toggleIn(m.tags, v) }) }),
|
|
3934
|
-
label
|
|
3935
|
-
)),
|
|
3936
|
-
import_react3.default.createElement("button", { type: "button", className: "dkm-mini", title: "\u4E00\u952E\u52FE\u9009\u5168\u90E8\u8F93\u5165\u7C7B\u578B\u4E0E\u6807\u6CE8", onClick: () => patchModel(i, allInputs(true)) }, "\u5168\u9009"),
|
|
3937
|
-
import_react3.default.createElement("button", { type: "button", className: "dkm-mini", title: "\u4E00\u952E\u53D6\u6D88\u5168\u90E8\u52FE\u9009\uFF08\u8F93\u5165\u7559\u7A7A = \u7EE7\u627F\u76EE\u5F55\u9ED8\u8BA4\uFF09", onClick: () => patchModel(i, allInputs(false)) }, "\u53D6\u6D88\u5168\u9009")
|
|
3938
|
-
),
|
|
3939
|
-
import_react3.default.createElement(
|
|
3940
|
-
"div",
|
|
3941
|
-
{ className: "dkm-efforts" },
|
|
3942
|
-
import_react3.default.createElement("span", { className: "dkm-label" }, "\u601D\u8003\u5F3A\u5EA6\uFF1A"),
|
|
3943
|
-
cur.kind === "deepseek" ? import_react3.default.createElement("span", { className: "dkm-sub" }, "\u968F Provider \u8BBE\u7F6E\uFF08Off/Low/High/Max\uFF0C\u5168\u6A21\u578B\u5171\u4EAB\uFF09") : import_react3.default.createElement(
|
|
3944
|
-
"span",
|
|
3945
|
-
null,
|
|
3946
|
-
import_react3.default.createElement(
|
|
3947
|
-
"select",
|
|
3948
|
-
{
|
|
3949
|
-
className: "dkm-select",
|
|
3950
|
-
value: m.effortsMode,
|
|
3951
|
-
onChange: (e) => patchModel(i, {
|
|
3952
|
-
effortsMode: e.target.value,
|
|
3953
|
-
effortLevels: e.target.value === "custom" && m.effortsMode !== "custom" ? { off: true, low: true, high: true } : m.effortLevels
|
|
3954
|
-
})
|
|
3955
|
-
},
|
|
3956
|
-
import_react3.default.createElement("option", { value: "inherit" }, "\u8DDF\u968F\u76EE\u5F55\u9ED8\u8BA4"),
|
|
3957
|
-
import_react3.default.createElement("option", { value: "off" }, "\u4E0D\u652F\u6301\u601D\u8003"),
|
|
3958
|
-
import_react3.default.createElement("option", { value: "custom" }, "\u81EA\u5B9A\u4E49\u6863\u4F4D")
|
|
3959
|
-
),
|
|
3960
|
-
m.effortsMode === "custom" ? DKM_PI_LEVELS.map((lv) => import_react3.default.createElement(
|
|
3961
|
-
"label",
|
|
3962
|
-
{ key: lv, className: "dkm-check" },
|
|
3963
|
-
import_react3.default.createElement("input", {
|
|
3964
|
-
type: "checkbox",
|
|
3965
|
-
checked: !!m.effortLevels[lv],
|
|
3966
|
-
onChange: () => {
|
|
3967
|
-
const nl = Object.assign({}, m.effortLevels);
|
|
3968
|
-
nl[lv] = !nl[lv];
|
|
3969
|
-
patchModel(i, { effortLevels: nl });
|
|
3970
|
-
}
|
|
3971
|
-
}),
|
|
3972
|
-
DKM_EFFORT_NAMES[lv] || lv
|
|
3973
|
-
)) : null,
|
|
3974
|
-
import_react3.default.createElement("button", { type: "button", className: "dkm-mini", title: "\u4E00\u952E\u52FE\u9009\u5168\u90E8\u5F3A\u5EA6\u6863\uFF08\u5207\u4E3A\u81EA\u5B9A\u4E49\uFF09", onClick: () => patchModel(i, allLevels(true)) }, "\u5168\u9009"),
|
|
3975
|
-
import_react3.default.createElement("button", { type: "button", className: "dkm-mini", title: "\u4E00\u952E\u53D6\u6D88\u5168\u90E8\u5F3A\u5EA6\u6863", onClick: () => patchModel(i, allLevels(false)) }, "\u53D6\u6D88\u5168\u9009")
|
|
3976
|
-
)
|
|
3977
|
-
)
|
|
3978
|
-
);
|
|
4051
|
+
const modelRow = (m, i) => ModelRow({
|
|
4052
|
+
m,
|
|
4053
|
+
i,
|
|
4054
|
+
kind: cur.kind,
|
|
4055
|
+
onPatch: (j, patch) => patchModel(j, patch),
|
|
4056
|
+
onDel: (j) => patchDraft({ models: draft.models.filter((_, k) => k !== j) })
|
|
4057
|
+
});
|
|
4058
|
+
if (page === "providers") {
|
|
4059
|
+
return import_react3.default.createElement(ProvidersPage, {
|
|
4060
|
+
data,
|
|
4061
|
+
providers,
|
|
4062
|
+
loading: snap.loading,
|
|
4063
|
+
error: snap.error,
|
|
4064
|
+
openCreate: pageOpenCreate,
|
|
4065
|
+
onCreateHandled: () => setPageOpenCreate(false),
|
|
4066
|
+
// 返回主页时顺手重读目录:子页面里增删改过的 Provider 立即反映到模型编辑器
|
|
4067
|
+
onBack: () => {
|
|
4068
|
+
setPage("settings");
|
|
4069
|
+
refreshModels();
|
|
4070
|
+
}
|
|
4071
|
+
});
|
|
4072
|
+
}
|
|
3979
4073
|
const body = [];
|
|
3980
4074
|
if (data) {
|
|
3981
4075
|
body.push(import_react3.default.createElement(
|
|
@@ -4115,6 +4209,44 @@ function ModelsView() {
|
|
|
4115
4209
|
)
|
|
4116
4210
|
));
|
|
4117
4211
|
}
|
|
4212
|
+
if (data) {
|
|
4213
|
+
const custom = providers.filter((p) => p.kind === "pi-ai");
|
|
4214
|
+
const missingKey = custom.filter((p) => p.apiKeyEnv && !p.apiKeyConfigured).length;
|
|
4215
|
+
body.push(import_react3.default.createElement(
|
|
4216
|
+
"div",
|
|
4217
|
+
{ key: "pf-entry", className: "dkp-card" },
|
|
4218
|
+
import_react3.default.createElement(
|
|
4219
|
+
"div",
|
|
4220
|
+
{ className: "dkp-rowhead" },
|
|
4221
|
+
import_react3.default.createElement(
|
|
4222
|
+
"span",
|
|
4223
|
+
{ className: "dkp-identity" },
|
|
4224
|
+
import_react3.default.createElement("span", { className: "dkp-name" }, "\u6A21\u578B\u63D0\u4F9B\u5546"),
|
|
4225
|
+
import_react3.default.createElement("span", { className: "dkp-tag" }, custom.length + " \u4E2A\u81EA\u5B9A\u4E49\u8DEF\u7531"),
|
|
4226
|
+
custom.length > 0 ? import_react3.default.createElement("span", {
|
|
4227
|
+
className: "dkp-dot " + (missingKey > 0 ? "warn" : "ok"),
|
|
4228
|
+
role: "img",
|
|
4229
|
+
title: missingKey > 0 ? "\u6709 " + missingKey + " \u4E2A Provider \u672A\u914D\u7F6E\u5BC6\u94A5" : "\u5BC6\u94A5\u5747\u5DF2\u914D\u7F6E",
|
|
4230
|
+
"aria-label": missingKey > 0 ? "\u6709 Provider \u672A\u914D\u7F6E\u5BC6\u94A5" : "\u5BC6\u94A5\u5747\u5DF2\u914D\u7F6E"
|
|
4231
|
+
}) : null
|
|
4232
|
+
),
|
|
4233
|
+
import_react3.default.createElement(
|
|
4234
|
+
"span",
|
|
4235
|
+
{ className: "dkp-actions" },
|
|
4236
|
+
import_react3.default.createElement("button", {
|
|
4237
|
+
type: "button",
|
|
4238
|
+
className: "dkp-btn ghost sm",
|
|
4239
|
+
onClick: () => setPage("providers")
|
|
4240
|
+
}, "\u7BA1\u7406")
|
|
4241
|
+
)
|
|
4242
|
+
),
|
|
4243
|
+
import_react3.default.createElement(
|
|
4244
|
+
"p",
|
|
4245
|
+
{ className: "dkp-hint" },
|
|
4246
|
+
"\u65B0\u589E / \u7F16\u8F91 / \u5220\u9664\u81EA\u5B9A\u4E49\u6A21\u578B Provider\uFF08OpenAI \u517C\u5BB9\u3001Anthropic \u7B49\uFF09\uFF0C\u5199\u5165\u5B98\u65B9\u914D\u7F6E\u5E76\u70ED\u751F\u6548\uFF1BAPI Key \u5B58\u672C\u673A\u51ED\u636E\u5E93\uFF08\u6587\u4EF6\u4EC5 root \u53EF\u8BFB\uFF09\u3002"
|
|
4247
|
+
)
|
|
4248
|
+
));
|
|
4249
|
+
}
|
|
4118
4250
|
if (data && providers.length === 0) {
|
|
4119
4251
|
body.push(import_react3.default.createElement("div", { key: "empty", className: "dkm-note" }, "\u6CA1\u6709\u53EF\u7F16\u8F91\u7684\u6A21\u578B Provider\uFF08Host \u4FA7\u5C1A\u672A\u914D\u7F6E\uFF09"));
|
|
4120
4252
|
}
|
|
@@ -4136,60 +4268,586 @@ function ModelsView() {
|
|
|
4136
4268
|
{ key: "prov", className: "dkm-prov" },
|
|
4137
4269
|
import_react3.default.createElement(
|
|
4138
4270
|
"div",
|
|
4139
|
-
{ className: "dkm-prov-head" },
|
|
4140
|
-
import_react3.default.createElement("span", { className: "dkm-name" }, cur.displayName),
|
|
4141
|
-
import_react3.default.createElement("span", { className: "dkm-badge" }, cur.kind === "deepseek" ? "\u5B98\u65B9 DeepSeek" : "\u81EA\u5B9A\u4E49\u8DEF\u7531"),
|
|
4142
|
-
import_react3.default.createElement("span", { className: "dkm-sub" }, [cur.api, cur.baseURL].filter(Boolean).join(" \xB7 "))
|
|
4143
|
-
),
|
|
4144
|
-
cur.kind === "deepseek" ? import_react3.default.createElement(
|
|
4145
|
-
"div",
|
|
4146
|
-
{ className: "dkm-controls" },
|
|
4147
|
-
import_react3.default.createElement("span", { className: "dkm-label" }, "\u601D\u8003\u6A21\u5F0F\uFF1A"),
|
|
4271
|
+
{ className: "dkm-prov-head" },
|
|
4272
|
+
import_react3.default.createElement("span", { className: "dkm-name" }, cur.displayName),
|
|
4273
|
+
import_react3.default.createElement("span", { className: "dkm-badge" }, cur.kind === "deepseek" ? "\u5B98\u65B9 DeepSeek" : "\u81EA\u5B9A\u4E49\u8DEF\u7531"),
|
|
4274
|
+
import_react3.default.createElement("span", { className: "dkm-sub" }, [cur.api, cur.baseURL].filter(Boolean).join(" \xB7 "))
|
|
4275
|
+
),
|
|
4276
|
+
cur.kind === "deepseek" ? import_react3.default.createElement(
|
|
4277
|
+
"div",
|
|
4278
|
+
{ className: "dkm-controls" },
|
|
4279
|
+
import_react3.default.createElement("span", { className: "dkm-label" }, "\u601D\u8003\u6A21\u5F0F\uFF1A"),
|
|
4280
|
+
import_react3.default.createElement(
|
|
4281
|
+
"select",
|
|
4282
|
+
{ className: "dkm-select", value: draft.thinking, onChange: (e) => patchDraft({ thinking: e.target.value }) },
|
|
4283
|
+
import_react3.default.createElement("option", { value: "enabled" }, "\u5F00\u542F"),
|
|
4284
|
+
import_react3.default.createElement("option", { value: "disabled" }, "\u5173\u95ED")
|
|
4285
|
+
),
|
|
4286
|
+
import_react3.default.createElement("span", { className: "dkm-label" }, "\u9ED8\u8BA4\u5F3A\u5EA6\uFF1A"),
|
|
4287
|
+
import_react3.default.createElement(
|
|
4288
|
+
"select",
|
|
4289
|
+
{ className: "dkm-select", value: draft.defaultEffort, onChange: (e) => patchDraft({ defaultEffort: e.target.value }) },
|
|
4290
|
+
DKM_DS_LEVELS.map((lv) => import_react3.default.createElement("option", { key: lv, value: lv }, DKM_EFFORT_NAMES[lv] || lv))
|
|
4291
|
+
)
|
|
4292
|
+
) : null,
|
|
4293
|
+
import_react3.default.createElement(
|
|
4294
|
+
"div",
|
|
4295
|
+
{ className: "dkm-toolbar" },
|
|
4296
|
+
import_react3.default.createElement("span", { className: "dkm-toolbar-label" }, "\u6279\u91CF\uFF08\u5168\u90E8\u6A21\u578B\uFF09\uFF1A"),
|
|
4297
|
+
import_react3.default.createElement("button", { type: "button", className: "dkm-mini", title: "\u5168\u90E8\u6A21\u578B\uFF1A\u52FE\u9009\u5168\u90E8\u8F93\u5165\u7C7B\u578B\u4E0E\u6807\u6CE8", onClick: () => bulkModels(() => allInputs(true)) }, "\u8F93\u5165\u5168\u9009"),
|
|
4298
|
+
import_react3.default.createElement("button", { type: "button", className: "dkm-mini", title: "\u5168\u90E8\u6A21\u578B\uFF1A\u53D6\u6D88\u5168\u90E8\u8F93\u5165\u52FE\u9009\uFF08\u7559\u7A7A = \u7EE7\u627F\u76EE\u5F55\u9ED8\u8BA4\uFF09", onClick: () => bulkModels(() => allInputs(false)) }, "\u8F93\u5165\u53D6\u6D88\u5168\u9009"),
|
|
4299
|
+
cur.kind !== "deepseek" ? import_react3.default.createElement("button", { type: "button", className: "dkm-mini", title: "\u5168\u90E8\u6A21\u578B\uFF1A\u52FE\u9009\u5168\u90E8\u5F3A\u5EA6\u6863\uFF08\u5207\u4E3A\u81EA\u5B9A\u4E49\uFF09", onClick: () => bulkModels(() => allLevels(true)) }, "\u5F3A\u5EA6\u5168\u9009") : null,
|
|
4300
|
+
cur.kind !== "deepseek" ? import_react3.default.createElement("button", { type: "button", className: "dkm-mini", title: "\u5168\u90E8\u6A21\u578B\uFF1A\u53D6\u6D88\u5168\u90E8\u5F3A\u5EA6\u6863", onClick: () => bulkModels(() => allLevels(false)) }, "\u5F3A\u5EA6\u53D6\u6D88\u5168\u9009") : null
|
|
4301
|
+
),
|
|
4302
|
+
import_react3.default.createElement(
|
|
4303
|
+
"div",
|
|
4304
|
+
{ style: { display: "flex", flexDirection: "column", gap: "8px" } },
|
|
4305
|
+
draft.models.map(modelRow),
|
|
4306
|
+
import_react3.default.createElement("button", {
|
|
4307
|
+
type: "button",
|
|
4308
|
+
className: "dkm-add",
|
|
4309
|
+
onClick: () => patchDraft({
|
|
4310
|
+
models: draft.models.concat([{ id: "", name: "", contextWindow: "", maxTokens: "", input: ["text"], tags: [], effortsMode: "inherit", effortLevels: {} }])
|
|
4311
|
+
})
|
|
4312
|
+
}, "+ \u6DFB\u52A0\u6A21\u578B")
|
|
4313
|
+
),
|
|
4314
|
+
import_react3.default.createElement(
|
|
4315
|
+
"div",
|
|
4316
|
+
{ className: "dkm-savebar" },
|
|
4317
|
+
import_react3.default.createElement("span", { className: "dkm-msg" }, dirty ? "\u6709\u672A\u4FDD\u5B58\u7684\u4FEE\u6539" : "\u65E0\u672A\u4FDD\u5B58\u4FEE\u6539"),
|
|
4318
|
+
import_react3.default.createElement("button", { type: "button", className: "dkm-save", disabled: !dirty || saving, onClick: save }, saving ? "\u4FDD\u5B58\u4E2D\u2026" : "\u4FDD\u5B58\u5199\u56DE\u5B98\u65B9\u914D\u7F6E"),
|
|
4319
|
+
import_react3.default.createElement("button", { type: "button", className: "dkb-refresh", disabled: saving || snap.loading, onClick: refreshModels }, snap.loading ? "\u5237\u65B0\u4E2D\u2026" : "\u91CD\u65B0\u62C9\u53D6"),
|
|
4320
|
+
msg ? import_react3.default.createElement("span", { className: "dkm-msg " + (msg.ok ? "ok" : "err") }, msg.text) : null
|
|
4321
|
+
)
|
|
4322
|
+
));
|
|
4323
|
+
}
|
|
4324
|
+
return import_react3.default.createElement("div", { className: "dkm-list" }, body);
|
|
4325
|
+
}
|
|
4326
|
+
function ProviderModelRow(props) {
|
|
4327
|
+
const m = props.m;
|
|
4328
|
+
const i = props.i;
|
|
4329
|
+
const check = (v, list, kind) => import_react3.default.createElement(
|
|
4330
|
+
"label",
|
|
4331
|
+
{ key: v[0], className: "dkp-check" },
|
|
4332
|
+
import_react3.default.createElement("input", {
|
|
4333
|
+
type: "checkbox",
|
|
4334
|
+
checked: list.indexOf(v[0]) >= 0,
|
|
4335
|
+
onChange: () => {
|
|
4336
|
+
const next = dkmToggleIn(list, v[0]);
|
|
4337
|
+
props.onPatch(i, kind === "input" ? { input: next.length > 0 ? next : ["text"] } : { tags: next });
|
|
4338
|
+
}
|
|
4339
|
+
}),
|
|
4340
|
+
v[1]
|
|
4341
|
+
);
|
|
4342
|
+
return import_react3.default.createElement(
|
|
4343
|
+
"div",
|
|
4344
|
+
{ className: "dkp-model-entry" },
|
|
4345
|
+
import_react3.default.createElement(
|
|
4346
|
+
"div",
|
|
4347
|
+
{ className: "dkp-model-row" },
|
|
4348
|
+
import_react3.default.createElement("input", { className: "dkp-input", placeholder: "\u6A21\u578B id\uFF08\u5FC5\u586B\uFF09", value: m.id, onChange: (e) => props.onPatch(i, { id: e.target.value }) }),
|
|
4349
|
+
import_react3.default.createElement("input", { className: "dkp-input", placeholder: "\u663E\u793A\u540D\u79F0\uFF08\u53EF\u9009\uFF09", value: m.name, onChange: (e) => props.onPatch(i, { name: e.target.value }) }),
|
|
4350
|
+
import_react3.default.createElement("input", { className: "dkp-input", placeholder: "\u4E0A\u4E0B\u6587\u7A97\u53E3", inputMode: "numeric", value: m.contextWindow, onChange: (e) => props.onPatch(i, { contextWindow: e.target.value }) }),
|
|
4351
|
+
import_react3.default.createElement("input", { className: "dkp-input", placeholder: "\u6700\u5927\u8F93\u51FA", inputMode: "numeric", value: m.maxTokens, onChange: (e) => props.onPatch(i, { maxTokens: e.target.value }) }),
|
|
4352
|
+
import_react3.default.createElement("button", { type: "button", className: "dkp-iconbtn danger", title: "\u5220\u9664\u8BE5\u6A21\u578B", "aria-label": "\u5220\u9664\u6A21\u578B", onClick: () => props.onDel(i) }, "\u2715")
|
|
4353
|
+
),
|
|
4354
|
+
import_react3.default.createElement(
|
|
4355
|
+
"div",
|
|
4356
|
+
{ className: "dkp-model-opts" },
|
|
4357
|
+
import_react3.default.createElement(
|
|
4358
|
+
"div",
|
|
4359
|
+
{ className: "dkp-checks" },
|
|
4360
|
+
import_react3.default.createElement("span", { className: "dkp-flabel" }, "\u8F93\u5165\u7C7B\u578B\uFF1A"),
|
|
4361
|
+
DKM_MODALITIES.map((v) => check(v, m.input, "input")),
|
|
4362
|
+
import_react3.default.createElement("span", { className: "dkp-flabel dkp-dim", title: "\u6807\u6CE8\u4EC5\u5728\u672C\u9762\u677F\u5C55\u793A\u4E0E\u6301\u4E45\u5316\uFF0C\u4E0D\u53C2\u4E0E\u8BF7\u6C42\u8DEF\u7531\uFF08\u5B98\u65B9 schema \u53EA\u63A5\u53D7\u6587\u672C/\u56FE\u7247\uFF09" }, "\u6807\u6CE8\uFF1A"),
|
|
4363
|
+
DKM_TAGS.map((v) => check(v, m.tags, "tags")),
|
|
4364
|
+
import_react3.default.createElement("button", { type: "button", className: "dkp-mini", title: "\u4E00\u952E\u52FE\u9009\u5168\u90E8\u8F93\u5165\u7C7B\u578B\u4E0E\u6807\u6CE8", onClick: () => props.onPatch(i, dkmAllInputs(true)) }, "\u5168\u9009"),
|
|
4365
|
+
import_react3.default.createElement("button", { type: "button", className: "dkp-mini", title: "\u4E00\u952E\u53D6\u6D88\u5168\u90E8\u52FE\u9009", onClick: () => props.onPatch(i, dkmAllInputs(false)) }, "\u53D6\u6D88\u5168\u9009")
|
|
4366
|
+
),
|
|
4367
|
+
import_react3.default.createElement(
|
|
4368
|
+
"div",
|
|
4369
|
+
{ className: "dkp-checks" },
|
|
4370
|
+
import_react3.default.createElement("span", { className: "dkp-flabel" }, "\u601D\u8003\u5F3A\u5EA6\uFF1A"),
|
|
4371
|
+
import_react3.default.createElement(
|
|
4372
|
+
"select",
|
|
4373
|
+
{
|
|
4374
|
+
className: "dkp-input dkp-select dkp-select-sm",
|
|
4375
|
+
value: m.effortsMode,
|
|
4376
|
+
onChange: (e) => props.onPatch(i, {
|
|
4377
|
+
effortsMode: e.target.value,
|
|
4378
|
+
effortLevels: e.target.value === "custom" && m.effortsMode !== "custom" ? { off: true, low: true, high: true } : m.effortLevels
|
|
4379
|
+
})
|
|
4380
|
+
},
|
|
4381
|
+
import_react3.default.createElement("option", { value: "inherit" }, "\u8DDF\u968F\u76EE\u5F55\u9ED8\u8BA4"),
|
|
4382
|
+
import_react3.default.createElement("option", { value: "off" }, "\u4E0D\u652F\u6301\u601D\u8003"),
|
|
4383
|
+
import_react3.default.createElement("option", { value: "custom" }, "\u81EA\u5B9A\u4E49\u6863\u4F4D")
|
|
4384
|
+
),
|
|
4385
|
+
m.effortsMode === "custom" ? DKM_PI_LEVELS.map((lv) => import_react3.default.createElement(
|
|
4386
|
+
"label",
|
|
4387
|
+
{ key: lv, className: "dkp-check" },
|
|
4388
|
+
import_react3.default.createElement("input", {
|
|
4389
|
+
type: "checkbox",
|
|
4390
|
+
checked: !!m.effortLevels[lv],
|
|
4391
|
+
onChange: () => {
|
|
4392
|
+
const nl = Object.assign({}, m.effortLevels);
|
|
4393
|
+
nl[lv] = !nl[lv];
|
|
4394
|
+
props.onPatch(i, { effortLevels: nl });
|
|
4395
|
+
}
|
|
4396
|
+
}),
|
|
4397
|
+
DKM_EFFORT_NAMES[lv] || lv
|
|
4398
|
+
)) : null,
|
|
4399
|
+
import_react3.default.createElement("button", { type: "button", className: "dkp-mini", title: "\u4E00\u952E\u52FE\u9009\u5168\u90E8\u5F3A\u5EA6\u6863\uFF08\u5207\u4E3A\u81EA\u5B9A\u4E49\uFF09", onClick: () => props.onPatch(i, dkmAllLevels(true)) }, "\u5168\u9009"),
|
|
4400
|
+
import_react3.default.createElement("button", { type: "button", className: "dkp-mini", title: "\u4E00\u952E\u53D6\u6D88\u5168\u90E8\u5F3A\u5EA6\u6863", onClick: () => props.onPatch(i, dkmAllLevels(false)) }, "\u53D6\u6D88\u5168\u9009")
|
|
4401
|
+
)
|
|
4402
|
+
)
|
|
4403
|
+
);
|
|
4404
|
+
}
|
|
4405
|
+
function ProvidersPage(props) {
|
|
4406
|
+
const data = props.data;
|
|
4407
|
+
const providers = props.providers || [];
|
|
4408
|
+
const piProviders = providers.filter((p) => p.kind === "pi-ai");
|
|
4409
|
+
const [pfMode, setPfMode] = import_react3.default.useState(null);
|
|
4410
|
+
const [pfDraft, setPfDraft] = import_react3.default.useState(null);
|
|
4411
|
+
const [pfDirty, setPfDirty] = import_react3.default.useState(false);
|
|
4412
|
+
const [pfSaving, setPfSaving] = import_react3.default.useState(false);
|
|
4413
|
+
const [pfMsg, setPfMsg] = import_react3.default.useState(null);
|
|
4414
|
+
const [pfDelArm, setPfDelArm] = import_react3.default.useState(null);
|
|
4415
|
+
const [pfFetching, setPfFetching] = import_react3.default.useState(false);
|
|
4416
|
+
const [pfFetchedList, setPfFetchedList] = import_react3.default.useState(null);
|
|
4417
|
+
const openPfCreate = () => {
|
|
4418
|
+
setPfMode("create");
|
|
4419
|
+
setPfDraft(emptyProviderForm());
|
|
4420
|
+
setPfDirty(false);
|
|
4421
|
+
setPfMsg(null);
|
|
4422
|
+
setPfDelArm(null);
|
|
4423
|
+
setPfFetchedList(null);
|
|
4424
|
+
};
|
|
4425
|
+
const openPfEdit = (p) => {
|
|
4426
|
+
setPfMode("edit");
|
|
4427
|
+
setPfDraft(providerFormFromProvider(p));
|
|
4428
|
+
setPfDirty(false);
|
|
4429
|
+
setPfMsg(null);
|
|
4430
|
+
setPfDelArm(null);
|
|
4431
|
+
setPfFetchedList(null);
|
|
4432
|
+
};
|
|
4433
|
+
const closePf = () => {
|
|
4434
|
+
setPfMode(null);
|
|
4435
|
+
setPfDraft(null);
|
|
4436
|
+
setPfDirty(false);
|
|
4437
|
+
setPfMsg(null);
|
|
4438
|
+
setPfDelArm(null);
|
|
4439
|
+
setPfFetchedList(null);
|
|
4440
|
+
};
|
|
4441
|
+
const patchPf = (patch) => {
|
|
4442
|
+
setPfDraft(Object.assign({}, pfDraft, patch));
|
|
4443
|
+
setPfDirty(true);
|
|
4444
|
+
setPfMsg(null);
|
|
4445
|
+
};
|
|
4446
|
+
const patchPfModel = (i, patch) => {
|
|
4447
|
+
const models = pfDraft.models.slice();
|
|
4448
|
+
models[i] = Object.assign({}, models[i], patch);
|
|
4449
|
+
patchPf({ models });
|
|
4450
|
+
};
|
|
4451
|
+
const delPfModel = (i) => patchPf({ models: pfDraft.models.filter((_, j) => j !== i) });
|
|
4452
|
+
const addPfModel = () => patchPf({ models: pfDraft.models.concat([emptyModelDraft()]) });
|
|
4453
|
+
const togglePfModel = (id, name, on) => {
|
|
4454
|
+
const base = pfDraft.models.filter((m) => String(m.id || "").trim());
|
|
4455
|
+
if (on) {
|
|
4456
|
+
if (base.some((m) => String(m.id).trim() === id)) return;
|
|
4457
|
+
base.push(Object.assign(emptyModelDraft(), { id, name: name || "", input: pfDraft.defaultInput.slice() }));
|
|
4458
|
+
} else {
|
|
4459
|
+
const i = base.findIndex((m) => String(m.id).trim() === id);
|
|
4460
|
+
if (i >= 0) base.splice(i, 1);
|
|
4461
|
+
}
|
|
4462
|
+
patchPf({ models: base });
|
|
4463
|
+
};
|
|
4464
|
+
const setAllPfModels = (on) => {
|
|
4465
|
+
const base = [];
|
|
4466
|
+
if (on && pfFetchedList) {
|
|
4467
|
+
for (const mm of pfFetchedList) {
|
|
4468
|
+
const id = String(mm && mm.id || "").trim();
|
|
4469
|
+
if (!id) continue;
|
|
4470
|
+
base.push(Object.assign(emptyModelDraft(), { id, name: mm && mm.name || "", input: pfDraft.defaultInput.slice() }));
|
|
4471
|
+
}
|
|
4472
|
+
}
|
|
4473
|
+
patchPf({ models: base });
|
|
4474
|
+
};
|
|
4475
|
+
const pfSelectedCount = () => pfDraft ? pfDraft.models.filter((m) => String(m.id || "").trim()).length : 0;
|
|
4476
|
+
const pfModelsPayload = () => pfDraft.models.map((m) => ({
|
|
4477
|
+
id: String(m.id || "").trim(),
|
|
4478
|
+
name: String(m.name || "").trim(),
|
|
4479
|
+
contextWindow: m.contextWindow === "" || m.contextWindow == null ? void 0 : Number(m.contextWindow),
|
|
4480
|
+
maxTokens: m.maxTokens === "" || m.maxTokens == null ? void 0 : Number(m.maxTokens),
|
|
4481
|
+
input: m.input,
|
|
4482
|
+
tags: m.tags,
|
|
4483
|
+
effortsMode: m.effortsMode,
|
|
4484
|
+
effortLevels: m.effortLevels,
|
|
4485
|
+
raw: m.raw
|
|
4486
|
+
}));
|
|
4487
|
+
const fetchPfModels = () => {
|
|
4488
|
+
if (!pfDraft || pfFetching) return;
|
|
4489
|
+
setPfFetching(true);
|
|
4490
|
+
setPfMsg(null);
|
|
4491
|
+
fetch("dsh-dock/models", {
|
|
4492
|
+
method: "POST",
|
|
4493
|
+
headers: { "content-type": "application/json" },
|
|
4494
|
+
body: JSON.stringify({
|
|
4495
|
+
action: "listModels",
|
|
4496
|
+
baseURL: pfDraft.baseURL,
|
|
4497
|
+
api: pfDraft.api,
|
|
4498
|
+
apiKeyEnv: pfDraft.apiKeyEnv,
|
|
4499
|
+
apiKey: pfDraft.apiKey
|
|
4500
|
+
}),
|
|
4501
|
+
signal: AbortSignal.timeout(3e4)
|
|
4502
|
+
}).then((res) => res.json().then((b) => ({ status: res.status, body: b })).catch(() => ({ status: res.status, body: {} }))).then((r) => {
|
|
4503
|
+
if (r.status === 200 && r.body && r.body.ok) {
|
|
4504
|
+
setPfFetchedList(Array.isArray(r.body.models) ? r.body.models : []);
|
|
4505
|
+
} else {
|
|
4506
|
+
setPfMsg({ ok: false, text: r.body && r.body.error || "HTTP " + r.status });
|
|
4507
|
+
}
|
|
4508
|
+
}).catch((e) => setPfMsg({ ok: false, text: e && e.message || String(e) })).then(() => setPfFetching(false));
|
|
4509
|
+
};
|
|
4510
|
+
const savePf = () => {
|
|
4511
|
+
if (!pfDraft || pfSaving) return;
|
|
4512
|
+
const route = pfDraft.route.trim();
|
|
4513
|
+
const baseURL = pfDraft.baseURL.trim();
|
|
4514
|
+
const apiKey = pfDraft.apiKey.trim();
|
|
4515
|
+
let apiKeyEnv = pfDraft.apiKeyEnv.trim();
|
|
4516
|
+
if (apiKey && !apiKeyEnv) {
|
|
4517
|
+
apiKeyEnv = dkmEnvFromRoute(route);
|
|
4518
|
+
setPfDraft(Object.assign({}, pfDraft, { apiKeyEnv }));
|
|
4519
|
+
}
|
|
4520
|
+
const models = pfModelsPayload();
|
|
4521
|
+
if (!route) {
|
|
4522
|
+
setPfMsg({ ok: false, text: "\u8DEF\u7531 key \u4E0D\u80FD\u4E3A\u7A7A\uFF08\u5982 modelscope\uFF09" });
|
|
4523
|
+
return;
|
|
4524
|
+
}
|
|
4525
|
+
if (!DKM_ROUTE_KEY_RE.test(route)) {
|
|
4526
|
+
setPfMsg({ ok: false, text: "\u8DEF\u7531 key \u975E\u6CD5\uFF1A\u53EA\u80FD\u542B\u5B57\u6BCD\u3001\u6570\u5B57\u4E0E . _ -\uFF0C\u4E14\u4EE5\u5B57\u6BCD/\u6570\u5B57\u5F00\u5934" });
|
|
4527
|
+
return;
|
|
4528
|
+
}
|
|
4529
|
+
if (!/^https?:\/\//i.test(baseURL)) {
|
|
4530
|
+
setPfMsg({ ok: false, text: "baseURL \u987B\u4EE5 http:// \u6216 https:// \u5F00\u5934" });
|
|
4531
|
+
return;
|
|
4532
|
+
}
|
|
4533
|
+
const ids = models.map((m) => m.id);
|
|
4534
|
+
if (ids.length === 0 || ids.some((x) => !x)) {
|
|
4535
|
+
setPfMsg({ ok: false, text: "\u6BCF\u4E2A\u6A21\u578B\u90FD\u8981\u6709 id\uFF08\u53EF\u70B9\u300C\u83B7\u53D6\u6A21\u578B\u5217\u8868\u300D\u81EA\u52A8\u62C9\u53D6\uFF09" });
|
|
4536
|
+
return;
|
|
4537
|
+
}
|
|
4538
|
+
if (new Set(ids).size !== ids.length) {
|
|
4539
|
+
setPfMsg({ ok: false, text: "\u6A21\u578B id \u6709\u91CD\u590D" });
|
|
4540
|
+
return;
|
|
4541
|
+
}
|
|
4542
|
+
const profile = Object.assign({}, pfDraft.extra || {});
|
|
4543
|
+
const dn = pfDraft.displayName.trim();
|
|
4544
|
+
if (dn) profile.displayName = dn;
|
|
4545
|
+
else delete profile.displayName;
|
|
4546
|
+
profile.api = pfDraft.api;
|
|
4547
|
+
profile.baseURL = baseURL;
|
|
4548
|
+
if (apiKeyEnv) profile.apiKeyEnv = apiKeyEnv;
|
|
4549
|
+
else delete profile.apiKeyEnv;
|
|
4550
|
+
profile.defaultInput = pfDraft.defaultInput;
|
|
4551
|
+
profile.models = models;
|
|
4552
|
+
const payload = {
|
|
4553
|
+
action: pfMode === "create" ? "create" : "update",
|
|
4554
|
+
route,
|
|
4555
|
+
profile,
|
|
4556
|
+
revisions: data && data.revisions || {}
|
|
4557
|
+
};
|
|
4558
|
+
if (apiKey) payload.apiKey = apiKey;
|
|
4559
|
+
setPfSaving(true);
|
|
4560
|
+
setPfMsg(null);
|
|
4561
|
+
fetch("dsh-dock/models", {
|
|
4562
|
+
method: "POST",
|
|
4563
|
+
headers: { "content-type": "application/json" },
|
|
4564
|
+
body: JSON.stringify(payload),
|
|
4565
|
+
signal: AbortSignal.timeout(3e4)
|
|
4566
|
+
}).then((res) => res.json().then((b) => ({ status: res.status, body: b })).catch(() => ({ status: res.status, body: {} }))).then((r) => {
|
|
4567
|
+
if (r.status === 200 && r.body && r.body.ok) {
|
|
4568
|
+
setPfMsg({ ok: true, text: "Provider\u300C" + route + "\u300D\u5DF2" + (pfMode === "create" ? "\u65B0\u589E" : "\u66F4\u65B0") + "\uFF1B\u4F1A\u8BDD\u6A21\u578B\u9009\u62E9\u5668\u5373\u65F6\u53EF\u9009" });
|
|
4569
|
+
setPfMode(null);
|
|
4570
|
+
setPfDraft(null);
|
|
4571
|
+
setPfDirty(false);
|
|
4572
|
+
modelsStore.load();
|
|
4573
|
+
} else {
|
|
4574
|
+
setPfMsg({ ok: false, text: r.body && r.body.error || "HTTP " + r.status });
|
|
4575
|
+
}
|
|
4576
|
+
}).catch((e) => setPfMsg({ ok: false, text: e && e.message || String(e) })).then(() => setPfSaving(false));
|
|
4577
|
+
};
|
|
4578
|
+
const deletePf = (p) => {
|
|
4579
|
+
const route = p.route || p.id;
|
|
4580
|
+
if (pfDelArm !== route) {
|
|
4581
|
+
setPfDelArm(route);
|
|
4582
|
+
setPfMsg(null);
|
|
4583
|
+
return;
|
|
4584
|
+
}
|
|
4585
|
+
setPfDelArm(null);
|
|
4586
|
+
setPfSaving(true);
|
|
4587
|
+
setPfMsg(null);
|
|
4588
|
+
fetch("dsh-dock/models", {
|
|
4589
|
+
method: "POST",
|
|
4590
|
+
headers: { "content-type": "application/json" },
|
|
4591
|
+
body: JSON.stringify({ action: "delete", route, revisions: data && data.revisions || {} }),
|
|
4592
|
+
signal: AbortSignal.timeout(2e4)
|
|
4593
|
+
}).then((res) => res.json().then((b) => ({ status: res.status, body: b })).catch(() => ({ status: res.status, body: {} }))).then((r) => {
|
|
4594
|
+
if (r.status === 200 && r.body && r.body.ok) {
|
|
4595
|
+
setPfMsg({ ok: true, text: "Provider\u300C" + route + "\u300D\u5DF2\u5220\u9664" });
|
|
4596
|
+
if (pfMode === "edit" && pfDraft && pfDraft.route === route) {
|
|
4597
|
+
setPfMode(null);
|
|
4598
|
+
setPfDraft(null);
|
|
4599
|
+
}
|
|
4600
|
+
modelsStore.load();
|
|
4601
|
+
} else {
|
|
4602
|
+
setPfMsg({ ok: false, text: r.body && r.body.error || "HTTP " + r.status });
|
|
4603
|
+
}
|
|
4604
|
+
}).catch((e) => setPfMsg({ ok: false, text: e && e.message || String(e) })).then(() => setPfSaving(false));
|
|
4605
|
+
};
|
|
4606
|
+
const openedRef = import_react3.default.useRef(false);
|
|
4607
|
+
import_react3.default.useEffect(() => {
|
|
4608
|
+
if (props.openCreate && !openedRef.current) {
|
|
4609
|
+
openedRef.current = true;
|
|
4610
|
+
openPfCreate();
|
|
4611
|
+
if (typeof props.onCreateHandled === "function") props.onCreateHandled();
|
|
4612
|
+
}
|
|
4613
|
+
}, []);
|
|
4614
|
+
const input = (p) => import_react3.default.createElement("input", Object.assign({ className: "dkp-input" }, p));
|
|
4615
|
+
const field = (label, node, hint) => import_react3.default.createElement(
|
|
4616
|
+
"div",
|
|
4617
|
+
{ className: "dkp-field", key: label },
|
|
4618
|
+
import_react3.default.createElement("label", { className: "dkp-flabel" }, label),
|
|
4619
|
+
node,
|
|
4620
|
+
hint ? import_react3.default.createElement("p", { className: "dkp-hint" }, hint) : null
|
|
4621
|
+
);
|
|
4622
|
+
const editor = !pfDraft ? null : import_react3.default.createElement(
|
|
4623
|
+
"div",
|
|
4624
|
+
{ className: "dkp-editor" },
|
|
4625
|
+
import_react3.default.createElement(
|
|
4626
|
+
"div",
|
|
4627
|
+
{ className: "dkp-editor-head" },
|
|
4628
|
+
import_react3.default.createElement("span", { className: "dkp-editor-title" }, pfMode === "create" ? "\u65B0\u589E Provider" : "\u7F16\u8F91 Provider"),
|
|
4629
|
+
pfMode === "edit" ? import_react3.default.createElement("span", { className: "dkp-editor-route" }, pfDraft.route) : null
|
|
4630
|
+
),
|
|
4631
|
+
field("\u8DEF\u7531 key", input({
|
|
4632
|
+
value: pfDraft.route,
|
|
4633
|
+
disabled: pfMode === "edit",
|
|
4634
|
+
placeholder: "acme-gateway",
|
|
4635
|
+
onChange: (e) => patchPf({ route: e.target.value })
|
|
4636
|
+
}), pfMode === "edit" ? "\u8DEF\u7531 key \u662F\u914D\u7F6E\u952E\uFF0C\u4FDD\u5B58\u540E\u4E0D\u5EFA\u8BAE\u4FEE\u6539\u3002" : "\u552F\u4E00\u6807\u8BC6\uFF1A\u53EA\u80FD\u542B\u5B57\u6BCD\u3001\u6570\u5B57\u4E0E . _ -\uFF0C\u4E14\u4EE5\u5B57\u6BCD/\u6570\u5B57\u5F00\u5934\u3002"),
|
|
4637
|
+
field("\u663E\u793A\u540D\u79F0", input({
|
|
4638
|
+
value: pfDraft.displayName,
|
|
4639
|
+
placeholder: pfDraft.route || "\u5982 \u9B54\u642D ModelScope",
|
|
4640
|
+
onChange: (e) => patchPf({ displayName: e.target.value })
|
|
4641
|
+
})),
|
|
4642
|
+
field("baseURL", input({
|
|
4643
|
+
value: pfDraft.baseURL,
|
|
4644
|
+
placeholder: pfDraft.api === "anthropic-messages" ? "https://gateway.example" : "https://gateway.example/v1",
|
|
4645
|
+
onChange: (e) => patchPf({ baseURL: e.target.value })
|
|
4646
|
+
}), "OpenAI \u517C\u5BB9\u7AEF\u70B9\u901A\u5E38\u4EE5 /v1 \u7ED3\u5C3E\uFF1BAnthropic Messages \u7531 SDK \u81EA\u884C\u8FFD\u52A0 /v1/messages\u3002"),
|
|
4647
|
+
field("API \u534F\u8BAE", import_react3.default.createElement(
|
|
4648
|
+
"select",
|
|
4649
|
+
{
|
|
4650
|
+
className: "dkp-input dkp-select",
|
|
4651
|
+
value: pfDraft.api,
|
|
4652
|
+
onChange: (e) => patchPf({ api: e.target.value })
|
|
4653
|
+
},
|
|
4654
|
+
DKM_APIS.map(([v, label]) => import_react3.default.createElement("option", { key: v, value: v }, label))
|
|
4655
|
+
)),
|
|
4656
|
+
field("API Key", import_react3.default.createElement("input", {
|
|
4657
|
+
className: "dkp-input",
|
|
4658
|
+
type: "password",
|
|
4659
|
+
autoComplete: "new-password",
|
|
4660
|
+
placeholder: pfMode === "edit" ? "\u7559\u7A7A = \u4E0D\u6539\u52A8\u5DF2\u5B58\u5BC6\u94A5" : "sk-\u2026\uFF08\u4EC5\u672C\u6B21\u5199\u5165\u672C\u673A\u51ED\u636E\u5E93\uFF0C\u4E0D\u56DE\u663E\uFF09",
|
|
4661
|
+
value: pfDraft.apiKey,
|
|
4662
|
+
onChange: (e) => patchPf({ apiKey: e.target.value })
|
|
4663
|
+
})),
|
|
4664
|
+
import_react3.default.createElement(
|
|
4665
|
+
"details",
|
|
4666
|
+
{ className: "dkp-customized" },
|
|
4667
|
+
import_react3.default.createElement("summary", { className: "dkp-summary" }, "\u81EA\u5B9A\u4E49\u8BBE\u7F6E"),
|
|
4668
|
+
import_react3.default.createElement(
|
|
4669
|
+
"div",
|
|
4670
|
+
{ className: "dkp-custombody" },
|
|
4671
|
+
field("apiKeyEnv", input({
|
|
4672
|
+
value: pfDraft.apiKeyEnv,
|
|
4673
|
+
placeholder: "\u7559\u7A7A = \u6309\u8DEF\u7531 key \u81EA\u52A8\u751F\u6210\uFF08" + (dkmEnvFromRoute(pfDraft.route) || "ROUTE_API_KEY") + "\uFF09",
|
|
4674
|
+
onChange: (e) => patchPf({ apiKeyEnv: e.target.value })
|
|
4675
|
+
}), "\u51ED\u636E\u5E93\u6761\u76EE\u540D\uFF1B\u7559\u7A7A\u65F6\u6309\u8DEF\u7531 key \u63A8\u5BFC\uFF0C\u4E00\u822C\u65E0\u9700\u586B\u5199\u3002"),
|
|
4676
|
+
import_react3.default.createElement(
|
|
4677
|
+
"div",
|
|
4678
|
+
{ className: "dkp-field" },
|
|
4679
|
+
import_react3.default.createElement("span", { className: "dkp-flabel" }, "\u9ED8\u8BA4\u8F93\u5165\u7C7B\u578B"),
|
|
4680
|
+
import_react3.default.createElement(
|
|
4681
|
+
"div",
|
|
4682
|
+
{ className: "dkp-checks" },
|
|
4683
|
+
DKM_MODALITIES.map(([v, label]) => import_react3.default.createElement(
|
|
4684
|
+
"label",
|
|
4685
|
+
{ key: v, className: "dkp-check" },
|
|
4686
|
+
import_react3.default.createElement("input", {
|
|
4687
|
+
type: "checkbox",
|
|
4688
|
+
checked: pfDraft.defaultInput.indexOf(v) >= 0,
|
|
4689
|
+
onChange: () => {
|
|
4690
|
+
const next = dkmToggleIn(pfDraft.defaultInput, v);
|
|
4691
|
+
patchPf({ defaultInput: next.length > 0 ? next : ["text"] });
|
|
4692
|
+
}
|
|
4693
|
+
}),
|
|
4694
|
+
label
|
|
4695
|
+
)),
|
|
4696
|
+
import_react3.default.createElement("span", { className: "dkp-hint" }, "\u6A21\u578B\u672A\u5355\u72EC\u58F0\u660E\u8F93\u5165\u7C7B\u578B\u65F6\u7EE7\u627F\u8FD9\u91CC\u3002")
|
|
4697
|
+
)
|
|
4698
|
+
)
|
|
4699
|
+
)
|
|
4700
|
+
),
|
|
4701
|
+
import_react3.default.createElement(
|
|
4702
|
+
"section",
|
|
4703
|
+
{ className: "dkp-catalog", "aria-label": "\u6A21\u578B" },
|
|
4704
|
+
import_react3.default.createElement(
|
|
4705
|
+
"div",
|
|
4706
|
+
{ className: "dkp-catalog-head" },
|
|
4148
4707
|
import_react3.default.createElement(
|
|
4149
|
-
"
|
|
4150
|
-
{ className: "
|
|
4151
|
-
import_react3.default.createElement("
|
|
4152
|
-
import_react3.default.createElement(
|
|
4708
|
+
"div",
|
|
4709
|
+
{ className: "dkp-catalog-titlewrap" },
|
|
4710
|
+
import_react3.default.createElement("span", { className: "dkp-catalog-title" }, "\u6A21\u578B"),
|
|
4711
|
+
import_react3.default.createElement(
|
|
4712
|
+
"span",
|
|
4713
|
+
{ className: "dkp-catalog-meta" },
|
|
4714
|
+
"\u5DF2\u9009 " + pfSelectedCount() + " \u4E2A" + (pfFetchedList ? " / \u4E0A\u6E38\u5171 " + pfFetchedList.length + " \u4E2A" : "")
|
|
4715
|
+
)
|
|
4153
4716
|
),
|
|
4154
|
-
import_react3.default.createElement("span", { className: "dkm-label" }, "\u9ED8\u8BA4\u5F3A\u5EA6\uFF1A"),
|
|
4155
4717
|
import_react3.default.createElement(
|
|
4156
|
-
"
|
|
4157
|
-
{ className: "
|
|
4158
|
-
|
|
4718
|
+
"div",
|
|
4719
|
+
{ className: "dkp-actions" },
|
|
4720
|
+
import_react3.default.createElement("button", {
|
|
4721
|
+
type: "button",
|
|
4722
|
+
className: "dkp-btn ghost sm",
|
|
4723
|
+
disabled: pfFetching || !pfDraft.baseURL,
|
|
4724
|
+
title: "\u8C03\u7528 baseURL/models \u62C9\u53D6\u8BE5\u7AEF\u70B9\u53EF\u7528\u6A21\u578B\uFF0C\u52FE\u9009\u540E\u52A0\u5165\u4E0B\u65B9\u5217\u8868",
|
|
4725
|
+
onClick: fetchPfModels
|
|
4726
|
+
}, pfFetching ? "\u62C9\u53D6\u4E2D\u2026" : "\u83B7\u53D6\u6A21\u578B\u5217\u8868"),
|
|
4727
|
+
pfFetchedList && pfFetchedList.length > 0 ? import_react3.default.createElement("button", { type: "button", className: "dkp-btn ghost sm", title: "\u52FE\u9009\u4E0A\u6E38\u8FD4\u56DE\u7684\u5168\u90E8\u6A21\u578B", onClick: () => setAllPfModels(true) }, "\u5168\u9009") : null,
|
|
4728
|
+
pfFetchedList && pfFetchedList.length > 0 ? import_react3.default.createElement("button", { type: "button", className: "dkp-btn ghost sm", title: "\u6E05\u7A7A\u5DF2\u52FE\u9009\u7684\u6A21\u578B", onClick: () => setAllPfModels(false) }, "\u6E05\u7A7A") : null
|
|
4159
4729
|
)
|
|
4160
|
-
) : null,
|
|
4161
|
-
import_react3.default.createElement(
|
|
4162
|
-
"div",
|
|
4163
|
-
{ className: "dkm-toolbar" },
|
|
4164
|
-
import_react3.default.createElement("span", { className: "dkm-toolbar-label" }, "\u6279\u91CF\uFF08\u5168\u90E8\u6A21\u578B\uFF09\uFF1A"),
|
|
4165
|
-
import_react3.default.createElement("button", { type: "button", className: "dkm-mini", title: "\u5168\u90E8\u6A21\u578B\uFF1A\u52FE\u9009\u5168\u90E8\u8F93\u5165\u7C7B\u578B\u4E0E\u6807\u6CE8", onClick: () => bulkModels(() => allInputs(true)) }, "\u8F93\u5165\u5168\u9009"),
|
|
4166
|
-
import_react3.default.createElement("button", { type: "button", className: "dkm-mini", title: "\u5168\u90E8\u6A21\u578B\uFF1A\u53D6\u6D88\u5168\u90E8\u8F93\u5165\u52FE\u9009\uFF08\u7559\u7A7A = \u7EE7\u627F\u76EE\u5F55\u9ED8\u8BA4\uFF09", onClick: () => bulkModels(() => allInputs(false)) }, "\u8F93\u5165\u53D6\u6D88\u5168\u9009"),
|
|
4167
|
-
cur.kind !== "deepseek" ? import_react3.default.createElement("button", { type: "button", className: "dkm-mini", title: "\u5168\u90E8\u6A21\u578B\uFF1A\u52FE\u9009\u5168\u90E8\u5F3A\u5EA6\u6863\uFF08\u5207\u4E3A\u81EA\u5B9A\u4E49\uFF09", onClick: () => bulkModels(() => allLevels(true)) }, "\u5F3A\u5EA6\u5168\u9009") : null,
|
|
4168
|
-
cur.kind !== "deepseek" ? import_react3.default.createElement("button", { type: "button", className: "dkm-mini", title: "\u5168\u90E8\u6A21\u578B\uFF1A\u53D6\u6D88\u5168\u90E8\u5F3A\u5EA6\u6863", onClick: () => bulkModels(() => allLevels(false)) }, "\u5F3A\u5EA6\u53D6\u6D88\u5168\u9009") : null
|
|
4169
4730
|
),
|
|
4170
|
-
import_react3.default.createElement(
|
|
4731
|
+
pfFetchedList ? import_react3.default.createElement(
|
|
4171
4732
|
"div",
|
|
4172
|
-
{
|
|
4173
|
-
|
|
4174
|
-
|
|
4175
|
-
|
|
4176
|
-
|
|
4177
|
-
|
|
4178
|
-
|
|
4179
|
-
|
|
4180
|
-
|
|
4733
|
+
{ className: "dkp-picker" },
|
|
4734
|
+
pfFetchedList.length === 0 ? import_react3.default.createElement("div", { className: "dkp-hint" }, "\u4E0A\u6E38\u6CA1\u6709\u8FD4\u56DE\u4EFB\u4F55\u6A21\u578B") : pfFetchedList.map((mm) => {
|
|
4735
|
+
const id = String(mm && mm.id || "").trim();
|
|
4736
|
+
if (!id) return null;
|
|
4737
|
+
const checked = pfDraft.models.some((m) => String(m.id || "").trim() === id);
|
|
4738
|
+
return import_react3.default.createElement(
|
|
4739
|
+
"label",
|
|
4740
|
+
{ key: id },
|
|
4741
|
+
import_react3.default.createElement("input", {
|
|
4742
|
+
type: "checkbox",
|
|
4743
|
+
checked,
|
|
4744
|
+
onChange: () => togglePfModel(id, mm && mm.name || "", !checked)
|
|
4745
|
+
}),
|
|
4746
|
+
import_react3.default.createElement("span", { className: "dkp-picker-id" }, id),
|
|
4747
|
+
mm && mm.name ? import_react3.default.createElement("span", { className: "dkp-picker-name" }, mm.name) : null
|
|
4748
|
+
);
|
|
4749
|
+
})
|
|
4750
|
+
) : null,
|
|
4751
|
+
pfDraft.models.length === 0 ? import_react3.default.createElement("div", { className: "dkp-empty" }, "\u8FD8\u6CA1\u6709\u6A21\u578B\u2014\u2014\u70B9\u300C\u83B7\u53D6\u6A21\u578B\u5217\u8868\u300D\u52FE\u9009\u4E0A\u6E38\u6A21\u578B\uFF0C\u6216\u300C\u6DFB\u52A0\u6A21\u578B\u300D\u624B\u52A8\u586B\u5199\u3002") : import_react3.default.createElement(
|
|
4752
|
+
"div",
|
|
4753
|
+
{ className: "dkp-model-list" },
|
|
4754
|
+
pfDraft.models.map((m, i) => import_react3.default.createElement(ProviderModelRow, { key: i, m, i, onPatch: patchPfModel, onDel: delPfModel }))
|
|
4181
4755
|
),
|
|
4756
|
+
import_react3.default.createElement("button", { type: "button", className: "dkp-addmodel", onClick: addPfModel }, "\uFF0B \u6DFB\u52A0\u6A21\u578B")
|
|
4757
|
+
),
|
|
4758
|
+
pfMsg && !pfMsg.ok ? import_react3.default.createElement("p", { className: "dkp-error" }, pfMsg.text) : null,
|
|
4759
|
+
import_react3.default.createElement(
|
|
4760
|
+
"div",
|
|
4761
|
+
{ className: "dkp-editor-actions" },
|
|
4762
|
+
import_react3.default.createElement("span", { className: "dkp-hint" }, pfDirty ? "\u6709\u672A\u4FDD\u5B58\u7684\u4FEE\u6539" : ""),
|
|
4763
|
+
import_react3.default.createElement("button", { type: "button", className: "dkp-btn ghost", onClick: closePf }, "\u53D6\u6D88"),
|
|
4182
4764
|
import_react3.default.createElement(
|
|
4183
|
-
"
|
|
4184
|
-
{ className: "
|
|
4185
|
-
|
|
4186
|
-
import_react3.default.createElement("button", { type: "button", className: "dkm-save", disabled: !dirty || saving, onClick: save }, saving ? "\u4FDD\u5B58\u4E2D\u2026" : "\u4FDD\u5B58\u5199\u56DE\u5B98\u65B9\u914D\u7F6E"),
|
|
4187
|
-
import_react3.default.createElement("button", { type: "button", className: "dkb-refresh", disabled: saving || snap.loading, onClick: refreshModels }, snap.loading ? "\u5237\u65B0\u4E2D\u2026" : "\u91CD\u65B0\u62C9\u53D6"),
|
|
4188
|
-
msg ? import_react3.default.createElement("span", { className: "dkm-msg " + (msg.ok ? "ok" : "err") }, msg.text) : null
|
|
4765
|
+
"button",
|
|
4766
|
+
{ type: "button", className: "dkp-btn primary", disabled: pfSaving, onClick: savePf },
|
|
4767
|
+
pfSaving ? "\u4FDD\u5B58\u4E2D\u2026" : pfMode === "create" ? "\u65B0\u589E Provider" : "\u4FDD\u5B58\u4FEE\u6539"
|
|
4189
4768
|
)
|
|
4769
|
+
)
|
|
4770
|
+
);
|
|
4771
|
+
const body = [
|
|
4772
|
+
import_react3.default.createElement("button", { key: "back", type: "button", className: "dkp-back", onClick: props.onBack }, "\u2190 \u6A21\u578B\u8BBE\u7F6E"),
|
|
4773
|
+
import_react3.default.createElement("h2", { key: "title", className: "dkp-title" }, "\u6A21\u578B\u63D0\u4F9B\u5546"),
|
|
4774
|
+
import_react3.default.createElement(
|
|
4775
|
+
"p",
|
|
4776
|
+
{ key: "intro", className: "dkp-intro" },
|
|
4777
|
+
"\u65B0\u589E / \u7F16\u8F91 / \u5220\u9664\u81EA\u5B9A\u4E49\u6A21\u578B Provider\uFF08OpenAI \u517C\u5BB9\u3001Anthropic \u7B49\uFF09\uFF0C\u5199\u5165\u5B98\u65B9\u914D\u7F6E\u5E76\u70ED\u751F\u6548\uFF1BAPI Key \u5B58\u672C\u673A\u51ED\u636E\u5E93\uFF08\u6587\u4EF6\u4EC5 root \u53EF\u8BFB\uFF09\u3002\u5185\u7F6E DeepSeek \u5B98\u65B9 Provider \u5728\u672C\u9875\u53EA\u8BFB\uFF0C\u5176\u6A21\u578B\u76EE\u5F55\u8BF7\u56DE\u300C\u6A21\u578B\u8BBE\u7F6E\u300D\u7F16\u8F91\u3002"
|
|
4778
|
+
)
|
|
4779
|
+
];
|
|
4780
|
+
if (props.error) {
|
|
4781
|
+
body.push(import_react3.default.createElement("p", { key: "err", className: "dkp-error" }, "\u6A21\u578B\u76EE\u5F55\u62C9\u53D6\u5931\u8D25\uFF1A" + props.error));
|
|
4782
|
+
}
|
|
4783
|
+
if (pfMsg && !pfDraft) {
|
|
4784
|
+
body.push(import_react3.default.createElement("p", { key: "msg", className: "dkp-msg " + (pfMsg.ok ? "ok" : "err"), role: "status" }, pfMsg.text));
|
|
4785
|
+
}
|
|
4786
|
+
if (!data) {
|
|
4787
|
+
body.push(import_react3.default.createElement("p", { key: "loading", className: "dkp-hint" }, props.loading ? "\u6B63\u5728\u62C9\u53D6\u6A21\u578B\u76EE\u5F55\u2026" : "\u7B49\u5F85\u62C9\u53D6\u6A21\u578B\u76EE\u5F55"));
|
|
4788
|
+
} else if (piProviders.length === 0) {
|
|
4789
|
+
body.push(import_react3.default.createElement("div", { key: "empty", className: "dkp-empty" }, "\u8FD8\u6CA1\u6709\u81EA\u5B9A\u4E49 Provider\u2014\u2014\u70B9\u4E0B\u65B9\u300C\u65B0\u589E Provider\u300D\u6DFB\u52A0\u3002"));
|
|
4790
|
+
} else {
|
|
4791
|
+
body.push(import_react3.default.createElement(
|
|
4792
|
+
"ul",
|
|
4793
|
+
{ key: "rows", className: "dkp-rows" },
|
|
4794
|
+
piProviders.map((p) => {
|
|
4795
|
+
const route = p.route || p.id;
|
|
4796
|
+
const editing = pfMode === "edit" && !!pfDraft && pfDraft.route === route;
|
|
4797
|
+
const keyMissing = !!(p.apiKeyEnv && !p.apiKeyConfigured);
|
|
4798
|
+
return import_react3.default.createElement(
|
|
4799
|
+
"li",
|
|
4800
|
+
{ key: p.id, className: "dkp-card" },
|
|
4801
|
+
import_react3.default.createElement(
|
|
4802
|
+
"div",
|
|
4803
|
+
{ className: "dkp-rowhead" },
|
|
4804
|
+
import_react3.default.createElement(
|
|
4805
|
+
"span",
|
|
4806
|
+
{ className: "dkp-identity" },
|
|
4807
|
+
import_react3.default.createElement("span", { className: "dkp-name" }, p.displayName || route),
|
|
4808
|
+
import_react3.default.createElement("span", { className: "dkp-tag" }, route),
|
|
4809
|
+
import_react3.default.createElement("span", { className: "dkp-tag" }, (p.models ? p.models.length : 0) + " \u6A21\u578B"),
|
|
4810
|
+
import_react3.default.createElement("span", {
|
|
4811
|
+
className: "dkp-dot " + (keyMissing ? "missing" : "ok"),
|
|
4812
|
+
role: "img",
|
|
4813
|
+
title: p.apiKeyEnv ? p.apiKeyConfigured ? p.apiKeyEnv + " \u5DF2\u914D\u7F6E" : p.apiKeyEnv + " \u672A\u914D\u7F6E" : "\u672A\u8BBE apiKeyEnv",
|
|
4814
|
+
"aria-label": p.apiKeyEnv ? p.apiKeyConfigured ? "\u5BC6\u94A5\u5DF2\u914D\u7F6E" : "\u5BC6\u94A5\u672A\u914D\u7F6E" : "\u672A\u8BBE apiKeyEnv"
|
|
4815
|
+
}),
|
|
4816
|
+
p.apiKeyEnv ? import_react3.default.createElement(
|
|
4817
|
+
"span",
|
|
4818
|
+
{ className: "dkp-tag" + (keyMissing ? " warn" : " ok") },
|
|
4819
|
+
p.apiKeyConfigured ? p.apiKeyEnv + " \u5DF2\u914D\u7F6E" : p.apiKeyEnv + " \u672A\u914D\u7F6E"
|
|
4820
|
+
) : null
|
|
4821
|
+
),
|
|
4822
|
+
import_react3.default.createElement(
|
|
4823
|
+
"span",
|
|
4824
|
+
{ className: "dkp-actions" },
|
|
4825
|
+
import_react3.default.createElement("button", {
|
|
4826
|
+
type: "button",
|
|
4827
|
+
className: "dkp-btn ghost sm",
|
|
4828
|
+
"aria-expanded": editing,
|
|
4829
|
+
onClick: () => editing ? closePf() : openPfEdit(p)
|
|
4830
|
+
}, editing ? "\u6536\u8D77" : "\u7F16\u8F91"),
|
|
4831
|
+
import_react3.default.createElement("button", {
|
|
4832
|
+
type: "button",
|
|
4833
|
+
className: "dkp-btn danger sm" + (pfDelArm === route ? " arm" : ""),
|
|
4834
|
+
title: pfDelArm === route ? "\u518D\u70B9\u4E00\u6B21\u786E\u8BA4\u5220\u9664" : "\u5220\u9664\u8BE5 Provider",
|
|
4835
|
+
onClick: () => deletePf(p)
|
|
4836
|
+
}, pfDelArm === route ? "\u786E\u8BA4\u5220\u9664\uFF1F" : "\u5220\u9664")
|
|
4837
|
+
)
|
|
4838
|
+
),
|
|
4839
|
+
import_react3.default.createElement("div", { className: "dkp-sub" }, [p.api, p.baseURL].filter(Boolean).join(" \xB7 ")),
|
|
4840
|
+
editing ? editor : null
|
|
4841
|
+
);
|
|
4842
|
+
})
|
|
4190
4843
|
));
|
|
4191
4844
|
}
|
|
4192
|
-
|
|
4845
|
+
body.push(import_react3.default.createElement(
|
|
4846
|
+
"div",
|
|
4847
|
+
{ key: "add", className: "dkp-addblock" },
|
|
4848
|
+
pfMode === "create" && pfDraft ? import_react3.default.createElement("div", { className: "dkp-card dkp-addcard" }, editor) : import_react3.default.createElement("button", { type: "button", className: "dkp-addbtn", onClick: openPfCreate }, "\uFF0B \u65B0\u589E Provider")
|
|
4849
|
+
));
|
|
4850
|
+
return import_react3.default.createElement("div", { className: "dkp-page" }, body);
|
|
4193
4851
|
}
|
|
4194
4852
|
function ModelsStat() {
|
|
4195
4853
|
const snap = useModels();
|
|
@@ -4205,7 +4863,7 @@ var feature2 = {
|
|
|
4205
4863
|
name: "\u6A21\u578B\u8BBE\u7F6E",
|
|
4206
4864
|
order: 100,
|
|
4207
4865
|
accent: "#22d3ee",
|
|
4208
|
-
description: "\u7F16\u8F91\u5404 Provider \u6A21\u578B\u76EE\u5F55\
|
|
4866
|
+
description: "\u7F16\u8F91\u5404 Provider \u6A21\u578B\u76EE\u5F55\uFF08\u8F93\u5165\u7C7B\u578B/\u601D\u8003\u5F3A\u5EA6\u6863\u4F4D\uFF09\uFF1B\u81EA\u5B9A\u4E49 Provider \u7684\u589E\u5220\u6539\u5728\u300C\u6A21\u578B\u63D0\u4F9B\u5546\u300D\u5B50\u9875\u9762\uFF0C\u5199\u56DE\u5B98\u65B9\u914D\u7F6E\u70ED\u751F\u6548\uFF0C\u4F1A\u8BDD\u6A21\u578B\u9009\u62E9\u5668\u5373\u65F6\u53EF\u9009",
|
|
4209
4867
|
css: [
|
|
4210
4868
|
".dkm-note{color:var(--dsw-alias-label-secondary);font-size:12px;}",
|
|
4211
4869
|
".dkm-warn{color:var(--dk-warn);}",
|
|
@@ -4250,7 +4908,99 @@ var feature2 = {
|
|
|
4250
4908
|
".dkm-mini{cursor:pointer;border:1px solid var(--dsw-alias-border-l2);background:transparent;color:var(--dsw-alias-label-tertiary);border-radius:999px;padding:1px 8px;font-family:inherit;font-size:11px;flex:none;}",
|
|
4251
4909
|
".dkm-mini:hover{color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-secondary);}",
|
|
4252
4910
|
".dkm-toolbar{display:flex;align-items:center;gap:6px;flex-wrap:wrap;border-top:1px dashed var(--dsw-alias-border-l1);padding-top:8px;}",
|
|
4253
|
-
".dkm-toolbar-label{color:var(--dsw-alias-label-tertiary);font-size:11px;flex:none;}"
|
|
4911
|
+
".dkm-toolbar-label{color:var(--dsw-alias-label-tertiary);font-size:11px;flex:none;}",
|
|
4912
|
+
// ---- 模型提供商子页面(dkp- 前缀):对齐官方「模型」设置页的排版与尺寸 ----
|
|
4913
|
+
// 官方用量参考:section 限宽 720、行卡片 .5px 描边 + radius-xl + 12/14 内距、
|
|
4914
|
+
// 输入高 32、按钮高 36(行内小按钮 28)、新增按钮 44 虚线、编辑器 bg-module-platform。
|
|
4915
|
+
".dkp-page{width:100%;max-width:720px;display:flex;flex-direction:column;gap:12px;color:var(--dsw-alias-label-primary);}",
|
|
4916
|
+
".dkp-back{box-sizing:border-box;align-self:flex-start;cursor:pointer;border:none;background:transparent;color:var(--dsw-alias-label-tertiary);border-radius:var(--dsw-radius-sm,6px);padding:4px 8px;margin-left:-8px;font-family:inherit;font-size:12px;line-height:18px;}",
|
|
4917
|
+
".dkp-back:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary);}",
|
|
4918
|
+
".dkp-title{margin:0;font-size:16px;font-weight:500;line-height:24px;}",
|
|
4919
|
+
".dkp-intro{margin:0;color:var(--dsw-alias-label-tertiary);font-size:14px;line-height:22px;}",
|
|
4920
|
+
".dkp-rows{list-style:none;margin:12px 0 0;padding:0;display:flex;flex-direction:column;gap:8px;}",
|
|
4921
|
+
".dkp-card{box-sizing:border-box;margin:0;border:.5px solid var(--dsw-alias-settings-card-stroke,var(--dsw-alias-border-l2));background:var(--dsw-alias-settings-card-fill,var(--dsw-alias-bg-layer-1));border-radius:var(--dsw-radius-xl,12px);padding:12px 14px;display:flex;flex-direction:column;gap:10px;}",
|
|
4922
|
+
".dkp-rowhead{display:flex;align-items:center;gap:10px;flex-wrap:wrap;}",
|
|
4923
|
+
".dkp-identity{display:inline-flex;align-items:center;gap:6px;min-width:0;flex-wrap:wrap;}",
|
|
4924
|
+
".dkp-name{font-size:14px;font-weight:500;line-height:22px;}",
|
|
4925
|
+
".dkp-tag{flex:none;border:.5px solid var(--dsw-alias-border-l3);border-radius:var(--dsw-radius-xs,4px);color:var(--dsw-alias-label-secondary);padding:1px 6px;font-size:11px;line-height:16px;}",
|
|
4926
|
+
".dkp-tag.ok{color:var(--dsw-alias-state-success-primary);border-color:currentColor;}",
|
|
4927
|
+
".dkp-tag.warn{color:var(--dk-warn);border-color:currentColor;}",
|
|
4928
|
+
".dkp-dot{box-sizing:border-box;flex:none;width:8px;height:8px;border-radius:50%;display:inline-block;}",
|
|
4929
|
+
".dkp-dot.ok{background:var(--dsw-alias-state-success-primary);}",
|
|
4930
|
+
".dkp-dot.missing{background:var(--dsw-alias-state-error-primary);}",
|
|
4931
|
+
".dkp-dot.warn{background:var(--dk-warn);}",
|
|
4932
|
+
".dkp-sub{margin:0;color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}",
|
|
4933
|
+
".dkp-hint{margin:0;color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px;}",
|
|
4934
|
+
".dkp-dim{color:var(--dsw-alias-label-tertiary);}",
|
|
4935
|
+
".dkp-error{margin:0;color:var(--dsw-alias-state-error-primary);font-size:12px;line-height:18px;}",
|
|
4936
|
+
".dkp-msg{margin:0;color:var(--dsw-alias-label-secondary);font-size:12px;line-height:18px;}",
|
|
4937
|
+
".dkp-msg.ok{color:var(--dsw-alias-state-success-primary);}",
|
|
4938
|
+
".dkp-msg.err{color:var(--dsw-alias-state-error-primary);}",
|
|
4939
|
+
".dkp-actions{flex:none;margin-left:auto;display:inline-flex;align-items:center;gap:4px;}",
|
|
4940
|
+
".dkp-btn{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;gap:4px;height:36px;padding:0 14px;border:none;border-radius:var(--dsw-radius-md,8px);background:transparent;color:var(--dsw-alias-label-primary);font:inherit;font-size:14px;line-height:22px;cursor:pointer;}",
|
|
4941
|
+
".dkp-btn.ghost{border:.5px solid var(--dsw-alias-border-l3);}",
|
|
4942
|
+
".dkp-btn.ghost:hover{background:var(--dsw-alias-interactive-bg-hover);}",
|
|
4943
|
+
".dkp-btn.primary{background:var(--dsw-alias-button-primary-fill,var(--dk-accent));color:var(--dsw-alias-label-primary-foreground,#fff);}",
|
|
4944
|
+
".dkp-btn.primary:hover{background:var(--dsw-alias-button-primary-hover,var(--dk-accent));}",
|
|
4945
|
+
".dkp-btn.danger{color:var(--dsw-alias-state-error-primary);}",
|
|
4946
|
+
".dkp-btn.danger:hover{background:var(--dsw-alias-interactive-bg-hover-danger,rgba(220,38,38,.1));}",
|
|
4947
|
+
".dkp-btn.arm{color:var(--dsw-alias-state-error-primary);border-color:currentColor;}",
|
|
4948
|
+
".dkp-btn.sm{height:28px;padding:0 10px;border-radius:var(--dsw-radius-sm,6px);font-size:12px;line-height:18px;}",
|
|
4949
|
+
".dkp-btn[disabled]{opacity:.4;cursor:default;}",
|
|
4950
|
+
".dkp-editor{border-radius:var(--dsw-radius-lg,10px);background:var(--dsw-alias-bg-module-platform,var(--dsw-alias-bg-layer-1));padding:14px 16px;display:flex;flex-direction:column;gap:14px;}",
|
|
4951
|
+
".dkp-editor-head{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;}",
|
|
4952
|
+
".dkp-editor-title{font-size:14px;font-weight:500;line-height:22px;}",
|
|
4953
|
+
".dkp-editor-route{color:var(--dsw-alias-label-tertiary);font-family:var(--ds-font-family-code,ui-monospace,monospace);font-size:12px;line-height:18px;}",
|
|
4954
|
+
".dkp-field{display:flex;flex-direction:column;gap:6px;min-width:0;}",
|
|
4955
|
+
".dkp-flabel{display:inline-flex;align-items:center;gap:10px;color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:500;line-height:18px;}",
|
|
4956
|
+
".dkp-input{box-sizing:border-box;width:100%;height:32px;padding:0 10px;border:.5px solid var(--dsw-alias-border-l4,var(--dsw-alias-border-l2));border-radius:var(--dsw-radius-md,8px);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);font:inherit;font-size:14px;line-height:22px;}",
|
|
4957
|
+
".dkp-input:focus{border-color:var(--dsw-alias-state-business-primary,var(--dk-accent));outline:none;}",
|
|
4958
|
+
".dkp-input::placeholder{color:var(--dsw-alias-label-dimmed,var(--dsw-alias-label-tertiary));}",
|
|
4959
|
+
".dkp-input:disabled{opacity:.6;cursor:default;}",
|
|
4960
|
+
"select.dkp-input{appearance:auto;cursor:pointer;max-width:240px;}",
|
|
4961
|
+
".dkp-select-sm{height:28px;max-width:160px;font-size:12px;line-height:18px;}",
|
|
4962
|
+
".dkp-checks{display:flex;align-items:center;gap:16px;flex-wrap:wrap;min-height:32px;}",
|
|
4963
|
+
".dkp-check{display:inline-flex;align-items:center;gap:6px;cursor:pointer;color:var(--dsw-alias-label-secondary);font-size:12px;line-height:18px;}",
|
|
4964
|
+
".dkp-check input{accent-color:var(--dk-accent);margin:0;}",
|
|
4965
|
+
".dkp-mini{cursor:pointer;border:1px solid var(--dsw-alias-border-l2);border-radius:999px;background:transparent;color:var(--dsw-alias-label-tertiary);padding:1px 8px;font-family:inherit;font-size:11px;line-height:16px;flex:none;}",
|
|
4966
|
+
".dkp-mini:hover{color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-secondary);}",
|
|
4967
|
+
".dkp-customized{border-top:.5px solid var(--dsw-alias-border-l2);padding-top:10px;}",
|
|
4968
|
+
".dkp-summary{display:flex;align-items:center;gap:6px;width:fit-content;margin-left:-4px;padding:2px 4px;border-radius:var(--dsw-radius-sm,6px);list-style:none;cursor:pointer;color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:500;line-height:18px;}",
|
|
4969
|
+
".dkp-summary::-webkit-details-marker{display:none;}",
|
|
4970
|
+
'.dkp-summary::before{content:"";width:5px;height:5px;border-right:1.5px solid;border-bottom:1.5px solid;transform:rotate(-45deg);transition:transform .12s;}',
|
|
4971
|
+
".dkp-customized[open]>.dkp-summary::before{transform:rotate(45deg);}",
|
|
4972
|
+
".dkp-summary:hover{color:var(--dsw-alias-label-primary);}",
|
|
4973
|
+
".dkp-custombody{display:flex;flex-direction:column;gap:12px;padding-top:12px;}",
|
|
4974
|
+
".dkp-catalog{border-top:.5px solid var(--dsw-alias-border-l2);padding-top:12px;display:flex;flex-direction:column;gap:10px;}",
|
|
4975
|
+
".dkp-catalog-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;flex-wrap:wrap;}",
|
|
4976
|
+
".dkp-catalog-titlewrap{display:flex;flex-direction:column;gap:2px;}",
|
|
4977
|
+
".dkp-catalog-title{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:500;line-height:18px;}",
|
|
4978
|
+
".dkp-catalog-meta{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px;}",
|
|
4979
|
+
".dkp-model-list{display:flex;flex-direction:column;gap:8px;}",
|
|
4980
|
+
".dkp-model-entry{border:.5px solid var(--dsw-alias-border-l4,var(--dsw-alias-border-l2));border-radius:var(--dsw-radius-lg,10px);padding:6px;display:flex;flex-direction:column;gap:6px;}",
|
|
4981
|
+
".dkp-model-row{display:grid;grid-template-columns:minmax(0,1.4fr) minmax(0,1fr) minmax(0,.7fr) minmax(0,.7fr) auto;gap:6px;align-items:center;}",
|
|
4982
|
+
".dkp-model-row .dkp-input{height:30px;padding:0 8px;font-size:13px;}",
|
|
4983
|
+
".dkp-model-opts{display:flex;flex-direction:column;gap:4px;padding:2px 2px 0;}",
|
|
4984
|
+
".dkp-iconbtn{box-sizing:border-box;width:28px;height:28px;display:inline-flex;align-items:center;justify-content:center;border:none;border-radius:var(--dsw-radius-sm,6px);background:transparent;color:var(--dsw-alias-label-tertiary);cursor:pointer;font-size:12px;line-height:1;}",
|
|
4985
|
+
".dkp-iconbtn:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary);}",
|
|
4986
|
+
".dkp-iconbtn.danger:hover{background:var(--dsw-alias-interactive-bg-hover-danger,rgba(220,38,38,.1));color:var(--dsw-alias-state-error-primary);}",
|
|
4987
|
+
".dkp-addmodel{box-sizing:border-box;align-self:flex-start;display:inline-flex;align-items:center;gap:4px;height:28px;padding:0 10px;border:.5px solid var(--dsw-alias-border-l3);border-radius:var(--dsw-radius-sm,6px);background:transparent;color:var(--dsw-alias-label-primary);font:inherit;font-size:12px;line-height:18px;cursor:pointer;}",
|
|
4988
|
+
".dkp-addmodel:hover{background:var(--dsw-alias-interactive-bg-hover);}",
|
|
4989
|
+
".dkp-picker{max-height:320px;overflow-y:auto;border:.5px solid var(--dsw-alias-border-l2);border-radius:var(--dsw-radius-md,8px);padding:4px 6px;display:flex;flex-direction:column;gap:2px;}",
|
|
4990
|
+
".dkp-picker label{display:flex;align-items:center;gap:8px;min-width:0;cursor:pointer;padding:6px 8px;border-radius:var(--dsw-radius-md,8px);}",
|
|
4991
|
+
".dkp-picker label:hover{background:var(--dsw-alias-interactive-bg-hover);}",
|
|
4992
|
+
".dkp-picker input{accent-color:var(--dk-accent);margin:0;flex:none;}",
|
|
4993
|
+
".dkp-picker-id{flex:none;font-family:var(--ds-font-family-code,ui-monospace,monospace);font-size:13px;line-height:20px;}",
|
|
4994
|
+
".dkp-picker-name{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}",
|
|
4995
|
+
".dkp-empty{border:1px dashed var(--dsw-alias-border-l3);border-radius:var(--dsw-radius-lg,10px);padding:12px;text-align:center;color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px;}",
|
|
4996
|
+
".dkp-addblock{display:flex;align-items:stretch;}",
|
|
4997
|
+
".dkp-addbtn{box-sizing:border-box;flex:1 1 auto;min-width:180px;height:44px;display:inline-flex;align-items:center;justify-content:center;gap:6px;border:1px dashed var(--dsw-alias-border-l3);border-radius:var(--dsw-radius-lg,10px);background:transparent;color:var(--dsw-alias-label-primary);font:inherit;font-size:14px;line-height:22px;cursor:pointer;}",
|
|
4998
|
+
".dkp-addbtn:hover{background:var(--dsw-alias-interactive-bg-hover);}",
|
|
4999
|
+
".dkp-addcard{flex:1 1 auto;padding:14px 16px;}",
|
|
5000
|
+
".dkp-addcard .dkp-editor{background:transparent;padding:0;}",
|
|
5001
|
+
".dkp-editor-actions{display:flex;align-items:center;justify-content:flex-end;gap:8px;flex-wrap:wrap;border-top:.5px solid var(--dsw-alias-border-l2);padding-top:12px;}",
|
|
5002
|
+
".dkp-editor-actions .dkp-hint{margin-right:auto;}",
|
|
5003
|
+
"@media (max-width:680px){.dkp-page{max-width:none;gap:14px}.dkp-intro{font-size:13px;line-height:20px}.dkp-model-row{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}.dkp-model-row .dkp-iconbtn{justify-self:end}.dkp-editor{padding:12px}.dkp-addcard{padding:12px 14px}.dkp-btn{height:40px}.dkp-btn.sm{height:34px}.dkp-addbtn{height:48px}}"
|
|
4254
5004
|
].join("\n"),
|
|
4255
5005
|
View: ModelsView,
|
|
4256
5006
|
HomeStat: ModelsStat
|
|
@@ -4402,7 +5152,7 @@ var balanceStore = {
|
|
|
4402
5152
|
load() {
|
|
4403
5153
|
if (this.snap.loading) return;
|
|
4404
5154
|
this.set({ loading: true });
|
|
4405
|
-
fetch("
|
|
5155
|
+
fetch("dsh-dock/balance", { signal: AbortSignal.timeout(2e4) }).then((res) => res.ok ? res.json() : Promise.reject(new Error("\u4F59\u989D\u63A5\u53E3 HTTP " + res.status))).then((data) => this.set({ data, loading: false, error: null })).catch((e) => this.set({ loading: false, error: e && e.message || String(e) }));
|
|
4406
5156
|
}
|
|
4407
5157
|
};
|
|
4408
5158
|
function useBalance(ctx) {
|
|
@@ -4725,7 +5475,7 @@ var feature5 = {
|
|
|
4725
5475
|
var import_react8 = require("react");
|
|
4726
5476
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
4727
5477
|
function rpcCall2(method, args) {
|
|
4728
|
-
return fetch("
|
|
5478
|
+
return fetch("dsh-dock/animation/" + method, {
|
|
4729
5479
|
method: "POST",
|
|
4730
5480
|
headers: { "content-type": "application/json" },
|
|
4731
5481
|
body: JSON.stringify(args === void 0 ? {} : args)
|
|
@@ -6402,7 +7152,7 @@ var feature6 = {
|
|
|
6402
7152
|
var import_react9 = require("react");
|
|
6403
7153
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
6404
7154
|
function rpcCall3(method, args) {
|
|
6405
|
-
return fetch("
|
|
7155
|
+
return fetch("dsh-dock/notify/" + method, {
|
|
6406
7156
|
method: "POST",
|
|
6407
7157
|
headers: { "content-type": "application/json" },
|
|
6408
7158
|
body: JSON.stringify(args === void 0 ? {} : args)
|
|
@@ -7166,7 +7916,7 @@ var feature7 = {
|
|
|
7166
7916
|
var import_react10 = require("react");
|
|
7167
7917
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
7168
7918
|
function rpcCall4(method, args) {
|
|
7169
|
-
return fetch("
|
|
7919
|
+
return fetch("dsh-dock/runstate/" + method, {
|
|
7170
7920
|
method: "POST",
|
|
7171
7921
|
headers: { "content-type": "application/json" },
|
|
7172
7922
|
body: JSON.stringify(args === void 0 ? {} : args)
|
|
@@ -10149,7 +10899,7 @@ function initialDash() {
|
|
|
10149
10899
|
}
|
|
10150
10900
|
function useTaskPulse() {
|
|
10151
10901
|
const [status, setStatus] = (0, import_react20.useState)({ loading: true, active: [], error: false });
|
|
10152
|
-
const refresh = (0, import_react20.useCallback)(() => fetch("
|
|
10902
|
+
const refresh = (0, import_react20.useCallback)(() => fetch("dsh-dock/animation/status", {
|
|
10153
10903
|
method: "POST",
|
|
10154
10904
|
headers: { "content-type": "application/json" },
|
|
10155
10905
|
body: "{}"
|
|
@@ -10922,7 +11672,7 @@ var import_react21 = require("react");
|
|
|
10922
11672
|
var import_qrcode = __toESM(require_browser(), 1);
|
|
10923
11673
|
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
10924
11674
|
function rpc(method, payload) {
|
|
10925
|
-
return fetch("
|
|
11675
|
+
return fetch("dsh-dock/mobile-relay/" + method, {
|
|
10926
11676
|
method: "POST",
|
|
10927
11677
|
headers: { "content-type": "application/json" },
|
|
10928
11678
|
body: JSON.stringify(payload || {})
|
|
@@ -11221,247 +11971,6 @@ function RemoteCard() {
|
|
|
11221
11971
|
function MobileRelayView() {
|
|
11222
11972
|
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(RemoteCard, {});
|
|
11223
11973
|
}
|
|
11224
|
-
function MobileRelayOverlay() {
|
|
11225
|
-
(0, import_react21.useEffect)(() => {
|
|
11226
|
-
if (typeof window === "undefined" || typeof document === "undefined") return void 0;
|
|
11227
|
-
const host = window.location && window.location.hostname || "";
|
|
11228
|
-
const loopback = host === "127.0.0.1" || host === "localhost" || host === "::1" || host.endsWith(".localhost");
|
|
11229
|
-
if (loopback) return void 0;
|
|
11230
|
-
if (typeof MutationObserver === "undefined") return void 0;
|
|
11231
|
-
let done = false;
|
|
11232
|
-
const tryDismiss = () => {
|
|
11233
|
-
if (done) return;
|
|
11234
|
-
const dialogs = document.querySelectorAll('[role="dialog"]');
|
|
11235
|
-
for (const dialog of dialogs) {
|
|
11236
|
-
const text = dialog.textContent || "";
|
|
11237
|
-
if (!/预览版说明|Preview Notice/.test(text)) continue;
|
|
11238
|
-
const btn = [...dialog.querySelectorAll("button")].find((b) => {
|
|
11239
|
-
const t = (b.textContent || "").trim();
|
|
11240
|
-
return t === "\u7EE7\u7EED" || t === "Continue";
|
|
11241
|
-
});
|
|
11242
|
-
if (btn) {
|
|
11243
|
-
done = true;
|
|
11244
|
-
btn.click();
|
|
11245
|
-
observer.disconnect();
|
|
11246
|
-
}
|
|
11247
|
-
break;
|
|
11248
|
-
}
|
|
11249
|
-
};
|
|
11250
|
-
const observer = new MutationObserver(tryDismiss);
|
|
11251
|
-
observer.observe(document.body, { childList: true, subtree: true });
|
|
11252
|
-
tryDismiss();
|
|
11253
|
-
const stopTimer = setTimeout(() => observer.disconnect(), 6e4);
|
|
11254
|
-
return () => {
|
|
11255
|
-
clearTimeout(stopTimer);
|
|
11256
|
-
observer.disconnect();
|
|
11257
|
-
};
|
|
11258
|
-
}, []);
|
|
11259
|
-
(0, import_react21.useEffect)(() => {
|
|
11260
|
-
if (typeof window === "undefined" || typeof document === "undefined") return void 0;
|
|
11261
|
-
const mq = window.matchMedia ? window.matchMedia("(max-width:700px)") : null;
|
|
11262
|
-
if (!mq) return void 0;
|
|
11263
|
-
if (window.__dshDockMobileDrawer === "host") return void 0;
|
|
11264
|
-
window.__dshDockMobileDrawer = "client";
|
|
11265
|
-
const narrow = () => mq.matches;
|
|
11266
|
-
const frameEl = () => document.querySelector('[class$="frame"]');
|
|
11267
|
-
const sidebarCollapsed = () => {
|
|
11268
|
-
const f = frameEl();
|
|
11269
|
-
return !!f && f.hasAttribute("data-sidebar-collapsed");
|
|
11270
|
-
};
|
|
11271
|
-
const dialogOpen = () => !!document.querySelector('[role="dialog"][class*="panel"]');
|
|
11272
|
-
const rightOpen = () => !!document.querySelector("[data-sidebar-right-panel][data-sidebar-right-open]");
|
|
11273
|
-
const collapse = () => {
|
|
11274
|
-
const b = document.querySelector('button[aria-label="\u6536\u8D77\u4FA7\u8FB9\u680F"],button[aria-label="Collapse sidebar"]');
|
|
11275
|
-
if (b) b.click();
|
|
11276
|
-
};
|
|
11277
|
-
const expand = () => {
|
|
11278
|
-
const b = document.querySelector('button[aria-label="\u6253\u5F00\u4FA7\u8FB9\u680F"],button[aria-label="Open sidebar"]');
|
|
11279
|
-
if (b) b.click();
|
|
11280
|
-
};
|
|
11281
|
-
const closeDetails = () => {
|
|
11282
|
-
const panel = document.querySelector("[data-sidebar-right-panel][data-sidebar-right-open]");
|
|
11283
|
-
if (!panel) return;
|
|
11284
|
-
const toggle = panel.querySelector("[data-sidebar-right-toggle]");
|
|
11285
|
-
if (toggle) toggle.click();
|
|
11286
|
-
};
|
|
11287
|
-
const scrim = document.createElement("div");
|
|
11288
|
-
scrim.className = "dsh-mobile-scrim";
|
|
11289
|
-
document.body.appendChild(scrim);
|
|
11290
|
-
document.querySelectorAll(".dsh-mobile-tabbar").forEach((el) => el.remove());
|
|
11291
|
-
const tabbar = document.createElement("nav");
|
|
11292
|
-
tabbar.className = "dsh-mobile-tabbar";
|
|
11293
|
-
tabbar.setAttribute("aria-label", "\u5E95\u90E8\u5BFC\u822A");
|
|
11294
|
-
let tasksActive = 0;
|
|
11295
|
-
let tasksWaiting = 0;
|
|
11296
|
-
const tabDefs = [
|
|
11297
|
-
{
|
|
11298
|
-
id: "sessions",
|
|
11299
|
-
label: "\u4F1A\u8BDD",
|
|
11300
|
-
icon: '<svg viewBox="0 0 24 24"><path d="M21 12a8 8 0 0 1-8 8H5l-2 2V12a8 8 0 0 1 8-8h2a8 8 0 0 1 8 8z"/></svg>',
|
|
11301
|
-
act: () => expand()
|
|
11302
|
-
},
|
|
11303
|
-
{
|
|
11304
|
-
id: "dock",
|
|
11305
|
-
label: "\u63D2\u4EF6",
|
|
11306
|
-
icon: '<svg viewBox="0 0 24 24"><rect x="4" y="4" width="7" height="7" rx="1.5"/><rect x="13" y="4" width="7" height="7" rx="1.5"/><rect x="4" y="13" width="7" height="7" rx="1.5"/><rect x="13" y="13" width="7" height="7" rx="1.5"/></svg>',
|
|
11307
|
-
act: () => {
|
|
11308
|
-
openPanel(tasksActive > 0 || tasksWaiting > 0 ? "runstate" : "home");
|
|
11309
|
-
}
|
|
11310
|
-
},
|
|
11311
|
-
{
|
|
11312
|
-
id: "settings",
|
|
11313
|
-
label: "\u8BBE\u7F6E",
|
|
11314
|
-
icon: '<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="3.2"/><path d="M19.4 15a1.7 1.7 0 0 0 .34 1.87l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06A1.7 1.7 0 0 0 15 19.4a1.7 1.7 0 0 0-1 1.55V21a2 2 0 1 1-4 0v-.09A1.7 1.7 0 0 0 9 19.4a1.7 1.7 0 0 0-1.87.34l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06A1.7 1.7 0 0 0 4.6 15a1.7 1.7 0 0 0-1.55-1H3a2 2 0 1 1 0-4h.09A1.7 1.7 0 0 0 4.6 9a1.7 1.7 0 0 0-.34-1.87l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06A1.7 1.7 0 0 0 9 4.6a1.7 1.7 0 0 0 1-1.55V3a2 2 0 1 1 4 0v.09a1.7 1.7 0 0 0 1 1.51 1.7 1.7 0 0 0 1.87-.34l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06A1.7 1.7 0 0 0 19.4 9c.23.6.86 1 1.51 1H21a2 2 0 1 1 0 4h-.09a1.7 1.7 0 0 0-1.51 1z"/></svg>',
|
|
11315
|
-
act: () => {
|
|
11316
|
-
const b = [...document.querySelectorAll("button")].find((x) => (x.getAttribute("aria-label") || "") === "\u8BBE\u7F6E" || (x.textContent || "").trim() === "\u8BBE\u7F6E");
|
|
11317
|
-
if (b) b.click();
|
|
11318
|
-
}
|
|
11319
|
-
}
|
|
11320
|
-
];
|
|
11321
|
-
let tasksBadge = null;
|
|
11322
|
-
const tabButtons = tabDefs.map((def) => {
|
|
11323
|
-
const b = document.createElement("button");
|
|
11324
|
-
b.type = "button";
|
|
11325
|
-
b.className = "dsh-mobile-tab";
|
|
11326
|
-
b.dataset.tab = def.id;
|
|
11327
|
-
b.innerHTML = def.icon + "<span>" + def.label + "</span>";
|
|
11328
|
-
b.addEventListener("click", () => def.act());
|
|
11329
|
-
if (def.id === "dock") {
|
|
11330
|
-
tasksBadge = document.createElement("span");
|
|
11331
|
-
tasksBadge.className = "dsh-mobile-tab-badge";
|
|
11332
|
-
tasksBadge.style.display = "none";
|
|
11333
|
-
b.appendChild(tasksBadge);
|
|
11334
|
-
}
|
|
11335
|
-
tabbar.appendChild(b);
|
|
11336
|
-
return b;
|
|
11337
|
-
});
|
|
11338
|
-
document.body.appendChild(tabbar);
|
|
11339
|
-
const syncTabs = () => {
|
|
11340
|
-
const expanded = !sidebarCollapsed();
|
|
11341
|
-
const settingsOpen = dialogOpen();
|
|
11342
|
-
for (const b of tabButtons) {
|
|
11343
|
-
const id = b.dataset.tab;
|
|
11344
|
-
const on = id === "sessions" && expanded || id === "dock" && panelNav.open || id === "settings" && settingsOpen;
|
|
11345
|
-
b.classList.toggle("on", on);
|
|
11346
|
-
}
|
|
11347
|
-
};
|
|
11348
|
-
const unsubPanel = subscribePanel(syncTabs);
|
|
11349
|
-
let runstateGone = false;
|
|
11350
|
-
const pollTasks = () => {
|
|
11351
|
-
if (runstateGone || !tasksBadge || !narrow() || document.visibilityState === "hidden" || !tabbar.isConnected) return;
|
|
11352
|
-
fetch("/dsh-dock/runstate/status", {
|
|
11353
|
-
method: "POST",
|
|
11354
|
-
headers: { "content-type": "application/json" },
|
|
11355
|
-
body: "{}"
|
|
11356
|
-
}).then(async (res) => {
|
|
11357
|
-
if (res.status === 404 || res.status === 405) {
|
|
11358
|
-
runstateGone = true;
|
|
11359
|
-
tasksActive = 0;
|
|
11360
|
-
tasksWaiting = 0;
|
|
11361
|
-
tasksBadge.style.display = "none";
|
|
11362
|
-
return null;
|
|
11363
|
-
}
|
|
11364
|
-
const body = await res.json().catch(() => null);
|
|
11365
|
-
if (!body) return null;
|
|
11366
|
-
const active = body.data && body.data.active || [];
|
|
11367
|
-
const waiting = active.filter((t) => t.approvals && t.approvals.length).length;
|
|
11368
|
-
tasksActive = active.length;
|
|
11369
|
-
tasksWaiting = waiting;
|
|
11370
|
-
if (waiting > 0) {
|
|
11371
|
-
tasksBadge.textContent = String(waiting);
|
|
11372
|
-
tasksBadge.className = "dsh-mobile-tab-badge wait";
|
|
11373
|
-
tasksBadge.style.display = "";
|
|
11374
|
-
} else if (active.length > 0) {
|
|
11375
|
-
tasksBadge.textContent = String(active.length);
|
|
11376
|
-
tasksBadge.className = "dsh-mobile-tab-badge";
|
|
11377
|
-
tasksBadge.style.display = "";
|
|
11378
|
-
} else {
|
|
11379
|
-
tasksBadge.style.display = "none";
|
|
11380
|
-
}
|
|
11381
|
-
}).catch(() => {
|
|
11382
|
-
});
|
|
11383
|
-
};
|
|
11384
|
-
const tasksTimer = setInterval(pollTasks, 3e3);
|
|
11385
|
-
const vv = window.visualViewport || null;
|
|
11386
|
-
const kbdSync = () => {
|
|
11387
|
-
if (!vv) return;
|
|
11388
|
-
const kbd = vv.height > 0 && window.innerHeight - vv.height > 120;
|
|
11389
|
-
document.documentElement.classList.toggle("dsh-dock-kbd", kbd);
|
|
11390
|
-
};
|
|
11391
|
-
const sync = () => {
|
|
11392
|
-
kbdSync();
|
|
11393
|
-
document.querySelectorAll(".dsh-mobile-tabbar").forEach((el) => {
|
|
11394
|
-
if (el !== tabbar) el.remove();
|
|
11395
|
-
});
|
|
11396
|
-
const on = narrow() && !!frameEl() && !dialogOpen();
|
|
11397
|
-
const collapsed = sidebarCollapsed();
|
|
11398
|
-
const right = rightOpen();
|
|
11399
|
-
if (scrim) scrim.style.display = on && !collapsed ? "" : "none";
|
|
11400
|
-
tabbar.style.display = narrow() && !!frameEl() && !panelNav.open && !right ? "" : "none";
|
|
11401
|
-
syncTabs();
|
|
11402
|
-
};
|
|
11403
|
-
sync();
|
|
11404
|
-
pollTasks();
|
|
11405
|
-
const observer = typeof MutationObserver !== "undefined" ? new MutationObserver(sync) : null;
|
|
11406
|
-
if (observer) observer.observe(document.documentElement, { attributes: true, attributeFilter: ["data-sidebar-collapsed"], subtree: true });
|
|
11407
|
-
const timer = setInterval(sync, 1500);
|
|
11408
|
-
const onMq = () => sync();
|
|
11409
|
-
if (mq.addEventListener) mq.addEventListener("change", onMq);
|
|
11410
|
-
else if (mq.addListener) mq.addListener(onMq);
|
|
11411
|
-
window.addEventListener("resize", kbdSync);
|
|
11412
|
-
if (vv && vv.addEventListener) vv.addEventListener("resize", kbdSync);
|
|
11413
|
-
const onVisible = () => {
|
|
11414
|
-
if (document.visibilityState === "visible") pollTasks();
|
|
11415
|
-
};
|
|
11416
|
-
document.addEventListener("visibilitychange", onVisible);
|
|
11417
|
-
const onClick = (e) => {
|
|
11418
|
-
if (!narrow()) return;
|
|
11419
|
-
const t = e.target;
|
|
11420
|
-
if (!t || !t.closest) return;
|
|
11421
|
-
if (t.closest(".dsh-mobile-tabbar")) return;
|
|
11422
|
-
const expanded = !!document.querySelector('button[aria-label="\u6536\u8D77\u4FA7\u8FB9\u680F"],button[aria-label="Collapse sidebar"]');
|
|
11423
|
-
const col = document.querySelector('[class*="sidebarCol"]');
|
|
11424
|
-
const inSidebar = col && col.contains(t);
|
|
11425
|
-
if (!expanded && !inSidebar) return;
|
|
11426
|
-
if (inSidebar) {
|
|
11427
|
-
const row = t.closest('[role="treeitem"]');
|
|
11428
|
-
const rowKey = row && row.getAttribute("data-row-key") || "";
|
|
11429
|
-
const sessionRow = rowKey && rowKey.startsWith("session:") || row && !rowKey && !row.querySelector('[role="treeitem"]') && row.closest('[role="tree"]');
|
|
11430
|
-
const fresh = t.closest('[class*="newSession"]');
|
|
11431
|
-
if (sessionRow || fresh) setTimeout(() => {
|
|
11432
|
-
collapse();
|
|
11433
|
-
closeDetails();
|
|
11434
|
-
}, 300);
|
|
11435
|
-
else {
|
|
11436
|
-
setTimeout(() => {
|
|
11437
|
-
if (document.querySelector('[role="dialog"]')) collapse();
|
|
11438
|
-
}, 260);
|
|
11439
|
-
}
|
|
11440
|
-
return;
|
|
11441
|
-
}
|
|
11442
|
-
if (t.closest('[role="dialog"],[class*="dockm"],[class*="dgfab"],[class*="dgwin"],[class*="dgame"],[data-sidebar-right-panel]')) return;
|
|
11443
|
-
collapse();
|
|
11444
|
-
};
|
|
11445
|
-
document.addEventListener("click", onClick, true);
|
|
11446
|
-
return () => {
|
|
11447
|
-
document.removeEventListener("click", onClick, true);
|
|
11448
|
-
if (observer) observer.disconnect();
|
|
11449
|
-
clearInterval(timer);
|
|
11450
|
-
clearInterval(tasksTimer);
|
|
11451
|
-
unsubPanel();
|
|
11452
|
-
if (mq.removeEventListener) mq.removeEventListener("change", onMq);
|
|
11453
|
-
else if (mq.removeListener) mq.removeListener(onMq);
|
|
11454
|
-
window.removeEventListener("resize", kbdSync);
|
|
11455
|
-
if (vv && vv.removeEventListener) vv.removeEventListener("resize", kbdSync);
|
|
11456
|
-
document.removeEventListener("visibilitychange", onVisible);
|
|
11457
|
-
document.documentElement.classList.remove("dsh-dock-kbd");
|
|
11458
|
-
if (scrim) scrim.remove();
|
|
11459
|
-
tabbar.remove();
|
|
11460
|
-
if (window.__dshDockMobileDrawer === "client") delete window.__dshDockMobileDrawer;
|
|
11461
|
-
};
|
|
11462
|
-
}, []);
|
|
11463
|
-
return null;
|
|
11464
|
-
}
|
|
11465
11974
|
function MobileRelayHomeStat() {
|
|
11466
11975
|
const [summary, setSummary] = (0, import_react21.useState)("\u672A\u5F00\u542F\uFF0C\u5F00\u542F\u540E\u53EF\u8FDC\u7A0B\u767B\u5F55");
|
|
11467
11976
|
(0, import_react21.useEffect)(() => {
|
|
@@ -11487,53 +11996,9 @@ var feature10 = {
|
|
|
11487
11996
|
defaultEnabled: false,
|
|
11488
11997
|
css: `
|
|
11489
11998
|
.dmr{--dmr-accent:var(--dk-accent,#2f6fed);--dmr-accent-soft:color-mix(in srgb,var(--dmr-accent) 13%,transparent);display:flex;flex-direction:column;gap:16px;max-width:720px;color:var(--dsw-alias-label-primary);font-size:13px;line-height:1.5}.dmr h3,.dmr h4,.dmr p{margin:0}.dmr h3{font-size:17px;line-height:1.25;letter-spacing:-.01em}.dmr h4{font-size:13px}.dmr-hero,.dmr-status-head{display:flex;align-items:flex-start;gap:12px}.dmr-hero>div,.dmr-status-head>div{min-width:0;display:flex;flex-direction:column;gap:4px}.dmr-hero p,.dmr-status-head p,.dmr-field small,.dmr-share small,.dmr-overview-card small,.dmr-task small,.dmr-note p{color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.55}.dmr-hero-icon{width:42px;height:42px;display:inline-flex;align-items:center;justify-content:center;flex:none;border-radius:14px;background:var(--dmr-accent-soft);color:var(--dmr-accent);border:1px solid color-mix(in srgb,var(--dmr-accent) 35%,var(--dsw-alias-border-l1))}.dmr-steps{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;margin:0;padding:0;list-style:none}.dmr-steps li{display:flex;gap:9px;padding:11px;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:12px}.dmr-steps li>span{width:21px;height:21px;display:inline-flex;align-items:center;justify-content:center;flex:none;border-radius:50%;font-size:11px;font-weight:700;color:var(--dmr-accent);background:var(--dmr-accent-soft)}.dmr-steps div{display:flex;flex-direction:column;gap:3px;min-width:0}.dmr-steps strong{font-size:12px}.dmr-steps small{font-size:11px;color:var(--dsw-alias-label-secondary);line-height:1.45}.dmr-field{display:flex;flex-direction:column;gap:6px;font-weight:600}.dmr-field input,.dmr-field select,.dmr-note textarea{box-sizing:border-box;width:100%;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);border-radius:10px;padding:10px 12px;min-height:44px;font:inherit;outline:none;transition:border-color .18s ease,box-shadow .18s ease}.dmr-field input:focus,.dmr-field select:focus,.dmr-note textarea:focus{border-color:var(--dmr-accent);box-shadow:0 0 0 3px var(--dmr-accent-soft)}.dmr-field small{font-weight:400}.dmr-network-grid{display:grid;grid-template-columns:minmax(0,1.4fr) minmax(150px,.6fr);gap:12px}.dmr-security{padding:12px 13px;border:1px solid color-mix(in srgb,var(--dk-warn) 48%,var(--dsw-alias-border-l1));border-radius:12px;background:color-mix(in srgb,var(--dk-warn) 9%,transparent)}.dmr-security strong{display:block;margin-bottom:4px;color:var(--dk-warn);font-size:12px}.dmr-security p{font-size:12px;color:var(--dsw-alias-label-secondary);line-height:1.55}.dmr-primary,.dmr-secondary,.dmr-text-button,.dmr-icon-button{font:inherit;touch-action:manipulation;cursor:pointer;transition:transform .15s ease,background .18s ease,border-color .18s ease,opacity .18s ease}.dmr-primary,.dmr-secondary{min-height:44px;display:inline-flex;align-items:center;justify-content:center;gap:8px;border-radius:10px;padding:9px 13px;font-weight:600}.dmr-primary{align-self:flex-start;border:1px solid var(--dmr-accent);background:var(--dmr-accent);color:#fff}.dmr-primary:hover{filter:brightness(1.05)}.dmr-secondary{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary)}.dmr-secondary:hover{border-color:var(--dmr-accent);background:var(--dmr-accent-soft)}.dmr-primary:active,.dmr-secondary:active,.dmr-icon-button:active{transform:scale(.98)}.dmr-primary:disabled,.dmr-secondary:disabled,.dmr-text-button:disabled,.dmr-icon-button:disabled{cursor:not-allowed;opacity:.5}.dmr-message{display:flex;align-items:flex-start;gap:7px;padding:10px 12px;border-radius:10px;font-size:12px}.dmr-message.success{color:var(--dsw-alias-state-success-primary);background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 10%,transparent)}.dmr-message.error{color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 10%,transparent)}.dmr-status-head{justify-content:space-between}.dmr-eyebrow{display:inline-flex;align-items:center;gap:6px;font-size:11px;font-weight:600;color:var(--dmr-accent)}.dmr-eyebrow i{width:7px;height:7px;border-radius:50%;background:currentColor;box-shadow:0 0 0 4px var(--dmr-accent-soft)}.dmr-icon-button{display:inline-flex;align-items:center;justify-content:center;flex:none;width:44px;height:44px;border:1px solid var(--dsw-alias-border-l2);border-radius:10px;background:transparent;color:var(--dsw-alias-label-secondary)}.dmr-icon-button:hover{color:var(--dsw-alias-state-error-primary);border-color:currentColor}.dmr-share{display:flex;flex-direction:column;gap:9px;padding:13px;border:1px solid color-mix(in srgb,var(--dmr-accent) 32%,var(--dsw-alias-border-l1));border-radius:13px;background:var(--dmr-accent-soft)}.dmr-share-layout{display:grid;grid-template-columns:196px minmax(0,1fr);gap:16px;align-items:center}.dmr-qr-card{box-sizing:border-box;display:flex;flex-direction:column;align-items:center;gap:5px;padding:10px;border-radius:12px;background:#fff;color:#111827;text-align:center}.dmr-qr-card img{display:block;width:176px;height:176px;max-width:100%;object-fit:contain}.dmr-qr-card strong{font-size:12px}.dmr-qr-card small{color:#4b5563;font-size:10px}.dmr-qr-loading{display:grid;place-items:center;width:176px;height:176px;color:#64748b;font-size:12px}.dmr-share-detail{min-width:0;display:flex;flex-direction:column;gap:10px}.dmr-share-detail>div:first-child{display:flex;flex-direction:column;gap:4px}.dmr-link{padding:10px 11px;border-radius:8px;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);font:12px/1.4 ui-monospace,SFMono-Regular,Menlo,monospace;word-break:break-all;color:var(--dsw-alias-label-secondary)}.dmr-share-actions{display:flex;gap:8px;flex-wrap:wrap}.dmr-share-actions .dmr-primary{align-self:auto}.dmr-overview{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}.dmr-overview-card{display:flex;flex-direction:column;gap:3px;padding:12px;border:1px solid var(--dsw-alias-border-l1);border-radius:12px;background:var(--dsw-alias-bg-layer-1)}.dmr-overview-card>span{font-size:11px;color:var(--dsw-alias-label-tertiary)}.dmr-overview-card strong{font-size:16px;letter-spacing:-.01em}.dmr-section{display:flex;flex-direction:column;gap:9px}.dmr-section-head{display:flex;align-items:center;justify-content:space-between;gap:10px}.dmr-section-head small{font-size:11px;color:var(--dsw-alias-label-tertiary)}.dmr-text-button{border:0;background:transparent;color:var(--dmr-accent);padding:8px;min-height:36px;font-weight:600}.dmr-task-list{display:flex;flex-direction:column;gap:8px}.dmr-task{display:flex;align-items:flex-start;gap:9px;padding:10px 11px;border:1px solid var(--dsw-alias-border-l1);border-radius:10px;background:var(--dsw-alias-bg-layer-1)}.dmr-task>div{display:flex;min-width:0;flex:1;flex-direction:column;gap:2px}.dmr-task strong{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dmr-phase{flex:none;border-radius:999px;padding:3px 8px;font-size:11px;background:var(--dmr-accent-soft);color:var(--dmr-accent)}.dmr-phase.write{color:var(--dsw-alias-state-success-primary)}.dmr-phase.code{color:var(--dk-warn)}.dmr-phase.search{color:#0d9488}.dmr-empty{padding:18px 12px;text-align:center;border:1px dashed var(--dsw-alias-border-l2);border-radius:10px;color:var(--dsw-alias-label-secondary);font-size:12px}.dmr-note{display:flex;flex-direction:column;gap:9px;padding-top:2px}.dmr-note blockquote{margin:0;padding:10px 12px;border-left:3px solid var(--dmr-accent);border-radius:0 9px 9px 0;background:var(--dmr-accent-soft);white-space:pre-wrap;font-size:12px}.dmr-note textarea{min-height:88px;resize:vertical;line-height:1.5}.dmr-note .dmr-secondary{align-self:flex-start}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}@media (max-width:680px){.dmr{gap:14px;font-size:14px}.dmr h3{font-size:18px}.dmr-steps{grid-template-columns:1fr;gap:8px}.dmr-steps li{padding:10px}.dmr-steps small,.dmr-hero p,.dmr-status-head p,.dmr-field small,.dmr-share small,.dmr-overview-card small,.dmr-task small,.dmr-note p{font-size:12px}.dmr-network-grid{grid-template-columns:1fr;gap:10px}.dmr-field input,.dmr-field select{font-size:16px}.dmr-primary,.dmr-secondary{width:100%;font-size:14px}.dmr-share-layout{grid-template-columns:1fr;gap:12px}.dmr-qr-card{width:min(240px,100%);margin:0 auto}.dmr-qr-card img,.dmr-qr-loading{width:210px;height:210px}.dmr-share-actions{flex-direction:column}.dmr-share-actions .dmr-primary{width:100%}.dmr-overview{gap:8px}.dmr-overview-card{padding:11px}.dmr-status-head{gap:8px}.dmr-link{font-size:11px}.dmr-note textarea{font-size:16px;min-height:104px}.dmr-note .dmr-secondary{align-self:stretch}.dmr-compact .dmr-hero-icon{width:40px;height:40px;border-radius:13px}}@media (prefers-reduced-motion:reduce){.dmr-primary,.dmr-secondary,.dmr-text-button,.dmr-icon-button,.dmr-field input,.dmr-field select,.dmr-note textarea{transition:none}}.dmr-lan{flex:none;margin-top:6px;padding-top:16px;border-top:1px solid var(--dsw-alias-border-l1)}.dmr-lan-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}.dmr-lan-title{min-width:0;display:flex;flex-direction:column;gap:4px}.dmr-lan-title p{color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.55}.dmr-lan-badge{flex:none;display:inline-flex;align-items:center;gap:6px;border-radius:999px;padding:5px 10px;font-size:11px;font-weight:700;border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-tertiary)}.dmr-lan-badge.on{border-color:color-mix(in srgb,var(--dmr-accent) 45%,transparent);background:var(--dmr-accent-soft);color:var(--dmr-accent)}.dmr-lan-active,.dmr-lan-idle{display:flex;flex-direction:column;gap:12px}.dmr-lan-active .dmr-share-detail small strong{color:var(--dsw-alias-state-error-primary)}.dmr-danger{border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary) 45%,var(--dsw-alias-border-l2));color:var(--dsw-alias-state-error-primary)}.dmr-danger:hover{border-color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 10%,transparent)}
|
|
11490
|
-
|
|
11491
|
-
* \u7EDF\u4E00\u8D70\u5E95\u90E8 Tab \u680F\u300C\u4F1A\u8BDD\u300D\u9875\u7B7E\uFF0C\u628A\u624B\u60AC\u6D6E\u5728\u5185\u5BB9\u4E0A\u8FD8\u538B\u8FC7\u8F93\u5165\u533A\uFF08\u7528\u6237\u5B9E\u6D4B\uFF09\u3002 */
|
|
11492
|
-
@media (max-width:700px){.dsh-mobile-scrim{position:fixed;inset:0;z-index:75;background:rgba(8,10,14,.45);backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px);touch-action:none}
|
|
11493
|
-
/* ---- \u4EFF ZCode \u624B\u673A\u7AEF\uFF1A\u5E95\u90E8 Tab \u680F + \u8F93\u5165\u533A\u5438\u9644\u5E95\u90E8 ---- */
|
|
11494
|
-
.dsh-mobile-tabbar{position:fixed;left:0;right:0;bottom:0;z-index:65;display:flex;align-items:stretch;justify-content:space-around;padding:6px 8px calc(8px + env(safe-area-inset-bottom,0px));background:color-mix(in srgb,var(--dsw-alias-bg-layer-2,#1c2230) 92%,transparent);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border-top:1px solid var(--dsw-alias-border-l1,rgba(127,139,161,.25));touch-action:manipulation}
|
|
11495
|
-
.dsh-mobile-tab{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;min-height:48px;padding:4px 0;border:0;background:transparent;color:var(--dsw-alias-label-tertiary,#8b95ab);font:600 11px/1.2 inherit;cursor:pointer;-webkit-tap-highlight-color:transparent;border-radius:10px}
|
|
11496
|
-
.dsh-mobile-tab svg{width:21px;height:21px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
|
|
11497
|
-
.dsh-mobile-tab.on{color:var(--dsw-alias-label-primary,#e6eaf2)}
|
|
11498
|
-
.dsh-mobile-tab.on svg{color:var(--dk-accent,#4d9fff)}
|
|
11499
|
-
.dsh-mobile-tab:active{transform:scale(.94)}
|
|
11500
|
-
/* \u300C\u4EFB\u52A1\u300D\u9875\u7B7E\u89D2\u6807\uFF1A\u8FDB\u884C\u4E2D=\u84DD\uFF08\u6570\u91CF\uFF09\uFF0C\u7B49\u5F85\u786E\u8BA4=\u7EA2\uFF08\u6570\u91CF+\u8109\u51B2\uFF09\u2014\u2014\u63A5\u529B\u573A\u666F\u91CC
|
|
11501
|
-
* \u7B49\u5F85\u786E\u8BA4\u662F\u6700\u9700\u8981\u4EBA\u4ECB\u5165\u7684\u72B6\u6001\uFF0C\u4E00\u773C\u53EF\u89C1\uFF1B\u6570\u636E\u6765\u81EA runstate \u5BBF\u4E3B\u8DEF\u7531\u4F4E\u9891\u8F6E\u8BE2\u3002 */
|
|
11502
|
-
.dsh-mobile-tab{position:relative}
|
|
11503
|
-
.dsh-mobile-tab-badge{position:absolute;top:0;right:calc(50% - 26px);box-sizing:border-box;min-width:16px;height:16px;padding:0 4px;border-radius:9px;display:flex;align-items:center;justify-content:center;background:#4d9fff;color:#fff;font-size:10px;font-weight:700;line-height:1;font-variant-numeric:tabular-nums;box-shadow:0 2px 8px rgba(0,0,0,.35);pointer-events:none}
|
|
11504
|
-
.dsh-mobile-tab-badge.wait{background:#ef4444;animation:dsh-badge-pulse 1.2s ease-in-out infinite}
|
|
11505
|
-
@keyframes dsh-badge-pulse{0%,100%{transform:scale(1)}50%{transform:scale(1.18)}}
|
|
11506
|
-
@media (prefers-reduced-motion:reduce){.dsh-mobile-tab-badge.wait{animation:none}}
|
|
11507
|
-
/* \u8F93\u5165\u533A\u5438\u9644\u5230 Tab \u680F\u4E0A\u65B9\uFF1A\u5BBF\u4E3B\u628A\u6B22\u8FCE\u5185\u5BB9 justify-content:center \u5782\u76F4\u5C45\u4E2D\uFF0C
|
|
11508
|
-
* \u624B\u673A\u89C6\u53E3\u4E0B\u8F93\u5165\u5361\u7247\u60AC\u5728\u4E2D\u90E8\u3001\u4E0B\u65B9\u7559\u51FA\u5927\u7247\u7A7A\u767D\u3002\u6539\u7528\u300C\u8F93\u5165\u533A margin-top:auto\u300D
|
|
11509
|
-
* \u8D34\u5E95\uFF0C\u5E76\u7ED9\u6EDA\u52A8\u4F53\u7559\u51FA Tab \u680F\u9AD8\u5EA6\u7684\u5185\u8FB9\u8DDD\uFF0C\u907F\u514D\u5185\u5BB9\u88AB Tab \u680F\u906E\u6321\u3002
|
|
11510
|
-
* \u26A0\uFE0F \u7EDD\u4E0D\u80FD\u7ED9\u6EDA\u52A8\u4F53\u52A0 justify-content:flex-end/center \u8D34\u5E95\uFF1A\u5185\u5BB9\u4F1A\u88AB\u6324\u5230\u6EDA\u52A8\u4F53
|
|
11511
|
-
* \u8D77\u70B9\u4E4B\u5916\uFF0CChrome \u4E0D\u628A\u8D77\u70B9\u65B9\u5411\u6EA2\u51FA\u7B97\u8FDB scrollHeight\uFF08\u624B\u673A\u89C6\u53E3\u5B9E\u6D4B
|
|
11512
|
-
* scrollHeight==clientHeight\u3001maxScroll==0\uFF09\uFF0C\u4F1A\u8BDD\u8BB0\u5F55\u5F7B\u5E95\u6EDA\u4E0D\u52A8\u3001\u9996\u6761\u6D88\u606F\u6C38\u8FDC
|
|
11513
|
-
* \u770B\u4E0D\u5230\u3002\u5BBF\u4E3B\u534A\u90E8\u65E7\u7248\u6CE8\u5165\u91CC\u8FD8\u7559\u7740\u90A3\u6761 flex-end\uFF08\u8981\u91CD\u542F dsh web \u624D\u6D88\u5931\uFF09\uFF0C\u8FD9\u91CC
|
|
11514
|
-
* \u7528\u66F4\u9AD8\u4F18\u5148\u7EA7\u7684\u9009\u62E9\u5668\u663E\u5F0F\u590D\u4F4D\uFF1A\u5237\u65B0\u9875\u9762\u5373\u4FEE\u597D\uFF0C\u4E0D\u5FC5\u7B49\u91CD\u542F\u3002 */
|
|
11515
|
-
[class*="scrollBody"][data-conversation-scroll]{justify-content:flex-start !important;padding-bottom:calc(72px + env(safe-area-inset-bottom,0px)) !important}
|
|
11516
|
-
[class*="scrollBody"]{padding-bottom:calc(72px + env(safe-area-inset-bottom,0px)) !important}
|
|
11517
|
-
[class*="scrollBody"]>[class*="composerSeat"]{margin-top:auto;padding-bottom:6px}
|
|
11518
|
-
/* \u8F93\u5165\u533A\u5DE5\u5177\u884C\u4E0A\u7684 dsh-dock chip\uFF08\u7528\u91CF/\u4F59\u989D\uFF09\uFF1A\u7A84\u5C4F\u4E0B 28cqw \u7684\u5BBD\u5EA6\u4E0A\u9650\u628A\u5B83\u4EEC\u6324\u6210
|
|
11519
|
-
* \u300C\u2026\u300D\u300C\u4F59..\u300D\uFF08\u624B\u673A\u5B9E\u6D4B\uFF09\uFF0C\u65E2\u8BFB\u4E0D\u51FA\u6570\u503C\u53C8\u767D\u5360\u8F93\u5165\u884C\u7A7A\u95F4\u3002\u624B\u673A\u7AEF\u6574\u7EC4\u6536\u8D77\uFF0C\u6570\u503C\u5728
|
|
11520
|
-
* \u5E95\u90E8\u300C\u529F\u80FD\u575E\u300D\u91CC\u770B\uFF08\u7528\u91CF/\u4F59\u989D\u9875\u4FE1\u606F\u66F4\u5168\uFF09\uFF1B\u684C\u9762\u7AEF\u4E0D\u52A8\u3002 */
|
|
11521
|
-
.dockchip-row{display:none}
|
|
11522
|
-
/* \u6536\u8D77\u7684\u4FA7\u680F\u8F68\u9053\uFF08collapsed rail\uFF09\u5728\u7A84\u5C4F\u53EA\u5269 1px \u5360\u4F4D\uFF0C\u4F46\u8F68\u9053\u91CC\u7684\u6309\u94AE
|
|
11523
|
-
* \u4ECD\u4F1A\u6EA2\u51FA\u8D34\u5728\u5DE6\u8FB9\u7F18\uFF08\u529F\u80FD\u575E/\u8FDB\u5316/\u8BBE\u7F6E\u4E09\u679A\u9732\u51FA\u534A\u8FB9\u7684\u5706\u94AE\uFF09\u3002\u9690\u85CF\u6574\u5217\uFF0C
|
|
11524
|
-
* \u8FD9\u4E9B\u5165\u53E3\u5DF2\u7531\u5E95\u90E8 Tab \u680F\u63A5\u7BA1\uFF1B\u5C55\u5F00\u62BD\u5C49\uFF08z 80\uFF09\u4E0D\u53D7\u5F71\u54CD\u3002 */
|
|
11525
|
-
[class*="sidebarCol"]:has([class*="collapsed"]){visibility:hidden}
|
|
11526
|
-
/* \u8F6F\u952E\u76D8\u5F39\u51FA\uFF08visualViewport \u5224\u5B9A\uFF0C\u6302 html.dsh-dock-kbd\uFF09\uFF1ATab \u680F\u6574\u4F53\u8BA9\u4F4D\uFF08\u6253\u5B57\u65F6
|
|
11527
|
-
* \u5B83\u53EA\u4F1A\u6324\u5360\u952E\u76D8\u4E0A\u65B9\u7684\u4E00\u7EBF\u7A7A\u95F4\uFF09\uFF0C\u6EDA\u52A8\u4F53\u7559\u767D\u6536\u7A84\u3002\u9009\u62E9\u5668\u7279\u5F02\u6027\u9AD8\u4E8E\u4E0A\u9762\u7684 72px
|
|
11528
|
-
* \u7559\u767D\u89C4\u5219\uFF0C\u80FD\u538B\u8FC7\u53BB\u3002\u5BBF\u4E3B\u63A5\u7BA1\u671F\u95F4\u7531\u5BBF\u4E3B\u811A\u672C\u540C\u6B65\u7F6E/\u6458\u8FD9\u4E2A\u7C7B\u3002 */
|
|
11529
|
-
html.dsh-dock-kbd .dsh-mobile-tabbar{display:none !important}
|
|
11530
|
-
html.dsh-dock-kbd [class*="scrollBody"]{padding-bottom:12px !important}
|
|
11531
|
-
/* \u529F\u80FD\u575E\u9762\u677F\u5728\u624B\u673A\u7AEF\u62AC\u5230\u539F\u751F\u5F39\u5C42\u4E4B\u4E0A\uFF1A\u4ECE\u4FA7\u680F\u8FDB\u7684\u5B98\u65B9\u63D2\u4EF6\u7BA1\u7406\u9875\u7B49\u539F\u751F\u5F39\u5C42 z \u5E8F\u9AD8\u4E8E
|
|
11532
|
-
* \u9762\u677F\u9ED8\u8BA4\u7684 200\uFF0C\u529F\u80FD\u575E\u5F00\u5728\u4E0B\u9762\u4F1A\u88AB\u76D6\u4F4F\u2014\u2014\u300C\u63D2\u4EF6\u300D\u9875\u7B7E\u70B9\u4E86\u50CF\u6CA1\u53CD\u5E94/\u9732\u51FA\u539F\u9875\u9762\u3002 */
|
|
11533
|
-
[class*="dockm-backdrop"]{z-index:2000 !important}}`,
|
|
11999
|
+
`,
|
|
11534
12000
|
View: MobileRelayView,
|
|
11535
|
-
HomeStat: MobileRelayHomeStat
|
|
11536
|
-
Overlay: MobileRelayOverlay
|
|
12001
|
+
HomeStat: MobileRelayHomeStat
|
|
11537
12002
|
};
|
|
11538
12003
|
|
|
11539
12004
|
// features/mobile/view.js
|
|
@@ -11541,54 +12006,36 @@ var import_react22 = __toESM(require("react"), 1);
|
|
|
11541
12006
|
var import_react23 = require("react");
|
|
11542
12007
|
var MOBILE_QUERY_NARROW = "(max-width: 820px)";
|
|
11543
12008
|
var MOBILE_QUERY_COARSE = "(pointer: coarse) and (hover: none)";
|
|
11544
|
-
var
|
|
11545
|
-
|
|
11546
|
-
|
|
11547
|
-
if (typeof localStorage !== "undefined") {
|
|
11548
|
-
const raw = localStorage.getItem(MOBILE_STORE_KEY);
|
|
11549
|
-
const obj = raw ? JSON.parse(raw) : null;
|
|
11550
|
-
if (obj && typeof obj === "object" && typeof obj.floating === "boolean") mobilePref.floating = obj.floating;
|
|
11551
|
-
}
|
|
11552
|
-
} catch {
|
|
11553
|
-
}
|
|
11554
|
-
var prefListeners = /* @__PURE__ */ new Set();
|
|
11555
|
-
function notifyPref() {
|
|
11556
|
-
for (const fn of prefListeners) {
|
|
11557
|
-
try {
|
|
11558
|
-
fn();
|
|
11559
|
-
} catch {
|
|
11560
|
-
}
|
|
11561
|
-
}
|
|
11562
|
-
}
|
|
11563
|
-
function floatingShown() {
|
|
11564
|
-
return mobilePref.floating !== false;
|
|
11565
|
-
}
|
|
11566
|
-
function setFloatingShown(value) {
|
|
11567
|
-
mobilePref.floating = value !== false;
|
|
12009
|
+
var MOBILE_QUERY_CHROME = "(max-width: 700px)";
|
|
12010
|
+
function mobileActive() {
|
|
12011
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return false;
|
|
11568
12012
|
try {
|
|
11569
|
-
|
|
12013
|
+
return window.matchMedia(MOBILE_QUERY_NARROW).matches || window.matchMedia(MOBILE_QUERY_COARSE).matches;
|
|
11570
12014
|
} catch {
|
|
12015
|
+
return false;
|
|
11571
12016
|
}
|
|
11572
|
-
notifyPref();
|
|
11573
12017
|
}
|
|
11574
|
-
function
|
|
11575
|
-
|
|
11576
|
-
return () => {
|
|
11577
|
-
prefListeners.delete(fn);
|
|
12018
|
+
function watchQuery(query, onChange) {
|
|
12019
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return () => {
|
|
11578
12020
|
};
|
|
11579
|
-
|
|
11580
|
-
function mobileActive() {
|
|
11581
|
-
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return false;
|
|
12021
|
+
let mq = null;
|
|
11582
12022
|
try {
|
|
11583
|
-
|
|
12023
|
+
mq = window.matchMedia(query);
|
|
11584
12024
|
} catch {
|
|
11585
|
-
return
|
|
12025
|
+
return () => {
|
|
12026
|
+
};
|
|
11586
12027
|
}
|
|
12028
|
+
const update = () => onChange(mq.matches);
|
|
12029
|
+
update();
|
|
12030
|
+
if (typeof mq.addEventListener === "function") mq.addEventListener("change", update);
|
|
12031
|
+
else if (typeof mq.addListener === "function") mq.addListener(update);
|
|
12032
|
+
return () => {
|
|
12033
|
+
if (typeof mq.removeEventListener === "function") mq.removeEventListener("change", update);
|
|
12034
|
+
else if (typeof mq.removeListener === "function") mq.removeListener(update);
|
|
12035
|
+
};
|
|
11587
12036
|
}
|
|
11588
|
-
function MobileOverlay(
|
|
11589
|
-
const ctx = props && props.ctx;
|
|
12037
|
+
function MobileOverlay() {
|
|
11590
12038
|
const [active, setActive] = (0, import_react23.useState)(() => mobileActive());
|
|
11591
|
-
const [floating, setFloating] = (0, import_react23.useState)(() => floatingShown());
|
|
11592
12039
|
(0, import_react23.useEffect)(() => {
|
|
11593
12040
|
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return void 0;
|
|
11594
12041
|
let mqs = [];
|
|
@@ -11628,56 +12075,217 @@ function MobileOverlay(props) {
|
|
|
11628
12075
|
document.body.removeAttribute("data-dk-mobile");
|
|
11629
12076
|
};
|
|
11630
12077
|
}, [active]);
|
|
11631
|
-
(0, import_react23.useEffect)(() =>
|
|
11632
|
-
|
|
11633
|
-
|
|
11634
|
-
|
|
11635
|
-
|
|
11636
|
-
|
|
11637
|
-
|
|
12078
|
+
(0, import_react23.useEffect)(() => mobileChrome(), []);
|
|
12079
|
+
return null;
|
|
12080
|
+
}
|
|
12081
|
+
function mobileChrome() {
|
|
12082
|
+
if (typeof window === "undefined" || typeof document === "undefined") return void 0;
|
|
12083
|
+
const mq = window.matchMedia ? window.matchMedia(MOBILE_QUERY_CHROME) : null;
|
|
12084
|
+
if (!mq) return void 0;
|
|
12085
|
+
if (window.__dshDockMobileDrawer === "host") return void 0;
|
|
12086
|
+
window.__dshDockMobileDrawer = "client";
|
|
12087
|
+
const narrow = () => mq.matches;
|
|
12088
|
+
const frameEl = () => document.querySelector('[class$="frame"]');
|
|
12089
|
+
const sidebarCollapsed = () => {
|
|
12090
|
+
const f = frameEl();
|
|
12091
|
+
return !!f && f.hasAttribute("data-sidebar-collapsed");
|
|
12092
|
+
};
|
|
12093
|
+
const dialogOpen = () => !!document.querySelector('[role="dialog"][class*="panel"]');
|
|
12094
|
+
const rightOpen = () => !!document.querySelector("[data-sidebar-right-panel][data-sidebar-right-open]");
|
|
12095
|
+
const collapse = () => {
|
|
12096
|
+
const b = document.querySelector('button[aria-label="\u6536\u8D77\u4FA7\u8FB9\u680F"],button[aria-label="Collapse sidebar"]');
|
|
12097
|
+
if (b) b.click();
|
|
12098
|
+
};
|
|
12099
|
+
const expand = () => {
|
|
12100
|
+
const b = document.querySelector('button[aria-label="\u6253\u5F00\u4FA7\u8FB9\u680F"],button[aria-label="Open sidebar"]');
|
|
12101
|
+
if (b) b.click();
|
|
12102
|
+
};
|
|
12103
|
+
const closeDetails = () => {
|
|
12104
|
+
const panel = document.querySelector("[data-sidebar-right-panel][data-sidebar-right-open]");
|
|
12105
|
+
if (!panel) return;
|
|
12106
|
+
const toggle = panel.querySelector("[data-sidebar-right-toggle]");
|
|
12107
|
+
if (toggle) toggle.click();
|
|
12108
|
+
};
|
|
12109
|
+
const scrim = document.createElement("div");
|
|
12110
|
+
scrim.className = "dsh-mobile-scrim";
|
|
12111
|
+
document.body.appendChild(scrim);
|
|
12112
|
+
document.querySelectorAll(".dsh-mobile-tabbar").forEach((el) => el.remove());
|
|
12113
|
+
const tabbar = document.createElement("nav");
|
|
12114
|
+
tabbar.className = "dsh-mobile-tabbar";
|
|
12115
|
+
tabbar.setAttribute("aria-label", "\u5E95\u90E8\u5BFC\u822A");
|
|
12116
|
+
let tasksActive = 0;
|
|
12117
|
+
let tasksWaiting = 0;
|
|
12118
|
+
const tabDefs = [
|
|
12119
|
+
{
|
|
12120
|
+
id: "sessions",
|
|
12121
|
+
label: "\u4F1A\u8BDD",
|
|
12122
|
+
icon: '<svg viewBox="0 0 24 24"><path d="M21 12a8 8 0 0 1-8 8H5l-2 2V12a8 8 0 0 1 8-8h2a8 8 0 0 1 8 8z"/></svg>',
|
|
12123
|
+
act: () => expand()
|
|
12124
|
+
},
|
|
12125
|
+
{
|
|
12126
|
+
id: "dock",
|
|
12127
|
+
label: "\u63D2\u4EF6",
|
|
12128
|
+
icon: '<svg viewBox="0 0 24 24"><rect x="4" y="4" width="7" height="7" rx="1.5"/><rect x="13" y="4" width="7" height="7" rx="1.5"/><rect x="4" y="13" width="7" height="7" rx="1.5"/><rect x="13" y="13" width="7" height="7" rx="1.5"/></svg>',
|
|
12129
|
+
act: () => {
|
|
12130
|
+
openPanel(tasksActive > 0 || tasksWaiting > 0 ? "runstate" : "home");
|
|
12131
|
+
}
|
|
12132
|
+
},
|
|
12133
|
+
{
|
|
12134
|
+
id: "settings",
|
|
12135
|
+
label: "\u8BBE\u7F6E",
|
|
12136
|
+
icon: '<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="3.2"/><path d="M19.4 15a1.7 1.7 0 0 0 .34 1.87l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06A1.7 1.7 0 0 0 15 19.4a1.7 1.7 0 0 0-1 1.55V21a2 2 0 1 1-4 0v-.09A1.7 1.7 0 0 0 9 19.4a1.7 1.7 0 0 0-1.87.34l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06A1.7 1.7 0 0 0 4.6 15a1.7 1.7 0 0 0-1.55-1H3a2 2 0 1 1 0-4h.09A1.7 1.7 0 0 0 4.6 9a1.7 1.7 0 0 0-.34-1.87l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06A1.7 1.7 0 0 0 9 4.6a1.7 1.7 0 0 0 1-1.55V3a2 2 0 1 1 4 0v.09a1.7 1.7 0 0 0 1 1.51 1.7 1.7 0 0 0 1.87-.34l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06A1.7 1.7 0 0 0 19.4 9c.23.6.86 1 1.51 1H21a2 2 0 1 1 0 4h-.09a1.7 1.7 0 0 0-1.51 1z"/></svg>',
|
|
12137
|
+
act: () => {
|
|
12138
|
+
const b = [...document.querySelectorAll("button")].find((x) => {
|
|
12139
|
+
const a = x.getAttribute("aria-label") || "";
|
|
12140
|
+
return a === "\u8BBE\u7F6E" || a === "Settings" || (x.textContent || "").trim() === "\u8BBE\u7F6E";
|
|
12141
|
+
});
|
|
12142
|
+
if (b) b.click();
|
|
12143
|
+
}
|
|
11638
12144
|
}
|
|
12145
|
+
];
|
|
12146
|
+
let tasksBadge = null;
|
|
12147
|
+
const tabButtons = tabDefs.map((def) => {
|
|
12148
|
+
const b = document.createElement("button");
|
|
12149
|
+
b.type = "button";
|
|
12150
|
+
b.className = "dsh-mobile-tab";
|
|
12151
|
+
b.dataset.tab = def.id;
|
|
12152
|
+
b.innerHTML = def.icon + "<span>" + def.label + "</span>";
|
|
12153
|
+
b.addEventListener("click", () => def.act());
|
|
12154
|
+
if (def.id === "dock") {
|
|
12155
|
+
tasksBadge = document.createElement("span");
|
|
12156
|
+
tasksBadge.className = "dsh-mobile-tab-badge";
|
|
12157
|
+
tasksBadge.style.display = "none";
|
|
12158
|
+
b.appendChild(tasksBadge);
|
|
12159
|
+
}
|
|
12160
|
+
tabbar.appendChild(b);
|
|
12161
|
+
return b;
|
|
11639
12162
|
});
|
|
11640
|
-
|
|
11641
|
-
|
|
11642
|
-
|
|
11643
|
-
|
|
11644
|
-
|
|
11645
|
-
|
|
11646
|
-
|
|
12163
|
+
document.body.appendChild(tabbar);
|
|
12164
|
+
const syncTabs = () => {
|
|
12165
|
+
const expanded = !sidebarCollapsed();
|
|
12166
|
+
const settingsOpen = dialogOpen();
|
|
12167
|
+
for (const b of tabButtons) {
|
|
12168
|
+
const id = b.dataset.tab;
|
|
12169
|
+
const on = id === "sessions" && expanded || id === "dock" && panelNav.open || id === "settings" && settingsOpen;
|
|
12170
|
+
b.classList.toggle("on", on);
|
|
11647
12171
|
}
|
|
11648
|
-
|
|
11649
|
-
|
|
11650
|
-
|
|
11651
|
-
|
|
11652
|
-
|
|
11653
|
-
|
|
11654
|
-
|
|
11655
|
-
|
|
11656
|
-
|
|
11657
|
-
|
|
11658
|
-
|
|
11659
|
-
|
|
11660
|
-
|
|
11661
|
-
|
|
11662
|
-
|
|
11663
|
-
|
|
11664
|
-
|
|
11665
|
-
|
|
11666
|
-
|
|
12172
|
+
};
|
|
12173
|
+
const unsubPanel = subscribePanel(syncTabs);
|
|
12174
|
+
let runstateGone = false;
|
|
12175
|
+
const pollTasks = () => {
|
|
12176
|
+
if (runstateGone || !tasksBadge || !narrow() || document.visibilityState === "hidden" || !tabbar.isConnected) return;
|
|
12177
|
+
fetch("dsh-dock/runstate/status", {
|
|
12178
|
+
method: "POST",
|
|
12179
|
+
headers: { "content-type": "application/json" },
|
|
12180
|
+
body: "{}"
|
|
12181
|
+
}).then(async (res) => {
|
|
12182
|
+
if (res.status === 404 || res.status === 405) {
|
|
12183
|
+
runstateGone = true;
|
|
12184
|
+
tasksActive = 0;
|
|
12185
|
+
tasksWaiting = 0;
|
|
12186
|
+
tasksBadge.style.display = "none";
|
|
12187
|
+
return null;
|
|
12188
|
+
}
|
|
12189
|
+
const body = await res.json().catch(() => null);
|
|
12190
|
+
if (!body) return null;
|
|
12191
|
+
const active = body.data && body.data.active || [];
|
|
12192
|
+
const waiting = active.filter((t) => t.approvals && t.approvals.length).length;
|
|
12193
|
+
tasksActive = active.length;
|
|
12194
|
+
tasksWaiting = waiting;
|
|
12195
|
+
if (waiting > 0) {
|
|
12196
|
+
tasksBadge.textContent = String(waiting);
|
|
12197
|
+
tasksBadge.className = "dsh-mobile-tab-badge wait";
|
|
12198
|
+
tasksBadge.style.display = "";
|
|
12199
|
+
} else if (active.length > 0) {
|
|
12200
|
+
tasksBadge.textContent = String(active.length);
|
|
12201
|
+
tasksBadge.className = "dsh-mobile-tab-badge";
|
|
12202
|
+
tasksBadge.style.display = "";
|
|
12203
|
+
} else {
|
|
12204
|
+
tasksBadge.style.display = "none";
|
|
12205
|
+
}
|
|
12206
|
+
}).catch(() => {
|
|
12207
|
+
});
|
|
12208
|
+
};
|
|
12209
|
+
const tasksTimer = setInterval(pollTasks, 3e3);
|
|
12210
|
+
const vv = window.visualViewport || null;
|
|
12211
|
+
const kbdSync = () => {
|
|
12212
|
+
if (!vv) return;
|
|
12213
|
+
const kbd = vv.height > 0 && window.innerHeight - vv.height > 120;
|
|
12214
|
+
document.documentElement.classList.toggle("dsh-dock-kbd", kbd);
|
|
12215
|
+
};
|
|
12216
|
+
const sync = () => {
|
|
12217
|
+
kbdSync();
|
|
12218
|
+
document.querySelectorAll(".dsh-mobile-tabbar").forEach((el) => {
|
|
12219
|
+
if (el !== tabbar) el.remove();
|
|
12220
|
+
});
|
|
12221
|
+
const on = narrow() && !!frameEl() && !dialogOpen();
|
|
12222
|
+
const collapsed = sidebarCollapsed();
|
|
12223
|
+
const right = rightOpen();
|
|
12224
|
+
if (scrim) scrim.style.display = on && !collapsed ? "" : "none";
|
|
12225
|
+
tabbar.style.display = narrow() && !!frameEl() && !panelNav.open && !right ? "" : "none";
|
|
12226
|
+
syncTabs();
|
|
12227
|
+
};
|
|
12228
|
+
sync();
|
|
12229
|
+
pollTasks();
|
|
12230
|
+
const observer = typeof MutationObserver !== "undefined" ? new MutationObserver(sync) : null;
|
|
12231
|
+
if (observer) observer.observe(document.documentElement, { attributes: true, attributeFilter: ["data-sidebar-collapsed"], subtree: true });
|
|
12232
|
+
const timer = setInterval(sync, 1500);
|
|
12233
|
+
const onMq = () => sync();
|
|
12234
|
+
if (mq.addEventListener) mq.addEventListener("change", onMq);
|
|
12235
|
+
else if (mq.addListener) mq.addListener(onMq);
|
|
12236
|
+
window.addEventListener("resize", kbdSync);
|
|
12237
|
+
if (vv && vv.addEventListener) vv.addEventListener("resize", kbdSync);
|
|
12238
|
+
const onVisible = () => {
|
|
12239
|
+
if (document.visibilityState === "visible") pollTasks();
|
|
12240
|
+
};
|
|
12241
|
+
document.addEventListener("visibilitychange", onVisible);
|
|
12242
|
+
const onClick = (e) => {
|
|
12243
|
+
if (!narrow()) return;
|
|
12244
|
+
const t = e.target;
|
|
12245
|
+
if (!t || !t.closest) return;
|
|
12246
|
+
if (t.closest(".dsh-mobile-tabbar")) return;
|
|
12247
|
+
const expanded = !!document.querySelector('button[aria-label="\u6536\u8D77\u4FA7\u8FB9\u680F"],button[aria-label="Collapse sidebar"]');
|
|
12248
|
+
const col = document.querySelector('[class*="sidebarCol"]');
|
|
12249
|
+
const inSidebar = col && col.contains(t);
|
|
12250
|
+
if (!expanded && !inSidebar) return;
|
|
12251
|
+
if (inSidebar) {
|
|
12252
|
+
const row = t.closest('[role="treeitem"]');
|
|
12253
|
+
const rowKey = row && row.getAttribute("data-row-key") || "";
|
|
12254
|
+
const sessionRow = rowKey && rowKey.startsWith("session:") || row && !rowKey && !row.querySelector('[role="treeitem"]') && row.closest('[role="tree"]');
|
|
12255
|
+
const fresh = t.closest('[class*="newSession"]');
|
|
12256
|
+
if (sessionRow || fresh) {
|
|
12257
|
+
setTimeout(() => {
|
|
12258
|
+
collapse();
|
|
12259
|
+
closeDetails();
|
|
12260
|
+
}, 300);
|
|
12261
|
+
return;
|
|
12262
|
+
}
|
|
12263
|
+
if (rowKey.startsWith("workspace:")) return;
|
|
12264
|
+
setTimeout(() => {
|
|
12265
|
+
if (document.querySelector('[role="dialog"]')) collapse();
|
|
12266
|
+
}, 260);
|
|
12267
|
+
return;
|
|
11667
12268
|
}
|
|
12269
|
+
if (t.closest('[role="dialog"],[class*="dockm"],[class*="dgfab"],[class*="dgwin"],[class*="dgame"],[data-sidebar-right-panel]')) return;
|
|
12270
|
+
collapse();
|
|
12271
|
+
};
|
|
12272
|
+
document.addEventListener("click", onClick, true);
|
|
12273
|
+
return () => {
|
|
12274
|
+
document.removeEventListener("click", onClick, true);
|
|
12275
|
+
if (observer) observer.disconnect();
|
|
12276
|
+
clearInterval(timer);
|
|
12277
|
+
clearInterval(tasksTimer);
|
|
12278
|
+
unsubPanel();
|
|
12279
|
+
if (mq.removeEventListener) mq.removeEventListener("change", onMq);
|
|
12280
|
+
else if (mq.removeListener) mq.removeListener(onMq);
|
|
12281
|
+
window.removeEventListener("resize", kbdSync);
|
|
12282
|
+
if (vv && vv.removeEventListener) vv.removeEventListener("resize", kbdSync);
|
|
12283
|
+
document.removeEventListener("visibilitychange", onVisible);
|
|
12284
|
+
document.documentElement.classList.remove("dsh-dock-kbd");
|
|
12285
|
+
if (scrim) scrim.remove();
|
|
12286
|
+
tabbar.remove();
|
|
12287
|
+
if (window.__dshDockMobileDrawer === "client") delete window.__dshDockMobileDrawer;
|
|
11668
12288
|
};
|
|
11669
|
-
return import_react22.default.createElement("button", {
|
|
11670
|
-
type: "button",
|
|
11671
|
-
className: "dkmob-fab",
|
|
11672
|
-
"aria-label": "\u5F00\u5173\u4FA7\u680F",
|
|
11673
|
-
title: "\u5F00\u5173\u4FA7\u680F",
|
|
11674
|
-
onClick: onToggle
|
|
11675
|
-
}, import_react22.default.createElement(
|
|
11676
|
-
"svg",
|
|
11677
|
-
{ width: 20, height: 20, viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: 1.3, "aria-hidden": true },
|
|
11678
|
-
import_react22.default.createElement("rect", { x: 1.5, y: 2.5, width: 13, height: 11, rx: 2 }),
|
|
11679
|
-
import_react22.default.createElement("line", { x1: 6, y1: 2.5, x2: 6, y2: 13.5 })
|
|
11680
|
-
));
|
|
11681
12289
|
}
|
|
11682
12290
|
function useViewportSize() {
|
|
11683
12291
|
const [size, setSize] = (0, import_react23.useState)(() => typeof window === "undefined" ? null : { w: window.innerWidth, h: window.innerHeight });
|
|
@@ -11689,31 +12297,38 @@ function useViewportSize() {
|
|
|
11689
12297
|
}, []);
|
|
11690
12298
|
return size;
|
|
11691
12299
|
}
|
|
11692
|
-
function
|
|
12300
|
+
function useMobileState() {
|
|
11693
12301
|
const [active, setActive] = (0, import_react23.useState)(() => mobileActive());
|
|
11694
|
-
const [
|
|
11695
|
-
const
|
|
12302
|
+
const [chrome, setChrome] = (0, import_react23.useState)(() => typeof window === "undefined" || typeof window.matchMedia !== "function" ? false : window.matchMedia(MOBILE_QUERY_CHROME).matches);
|
|
12303
|
+
const [owner, setOwner] = (0, import_react23.useState)(() => typeof window === "undefined" ? null : window.__dshDockMobileDrawer || null);
|
|
11696
12304
|
(0, import_react23.useEffect)(() => {
|
|
11697
|
-
|
|
12305
|
+
const offChrome = watchQuery(MOBILE_QUERY_CHROME, setChrome);
|
|
11698
12306
|
let mqs = [];
|
|
11699
12307
|
try {
|
|
11700
12308
|
mqs = [window.matchMedia(MOBILE_QUERY_NARROW), window.matchMedia(MOBILE_QUERY_COARSE)];
|
|
11701
12309
|
} catch {
|
|
11702
|
-
|
|
12310
|
+
mqs = [];
|
|
11703
12311
|
}
|
|
11704
|
-
const
|
|
11705
|
-
update();
|
|
12312
|
+
const compute = () => setActive(mqs.some((mq) => mq.matches));
|
|
11706
12313
|
for (const mq of mqs) {
|
|
11707
|
-
if (typeof mq.addEventListener === "function") mq.addEventListener("change",
|
|
11708
|
-
else if (typeof mq.addListener === "function") mq.addListener(
|
|
12314
|
+
if (typeof mq.addEventListener === "function") mq.addEventListener("change", compute);
|
|
12315
|
+
else if (typeof mq.addListener === "function") mq.addListener(compute);
|
|
11709
12316
|
}
|
|
12317
|
+
const timer = setInterval(() => setOwner(typeof window === "undefined" ? null : window.__dshDockMobileDrawer || null), 1e3);
|
|
11710
12318
|
return () => {
|
|
12319
|
+
offChrome();
|
|
11711
12320
|
for (const mq of mqs) {
|
|
11712
|
-
if (typeof mq.removeEventListener === "function") mq.removeEventListener("change",
|
|
11713
|
-
else if (typeof mq.removeListener === "function") mq.removeListener(
|
|
12321
|
+
if (typeof mq.removeEventListener === "function") mq.removeEventListener("change", compute);
|
|
12322
|
+
else if (typeof mq.removeListener === "function") mq.removeListener(compute);
|
|
11714
12323
|
}
|
|
12324
|
+
clearInterval(timer);
|
|
11715
12325
|
};
|
|
11716
12326
|
}, []);
|
|
12327
|
+
return { active, chrome, owner };
|
|
12328
|
+
}
|
|
12329
|
+
function MobileView() {
|
|
12330
|
+
const { active, chrome, owner } = useMobileState();
|
|
12331
|
+
const size = useViewportSize();
|
|
11717
12332
|
return import_react22.default.createElement(
|
|
11718
12333
|
"div",
|
|
11719
12334
|
{ className: "dkmob-root" },
|
|
@@ -11732,73 +12347,44 @@ function MobileView() {
|
|
|
11732
12347
|
import_react22.default.createElement(
|
|
11733
12348
|
"div",
|
|
11734
12349
|
{ className: "dkmob-row" },
|
|
11735
|
-
import_react22.default.createElement("span", { className: "dkmob-label" }, "\
|
|
11736
|
-
import_react22.default.createElement("
|
|
11737
|
-
|
|
11738
|
-
|
|
11739
|
-
|
|
11740
|
-
"
|
|
11741
|
-
"
|
|
11742
|
-
|
|
11743
|
-
onClick: () => setFloatingShown(!floating)
|
|
11744
|
-
}),
|
|
11745
|
-
import_react22.default.createElement("span", { className: "dkmob-dim" }, "44px \u5706\u94AE\u56FA\u5B9A\u5728\u5DE6\u4E0B\u89D2\uFF0C\u8C03\u7528 dsh \u5B98\u65B9 toggleSidebar \u5F00\u5408\u7A84\u5C4F\u62BD\u5C49\uFF1B\u4E0D\u9700\u8981\u65F6\u53EF\u5728\u6B64\u5173\u95ED\u3002")
|
|
12350
|
+
import_react22.default.createElement("span", { className: "dkmob-label" }, "\u624B\u673A\u7AEF chrome"),
|
|
12351
|
+
import_react22.default.createElement("span", { className: "dkmob-state" + (chrome ? " on" : "") }, chrome ? "\u2264700px\uFF0C\u751F\u6548\u4E2D" : "\u672A\u547D\u4E2D"),
|
|
12352
|
+
import_react22.default.createElement(
|
|
12353
|
+
"span",
|
|
12354
|
+
{ className: "dkmob-dim" },
|
|
12355
|
+
"\u5E95\u90E8 Tab \u680F\uFF08\u4F1A\u8BDD / \u63D2\u4EF6 / \u8BBE\u7F6E\uFF09+ \u4FA7\u680F\u62BD\u5C49\u906E\u7F69 + \u8F6F\u952E\u76D8\u8BA9\u4F4D\uFF1B\u4F1A\u8BDD\u5165\u53E3\u5728\u5E95\u90E8\u300C\u4F1A\u8BDD\u300D\u9875\u7B7E\uFF0C\u4E0D\u8BBE\u5DE6\u7F18\u6D6E\u52A8\u6309\u94AE\u3002",
|
|
12356
|
+
owner === "host" ? "\u5F53\u524D\u7531\u5BBF\u4E3B\u6CE8\u5165\u7248\u9A71\u52A8\uFF08\u91CD\u542F dsh web \u540E\u751F\u6548\u7684\u90A3\u5957\uFF09\u3002" : owner === "client" ? "\u5F53\u524D\u7531\u5BA2\u6237\u7AEF\u81EA\u5EFA\u7248\u9A71\u52A8\uFF08\u5237\u65B0\u5373\u751F\u6548\uFF09\u3002" : ""
|
|
12357
|
+
)
|
|
11746
12358
|
),
|
|
11747
12359
|
import_react22.default.createElement(
|
|
11748
12360
|
"div",
|
|
11749
12361
|
{ className: "dkmob-note" },
|
|
11750
12362
|
"\u751F\u6548\u4E2D\u7684\u4F18\u5316\uFF1A\u8F93\u5165\u7C7B\u63A7\u4EF6\u5B57\u53F7\u62C9\u5230 16px\uFF08\u907F\u514D iOS \u805A\u7126\u7F29\u653E\u6574\u9875\uFF09\xB7 \u7EAF\u56FE\u6807\u6309\u94AE\u9762\u79EF\u515C\u5E95 \u226536px \xB7 ",
|
|
11751
|
-
"\u53BB\u6389\u70B9\u6309\u9AD8\u4EAE\u4E0E\u53CC\u51FB\u7F29\u653E\u5224\u5B9A \xB7 \u4EE3\u7801\u5757\u6A2A\u5411\u6EDA\u52A8\u3001\u884C\u5185\u4EE3\u7801\u81EA\u52A8\u6362\u884C \xB7
|
|
12363
|
+
"\u53BB\u6389\u70B9\u6309\u9AD8\u4EAE\u4E0E\u53CC\u51FB\u7F29\u653E\u5224\u5B9A \xB7 \u4EE3\u7801\u5757\u6A2A\u5411\u6EDA\u52A8\u3001\u884C\u5185\u4EE3\u7801\u81EA\u52A8\u6362\u884C \xB7 \u6EDA\u52A8\u4F53 touch-action:pan-y + iOS \u60EF\u6027\u6EDA\u52A8 \xB7 ",
|
|
12364
|
+
"\u8BBE\u7F6E\u5F39\u5C42\u5185\u5BB9\u5217 min-height:0\uFF08\u5426\u5219\u7A84\u5C4F\u5F39\u5C42\u88AB\u5185\u5BB9\u6491\u9AD8\u540E\u6574\u7247\u6ED1\u4E0D\u52A8\uFF09\xB7 viewport meta \u8865 viewport-fit=cover",
|
|
11752
12365
|
"\uFF08standalone \u5168\u5C4F\u65F6\u7ED9\u5706\u89D2/\u5218\u6D77\u7559\u5B89\u5168\u533A\uFF09\u3002\u505C\u7528\u672C\u529F\u80FD\u5373\u5168\u90E8\u8FD8\u539F\u3002"
|
|
11753
12366
|
)
|
|
11754
12367
|
);
|
|
11755
12368
|
}
|
|
11756
12369
|
function MobileStat() {
|
|
11757
|
-
const
|
|
11758
|
-
const [floating, setFloating] = (0, import_react23.useState)(() => floatingShown());
|
|
11759
|
-
(0, import_react23.useEffect)(() => {
|
|
11760
|
-
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return void 0;
|
|
11761
|
-
let mqs = [];
|
|
11762
|
-
try {
|
|
11763
|
-
mqs = [window.matchMedia(MOBILE_QUERY_NARROW), window.matchMedia(MOBILE_QUERY_COARSE)];
|
|
11764
|
-
} catch {
|
|
11765
|
-
return void 0;
|
|
11766
|
-
}
|
|
11767
|
-
const update = () => setActive(mqs.some((mq) => mq.matches));
|
|
11768
|
-
update();
|
|
11769
|
-
for (const mq of mqs) {
|
|
11770
|
-
if (typeof mq.addEventListener === "function") mq.addEventListener("change", update);
|
|
11771
|
-
else if (typeof mq.addListener === "function") mq.addListener(update);
|
|
11772
|
-
}
|
|
11773
|
-
return () => {
|
|
11774
|
-
for (const mq of mqs) {
|
|
11775
|
-
if (typeof mq.removeEventListener === "function") mq.removeEventListener("change", update);
|
|
11776
|
-
else if (typeof mq.removeListener === "function") mq.removeListener(update);
|
|
11777
|
-
}
|
|
11778
|
-
};
|
|
11779
|
-
}, []);
|
|
11780
|
-
(0, import_react23.useEffect)(() => subscribePref(() => setFloating(floatingShown())), []);
|
|
12370
|
+
const { active, chrome } = useMobileState();
|
|
11781
12371
|
if (!active) return import_react22.default.createElement("span", null, "\u5F53\u524D\u89C6\u53E3\u672A\u547D\u4E2D\u624B\u673A\u5F62\u6001\uFF0C\u6837\u5F0F\u672A\u6CE8\u5165");
|
|
11782
|
-
return import_react22.default.createElement("span", null, "\u624B\u673A\u6A21\u5F0F\u751F\u6548\u4E2D \xB7
|
|
12372
|
+
return import_react22.default.createElement("span", null, "\u624B\u673A\u6A21\u5F0F\u751F\u6548\u4E2D \xB7 " + (chrome ? "\u5E95\u90E8 Tab \u680F\u5DF2\u63A5\u7BA1\u4F1A\u8BDD\u5165\u53E3" : "chrome \u5E26\u5BBD\u672A\u547D\u4E2D\uFF08\u2264700px \u624D\u542F\u7528\uFF09"));
|
|
11783
12373
|
}
|
|
11784
12374
|
var css6 = [
|
|
11785
|
-
// 浮动侧栏按钮:44px 触控面积(Apple HIG 最低建议),token 取主题变量自动适配亮暗色;
|
|
11786
|
-
// z-index 190 压在功能坞弹层(dockm-backdrop,200)之下,弹层打开时被遮罩盖住不误触。
|
|
11787
|
-
".dkmob-fab{position:fixed;left:calc(env(safe-area-inset-left,0px) + 62px);bottom:calc(env(safe-area-inset-bottom,0px) + 74px);z-index:190;width:44px;height:44px;border-radius:50%;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-secondary);display:inline-flex;align-items:center;justify-content:center;padding:0;box-shadow:0 4px 14px rgb(0 0 0 / .22);cursor:pointer;touch-action:manipulation;-webkit-tap-highlight-color:transparent;transition:transform .12s var(--ds-ease-in-out),background .15s var(--ds-ease-in-out),color .15s var(--ds-ease-in-out);}",
|
|
11788
|
-
".dkmob-fab:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary);}",
|
|
11789
|
-
".dkmob-fab:active{transform:scale(.94);}",
|
|
11790
12375
|
// 输入类控件 16px:防 iOS 聚焦自动放大(<16px 的输入框聚焦时 Safari 强制缩放页面)
|
|
11791
12376
|
'body[data-dk-mobile="1"] :is(textarea, input:not([type]), input[type="text"], input[type="search"], input[type="url"], input[type="password"], input[type="number"], input[type="email"], [contenteditable="true"]){font-size:16px !important;}',
|
|
11792
12377
|
// 触控基础:去点按高亮、消双击缩放判定
|
|
11793
12378
|
'body[data-dk-mobile="1"] :is(button, [role="button"]){-webkit-tap-highlight-color:transparent;touch-action:manipulation;}',
|
|
11794
12379
|
// 纯图标按钮面积兜底:实测窄屏下一批 28×28 的工具钮很难点中;36px 是不引起行高剧变的上限。
|
|
11795
|
-
// 只收「唯一子元素是 svg
|
|
11796
|
-
|
|
11797
|
-
'body[data-dk-mobile="1"] button:has(> svg:only-child):not(.dsh-mobile-drawer-btn):not(.dkmob-fab){min-width:36px;min-height:36px;}',
|
|
12380
|
+
// 只收「唯一子元素是 svg」的按钮,避免撑坏带文字的行内控件;排除本模块 chrome 按钮。
|
|
12381
|
+
'body[data-dk-mobile="1"] button:has(> svg:only-child):not(.dsh-mobile-tab){min-width:36px;min-height:36px;}',
|
|
11798
12382
|
// 代码块横向滚动、行内代码换行:窄屏不撑破版面
|
|
11799
12383
|
'body[data-dk-mobile="1"] pre{max-width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;}',
|
|
11800
12384
|
'body[data-dk-mobile="1"] code{overflow-wrap:anywhere;}',
|
|
11801
12385
|
'body[data-dk-mobile="1"] pre code{overflow-wrap:normal;}',
|
|
12386
|
+
// 滚动兜底:所有纵向滚动体可纵向平移 + iOS 惯性滚动(祖先合成层/触控声明不再吃掉触摸滚动)。
|
|
12387
|
+
'body[data-dk-mobile="1"] :is([class*="scrollBody"], [class*="sidebarCol"] [class*="list"], [role="dialog"] [class*="options"], [class*="dockm-content"]){-webkit-overflow-scrolling:touch;overscroll-behavior-y:contain;touch-action:pan-y;}',
|
|
11802
12388
|
// iOS 横竖屏切换时的字号自动膨胀关掉(:has 挂到 html 上;dsh 自身样式已依赖 :has,基线足够)
|
|
11803
12389
|
'html:has(body[data-dk-mobile="1"]){-webkit-text-size-adjust:100%;text-size-adjust:100%;}',
|
|
11804
12390
|
// 功能页自身
|
|
@@ -11808,14 +12394,66 @@ var css6 = [
|
|
|
11808
12394
|
".dkmob-state{flex:none;border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-tertiary);border-radius:999px;padding:1px 10px;font-size:11px;}",
|
|
11809
12395
|
".dkmob-state.on{color:var(--dsw-alias-state-success-primary);border-color:var(--dsw-alias-state-success-primary);}",
|
|
11810
12396
|
".dkmob-dim{color:var(--dsw-alias-label-secondary);font-size:12px;}",
|
|
11811
|
-
".dkmob-note{color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.7;border-top:1px solid var(--dsw-alias-border-l1);padding-top:10px;}"
|
|
12397
|
+
".dkmob-note{color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.7;border-top:1px solid var(--dsw-alias-border-l1);padding-top:10px;}",
|
|
12398
|
+
// 手机端 chrome:底部 Tab 栏 + 抽屉遮罩(窄屏 ≤700px;与宿主半部同款)
|
|
12399
|
+
"@media (max-width:700px){",
|
|
12400
|
+
".dsh-mobile-scrim{position:fixed;inset:0;z-index:75;background:rgba(8,10,14,.45);backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px);touch-action:none}",
|
|
12401
|
+
".dsh-mobile-tabbar{position:fixed;left:0;right:0;bottom:0;z-index:65;display:flex;align-items:stretch;justify-content:space-around;padding:6px 8px calc(8px + env(safe-area-inset-bottom,0px));background:color-mix(in srgb,var(--dsw-alias-bg-layer-2,#1c2230) 92%,transparent);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border-top:1px solid var(--dsw-alias-border-l1,rgba(127,139,161,.25));touch-action:manipulation}",
|
|
12402
|
+
".dsh-mobile-tab{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;min-height:48px;padding:4px 0;border:0;background:transparent;color:var(--dsw-alias-label-tertiary,#8b95ab);font:600 11px/1.2 inherit;cursor:pointer;-webkit-tap-highlight-color:transparent;border-radius:10px;position:relative}",
|
|
12403
|
+
".dsh-mobile-tab svg{width:21px;height:21px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}",
|
|
12404
|
+
".dsh-mobile-tab.on{color:var(--dsw-alias-label-primary,#e6eaf2)}",
|
|
12405
|
+
".dsh-mobile-tab.on svg{color:var(--dk-accent,#4d9fff)}",
|
|
12406
|
+
".dsh-mobile-tab:active{transform:scale(.94)}",
|
|
12407
|
+
".dsh-mobile-tab-badge{position:absolute;top:0;right:calc(50% - 26px);box-sizing:border-box;min-width:16px;height:16px;padding:0 4px;border-radius:9px;display:flex;align-items:center;justify-content:center;background:#4d9fff;color:#fff;font-size:10px;font-weight:700;line-height:1;font-variant-numeric:tabular-nums;box-shadow:0 2px 8px rgba(0,0,0,.35);pointer-events:none}",
|
|
12408
|
+
".dsh-mobile-tab-badge.wait{background:#ef4444;animation:dsh-badge-pulse 1.2s ease-in-out infinite}",
|
|
12409
|
+
"@keyframes dsh-badge-pulse{0%,100%{transform:scale(1)}50%{transform:scale(1.18)}}",
|
|
12410
|
+
"@media (prefers-reduced-motion:reduce){.dsh-mobile-tab-badge.wait{animation:none}}",
|
|
12411
|
+
// ⚠️ 「设置页滑不动」的关键兜底(客户端无条件携带 = 刷新即生效,不必等宿主重启):
|
|
12412
|
+
// 窄屏把设置弹层改成纵向堆叠后,内容列若是默认 min-height:auto 就会被内容撑高
|
|
12413
|
+
// (无头 390×844 实测列高 1216px 塞在 844px 视口里)、再被 .panel 的 overflow:hidden
|
|
12414
|
+
// 裁掉——列内滚动容器([class*=options])因此 scrollHeight==clientHeight,手指怎么滑
|
|
12415
|
+
// 都不动。补 min-height:0 后 scrollTop 0 → 425。宿主半部 MOBILE_LAYOUT_CSS 同款;
|
|
12416
|
+
// 两处都写是因为宿主注入要重启 dsh web 才更新,而客户端样式刷新即生效,覆盖窗口期。
|
|
12417
|
+
'[role="dialog"][class*="panel"]>[class*="content"]{min-height:0!important}',
|
|
12418
|
+
// 输入区吸附到 Tab 栏上方 + 滚动体留白(与宿主半部同款)。
|
|
12419
|
+
// ⚠️ 绝不能给滚动体加 justify-content:flex-end/center 贴底:内容会被挤到滚动体
|
|
12420
|
+
// 起点之外,Chrome 不把起点方向溢出算进 scrollHeight(手机视口实测
|
|
12421
|
+
// scrollHeight==clientHeight、maxScroll==0),会话记录彻底滚不动、首条消息永远看不到。
|
|
12422
|
+
// 宿主半部旧版注入里还留着那条 flex-end(要重启 dsh web 才消失),这里用更高优先级
|
|
12423
|
+
// 的选择器显式复位:刷新页面即修好,不必等重启。
|
|
12424
|
+
'[class*="scrollBody"][data-conversation-scroll]{justify-content:flex-start !important;padding-bottom:calc(72px + env(safe-area-inset-bottom,0px)) !important}',
|
|
12425
|
+
'html:not(.dsh-dock-kbd) [class*="scrollBody"]{padding-bottom:calc(72px + env(safe-area-inset-bottom,0px)) !important}',
|
|
12426
|
+
'html.dsh-dock-kbd [class*="scrollBody"]{padding-bottom:12px !important}',
|
|
12427
|
+
'[class*="scrollBody"]>[class*="composerSeat"]{margin-top:auto;padding-bottom:6px}',
|
|
12428
|
+
// 输入区工具行上的 dsh-dock chip(用量/余额):窄屏下 28cqw 的宽度上限把它们挤成
|
|
12429
|
+
// 「…」「余..」(手机实测),既读不出数值又白占输入行空间。手机端整组收起,数值在
|
|
12430
|
+
// 底部「插件」里看(用量/余额页信息更全);桌面端不动。
|
|
12431
|
+
".dockchip-row{display:none}",
|
|
12432
|
+
'[class*="sidebarCol"]:has([class*="collapsed"]){visibility:hidden}',
|
|
12433
|
+
// ⚠️ 列级 visibility:hidden 在 dsh 0.2.0 上挡不住:工作区浏览器给自己的
|
|
12434
|
+
// headerActions/sectionLabel 显式声明 visibility:visible(展开/收拢动画用),visibility
|
|
12435
|
+
// 可被后代覆盖,轨道按钮会从隐藏列里「透」出来(实测手机截图左缘游离按钮)。
|
|
12436
|
+
// display:none 不可被后代翻转——但只能打在**轨道根节点**上(类名同时含 root 与
|
|
12437
|
+
// collapsed 两个语义后缀),绝不能打在列上:frame 是「侧栏 0px + 中列 1fr + 右轨 0px」
|
|
12438
|
+
// 的网格,列 display:none 会从网格流里摘掉,中列被自动放置顶进 0px 轨(实测整页空屏)。
|
|
12439
|
+
// 弹层打开时豁免(设置弹层挂在列内部,display:none 会连坐成空气弹层),此时列退回
|
|
12440
|
+
// visibility 机制(由下一条 [role=dialog] 强制可见),窄屏弹层全屏铺满盖住透出的轨道。
|
|
12441
|
+
'[class*="sidebarCol"]:has([class*="collapsed"]):not(:has([role="dialog"])) [class*="root"][class*="collapsed"]{display:none !important}',
|
|
12442
|
+
// 设置/插件管理弹层挂在侧栏列内部:上面隐藏整列会把它连坐隐藏(空气弹层)。
|
|
12443
|
+
// visibility 可被后代覆盖,弹层关闭态整体卸载,所以只在真正打开时命中。
|
|
12444
|
+
'[class*="sidebarCol"]:has([class*="collapsed"]) [role="dialog"]{visibility:visible}',
|
|
12445
|
+
"html.dsh-dock-kbd .dsh-mobile-tabbar{display:none !important}",
|
|
12446
|
+
// 功能坞面板在手机端抬到原生弹层之上:从侧栏进的官方插件管理页等原生弹层 z 序高于
|
|
12447
|
+
// 面板默认的 200,功能坞开在下面会被盖住——「插件」页签点了像没反应/露出原页面。
|
|
12448
|
+
'[class*="dockm-backdrop"]{z-index:2000 !important}',
|
|
12449
|
+
"}"
|
|
11812
12450
|
].join("\n");
|
|
11813
12451
|
var feature11 = {
|
|
11814
12452
|
id: "mobile",
|
|
11815
12453
|
name: "\u624B\u673A\u9002\u914D",
|
|
11816
12454
|
order: 170,
|
|
11817
12455
|
accent: "#34d399",
|
|
11818
|
-
description: "\u624B\u673A/\u7A84\u5C4F\u6392\u7248\u4E0E\u89E6\u63A7\u515C\u5E95\
|
|
12456
|
+
description: "\u624B\u673A/\u7A84\u5C4F\u6392\u7248\u4E0E\u89E6\u63A7\u515C\u5E95\uFF1A\u5E95\u90E8 Tab \u680F + \u4FA7\u680F\u62BD\u5C49\u300116px \u8F93\u5165\u9632 iOS \u7F29\u653E\u3001\u56FE\u6807\u6309\u94AE\u89E6\u63A7\u9762\u79EF\u3001\u4EE3\u7801\u5757\u6EDA\u52A8\u3001\u6EDA\u52A8\u515C\u5E95",
|
|
11819
12457
|
defaultEnabled: true,
|
|
11820
12458
|
css: css6,
|
|
11821
12459
|
Overlay: MobileOverlay,
|
|
@@ -11824,7 +12462,7 @@ var feature11 = {
|
|
|
11824
12462
|
};
|
|
11825
12463
|
|
|
11826
12464
|
// src/client.jsx
|
|
11827
|
-
var DOCK_VERSION = "0.
|
|
12465
|
+
var DOCK_VERSION = "0.14.0";
|
|
11828
12466
|
var BUILTIN_FEATURES = [feature, feature2, feature3, feature4, feature5, feature6, feature7, feature8, feature9, feature10, feature11];
|
|
11829
12467
|
var PLANNED_FEATURES = [];
|
|
11830
12468
|
var PLANNED_NOTES = {};
|