dsh-dock 0.19.0 → 0.20.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 +10 -14
- package/client.js +360 -614
- package/features/animation/view.jsx +26 -12
- package/features/mobile-relay/host.js +3 -4
- package/features/mobile-relay/view.jsx +1 -2
- package/features/notify/host.js +2 -1
- package/features/notify/view.jsx +200 -39
- package/features/runstate/host.js +1 -11
- package/features/runstate/view.jsx +32 -15
- package/index.js +0 -3
- package/package.json +2 -2
- package/src/client.jsx +2 -3
- package/src/host-core.js +2 -1
- package/src/shared.js +86 -0
- package/src/task-track.js +87 -0
- package/features/mobile/host.js +0 -315
- package/features/mobile/view.js +0 -530
package/client.js
CHANGED
|
@@ -2126,7 +2126,7 @@ __export(client_exports, {
|
|
|
2126
2126
|
inject: () => inject
|
|
2127
2127
|
});
|
|
2128
2128
|
module.exports = __toCommonJS(client_exports);
|
|
2129
|
-
var
|
|
2129
|
+
var import_react24 = __toESM(require("react"), 1);
|
|
2130
2130
|
|
|
2131
2131
|
// src/shared.js
|
|
2132
2132
|
var import_react = __toESM(require("react"), 1);
|
|
@@ -2295,6 +2295,51 @@ function subscribePanel(fn) {
|
|
|
2295
2295
|
navListeners.delete(fn);
|
|
2296
2296
|
};
|
|
2297
2297
|
}
|
|
2298
|
+
function taskApprovals(task) {
|
|
2299
|
+
return task && Array.isArray(task.approvals) ? task.approvals : [];
|
|
2300
|
+
}
|
|
2301
|
+
function taskQuestions(task) {
|
|
2302
|
+
return task && Array.isArray(task.questions) ? task.questions : [];
|
|
2303
|
+
}
|
|
2304
|
+
function taskWaiting(task) {
|
|
2305
|
+
return taskApprovals(task).length > 0 || taskQuestions(task).length > 0;
|
|
2306
|
+
}
|
|
2307
|
+
function waitingCountOf(active) {
|
|
2308
|
+
return (active || []).reduce((n, t) => n + taskApprovals(t).length + taskQuestions(t).length, 0);
|
|
2309
|
+
}
|
|
2310
|
+
var TASK_STALL_MS = 18e3;
|
|
2311
|
+
var TASK_BUSY_MS = 18e4;
|
|
2312
|
+
function numOf(v) {
|
|
2313
|
+
const n = Number(v);
|
|
2314
|
+
return Number.isFinite(n) && n > 0 ? n : 0;
|
|
2315
|
+
}
|
|
2316
|
+
function taskActivityAt(task) {
|
|
2317
|
+
if (!task) return 0;
|
|
2318
|
+
return Math.max(numOf(task.lastActivityAt), numOf(task.lastMotionAt), numOf(task.phaseAt));
|
|
2319
|
+
}
|
|
2320
|
+
function taskBusy(task, now, capMs) {
|
|
2321
|
+
if (!task) return false;
|
|
2322
|
+
const at = typeof now === "number" ? now : Date.now();
|
|
2323
|
+
const cap = typeof capMs === "number" && capMs > 0 ? capMs : TASK_BUSY_MS;
|
|
2324
|
+
if (task.compacting === true) {
|
|
2325
|
+
const since = numOf(task.compactStartedAt);
|
|
2326
|
+
if (!since || at - since < cap) return true;
|
|
2327
|
+
}
|
|
2328
|
+
if (typeof task.pendingTool === "string" && task.pendingTool) {
|
|
2329
|
+
const since = numOf(task.toolStartedAt);
|
|
2330
|
+
if (!since || at - since < cap) return true;
|
|
2331
|
+
}
|
|
2332
|
+
return false;
|
|
2333
|
+
}
|
|
2334
|
+
function taskStalled(task, now, thresholdMs) {
|
|
2335
|
+
if (!task || taskWaiting(task) || taskBusy(task, now)) return 0;
|
|
2336
|
+
const at = typeof now === "number" ? now : Date.now();
|
|
2337
|
+
const limit = typeof thresholdMs === "number" && thresholdMs > 0 ? thresholdMs : TASK_STALL_MS;
|
|
2338
|
+
const lastAct = taskActivityAt(task);
|
|
2339
|
+
if (!lastAct) return 0;
|
|
2340
|
+
const stalled = at - lastAct;
|
|
2341
|
+
return stalled >= limit ? stalled : 0;
|
|
2342
|
+
}
|
|
2298
2343
|
|
|
2299
2344
|
// features/tokenlog/view.jsx
|
|
2300
2345
|
var import_react2 = __toESM(require("react"), 1);
|
|
@@ -6200,13 +6245,15 @@ function MissionDeparture(props) {
|
|
|
6200
6245
|
}
|
|
6201
6246
|
function ProgrammingStuck(props) {
|
|
6202
6247
|
const waiting = !!props.waiting;
|
|
6248
|
+
const task = props.task;
|
|
6249
|
+
const label = !waiting ? "\u7F16\u7A0B\u7B49\u5F85\u4E2D" : taskApprovals(task).length > 0 ? "\u7B49\u5F85\u786E\u8BA4" : "\u7B49\u5F85\u56DE\u7B54";
|
|
6203
6250
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dkan-space-stuck" + (waiting ? " waiting" : ""), "aria-hidden": "true", children: [
|
|
6204
6251
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(FreighterHull, { units: 3, empty: true }),
|
|
6205
6252
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dkan-stuck-code", children: [
|
|
6206
6253
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", {}),
|
|
6207
6254
|
`{ }`
|
|
6208
6255
|
] }),
|
|
6209
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children:
|
|
6256
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: label }),
|
|
6210
6257
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("small", { children: truncate(props.task && props.task.title || "\u5DE5\u5177\u6682\u65E0\u65B0\u54CD\u5E94", 28) })
|
|
6211
6258
|
] });
|
|
6212
6259
|
}
|
|
@@ -6359,7 +6406,8 @@ function AnimationOverlay(props) {
|
|
|
6359
6406
|
const animOn = !!(cfg && cfg.animationEnabled && active.length > 0);
|
|
6360
6407
|
const mode = cfg && cfg.effectMode ? cfg.effectMode : "flow";
|
|
6361
6408
|
const phase = active.length > 0 ? active.reduce((best, x) => !best || (x.phaseAt || 0) > (best.phaseAt || 0) ? x : best, null).phase : "think";
|
|
6362
|
-
const waitingTask = active.find((x) =>
|
|
6409
|
+
const waitingTask = active.find((x) => taskWaiting(x)) || null;
|
|
6410
|
+
const waitWord = waitingTask && taskApprovals(waitingTask).length === 0 ? "\u7B49\u5F85\u56DE\u7B54" : "\u7B49\u5F85\u786E\u8BA4";
|
|
6363
6411
|
const sessionTitleRef = (0, import_react9.useRef)({ at: 0, title: "" });
|
|
6364
6412
|
const currentTitle = (0, import_react9.useMemo)(() => {
|
|
6365
6413
|
const c = sessionTitleRef.current;
|
|
@@ -6370,7 +6418,7 @@ function AnimationOverlay(props) {
|
|
|
6370
6418
|
return c.title;
|
|
6371
6419
|
}, [snap.status]);
|
|
6372
6420
|
const onScreenTasks = (0, import_react9.useMemo)(() => active.filter((x) => taskOnScreen(x, currentTitle)), [active, currentTitle]);
|
|
6373
|
-
const waitingTaskOnScreen = onScreenTasks.find((x) =>
|
|
6421
|
+
const waitingTaskOnScreen = onScreenTasks.find((x) => taskWaiting(x)) || null;
|
|
6374
6422
|
useTicker(ctx, animOn);
|
|
6375
6423
|
const now = Date.now();
|
|
6376
6424
|
const elapsed = active.length > 0 ? fmtClock(now - Math.min(...active.map((x) => x.startTime || now))) : "";
|
|
@@ -6404,7 +6452,7 @@ function AnimationOverlay(props) {
|
|
|
6404
6452
|
const spaceModeOn = !!(cfg && cfg.animationEnabled && mode === "space" && !panelOpen);
|
|
6405
6453
|
const spaceDocks = useSpaceDocks(spaceModeOn);
|
|
6406
6454
|
const spaceGalaxies = spaceModeOn && spaceDocks ? spaceGalaxyLayout() : null;
|
|
6407
|
-
const stuckTask = onScreenTasks.find((task) => task.phase === "code" &&
|
|
6455
|
+
const stuckTask = onScreenTasks.find((task) => task.phase === "code" && taskStalled(task, now, 18e3)) || null;
|
|
6408
6456
|
const robotScaleFromConfig = Math.max(0.85, Math.min(2.2, Number(cfg && cfg.robotScale) || 1.35));
|
|
6409
6457
|
const speedStyle = { "--dkan-speed": Number(speed).toFixed(2) };
|
|
6410
6458
|
const saveRobotScale = (0, import_react9.useCallback)((robotScale) => {
|
|
@@ -6519,7 +6567,7 @@ function AnimationOverlay(props) {
|
|
|
6519
6567
|
ambientOn && mode === "flow" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dkan-line", style: speedStyle, "aria-hidden": "true" }) : null,
|
|
6520
6568
|
ambientOn && AMBIENT_EFFECT_MODES.has(mode) && (mode !== "space" || spaceGalaxies) ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AmbientLayer, { mode, phase, speed: Number(speed).toFixed(2), tasks: active, galaxies: spaceGalaxies }) : null,
|
|
6521
6569
|
spaceModeOn && spaceDocks && active.length === 0 && deliveries.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ReadyFreighter, { dock: spaceDocks.ready }) : null,
|
|
6522
|
-
spaceModeOn && stuckTask ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ProgrammingStuck, { task: stuckTask, waiting:
|
|
6570
|
+
spaceModeOn && stuckTask ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ProgrammingStuck, { task: stuckTask, waiting: taskWaiting(stuckTask) }) : null,
|
|
6523
6571
|
!panelOpen ? departures.map((departure) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(MissionDeparture, { departure }, departure.id)) : null,
|
|
6524
6572
|
ambientOn && mode === "orbit" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dkan-orbit", style: speedStyle, "aria-hidden": "true" }) : null,
|
|
6525
6573
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(BurstLayer, { bursts }),
|
|
@@ -6530,7 +6578,7 @@ function AnimationOverlay(props) {
|
|
|
6530
6578
|
role: "button",
|
|
6531
6579
|
tabIndex: 0,
|
|
6532
6580
|
style: Object.assign({}, botCardStyle, waitingTask ? { "--dkan-phase": "#b45309" } : null),
|
|
6533
|
-
title: active.length + " \u4E2A\u4EFB\u52A1 \xB7 " + (waitingTask ?
|
|
6581
|
+
title: active.length + " \u4E2A\u4EFB\u52A1 \xB7 " + (waitingTask ? waitWord : phaseLabel(phase)) + " \xB7 \u70B9\u51FB\u67E5\u770B\u4EFB\u52A1\u52A8\u753B\u9875 \xB7 \u53EF\u62D6\u52A8\u5230\u4EFB\u610F\u4F4D\u7F6E",
|
|
6534
6582
|
onPointerDown: onBotPointerDown,
|
|
6535
6583
|
onPointerMove: onBotPointerMove,
|
|
6536
6584
|
onPointerUp: onBotPointerUp,
|
|
@@ -6549,7 +6597,7 @@ function AnimationOverlay(props) {
|
|
|
6549
6597
|
" \u4E2A\u4EFB\u52A1",
|
|
6550
6598
|
elapsed ? " \xB7 " + elapsed : "",
|
|
6551
6599
|
" \xB7 ",
|
|
6552
|
-
waitingTask ?
|
|
6600
|
+
waitingTask ? waitWord : phaseLabel(phase)
|
|
6553
6601
|
] }),
|
|
6554
6602
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
6555
6603
|
"button",
|
|
@@ -6581,7 +6629,7 @@ function AnimationOverlay(props) {
|
|
|
6581
6629
|
type: "button",
|
|
6582
6630
|
className: "dkan-badge" + (mode === "breathe" ? " dkan-badge-breathe" : ""),
|
|
6583
6631
|
style: Object.assign({}, speedStyle, { "--dkan-phase": phaseColor(waitingTask ? "code" : phase) }),
|
|
6584
|
-
title: active.length + " \u4E2A\u4EFB\u52A1\u8FDB\u884C\u4E2D \xB7 " + (waitingTask ?
|
|
6632
|
+
title: active.length + " \u4E2A\u4EFB\u52A1\u8FDB\u884C\u4E2D \xB7 " + (waitingTask ? waitWord : phaseLabel(phase)) + " \xB7 \u70B9\u51FB\u67E5\u770B\u4EFB\u52A1\u52A8\u753B\u9875",
|
|
6585
6633
|
onClick: () => openPanel("animation"),
|
|
6586
6634
|
children: [
|
|
6587
6635
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dkan-dotwrap", children: [
|
|
@@ -6594,7 +6642,7 @@ function AnimationOverlay(props) {
|
|
|
6594
6642
|
" \u4E2A\u4EFB\u52A1",
|
|
6595
6643
|
elapsed ? " \xB7 " + elapsed : "",
|
|
6596
6644
|
" \xB7 ",
|
|
6597
|
-
waitingTask ?
|
|
6645
|
+
waitingTask ? waitWord : phaseLabel(phase)
|
|
6598
6646
|
] })
|
|
6599
6647
|
]
|
|
6600
6648
|
}
|
|
@@ -6776,7 +6824,7 @@ function AnimationView(props) {
|
|
|
6776
6824
|
}
|
|
6777
6825
|
if (saveErr) rows.push(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dkan-note dkan-err", children: saveErr }, "err"));
|
|
6778
6826
|
rows.push(
|
|
6779
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dkan-note", children: "\u4EFB\u52A1\u8FD0\u884C\u72B6\u6001\uFF08\u8FDB\u884C\u4E2D\u4EFB\u52A1\u3001\u9636\u6BB5\u3001Token\u3001\u7B49\
|
|
6827
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dkan-note", children: "\u4EFB\u52A1\u8FD0\u884C\u72B6\u6001\uFF08\u8FDB\u884C\u4E2D\u4EFB\u52A1\u3001\u9636\u6BB5\u3001Token\u3001\u7B49\u4EBA\u4ECB\u5165\uFF08\u7B49\u6279\u51C6 / \u7B49\u56DE\u7B54\uFF09\u4E0E\u6700\u8FD1\u5B8C\u6210\uFF09\u5DF2\u72EC\u7ACB\u6210\u5DE6\u4FA7\u300C\u8FD0\u884C\u72B6\u6001\u300D\u83DC\u5355\uFF1B\u672C\u9875\u53EA\u8D1F\u8D23\u52A8\u6548\u3002" }, "hint")
|
|
6780
6828
|
);
|
|
6781
6829
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dkan-root", children: rows });
|
|
6782
6830
|
}
|
|
@@ -7295,6 +7343,50 @@ function utterCtor() {
|
|
|
7295
7343
|
function voiceSupported() {
|
|
7296
7344
|
return synthOf() !== null && utterCtor() !== null;
|
|
7297
7345
|
}
|
|
7346
|
+
var VOICE_CLIENT_KEY = "dsh-dock/notify/voice-client/v1";
|
|
7347
|
+
function voiceClientEnabled() {
|
|
7348
|
+
try {
|
|
7349
|
+
if (typeof localStorage === "undefined") return true;
|
|
7350
|
+
return localStorage.getItem(VOICE_CLIENT_KEY) !== "0";
|
|
7351
|
+
} catch {
|
|
7352
|
+
return true;
|
|
7353
|
+
}
|
|
7354
|
+
}
|
|
7355
|
+
function setVoiceClientEnabled(on) {
|
|
7356
|
+
try {
|
|
7357
|
+
if (typeof localStorage !== "undefined") localStorage.setItem(VOICE_CLIENT_KEY, on ? "1" : "0");
|
|
7358
|
+
} catch {
|
|
7359
|
+
}
|
|
7360
|
+
}
|
|
7361
|
+
function voiceAllowed(cfg) {
|
|
7362
|
+
return !!cfg && cfg.voiceNotify === true && voiceClientEnabled();
|
|
7363
|
+
}
|
|
7364
|
+
function useVoiceClientEnabled() {
|
|
7365
|
+
const [on, setOn] = (0, import_react10.useState)(() => voiceClientEnabled());
|
|
7366
|
+
(0, import_react10.useEffect)(() => {
|
|
7367
|
+
const sync = () => setOn(voiceClientEnabled());
|
|
7368
|
+
if (typeof window === "undefined" || typeof window.addEventListener !== "function") return void 0;
|
|
7369
|
+
window.addEventListener("storage", sync);
|
|
7370
|
+
return () => {
|
|
7371
|
+
if (typeof window.removeEventListener === "function") window.removeEventListener("storage", sync);
|
|
7372
|
+
};
|
|
7373
|
+
}, []);
|
|
7374
|
+
const set = (0, import_react10.useCallback)((next) => {
|
|
7375
|
+
const v = next !== false;
|
|
7376
|
+
setVoiceClientEnabled(v);
|
|
7377
|
+
setOn(v);
|
|
7378
|
+
if (!v) {
|
|
7379
|
+
const s = synthOf();
|
|
7380
|
+
if (s) {
|
|
7381
|
+
try {
|
|
7382
|
+
s.cancel();
|
|
7383
|
+
} catch {
|
|
7384
|
+
}
|
|
7385
|
+
}
|
|
7386
|
+
}
|
|
7387
|
+
}, []);
|
|
7388
|
+
return [on, set];
|
|
7389
|
+
}
|
|
7298
7390
|
function localVoices() {
|
|
7299
7391
|
const s = synthOf();
|
|
7300
7392
|
if (!s) return [];
|
|
@@ -7469,6 +7561,25 @@ function confirmBroadcastText(task, approval, cfg) {
|
|
|
7469
7561
|
parts.push("\u6B63\u5728\u7B49\u5F85\u4F60\u6279\u51C6" + (scene ? "\u6267\u884C" + scene : "") + "\uFF0C\u5DE5\u5177\u662F" + tool + "\uFF0C\u8BF7\u56DE\u5230\u4F1A\u8BDD\u5904\u7406\u3002");
|
|
7470
7562
|
return parts.join("");
|
|
7471
7563
|
}
|
|
7564
|
+
function questionBroadcastText(task, question, cfg) {
|
|
7565
|
+
const mode = voiceTone(cfg);
|
|
7566
|
+
if (mode === "brief") return "\u4EFB\u52A1\u9700\u8981\u4F60\u56DE\u7B54";
|
|
7567
|
+
const who = task && task.title ? "\u4EFB\u52A1\u300C" + truncate2(task.title, 30) + "\u300D" : "\u4EFB\u52A1";
|
|
7568
|
+
const head = question && question.header || "";
|
|
7569
|
+
const body = question && question.question || "";
|
|
7570
|
+
const what = body ? truncate2(body.replace(/[#*_`>\[\]()!]/g, ""), 40) : "";
|
|
7571
|
+
if (mode === "medium") {
|
|
7572
|
+
const tail = what ? "\uFF1A" + what : head ? "\uFF1A" + head : "";
|
|
7573
|
+
return who + "\u5728\u7B49\u4F60\u56DE\u7B54" + tail + "\u3002";
|
|
7574
|
+
}
|
|
7575
|
+
const parts = [];
|
|
7576
|
+
if (task && task.title) parts.push("\u4EFB\u52A1\uFF1A" + truncate2(task.title, 30) + "\u3002");
|
|
7577
|
+
parts.push(what ? "\u6B63\u5728\u7B49\u4F60\u56DE\u7B54\u95EE\u9898\uFF1A" + what + "\u3002" : "\u6B63\u5728\u7B49\u4F60\u56DE\u7B54\u95EE\u9898\u3002");
|
|
7578
|
+
const count = question && question.count || 0;
|
|
7579
|
+
if (count > 1) parts.push("\u5171 " + count + " \u4E2A\u95EE\u9898\u3002");
|
|
7580
|
+
parts.push("\u8BF7\u56DE\u5230\u4F1A\u8BDD\u9009\u62E9\u7B54\u6848\u3002");
|
|
7581
|
+
return parts.join("");
|
|
7582
|
+
}
|
|
7472
7583
|
function stuckBroadcastText(task, cfg) {
|
|
7473
7584
|
const mode = voiceTone(cfg);
|
|
7474
7585
|
const where = (task && task.isSubtask ? "\u5B50\u4EFB\u52A1" : "\u4E3B\u4EFB\u52A1") + (task && task.title ? "\u300C" + truncate2(task.title, 30) + "\u300D" : "");
|
|
@@ -7485,6 +7596,10 @@ function stuckBroadcastText(task, cfg) {
|
|
|
7485
7596
|
return parts.join("");
|
|
7486
7597
|
}
|
|
7487
7598
|
var STUCK_MS = 18e3;
|
|
7599
|
+
function stuckMsOf(cfg) {
|
|
7600
|
+
const v = cfg && Number(cfg.stuckMs);
|
|
7601
|
+
return Number.isFinite(v) && v > 0 ? v : STUCK_MS;
|
|
7602
|
+
}
|
|
7488
7603
|
var notifyStore = {
|
|
7489
7604
|
snap: { status: null, loading: false, error: null },
|
|
7490
7605
|
listeners: /* @__PURE__ */ new Set(),
|
|
@@ -7644,6 +7759,7 @@ function NotifyOverlay(props) {
|
|
|
7644
7759
|
const [stackHover, setStackHover] = (0, import_react10.useState)(false);
|
|
7645
7760
|
const prevActiveRef = (0, import_react10.useRef)(null);
|
|
7646
7761
|
const remindedApprovalsRef = (0, import_react10.useRef)(/* @__PURE__ */ new Map());
|
|
7762
|
+
const remindedQuestionsRef = (0, import_react10.useRef)(/* @__PURE__ */ new Map());
|
|
7647
7763
|
const toastSeqRef = (0, import_react10.useRef)(0);
|
|
7648
7764
|
const pushToast = (0, import_react10.useCallback)((toast) => {
|
|
7649
7765
|
const st = notifyStore.snap.status;
|
|
@@ -7698,7 +7814,7 @@ function NotifyOverlay(props) {
|
|
|
7698
7814
|
if (!activeIds.has(sid)) remindedApprovalsRef.current.delete(sid);
|
|
7699
7815
|
}
|
|
7700
7816
|
for (const task of st.active) {
|
|
7701
|
-
const approvals =
|
|
7817
|
+
const approvals = taskApprovals(task);
|
|
7702
7818
|
if (approvals.length === 0) continue;
|
|
7703
7819
|
let seen = remindedApprovalsRef.current.get(task.sessionId);
|
|
7704
7820
|
if (!seen) {
|
|
@@ -7708,7 +7824,7 @@ function NotifyOverlay(props) {
|
|
|
7708
7824
|
const fresh = approvals.filter((a) => a && !seen.has(a.id));
|
|
7709
7825
|
if (fresh.length === 0) continue;
|
|
7710
7826
|
for (const a of fresh) seen.add(a.id);
|
|
7711
|
-
if (cfg
|
|
7827
|
+
if (voiceAllowed(cfg) && cfg.voiceOnConfirm !== false) {
|
|
7712
7828
|
speakVoice(confirmBroadcastText(task, fresh[0], cfg), cfg);
|
|
7713
7829
|
}
|
|
7714
7830
|
if (cfg.notifyOnConfirm === false) continue;
|
|
@@ -7749,19 +7865,74 @@ function NotifyOverlay(props) {
|
|
|
7749
7865
|
}
|
|
7750
7866
|
}
|
|
7751
7867
|
}, [snap.status]);
|
|
7868
|
+
(0, import_react10.useEffect)(() => {
|
|
7869
|
+
const st = snap.status;
|
|
7870
|
+
if (!st || !st.active) return;
|
|
7871
|
+
const cfg = st.config || {};
|
|
7872
|
+
const activeIds = new Set(st.active.map((x) => x.sessionId));
|
|
7873
|
+
for (const [sid, seen] of remindedQuestionsRef.current) {
|
|
7874
|
+
if (!activeIds.has(sid)) remindedQuestionsRef.current.delete(sid);
|
|
7875
|
+
}
|
|
7876
|
+
for (const task of st.active) {
|
|
7877
|
+
const questions = taskQuestions(task);
|
|
7878
|
+
if (questions.length === 0) continue;
|
|
7879
|
+
let seen = remindedQuestionsRef.current.get(task.sessionId);
|
|
7880
|
+
if (!seen) {
|
|
7881
|
+
seen = /* @__PURE__ */ new Set();
|
|
7882
|
+
remindedQuestionsRef.current.set(task.sessionId, seen);
|
|
7883
|
+
}
|
|
7884
|
+
const fresh = questions.filter((q) => q && q.id && !seen.has(q.id));
|
|
7885
|
+
if (fresh.length === 0) continue;
|
|
7886
|
+
for (const q of fresh) seen.add(q.id);
|
|
7887
|
+
if (voiceAllowed(cfg) && cfg.voiceOnConfirm !== false) {
|
|
7888
|
+
speakVoice(questionBroadcastText(task, fresh[0], cfg), cfg);
|
|
7889
|
+
}
|
|
7890
|
+
if (cfg.notifyOnConfirm === false) continue;
|
|
7891
|
+
const tone = cardTone(cfg);
|
|
7892
|
+
const head = fresh[0].header || "";
|
|
7893
|
+
const body = fresh[0].question || "";
|
|
7894
|
+
const lines = ["\u4EFB\u52A1\uFF1A" + (task.title || "(\u65E0\u6807\u9898)")];
|
|
7895
|
+
if (body) lines.push((head ? head + "\uFF1A" : "\u95EE\u9898\uFF1A") + truncate2(body, 140));
|
|
7896
|
+
else if (head) lines.push("\u95EE\u9898\uFF1A" + head);
|
|
7897
|
+
const count = fresh[0].count || 0;
|
|
7898
|
+
if (count > 1) lines.push(tone === "brief" ? "\u5171 " + count + " \u4E2A\u95EE\u9898" : "\u5171 " + count + " \u4E2A\u95EE\u9898\u7B49\u4F60\u9009\u62E9");
|
|
7899
|
+
if (tone === "detailed") lines.push("\u8BF7\u5728\u4F1A\u8BDD\u91CC\u9009\u597D\u7B54\u6848\u540E\u7EE7\u7EED");
|
|
7900
|
+
pushToast({
|
|
7901
|
+
id: ++toastSeqRef.current,
|
|
7902
|
+
kind: "confirm",
|
|
7903
|
+
title: "\u4EFB\u52A1\u9700\u8981\u4F60\u56DE\u7B54",
|
|
7904
|
+
body: lines.join("\n"),
|
|
7905
|
+
// 点卡片直达该会话去选答案(与需确认卡同哲学:问题没答完卡片就该在)
|
|
7906
|
+
sessionId: task.sessionId || "",
|
|
7907
|
+
sessionTitle: task.title || "",
|
|
7908
|
+
// 与这批提问绑定:回答落地后宿主把它们移出 questions,下面的对账 effect 据此收起
|
|
7909
|
+
questionKeys: fresh.map((q) => task.sessionId + "|" + q.id)
|
|
7910
|
+
});
|
|
7911
|
+
if (cfg.soundNotify !== false) playAskSound(cfg.soundEffect);
|
|
7912
|
+
if (cfg.systemNotify && typeof document !== "undefined" && document.hidden && typeof Notification !== "undefined" && Notification.permission === "granted") {
|
|
7913
|
+
try {
|
|
7914
|
+
new Notification("dsh \u4EFB\u52A1\u9700\u8981\u4F60\u56DE\u7B54", {
|
|
7915
|
+
body: (task.title || "(\u65E0\u6807\u9898)") + " \xB7 " + (head || "\u6709\u4E00\u95EE\u5728\u7B49\u4F60\u9009\u62E9"),
|
|
7916
|
+
tag: "dsh-dock-question-" + task.sessionId
|
|
7917
|
+
});
|
|
7918
|
+
} catch {
|
|
7919
|
+
}
|
|
7920
|
+
}
|
|
7921
|
+
}
|
|
7922
|
+
}, [snap.status]);
|
|
7752
7923
|
(0, import_react10.useEffect)(() => {
|
|
7753
7924
|
const st = snap.status;
|
|
7754
7925
|
if (!st || !st.active) return;
|
|
7755
7926
|
const live = /* @__PURE__ */ new Set();
|
|
7756
7927
|
for (const task of st.active) {
|
|
7757
|
-
const
|
|
7758
|
-
for (const
|
|
7928
|
+
for (const a of taskApprovals(task)) if (a && a.id) live.add(task.sessionId + "|" + a.id);
|
|
7929
|
+
for (const q of taskQuestions(task)) if (q && q.id) live.add(task.sessionId + "|" + q.id);
|
|
7759
7930
|
}
|
|
7760
7931
|
setToasts((prev) => {
|
|
7761
7932
|
let changed = false;
|
|
7762
7933
|
const next = prev.map((x) => {
|
|
7763
7934
|
if (x.kind !== "confirm" || x.closing) return x;
|
|
7764
|
-
const keys = Array.isArray(x.approvalKeys) ? x.approvalKeys : [];
|
|
7935
|
+
const keys = [].concat(Array.isArray(x.approvalKeys) ? x.approvalKeys : []).concat(Array.isArray(x.questionKeys) ? x.questionKeys : []);
|
|
7765
7936
|
if (keys.length === 0 || keys.some((k) => live.has(k))) return x;
|
|
7766
7937
|
changed = true;
|
|
7767
7938
|
return Object.assign({}, x, { closing: true });
|
|
@@ -7804,8 +7975,7 @@ function NotifyOverlay(props) {
|
|
|
7804
7975
|
if (t.isSubtask && t.parentSessionId) parentsWaitingOnSubtask.add(t.parentSessionId);
|
|
7805
7976
|
}
|
|
7806
7977
|
for (const task of st.active) {
|
|
7807
|
-
|
|
7808
|
-
if (approvals.length > 0) {
|
|
7978
|
+
if (taskWaiting(task)) {
|
|
7809
7979
|
stuckSeenRef.current.delete(task.sessionId);
|
|
7810
7980
|
continue;
|
|
7811
7981
|
}
|
|
@@ -7813,13 +7983,13 @@ function NotifyOverlay(props) {
|
|
|
7813
7983
|
continue;
|
|
7814
7984
|
}
|
|
7815
7985
|
if (parentsWaitingOnSubtask.has(task.sessionId)) continue;
|
|
7816
|
-
const lastAct = task
|
|
7817
|
-
|
|
7986
|
+
const lastAct = taskActivityAt(task);
|
|
7987
|
+
const stuckMs = taskStalled(task, now, stuckMsOf(cfg));
|
|
7988
|
+
if (!stuckMs) continue;
|
|
7818
7989
|
const prev = stuckSeenRef.current.get(task.sessionId);
|
|
7819
7990
|
if (prev === lastAct) continue;
|
|
7820
7991
|
stuckSeenRef.current.set(task.sessionId, lastAct);
|
|
7821
|
-
|
|
7822
|
-
if (cfg.voiceNotify === true && cfg.voiceOnStuck !== false) {
|
|
7992
|
+
if (voiceAllowed(cfg) && cfg.voiceOnStuck !== false) {
|
|
7823
7993
|
speakVoice(stuckBroadcastText(task, Object.assign({}, cfg, { stuckMs })), cfg);
|
|
7824
7994
|
}
|
|
7825
7995
|
if (cfg.notifyOnStuck === false) continue;
|
|
@@ -7856,7 +8026,7 @@ function NotifyOverlay(props) {
|
|
|
7856
8026
|
const next = prev.map((x) => {
|
|
7857
8027
|
if (x.kind !== "stuck" || x.closing) return x;
|
|
7858
8028
|
const task = byId.get(x.sessionId);
|
|
7859
|
-
const stillStalled = !!task && (task
|
|
8029
|
+
const stillStalled = !!task && taskActivityAt(task) === x.stuckAt && !taskWaiting(task);
|
|
7860
8030
|
if (stillStalled) return x;
|
|
7861
8031
|
changed = true;
|
|
7862
8032
|
return Object.assign({}, x, { closing: true });
|
|
@@ -7869,7 +8039,7 @@ function NotifyOverlay(props) {
|
|
|
7869
8039
|
const success = isSuccessReason2(reason);
|
|
7870
8040
|
const info = endInfo(reason);
|
|
7871
8041
|
const wanted = success ? cfg.notifyOnComplete : cfg.notifyOnError;
|
|
7872
|
-
if (cfg
|
|
8042
|
+
if (voiceAllowed(cfg) && (success ? cfg.voiceOnComplete !== false : cfg.voiceOnError !== false)) {
|
|
7873
8043
|
speakVoice(endBroadcastText(success, record, task, cfg), cfg);
|
|
7874
8044
|
}
|
|
7875
8045
|
if (wanted === false) return;
|
|
@@ -7935,6 +8105,7 @@ function NotifyOverlay(props) {
|
|
|
7935
8105
|
function NotifyView(props) {
|
|
7936
8106
|
const snap = useNotify();
|
|
7937
8107
|
const voices = useLocalVoices();
|
|
8108
|
+
const [voiceClientOn, setVoiceClientOn] = useVoiceClientEnabled();
|
|
7938
8109
|
const [cfg, setCfg] = (0, import_react10.useState)(null);
|
|
7939
8110
|
const [saveErr, setSaveErr] = (0, import_react10.useState)("");
|
|
7940
8111
|
const [testing, setTesting] = (0, import_react10.useState)(false);
|
|
@@ -8110,7 +8281,7 @@ function NotifyView(props) {
|
|
|
8110
8281
|
children: cfg.notifyOnConfirm !== false ? "\u5F00" : "\u5173"
|
|
8111
8282
|
}
|
|
8112
8283
|
),
|
|
8113
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-row-sub", children: "\u5DE5\u5177\u7B49\
|
|
8284
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-row-sub", children: "\u5DE5\u5177\u7B49\u4F60\u6279\u51C6\u3001\u6216\u4F1A\u8BDD\u63D0\u95EE\u7B49\u4F60\u9009\u7B54\u6848\u65F6\u5F39\u5361\u7247\u5E76\u54CD\u786E\u8BA4\u97F3\uFF1B\u5904\u7406\u5B8C\u81EA\u52A8\u6536\u8D77\uFF0C\u6CA1\u5904\u7406\u5B8C\u5C31\u4E00\u76F4\u663E\u793A\uFF08\u70B9\u5361\u7247\u76F4\u8FBE\u4F1A\u8BDD\uFF09\u3002\u8FD9\u4E24\u79CD\u300C\u505C\u5728\u539F\u5730\u7B49\u4EBA\u300D\u90FD\u4E0D\u7B97\u5361\u4F4F" })
|
|
8114
8285
|
] }),
|
|
8115
8286
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dknt-row", children: [
|
|
8116
8287
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-row-label", children: "\u5361\u4F4F\u63D0\u9192" }),
|
|
@@ -8123,7 +8294,7 @@ function NotifyView(props) {
|
|
|
8123
8294
|
children: cfg.notifyOnStuck !== false ? "\u5F00" : "\u5173"
|
|
8124
8295
|
}
|
|
8125
8296
|
),
|
|
8126
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-row-sub", children: "\u7F16\u7A0B\u9636\u6BB5
|
|
8297
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-row-sub", children: "\u7F16\u7A0B\u9636\u6BB5\u957F\u65F6\u95F4\u6CA1\u6709\u52A8\u9759\u65F6\u5F39\u5361\u7247\uFF0C\u5199\u660E\u662F\u4E3B\u4EFB\u52A1\u8FD8\u662F\u5B50\u4EFB\u52A1\u3001\u505C\u6EDE\u4E86\u591A\u4E45\u3001\u6700\u540E\u5728\u6267\u884C\u4EC0\u4E48\uFF1B\u6062\u590D\u6D3B\u52A8 / \u4EFB\u52A1\u7ED3\u675F\u81EA\u52A8\u6536\u8D77\uFF0C\u540C\u4E00\u505C\u70B9\u53EA\u5F39\u4E00\u6B21\u3002\u7B49\u6279\u51C6\u3001\u7B49\u56DE\u7B54\u3001\u547D\u4EE4\u8FD8\u5728\u8DD1\u3001\u6B63\u5728\u538B\u7F29\u4E0A\u4E0B\u6587\u7684\u4F1A\u8BDD\u90FD\u4E0D\u7B97\u5361\u4F4F\uFF08\u90A3\u4E9B\u90FD\u662F\u5728\u5E72\u6D3B\uFF0C\u522B\u91CD\u590D\u8F70\u70B8\uFF09\uFF08\u8BED\u97F3\u64AD\u62A5\u8D70\u300C\u8BED\u97F3\u64AD\u62A5\u300D\u533A\u7684\u5361\u4F4F\u5F00\u5173\uFF0C\u4E92\u4E0D\u5E72\u6270\uFF09" })
|
|
8127
8298
|
] })
|
|
8128
8299
|
] })
|
|
8129
8300
|
] }, "events"),
|
|
@@ -8220,9 +8391,9 @@ function NotifyView(props) {
|
|
|
8220
8391
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dknt-sec", children: [
|
|
8221
8392
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dknt-sec-head", children: [
|
|
8222
8393
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-sec-title", children: "\u8BED\u97F3\u64AD\u62A5" }),
|
|
8223
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-sec-sub", children: "\u4EFB\u52A1\u5B8C\u6210 / \u505C\u6B62 / \u9700\u8981\u6388\u6743 / \u5361\u4F4F\u65F6\u7528\u6D4F\u89C8\u5668\u8BED\u97F3\uFF08TTS\uFF09\u8BF4\u4E00\u53E5\u8BDD\uFF1B\u4E0E\
|
|
8394
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-sec-sub", children: "\u4EFB\u52A1\u5B8C\u6210 / \u505C\u6B62 / \u9700\u8981\u6388\u6743 / \u9700\u56DE\u7B54 / \u5361\u4F4F\u65F6\u7528\u6D4F\u89C8\u5668\u8BED\u97F3\uFF08TTS\uFF09\u8BF4\u4E00\u53E5\u8BDD\uFF1B\u670D\u52A1\u7AEF\u603B\u5F00\u5173\uFF08\u8DE8\u6D4F\u89C8\u5668\uFF09\u4E0E\u672C\u673A\u5F00\u5173\uFF08\u5F53\u524D\u6D4F\u89C8\u5668\uFF09\u90FD\u5F00\u542F\u624D\u64AD\u62A5" }),
|
|
8224
8395
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "dknt-sec-sw", children: [
|
|
8225
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-sec-swlabel" + (cfg.voiceNotify ? " on" : ""), children: cfg.voiceNotify ? "\u5DF2\u5F00\u542F" : "\u5DF2\u5173\u95ED" }),
|
|
8396
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-sec-swlabel" + (cfg.voiceNotify ? " on" : ""), children: cfg.voiceNotify ? "\u670D\u52A1\u7AEF\uFF1A\u5DF2\u5F00\u542F" : "\u670D\u52A1\u7AEF\uFF1A\u5DF2\u5173\u95ED" }),
|
|
8226
8397
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
8227
8398
|
"button",
|
|
8228
8399
|
{
|
|
@@ -8230,13 +8401,30 @@ function NotifyView(props) {
|
|
|
8230
8401
|
className: "dock-sw" + (cfg.voiceNotify ? " on" : ""),
|
|
8231
8402
|
role: "switch",
|
|
8232
8403
|
"aria-checked": cfg.voiceNotify,
|
|
8233
|
-
"aria-label": "\u5F00\u5173\u8BED\u97F3\u64AD\u62A5",
|
|
8234
|
-
title: cfg.voiceNotify ? "\u5173\u95ED\u8BED\u97F3\u64AD\u62A5" : "\u5F00\u542F\u8BED\u97F3\u64AD\u62A5",
|
|
8404
|
+
"aria-label": "\u5F00\u5173\u8BED\u97F3\u64AD\u62A5\uFF08\u670D\u52A1\u7AEF\u603B\u5F00\u5173\uFF09",
|
|
8405
|
+
title: cfg.voiceNotify ? "\u5173\u95ED\u8BED\u97F3\u64AD\u62A5\uFF08\u670D\u52A1\u7AEF\u603B\u5F00\u5173\uFF09" : "\u5F00\u542F\u8BED\u97F3\u64AD\u62A5\uFF08\u670D\u52A1\u7AEF\u603B\u5F00\u5173\uFF09",
|
|
8235
8406
|
onClick: () => patch({ voiceNotify: !cfg.voiceNotify })
|
|
8236
8407
|
}
|
|
8237
8408
|
)
|
|
8238
8409
|
] })
|
|
8239
8410
|
] }),
|
|
8411
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dknt-row", children: [
|
|
8412
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-row-label", children: "\u672C\u673A\u64AD\u62A5" }),
|
|
8413
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
8414
|
+
"button",
|
|
8415
|
+
{
|
|
8416
|
+
type: "button",
|
|
8417
|
+
className: "dknt-miniswitch" + (voiceClientOn ? " on" : ""),
|
|
8418
|
+
role: "switch",
|
|
8419
|
+
"aria-checked": voiceClientOn,
|
|
8420
|
+
"aria-label": "\u5F00\u5173\u672C\u673A\u8BED\u97F3\u64AD\u62A5",
|
|
8421
|
+
title: voiceClientOn ? "\u5173\u95ED\u672C\u673A\u8BED\u97F3\u64AD\u62A5" : "\u5F00\u542F\u672C\u673A\u8BED\u97F3\u64AD\u62A5",
|
|
8422
|
+
onClick: () => setVoiceClientOn(!voiceClientOn),
|
|
8423
|
+
children: voiceClientOn ? "\u5F00" : "\u5173"
|
|
8424
|
+
}
|
|
8425
|
+
),
|
|
8426
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-row-sub", children: voiceClientOn ? "\u672C\u6D4F\u89C8\u5668\u4F1A\u64AD\u62A5\uFF08\u8BBE\u7F6E\u4FDD\u5B58\u5728\u5F53\u524D\u6D4F\u89C8\u5668\uFF1B\u670D\u52A1\u7AEF\u603B\u5F00\u5173\u5173\u95ED\u65F6\u4E0D\u751F\u6548\uFF09" : "\u672C\u6D4F\u89C8\u5668\u4E0D\u64AD\u62A5\uFF08\u8BBE\u7F6E\u4FDD\u5B58\u5728\u5F53\u524D\u6D4F\u89C8\u5668\uFF0C\u4E0D\u5F71\u54CD\u5176\u4ED6\u6D4F\u89C8\u5668\uFF09" })
|
|
8427
|
+
] }),
|
|
8240
8428
|
cfg.voiceNotify ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dknt-rows-narrow", children: [
|
|
8241
8429
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dknt-row", children: [
|
|
8242
8430
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-row-label", children: "\u64AD\u62A5\u53E3\u5F84" }),
|
|
@@ -8259,7 +8447,7 @@ function NotifyView(props) {
|
|
|
8259
8447
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-row-sub", style: { minWidth: 0 }, children: [
|
|
8260
8448
|
["voiceOnComplete", "\u5B8C\u6210", cfg.voiceOnComplete !== false],
|
|
8261
8449
|
["voiceOnError", "\u505C\u6B62", cfg.voiceOnError !== false],
|
|
8262
|
-
["voiceOnConfirm", "\u9700\u6388\u6743", cfg.voiceOnConfirm !== false],
|
|
8450
|
+
["voiceOnConfirm", "\u9700\u6388\u6743/\u9700\u56DE\u7B54", cfg.voiceOnConfirm !== false],
|
|
8263
8451
|
["voiceOnStuck", "\u5361\u4F4F", cfg.voiceOnStuck !== false]
|
|
8264
8452
|
].map(([key, label, on]) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
8265
8453
|
"button",
|
|
@@ -8267,7 +8455,7 @@ function NotifyView(props) {
|
|
|
8267
8455
|
type: "button",
|
|
8268
8456
|
className: "dknt-miniswitch" + (on ? " on" : ""),
|
|
8269
8457
|
style: { marginRight: 6 },
|
|
8270
|
-
title: key === "voiceOnStuck" ? "\u7F16\u7A0B\u9636\u6BB5
|
|
8458
|
+
title: key === "voiceOnStuck" ? "\u7F16\u7A0B\u9636\u6BB5\u957F\u65F6\u95F4\u6CA1\u6709\u52A8\u9759\u65F6\u64AD\u62A5\u4E00\u6B21\uFF08\u6062\u590D\u540E\u53EF\u518D\u62A5\uFF1B\u547D\u4EE4\u5728\u8DD1 / \u6B63\u5728\u538B\u7F29\u4E0A\u4E0B\u6587\u4E0D\u7B97\uFF09" : "",
|
|
8271
8459
|
onClick: () => patch({ [key]: !on }),
|
|
8272
8460
|
children: [
|
|
8273
8461
|
label,
|
|
@@ -8394,7 +8582,7 @@ function NotifyView(props) {
|
|
|
8394
8582
|
),
|
|
8395
8583
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-row-sub", children: "\u672A\u6307\u5B9A\u97F3\u8272\u65F6\u6309\u8BED\u8A00\u81EA\u52A8\u6311\uFF1B\u5DF2\u9009\u97F3\u8272\u7684\u8BED\u8A00\u4F1A\u8986\u76D6\u8FD9\u91CC" })
|
|
8396
8584
|
] })
|
|
8397
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dknt-note", children: "\u672A\u5F00\u542F\u2014\u2014\u4EFB\u52A1\u4E8B\u4EF6\u4E0D\u64AD\u62A5\u8BED\u97F3\uFF08\u63D0\u793A\u97F3\u3001\u7CFB\u7EDF\u901A\u77E5\u4E0D\u53D7\u5F71\u54CD\uFF09\u3002" })
|
|
8585
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dknt-note", children: "\u670D\u52A1\u7AEF\u603B\u5F00\u5173\u672A\u5F00\u542F\u2014\u2014\u4EFB\u52A1\u4E8B\u4EF6\u4E0D\u64AD\u62A5\u8BED\u97F3\uFF08\u63D0\u793A\u97F3\u3001\u7CFB\u7EDF\u901A\u77E5\u4E0D\u53D7\u5F71\u54CD\uFF09\uFF1B\u4E0A\u9762\u7684\u300C\u672C\u673A\u64AD\u62A5\u300D\u53EA\u51B3\u5B9A\u672C\u6D4F\u89C8\u5668\u662F\u5426\u51FA\u58F0\u3002" })
|
|
8398
8586
|
] }, "voice"),
|
|
8399
8587
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dknt-sec", children: [
|
|
8400
8588
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dknt-sec-head", children: [
|
|
@@ -8518,7 +8706,7 @@ function NotifyView(props) {
|
|
|
8518
8706
|
}
|
|
8519
8707
|
if (saveErr) rows.push(/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dknt-note dknt-err", children: saveErr }, "err"));
|
|
8520
8708
|
rows.push(
|
|
8521
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dknt-note", children: "\u4EFB\u52A1\u8FD0\u884C\u72B6\u6001\uFF08\u8FDB\u884C\u4E2D\u4EFB\u52A1\u3001\u7B49\
|
|
8709
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dknt-note", children: "\u4EFB\u52A1\u8FD0\u884C\u72B6\u6001\uFF08\u8FDB\u884C\u4E2D\u4EFB\u52A1\u3001\u7B49\u4EBA\u4ECB\u5165\uFF08\u7B49\u6279\u51C6 / \u7B49\u56DE\u7B54\uFF09\u4E0E\u6700\u8FD1\u5B8C\u6210\uFF09\u5DF2\u72EC\u7ACB\u6210\u5DE6\u4FA7\u300C\u8FD0\u884C\u72B6\u6001\u300D\u83DC\u5355\uFF1B\u672C\u9875\u53EA\u8D1F\u8D23\u7ED3\u675F\u4E0E\u9700\u786E\u8BA4 / \u9700\u56DE\u7B54\u65F6\u7684\u63D0\u9192\u3002" }, "hint")
|
|
8522
8710
|
);
|
|
8523
8711
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dknt-root", children: rows });
|
|
8524
8712
|
}
|
|
@@ -8527,8 +8715,10 @@ function NotifyStat(props) {
|
|
|
8527
8715
|
const cfg = snap.status && snap.status.config;
|
|
8528
8716
|
if (snap.error) return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dknt-err", children: "\u901A\u77E5\u72B6\u6001\u4E0D\u53EF\u7528\uFF08\u5BBF\u4E3B\u9700\u91CD\u542F\u52A0\u8F7D\u901A\u77E5\u8DEF\u7531\uFF09" });
|
|
8529
8717
|
if (!cfg) return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "\u7B49\u5F85\u901A\u77E5\u914D\u7F6E\u2026" });
|
|
8530
|
-
const events = [cfg.notifyOnComplete ? "\u5B8C\u6210" : "", cfg.notifyOnError ? "\u5F02\u5E38" : "", cfg.notifyOnConfirm !== false ? "\u9700\u786E\u8BA4" : ""].filter(Boolean);
|
|
8531
|
-
const
|
|
8718
|
+
const events = [cfg.notifyOnComplete ? "\u5B8C\u6210" : "", cfg.notifyOnError ? "\u5F02\u5E38" : "", cfg.notifyOnConfirm !== false ? "\u9700\u786E\u8BA4/\u9700\u56DE\u7B54" : ""].filter(Boolean);
|
|
8719
|
+
const voiceMode = cfg.voiceMode === "detailed" ? "\xB7\u8BE6" : cfg.voiceMode === "medium" ? "\xB7\u9002" : "\xB7\u7B80";
|
|
8720
|
+
const voice = !cfg.voiceNotify ? "" : voiceClientEnabled() ? "\u8BED\u97F3\u64AD\u62A5" + voiceMode : "\u8BED\u97F3\u64AD\u62A5\xB7\u672C\u673A\u5DF2\u5173";
|
|
8721
|
+
const extras = [cfg.soundNotify !== false ? "\u63D0\u793A\u97F3" : "", cfg.systemNotify ? "\u7CFB\u7EDF\u901A\u77E5" : "", voice].filter(Boolean);
|
|
8532
8722
|
const push = [cfg.dingtalkEnabled ? "\u9489\u9489" : "", cfg.feishuEnabled ? "\u98DE\u4E66" : ""].filter(Boolean);
|
|
8533
8723
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: (events.length ? "\u901A\u77E5\uFF1A" + events.join("/") : "\u901A\u77E5\u4E8B\u4EF6\u5168\u5173") + (extras.length ? " \xB7 " + extras.join("/") : "") + (push.length ? " \xB7 \u63A8\u9001\uFF1A" + push.join("/") : "") });
|
|
8534
8724
|
}
|
|
@@ -8697,16 +8887,20 @@ function useRunState() {
|
|
|
8697
8887
|
return snap;
|
|
8698
8888
|
}
|
|
8699
8889
|
function waitingOf(active) {
|
|
8700
|
-
return (active
|
|
8890
|
+
return waitingCountOf(active);
|
|
8701
8891
|
}
|
|
8702
8892
|
function TaskCard(props) {
|
|
8703
8893
|
const t = props.t;
|
|
8704
8894
|
const info = endInfo2(t.endReason);
|
|
8705
|
-
const waiting = !props.done &&
|
|
8895
|
+
const waiting = !props.done && taskWaiting(t);
|
|
8896
|
+
const approvals = taskApprovals(t);
|
|
8897
|
+
const questions = taskQuestions(t);
|
|
8898
|
+
const waitLabel = approvals.length > 0 ? "\u7B49\u5F85\u786E\u8BA4" : questions.length > 0 ? "\u7B49\u5F85\u56DE\u7B54" : "";
|
|
8899
|
+
const waitDetail = approvals.length > 0 ? approvals.map((a) => (a && a.toolName ? a.toolName : "\u672A\u77E5\u5DE5\u5177") + (a && a.reason ? "\uFF1A" + truncate3(a.reason, 80) : "")).join("\uFF1B") : questions.map((q) => (q && q.header ? q.header : "\u63D0\u95EE") + (q && q.question ? "\uFF1A" + truncate3(q.question, 80) : "")).join("\uFF1B");
|
|
8706
8900
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "dkrs-task", children: [
|
|
8707
8901
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "dkrs-task-head", children: [
|
|
8708
8902
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "dkrs-task-title", title: t.title, children: t.title || "(\u65E0\u6807\u9898)" }),
|
|
8709
|
-
props.done ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "dkrs-tag " + info.cls, children: info.label }) : waiting ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "dkrs-tag warn", children:
|
|
8903
|
+
props.done ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "dkrs-tag " + info.cls, children: info.label }) : waiting ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "dkrs-tag warn", children: waitLabel }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "dkrs-tag on", children: phaseLabel2(t.phase) })
|
|
8710
8904
|
] }),
|
|
8711
8905
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "dkrs-task-meta", children: [
|
|
8712
8906
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: (t.models && t.models.length ? t.models.join(", ") : "\u672A\u77E5") + (t.provider ? "\uFF08" + t.provider + "\uFF09" : "") }),
|
|
@@ -8715,7 +8909,7 @@ function TaskCard(props) {
|
|
|
8715
8909
|
t.totalTokens ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "\u21A7" + fmtCompact3(t.inputTokens) + " \u21A5" + fmtCompact3(t.outputTokens) }) : null,
|
|
8716
8910
|
props.done && t.endTime ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: fmtTime3(t.endTime) }) : null
|
|
8717
8911
|
] }),
|
|
8718
|
-
waiting ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "dkrs-task-wait", children:
|
|
8912
|
+
waiting && waitDetail ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "dkrs-task-wait", children: waitDetail }) : null,
|
|
8719
8913
|
props.done && t.errorMessage ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "dkrs-task-err", children: truncate3(t.errorMessage, 120) }) : null
|
|
8720
8914
|
] });
|
|
8721
8915
|
}
|
|
@@ -8725,6 +8919,9 @@ function RunStateView() {
|
|
|
8725
8919
|
const active = st && st.active ? st.active : [];
|
|
8726
8920
|
const recent = st && st.recent ? st.recent.slice(0, 10) : [];
|
|
8727
8921
|
const waitingCount = waitingOf(active);
|
|
8922
|
+
const waitApprovals = (active || []).reduce((n, t) => n + taskApprovals(t).length, 0);
|
|
8923
|
+
const waitQuestions = (active || []).reduce((n, t) => n + taskQuestions(t).length, 0);
|
|
8924
|
+
const waitBannerHint = waitApprovals > 0 && waitQuestions > 0 ? waitApprovals + " \u9879\u7B49\u6279\u51C6\u3001" + waitQuestions + " \u9879\u7B49\u4F60\u56DE\u7B54" : waitApprovals > 0 ? "\u4EFB\u52A1\u505C\u5728\u9700\u8981\u4F60\u6279\u51C6\u7684\u6B65\u9AA4\u4E0A" : "\u4EFB\u52A1\u5728\u7B49\u4F60\u56DE\u7B54\u95EE\u9898";
|
|
8728
8925
|
(0, import_react11.useEffect)(() => {
|
|
8729
8926
|
let stopped = false;
|
|
8730
8927
|
let timer = null;
|
|
@@ -8740,7 +8937,7 @@ function RunStateView() {
|
|
|
8740
8937
|
if (timer) clearTimeout(timer);
|
|
8741
8938
|
};
|
|
8742
8939
|
}, []);
|
|
8743
|
-
const sub = snap.error ? "\u72B6\u6001\u62C9\u53D6\u5931\u8D25\uFF1A" + snap.error : !st ? snap.loading ? "\u6B63\u5728\u62C9\u53D6\u4EFB\u52A1\u72B6\u6001\u2026" : "\u7B49\u5F85\u4EFB\u52A1\u72B6\u6001" : waitingCount > 0 ? waitingCount + " \u9879\u7B49\
|
|
8940
|
+
const sub = snap.error ? "\u72B6\u6001\u62C9\u53D6\u5931\u8D25\uFF1A" + snap.error : !st ? snap.loading ? "\u6B63\u5728\u62C9\u53D6\u4EFB\u52A1\u72B6\u6001\u2026" : "\u7B49\u5F85\u4EFB\u52A1\u72B6\u6001" : waitingCount > 0 ? waitingCount + " \u9879\u7B49\u4F60\u4ECB\u5165 \xB7 " + active.length + " \u4E2A\u4EFB\u52A1\u8FDB\u884C\u4E2D" : active.length > 0 ? active.length + " \u4E2A\u4EFB\u52A1\u8FDB\u884C\u4E2D" : recent.length > 0 ? "\u7A7A\u95F2 \xB7 \u663E\u793A\u6700\u8FD1\u5B8C\u6210" : "\u7A7A\u95F2 \xB7 \u6682\u65E0\u4EFB\u52A1\u8BB0\u5F55";
|
|
8744
8941
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "dkrs-root", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "dkrs-sec", children: [
|
|
8745
8942
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "dkrs-sec-head", children: [
|
|
8746
8943
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "dkrs-sec-title", children: "\u8FD0\u884C\u72B6\u6001" }),
|
|
@@ -8750,7 +8947,9 @@ function RunStateView() {
|
|
|
8750
8947
|
waitingCount > 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "dkrs-waitbanner", children: [
|
|
8751
8948
|
"\u270B ",
|
|
8752
8949
|
waitingCount,
|
|
8753
|
-
" \u9879\u7B49\
|
|
8950
|
+
" \u9879\u7B49\u4F60\u4ECB\u5165\uFF1A",
|
|
8951
|
+
waitBannerHint,
|
|
8952
|
+
"\uFF0C\u8BF7\u5728\u4F1A\u8BDD\u91CC\u5904\u7406\u540E\u7EE7\u7EED\u3002"
|
|
8754
8953
|
] }) : null,
|
|
8755
8954
|
active.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "dkrs-tasks", children: active.map((t) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(TaskCard, { t }, t.sessionId)) }) : null,
|
|
8756
8955
|
!snap.error && active.length === 0 && recent.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "dkrs-note", children: "\u53D1\u8D77\u65B0\u4F1A\u8BDD\u4EFB\u52A1\u540E\uFF0C\u8FD9\u91CC\u4F1A\u663E\u793A\u8FDB\u884C\u4E2D\u4E0E\u6700\u8FD1\u5B8C\u6210\u7684\u4EFB\u52A1\uFF08\u52A8\u6548\u89C1\u5DE6\u4FA7\u300C\u4EFB\u52A1\u52A8\u753B\u300D\uFF0C\u63D0\u9192\u89C1\u300C\u4EFB\u52A1\u901A\u77E5\u300D\uFF09\u3002" }) : null,
|
|
@@ -8775,7 +8974,7 @@ function RunStateStat(props) {
|
|
|
8775
8974
|
if (waiting > 0) return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "dkrs-warn", children: [
|
|
8776
8975
|
"\u270B ",
|
|
8777
8976
|
waiting,
|
|
8778
|
-
" \u9879\u7B49\
|
|
8977
|
+
" \u9879\u7B49\u4F60\u4ECB\u5165 \xB7 ",
|
|
8779
8978
|
active.length,
|
|
8780
8979
|
" \u4E2A\u4EFB\u52A1\u8FDB\u884C\u4E2D"
|
|
8781
8980
|
] });
|
|
@@ -8797,7 +8996,7 @@ var css4 = [
|
|
|
8797
8996
|
".dkrs-sec-sub{font-size:11px;color:var(--dsw-alias-label-tertiary);flex:1;min-width:120px;}",
|
|
8798
8997
|
".dkrs-refresh{cursor:pointer;flex:none;color:var(--dsw-alias-label-primary);background:transparent;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:2px 10px;font-family:inherit;font-size:12px;}",
|
|
8799
8998
|
".dkrs-refresh:hover{background:var(--dsw-alias-interactive-bg-hover);}",
|
|
8800
|
-
//
|
|
8999
|
+
// 等人介入横幅:琥珀描边,常驻在列表上方(任务卡各自也带「等待确认」/「等待回答」标签)
|
|
8801
9000
|
".dkrs-waitbanner{border:1px solid color-mix(in srgb,var(--dk-warn) 45%,transparent);background:color-mix(in srgb,var(--dk-warn) 10%,transparent);color:var(--dk-warn);border-radius:8px;padding:6px 10px;font-size:12px;line-height:1.6;}",
|
|
8802
9001
|
".dkrs-done-title{font-size:12px;font-weight:600;color:var(--dsw-alias-label-secondary);}",
|
|
8803
9002
|
// 任务列表
|
|
@@ -8820,7 +9019,7 @@ var feature9 = {
|
|
|
8820
9019
|
name: "\u8FD0\u884C\u72B6\u6001",
|
|
8821
9020
|
order: 150,
|
|
8822
9021
|
accent: "#38bdf8",
|
|
8823
|
-
description: "\u4EFB\u52A1\u8FD0\u884C\u72B6\u6001\u4E00\u89C8\uFF1A\u8FDB\u884C\u4E2D\u4EFB\u52A1\u7684\u9636\u6BB5 / \u8017\u65F6 / Token / \u7B49\
|
|
9022
|
+
description: "\u4EFB\u52A1\u8FD0\u884C\u72B6\u6001\u4E00\u89C8\uFF1A\u8FDB\u884C\u4E2D\u4EFB\u52A1\u7684\u9636\u6BB5 / \u8017\u65F6 / Token / \u7B49\u4EBA\u4ECB\u5165\uFF08\u7B49\u6279\u51C6 / \u7B49\u56DE\u7B54\uFF09\u4E0E\u6700\u8FD1\u5B8C\u6210\u8BB0\u5F55\uFF08\u53EA\u8BFB\uFF09",
|
|
8824
9023
|
css: css4,
|
|
8825
9024
|
View: RunStateView,
|
|
8826
9025
|
HomeStat: RunStateStat
|
|
@@ -14003,462 +14202,9 @@ var feature12 = {
|
|
|
14003
14202
|
HomeStat: MobileRelayHomeStat
|
|
14004
14203
|
};
|
|
14005
14204
|
|
|
14006
|
-
// features/mobile/view.js
|
|
14007
|
-
var import_react24 = __toESM(require("react"), 1);
|
|
14008
|
-
var import_react25 = require("react");
|
|
14009
|
-
var MOBILE_QUERY_NARROW = "(max-width: 820px)";
|
|
14010
|
-
var MOBILE_QUERY_COARSE = "(pointer: coarse) and (hover: none)";
|
|
14011
|
-
var MOBILE_QUERY_CHROME = "(max-width: 700px)";
|
|
14012
|
-
function mobileActive() {
|
|
14013
|
-
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return false;
|
|
14014
|
-
try {
|
|
14015
|
-
return window.matchMedia(MOBILE_QUERY_NARROW).matches || window.matchMedia(MOBILE_QUERY_COARSE).matches;
|
|
14016
|
-
} catch {
|
|
14017
|
-
return false;
|
|
14018
|
-
}
|
|
14019
|
-
}
|
|
14020
|
-
function watchQuery(query, onChange) {
|
|
14021
|
-
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return () => {
|
|
14022
|
-
};
|
|
14023
|
-
let mq = null;
|
|
14024
|
-
try {
|
|
14025
|
-
mq = window.matchMedia(query);
|
|
14026
|
-
} catch {
|
|
14027
|
-
return () => {
|
|
14028
|
-
};
|
|
14029
|
-
}
|
|
14030
|
-
const update = () => onChange(mq.matches);
|
|
14031
|
-
update();
|
|
14032
|
-
if (typeof mq.addEventListener === "function") mq.addEventListener("change", update);
|
|
14033
|
-
else if (typeof mq.addListener === "function") mq.addListener(update);
|
|
14034
|
-
return () => {
|
|
14035
|
-
if (typeof mq.removeEventListener === "function") mq.removeEventListener("change", update);
|
|
14036
|
-
else if (typeof mq.removeListener === "function") mq.removeListener(update);
|
|
14037
|
-
};
|
|
14038
|
-
}
|
|
14039
|
-
function MobileOverlay() {
|
|
14040
|
-
const [active, setActive] = (0, import_react25.useState)(() => mobileActive());
|
|
14041
|
-
(0, import_react25.useEffect)(() => {
|
|
14042
|
-
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return void 0;
|
|
14043
|
-
let mqs = [];
|
|
14044
|
-
try {
|
|
14045
|
-
mqs = [window.matchMedia(MOBILE_QUERY_NARROW), window.matchMedia(MOBILE_QUERY_COARSE)];
|
|
14046
|
-
} catch {
|
|
14047
|
-
return void 0;
|
|
14048
|
-
}
|
|
14049
|
-
const update = () => setActive(mqs.some((mq) => mq.matches));
|
|
14050
|
-
update();
|
|
14051
|
-
for (const mq of mqs) {
|
|
14052
|
-
if (typeof mq.addEventListener === "function") mq.addEventListener("change", update);
|
|
14053
|
-
else if (typeof mq.addListener === "function") mq.addListener(update);
|
|
14054
|
-
}
|
|
14055
|
-
return () => {
|
|
14056
|
-
for (const mq of mqs) {
|
|
14057
|
-
if (typeof mq.removeEventListener === "function") mq.removeEventListener("change", update);
|
|
14058
|
-
else if (typeof mq.removeListener === "function") mq.removeListener(update);
|
|
14059
|
-
}
|
|
14060
|
-
};
|
|
14061
|
-
}, []);
|
|
14062
|
-
(0, import_react25.useEffect)(() => {
|
|
14063
|
-
if (typeof document === "undefined") return void 0;
|
|
14064
|
-
if (active) {
|
|
14065
|
-
document.body.setAttribute("data-dk-mobile", "1");
|
|
14066
|
-
try {
|
|
14067
|
-
const meta = document.querySelector('meta[name="viewport"]');
|
|
14068
|
-
if (meta && !/(^|,)\s*viewport-fit\s*=/.test(meta.content || "")) {
|
|
14069
|
-
meta.setAttribute("content", (meta.content || "width=device-width, initial-scale=1") + ", viewport-fit=cover");
|
|
14070
|
-
}
|
|
14071
|
-
} catch {
|
|
14072
|
-
}
|
|
14073
|
-
} else {
|
|
14074
|
-
document.body.removeAttribute("data-dk-mobile");
|
|
14075
|
-
}
|
|
14076
|
-
return () => {
|
|
14077
|
-
document.body.removeAttribute("data-dk-mobile");
|
|
14078
|
-
};
|
|
14079
|
-
}, [active]);
|
|
14080
|
-
(0, import_react25.useEffect)(() => mobileChrome(), []);
|
|
14081
|
-
return null;
|
|
14082
|
-
}
|
|
14083
|
-
function mobileChrome() {
|
|
14084
|
-
if (typeof window === "undefined" || typeof document === "undefined") return void 0;
|
|
14085
|
-
const mq = window.matchMedia ? window.matchMedia(MOBILE_QUERY_CHROME) : null;
|
|
14086
|
-
if (!mq) return void 0;
|
|
14087
|
-
if (window.__dshDockMobileDrawer === "host") return void 0;
|
|
14088
|
-
window.__dshDockMobileDrawer = "client";
|
|
14089
|
-
const narrow = () => mq.matches;
|
|
14090
|
-
const frameEl = () => document.querySelector('[class$="frame"]');
|
|
14091
|
-
const sidebarCollapsed = () => {
|
|
14092
|
-
const f = frameEl();
|
|
14093
|
-
return !!f && f.hasAttribute("data-sidebar-collapsed");
|
|
14094
|
-
};
|
|
14095
|
-
const dialogOpen = () => !!document.querySelector('[role="dialog"][class*="panel"]');
|
|
14096
|
-
const rightOpen = () => !!document.querySelector("[data-sidebar-right-panel][data-sidebar-right-open]");
|
|
14097
|
-
const collapse = () => {
|
|
14098
|
-
const b = document.querySelector('button[aria-label="\u6536\u8D77\u4FA7\u8FB9\u680F"],button[aria-label="Collapse sidebar"]');
|
|
14099
|
-
if (b) b.click();
|
|
14100
|
-
};
|
|
14101
|
-
const expand = () => {
|
|
14102
|
-
const b = document.querySelector('button[aria-label="\u6253\u5F00\u4FA7\u8FB9\u680F"],button[aria-label="Open sidebar"]');
|
|
14103
|
-
if (b) b.click();
|
|
14104
|
-
};
|
|
14105
|
-
const closeDetails = () => {
|
|
14106
|
-
const panel = document.querySelector("[data-sidebar-right-panel][data-sidebar-right-open]");
|
|
14107
|
-
if (!panel) return;
|
|
14108
|
-
const toggle = panel.querySelector("[data-sidebar-right-toggle]");
|
|
14109
|
-
if (toggle) toggle.click();
|
|
14110
|
-
};
|
|
14111
|
-
const scrim = document.createElement("div");
|
|
14112
|
-
scrim.className = "dsh-mobile-scrim";
|
|
14113
|
-
document.body.appendChild(scrim);
|
|
14114
|
-
document.querySelectorAll(".dsh-mobile-tabbar").forEach((el) => el.remove());
|
|
14115
|
-
const burger = document.createElement("button");
|
|
14116
|
-
burger.type = "button";
|
|
14117
|
-
burger.className = "dsh-mobile-burger";
|
|
14118
|
-
burger.setAttribute("aria-label", "\u6253\u5F00\u4F1A\u8BDD\u5217\u8868");
|
|
14119
|
-
burger.setAttribute("aria-expanded", "false");
|
|
14120
|
-
burger.innerHTML = '<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M4 7h16"/><path d="M4 12h16"/><path d="M4 17h16"/></svg><span class="dsh-mobile-burger-badge" hidden></span>';
|
|
14121
|
-
burger.addEventListener("click", () => expand());
|
|
14122
|
-
document.body.appendChild(burger);
|
|
14123
|
-
const syncBurger = () => {
|
|
14124
|
-
const expanded = !sidebarCollapsed();
|
|
14125
|
-
burger.setAttribute("aria-expanded", expanded ? "true" : "false");
|
|
14126
|
-
burger.classList.toggle("on", expanded);
|
|
14127
|
-
};
|
|
14128
|
-
const badge = burger.querySelector(".dsh-mobile-burger-badge");
|
|
14129
|
-
let runstateGone = false;
|
|
14130
|
-
const pollTasks = () => {
|
|
14131
|
-
if (runstateGone || !badge || !narrow() || document.visibilityState === "hidden" || !burger.isConnected) return;
|
|
14132
|
-
const on = stateOf("runstate").enabled !== false;
|
|
14133
|
-
if (!on && !window.__dshDockRunstate) {
|
|
14134
|
-
badge.hidden = true;
|
|
14135
|
-
return;
|
|
14136
|
-
}
|
|
14137
|
-
fetch("dsh-dock/runstate/status", {
|
|
14138
|
-
method: "POST",
|
|
14139
|
-
headers: { "content-type": "application/json" },
|
|
14140
|
-
body: "{}"
|
|
14141
|
-
}).then(async (res) => {
|
|
14142
|
-
if (res.status === 404 || res.status === 405) {
|
|
14143
|
-
runstateGone = true;
|
|
14144
|
-
badge.hidden = true;
|
|
14145
|
-
return null;
|
|
14146
|
-
}
|
|
14147
|
-
const body = await res.json().catch(() => null);
|
|
14148
|
-
if (!body) return null;
|
|
14149
|
-
const active = body.data && body.data.active || [];
|
|
14150
|
-
const waiting = active.reduce((n, t) => n + (Array.isArray(t.approvals) ? t.approvals.length : 0), 0);
|
|
14151
|
-
if (waiting > 0) {
|
|
14152
|
-
badge.textContent = waiting > 99 ? "99+" : String(waiting);
|
|
14153
|
-
badge.className = "dsh-mobile-burger-badge wait";
|
|
14154
|
-
badge.hidden = false;
|
|
14155
|
-
burger.setAttribute("title", waiting + " \u4E2A\u4EFB\u52A1\u7B49\u5F85\u4F60\u786E\u8BA4");
|
|
14156
|
-
} else if (active.length > 0) {
|
|
14157
|
-
badge.textContent = active.length > 99 ? "99+" : String(active.length);
|
|
14158
|
-
badge.className = "dsh-mobile-burger-badge";
|
|
14159
|
-
badge.hidden = false;
|
|
14160
|
-
burger.setAttribute("title", active.length + " \u4E2A\u4EFB\u52A1\u8FDB\u884C\u4E2D");
|
|
14161
|
-
} else {
|
|
14162
|
-
badge.hidden = true;
|
|
14163
|
-
burger.removeAttribute("title");
|
|
14164
|
-
}
|
|
14165
|
-
}).catch(() => {
|
|
14166
|
-
});
|
|
14167
|
-
};
|
|
14168
|
-
const tasksTimer = setInterval(pollTasks, 3e3);
|
|
14169
|
-
const onVisible = () => {
|
|
14170
|
-
if (document.visibilityState === "visible") pollTasks();
|
|
14171
|
-
};
|
|
14172
|
-
document.addEventListener("visibilitychange", onVisible);
|
|
14173
|
-
pollTasks();
|
|
14174
|
-
const vv = window.visualViewport || null;
|
|
14175
|
-
const kbdSync = () => {
|
|
14176
|
-
if (!vv) return;
|
|
14177
|
-
const kbd = vv.height > 0 && window.innerHeight - vv.height > 120;
|
|
14178
|
-
document.documentElement.classList.toggle("dsh-dock-kbd", kbd);
|
|
14179
|
-
};
|
|
14180
|
-
const sync = () => {
|
|
14181
|
-
kbdSync();
|
|
14182
|
-
document.querySelectorAll(".dsh-mobile-tabbar").forEach((el) => el.remove());
|
|
14183
|
-
const on = narrow() && !!frameEl() && !dialogOpen();
|
|
14184
|
-
const collapsed = sidebarCollapsed();
|
|
14185
|
-
const right = rightOpen();
|
|
14186
|
-
if (scrim) scrim.style.display = on && !collapsed ? "" : "none";
|
|
14187
|
-
burger.style.display = narrow() && !!frameEl() && !panelNav.open && !right ? "" : "none";
|
|
14188
|
-
syncBurger();
|
|
14189
|
-
};
|
|
14190
|
-
sync();
|
|
14191
|
-
const observer = typeof MutationObserver !== "undefined" ? new MutationObserver(sync) : null;
|
|
14192
|
-
if (observer) observer.observe(document.documentElement, { attributes: true, attributeFilter: ["data-sidebar-collapsed"], subtree: true });
|
|
14193
|
-
const timer = setInterval(sync, 1500);
|
|
14194
|
-
const onMq = () => sync();
|
|
14195
|
-
if (mq.addEventListener) mq.addEventListener("change", onMq);
|
|
14196
|
-
else if (mq.addListener) mq.addListener(onMq);
|
|
14197
|
-
window.addEventListener("resize", kbdSync);
|
|
14198
|
-
if (vv && vv.addEventListener) vv.addEventListener("resize", kbdSync);
|
|
14199
|
-
const onClick = (e) => {
|
|
14200
|
-
if (!narrow()) return;
|
|
14201
|
-
const t = e.target;
|
|
14202
|
-
if (!t || !t.closest) return;
|
|
14203
|
-
if (t.closest(".dsh-mobile-burger")) return;
|
|
14204
|
-
const expanded = !!document.querySelector('button[aria-label="\u6536\u8D77\u4FA7\u8FB9\u680F"],button[aria-label="Collapse sidebar"]');
|
|
14205
|
-
const col = document.querySelector('[class*="sidebarCol"]');
|
|
14206
|
-
const inSidebar = col && col.contains(t);
|
|
14207
|
-
if (!expanded && !inSidebar) return;
|
|
14208
|
-
if (inSidebar) {
|
|
14209
|
-
const row = t.closest('[role="treeitem"]');
|
|
14210
|
-
const rowKey = row && row.getAttribute("data-row-key") || "";
|
|
14211
|
-
const sessionRow = rowKey && rowKey.startsWith("session:") || row && !rowKey && !row.querySelector('[role="treeitem"]') && row.closest('[role="tree"]');
|
|
14212
|
-
const fresh = t.closest('[class*="newSession"]');
|
|
14213
|
-
if (sessionRow || fresh) {
|
|
14214
|
-
setTimeout(() => {
|
|
14215
|
-
collapse();
|
|
14216
|
-
closeDetails();
|
|
14217
|
-
}, 300);
|
|
14218
|
-
return;
|
|
14219
|
-
}
|
|
14220
|
-
if (rowKey.startsWith("workspace:")) return;
|
|
14221
|
-
setTimeout(() => {
|
|
14222
|
-
if (document.querySelector('[role="dialog"]')) collapse();
|
|
14223
|
-
}, 260);
|
|
14224
|
-
return;
|
|
14225
|
-
}
|
|
14226
|
-
if (t.closest('[role="dialog"],[class*="dockm"],[class*="dgfab"],[class*="dgwin"],[class*="dgame"],[data-sidebar-right-panel]')) return;
|
|
14227
|
-
collapse();
|
|
14228
|
-
};
|
|
14229
|
-
document.addEventListener("click", onClick, true);
|
|
14230
|
-
return () => {
|
|
14231
|
-
document.removeEventListener("click", onClick, true);
|
|
14232
|
-
if (observer) observer.disconnect();
|
|
14233
|
-
clearInterval(timer);
|
|
14234
|
-
clearInterval(tasksTimer);
|
|
14235
|
-
document.removeEventListener("visibilitychange", onVisible);
|
|
14236
|
-
if (mq.removeEventListener) mq.removeEventListener("change", onMq);
|
|
14237
|
-
else if (mq.removeListener) mq.removeListener(onMq);
|
|
14238
|
-
window.removeEventListener("resize", kbdSync);
|
|
14239
|
-
if (vv && vv.removeEventListener) vv.removeEventListener("resize", kbdSync);
|
|
14240
|
-
document.documentElement.classList.remove("dsh-dock-kbd");
|
|
14241
|
-
if (scrim) scrim.remove();
|
|
14242
|
-
burger.remove();
|
|
14243
|
-
if (window.__dshDockMobileDrawer === "client") delete window.__dshDockMobileDrawer;
|
|
14244
|
-
};
|
|
14245
|
-
}
|
|
14246
|
-
function useViewportSize() {
|
|
14247
|
-
const [size, setSize] = (0, import_react25.useState)(() => typeof window === "undefined" ? null : { w: window.innerWidth, h: window.innerHeight });
|
|
14248
|
-
(0, import_react25.useEffect)(() => {
|
|
14249
|
-
if (typeof window === "undefined") return void 0;
|
|
14250
|
-
const update = () => setSize({ w: window.innerWidth, h: window.innerHeight });
|
|
14251
|
-
window.addEventListener("resize", update);
|
|
14252
|
-
return () => window.removeEventListener("resize", update);
|
|
14253
|
-
}, []);
|
|
14254
|
-
return size;
|
|
14255
|
-
}
|
|
14256
|
-
function useMobileState() {
|
|
14257
|
-
const [active, setActive] = (0, import_react25.useState)(() => mobileActive());
|
|
14258
|
-
const [chrome, setChrome] = (0, import_react25.useState)(() => typeof window === "undefined" || typeof window.matchMedia !== "function" ? false : window.matchMedia(MOBILE_QUERY_CHROME).matches);
|
|
14259
|
-
const [owner, setOwner] = (0, import_react25.useState)(() => typeof window === "undefined" ? null : window.__dshDockMobileDrawer || null);
|
|
14260
|
-
(0, import_react25.useEffect)(() => {
|
|
14261
|
-
const offChrome = watchQuery(MOBILE_QUERY_CHROME, setChrome);
|
|
14262
|
-
let mqs = [];
|
|
14263
|
-
try {
|
|
14264
|
-
mqs = [window.matchMedia(MOBILE_QUERY_NARROW), window.matchMedia(MOBILE_QUERY_COARSE)];
|
|
14265
|
-
} catch {
|
|
14266
|
-
mqs = [];
|
|
14267
|
-
}
|
|
14268
|
-
const compute = () => setActive(mqs.some((mq) => mq.matches));
|
|
14269
|
-
for (const mq of mqs) {
|
|
14270
|
-
if (typeof mq.addEventListener === "function") mq.addEventListener("change", compute);
|
|
14271
|
-
else if (typeof mq.addListener === "function") mq.addListener(compute);
|
|
14272
|
-
}
|
|
14273
|
-
const timer = setInterval(() => setOwner(typeof window === "undefined" ? null : window.__dshDockMobileDrawer || null), 1e3);
|
|
14274
|
-
return () => {
|
|
14275
|
-
offChrome();
|
|
14276
|
-
for (const mq of mqs) {
|
|
14277
|
-
if (typeof mq.removeEventListener === "function") mq.removeEventListener("change", compute);
|
|
14278
|
-
else if (typeof mq.removeListener === "function") mq.removeListener(compute);
|
|
14279
|
-
}
|
|
14280
|
-
clearInterval(timer);
|
|
14281
|
-
};
|
|
14282
|
-
}, []);
|
|
14283
|
-
return { active, chrome, owner };
|
|
14284
|
-
}
|
|
14285
|
-
function MobileView() {
|
|
14286
|
-
const { active, chrome, owner } = useMobileState();
|
|
14287
|
-
const size = useViewportSize();
|
|
14288
|
-
return import_react24.default.createElement(
|
|
14289
|
-
"div",
|
|
14290
|
-
{ className: "dkmob-root" },
|
|
14291
|
-
import_react24.default.createElement(
|
|
14292
|
-
"div",
|
|
14293
|
-
{ className: "dkmob-row" },
|
|
14294
|
-
import_react24.default.createElement("span", { className: "dkmob-label" }, "\u624B\u673A\u6A21\u5F0F"),
|
|
14295
|
-
import_react24.default.createElement("span", { className: "dkmob-state" + (active ? " on" : "") }, active ? "\u5DF2\u547D\u4E2D" : "\u672A\u547D\u4E2D"),
|
|
14296
|
-
import_react24.default.createElement(
|
|
14297
|
-
"span",
|
|
14298
|
-
{ className: "dkmob-dim" },
|
|
14299
|
-
size ? size.w + "\xD7" + size.h + "px" : "",
|
|
14300
|
-
"\uFF08\u2264820px \u5BBD\uFF0C\u6216\u4E3B\u6307\u9488\u4E3A\u89E6\u5C4F\u65E0\u60AC\u505C\u65F6\u547D\u4E2D\uFF1B\u684C\u9762\u628A\u7A97\u53E3\u62D6\u7A84\u4E5F\u4F1A\u547D\u4E2D\uFF0C\u65B9\u4FBF\u8C03\u8BD5\uFF09"
|
|
14301
|
-
)
|
|
14302
|
-
),
|
|
14303
|
-
import_react24.default.createElement(
|
|
14304
|
-
"div",
|
|
14305
|
-
{ className: "dkmob-row" },
|
|
14306
|
-
import_react24.default.createElement("span", { className: "dkmob-label" }, "\u624B\u673A\u7AEF chrome"),
|
|
14307
|
-
import_react24.default.createElement("span", { className: "dkmob-state" + (chrome ? " on" : "") }, chrome ? "\u2264700px\uFF0C\u751F\u6548\u4E2D" : "\u672A\u547D\u4E2D"),
|
|
14308
|
-
import_react24.default.createElement(
|
|
14309
|
-
"span",
|
|
14310
|
-
{ className: "dkmob-dim" },
|
|
14311
|
-
"\u5DE6\u4E0A\u89D2\u6C49\u5821\u83DC\u5355\uFF08\u5C55\u5F00\u5DE6\u4FA7\u4F1A\u8BDD\u62BD\u5C49\uFF09+ \u4FA7\u680F\u62BD\u5C49\u906E\u7F69 + \u8F6F\u952E\u76D8\u8BA9\u4F4D\uFF1B\u5E95\u90E8 Tab \u680F\u5DF2\u6309\u7528\u6237\u8981\u6C42\u79FB\u9664\uFF0C\u63D2\u4EF6/\u8BBE\u7F6E\u7B49\u5165\u53E3\u5728\u62BD\u5C49\u91CC\u3002",
|
|
14312
|
-
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" : ""
|
|
14313
|
-
)
|
|
14314
|
-
),
|
|
14315
|
-
import_react24.default.createElement(
|
|
14316
|
-
"div",
|
|
14317
|
-
{ className: "dkmob-note" },
|
|
14318
|
-
"\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 ",
|
|
14319
|
-
"\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 ",
|
|
14320
|
-
"\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",
|
|
14321
|
-
"\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"
|
|
14322
|
-
)
|
|
14323
|
-
);
|
|
14324
|
-
}
|
|
14325
|
-
function MobileStat() {
|
|
14326
|
-
const { active, chrome } = useMobileState();
|
|
14327
|
-
if (!active) return import_react24.default.createElement("span", null, "\u5F53\u524D\u89C6\u53E3\u672A\u547D\u4E2D\u624B\u673A\u5F62\u6001\uFF0C\u6837\u5F0F\u672A\u6CE8\u5165");
|
|
14328
|
-
return import_react24.default.createElement("span", null, "\u624B\u673A\u6A21\u5F0F\u751F\u6548\u4E2D \xB7 " + (chrome ? "\u5DE6\u4E0A\u89D2\u6C49\u5821\u83DC\u5355\u5DF2\u63A5\u7BA1\u4F1A\u8BDD\u5165\u53E3" : "chrome \u5E26\u5BBD\u672A\u547D\u4E2D\uFF08\u2264700px \u624D\u542F\u7528\uFF09"));
|
|
14329
|
-
}
|
|
14330
|
-
var css6 = [
|
|
14331
|
-
// 输入类控件 16px:防 iOS 聚焦自动放大(<16px 的输入框聚焦时 Safari 强制缩放页面)
|
|
14332
|
-
'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;}',
|
|
14333
|
-
// 触控基础:去点按高亮、消双击缩放判定
|
|
14334
|
-
'body[data-dk-mobile="1"] :is(button, [role="button"]){-webkit-tap-highlight-color:transparent;touch-action:manipulation;}',
|
|
14335
|
-
// 纯图标按钮面积兜底:实测窄屏下一批 28×28 的工具钮很难点中;36px 是不引起行高剧变的上限。
|
|
14336
|
-
// 只收「唯一子元素是 svg」的按钮,避免撑坏带文字的行内控件;排除本模块 chrome 按钮。
|
|
14337
|
-
'body[data-dk-mobile="1"] button:has(> svg:only-child):not(.dsh-mobile-burger){min-width:36px;min-height:36px;}',
|
|
14338
|
-
// 代码块横向滚动、行内代码换行:窄屏不撑破版面
|
|
14339
|
-
'body[data-dk-mobile="1"] pre{max-width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;}',
|
|
14340
|
-
'body[data-dk-mobile="1"] code{overflow-wrap:anywhere;}',
|
|
14341
|
-
'body[data-dk-mobile="1"] pre code{overflow-wrap:normal;}',
|
|
14342
|
-
// 滚动兜底:所有纵向滚动体可纵向平移 + iOS 惯性滚动(祖先合成层/触控声明不再吃掉触摸滚动)。
|
|
14343
|
-
'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;}',
|
|
14344
|
-
// iOS 横竖屏切换时的字号自动膨胀关掉(:has 挂到 html 上;dsh 自身样式已依赖 :has,基线足够)
|
|
14345
|
-
'html:has(body[data-dk-mobile="1"]){-webkit-text-size-adjust:100%;text-size-adjust:100%;}',
|
|
14346
|
-
// 功能页自身
|
|
14347
|
-
".dkmob-root{display:flex;flex-direction:column;gap:10px;color:var(--dsw-alias-label-primary);font-size:13px;line-height:1.6;}",
|
|
14348
|
-
".dkmob-row{display:flex;align-items:center;gap:8px;flex-wrap:wrap;}",
|
|
14349
|
-
".dkmob-label{font-weight:600;flex:none;}",
|
|
14350
|
-
".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;}",
|
|
14351
|
-
".dkmob-state.on{color:var(--dsw-alias-state-success-primary);border-color:var(--dsw-alias-state-success-primary);}",
|
|
14352
|
-
".dkmob-dim{color:var(--dsw-alias-label-secondary);font-size:12px;}",
|
|
14353
|
-
".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;}",
|
|
14354
|
-
// 手机端 chrome:左上角汉堡菜单 + 抽屉遮罩(窄屏 ≤700px;与宿主半部同款)
|
|
14355
|
-
"@media (max-width:700px){",
|
|
14356
|
-
".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}",
|
|
14357
|
-
// 左上角汉堡菜单(三条横线):44×44 触控面积,避让刘海/圆角安全区;z 66 高于正文、
|
|
14358
|
-
// 低于遮罩 75 / 抽屉 80——抽屉展开时被自然盖住。
|
|
14359
|
-
// ⚠️ 视觉上刻意「不贴合卡片」:页面左上角本来就是空的,原生同类控件(右上的侧栏开关)
|
|
14360
|
-
// 是**裸图标**——无底色、无边框、无阴影。早期版本做成白底圆角卡片 + 阴影 + 模糊,
|
|
14361
|
-
// 悬浮在白底页面上像一块贴上去的异物(用户实测反馈「没有贴合边缘,很突兀」)。
|
|
14362
|
-
// 现在与原生同款:透明底、无边框无阴影,只留图标;点按才给极轻的底色反馈。
|
|
14363
|
-
// 视觉重量靠图标本身撑住(22px、1.9px 描边、主文字色),不靠容器。
|
|
14364
|
-
".dsh-mobile-burger{position:fixed;left:env(safe-area-inset-left,0px);top:env(safe-area-inset-top,0px);z-index:66;box-sizing:border-box;width:44px;height:44px;display:flex;align-items:center;justify-content:center;padding:0;border:0;border-radius:0;background:transparent;color:var(--dsw-alias-label-primary,#e6eaf2);cursor:pointer;-webkit-tap-highlight-color:transparent;touch-action:manipulation;transition:color .15s var(--ds-ease-in-out,ease)}",
|
|
14365
|
-
".dsh-mobile-burger svg{width:22px;height:22px;fill:none;stroke:currentColor;stroke-width:1.9;stroke-linecap:round}",
|
|
14366
|
-
// 展开态:图标换成强调色(与原生「已激活」的语义一致),不引入额外容器。
|
|
14367
|
-
".dsh-mobile-burger.on{color:var(--dk-accent,#4d9fff)}",
|
|
14368
|
-
// 点按反馈走图标本身(用 :active 的底色透出,范围就是 44×44 触控区)。
|
|
14369
|
-
".dsh-mobile-burger:active{background:color-mix(in srgb,currentColor 12%,transparent)}",
|
|
14370
|
-
// 待确认任务角标:锚在按钮右上角的小圆点/数字。刻意做成「贴边小圆点」而不是
|
|
14371
|
-
// 底部 Tab 栏那种带容器的页签角标——汉堡是裸图标,角标再带容器就又突兀了。
|
|
14372
|
-
// 等待确认(要人介入)= 红点 + 脉冲;进行中 = 蓝色数字(弱一级,不抢注意力)。
|
|
14373
|
-
".dsh-mobile-burger-badge{position:absolute;top:4px;right:4px;box-sizing:border-box;min-width:8px;height:8px;padding:0;border-radius:999px;background:#4d9fff;font:700 9px/8px inherit;font-variant-numeric:tabular-nums;text-align:center;color:#fff;pointer-events:none;box-shadow:0 0 0 2px var(--dsw-alias-bg-layer-1,#12151b)}",
|
|
14374
|
-
".dsh-mobile-burger-badge[hidden]{display:none}",
|
|
14375
|
-
".dsh-mobile-burger-badge:not([hidden]){min-width:16px;height:16px;line-height:16px;padding:0 4px}",
|
|
14376
|
-
".dsh-mobile-burger-badge.wait{background:#ef4444;animation:dsh-burger-badge-pulse 1.2s ease-in-out infinite}",
|
|
14377
|
-
"@keyframes dsh-burger-badge-pulse{0%,100%{transform:scale(1)}50%{transform:scale(1.18)}}",
|
|
14378
|
-
"@media (prefers-reduced-motion:reduce){.dsh-mobile-burger-badge.wait{animation:none}}",
|
|
14379
|
-
// ⚠️ 给标题让出汉堡宽度(用户实测:标题被汉堡压住——截图里「更新所有仓库代码」的首字
|
|
14380
|
-
// 直接叠在三条横线上)。汉堡是 fixed 定位(贴安全区、44×44),**不占布局**,而原生标题
|
|
14381
|
-
// 从头部的 padding-left:20px 起排——真实实例 390×844 逐字实测:会话标题首字 x=28、
|
|
14382
|
-
// 汉堡右缘 44 → **重叠 16px**;插件页/自动化任务页的页头(自身 padding-left:0,靠外层
|
|
14383
|
-
// 容器给 24px)首字 x=24 → 重叠 20px。
|
|
14384
|
-
// 改法照原生排版习惯走:**给容器补内边距**,而不是给汉堡加底色/加宽(那是把问题搬到视觉上)。
|
|
14385
|
-
// · 会话页头 header:has([class*="titleRow"])(唯一含 titleRow 的 header):左内边距
|
|
14386
|
-
// 20px → 44px,正好等于汉堡宽度;标题自带 8px 内边距 → 首字落在 x=52,与汉堡留 8px。
|
|
14387
|
-
// · 插件页/自动化任务页头 [class$="_pageHead"] / [class$="_pageHeading"]
|
|
14388
|
-
// (DSH 0.2.0-rc.2 实测:plugin-manager 的 ZVcBiW_pageHead、schedule 的
|
|
14389
|
-
// CxUija_pageHeading):左内边距 0 → 28px → 首字 x=52,同样留 8px。
|
|
14390
|
-
// 这两条页头是 flex + gap:16px(标题块 | 工具栏),补内边距会压缩内容宽度——实测
|
|
14391
|
-
// 430/390/360/320px 下「添加插件」按钮与描述文案会被挤到换行(按钮从单行变两行)。
|
|
14392
|
-
// 故同时把 gap 收到 4px 补回 12px:四个宽度实测行数零回归、无横向溢出。
|
|
14393
|
-
// 用 `[class$=…]`(语义后缀)而非 `[class*=…]`:DSH 类名是「哈希前缀 + 语义后缀」,
|
|
14394
|
-
// 后缀稳定、前缀随版本变;`$=` 也避开 `pageHeadActions` 这类同前缀的无关元素。
|
|
14395
|
-
// 挂 body[data-dk-mobile="1"]:本模块 css 字段会被无条件并入全局样式,停用本功能即摘掉
|
|
14396
|
-
// body 属性 → 规则空转、原生排版还原(与文件头「开关协议」一致)。
|
|
14397
|
-
'body[data-dk-mobile="1"] header:has([class*="titleRow"]){padding-left:calc(44px + env(safe-area-inset-left,0px))}',
|
|
14398
|
-
'body[data-dk-mobile="1"] [class$="_pageHead"],body[data-dk-mobile="1"] [class$="_pageHeading"]{padding-left:calc(28px + env(safe-area-inset-left,0px));gap:4px}',
|
|
14399
|
-
// ⚠️ 「设置页滑不动」的关键兜底(客户端无条件携带 = 刷新即生效,不必等宿主重启):
|
|
14400
|
-
// 窄屏把设置弹层改成纵向堆叠后,内容列若是默认 min-height:auto 就会被内容撑高
|
|
14401
|
-
// (无头 390×844 实测列高 1216px 塞在 844px 视口里)、再被 .panel 的 overflow:hidden
|
|
14402
|
-
// 裁掉——列内滚动容器([class*=options])因此 scrollHeight==clientHeight,手指怎么滑
|
|
14403
|
-
// 都不动。补 min-height:0 后 scrollTop 0 → 425。宿主半部 MOBILE_LAYOUT_CSS 同款;
|
|
14404
|
-
// 两处都写是因为宿主注入要重启 dsh web 才更新,而客户端样式刷新即生效,覆盖窗口期。
|
|
14405
|
-
'[role="dialog"][class*="panel"]>[class*="content"]{min-height:0!important}',
|
|
14406
|
-
// 输入区吸附到视口底部 + 滚动体留白(与宿主半部同款)。
|
|
14407
|
-
// ⚠️ 底部留白只保留 iPhone home indicator 的安全区,不再额外留白。沿革:原 72px 是
|
|
14408
|
-
// 「底部 Tab 栏高度 + 安全区」;Tab 栏移除后先收到 24px,但实测(真实实例 390×844
|
|
14409
|
-
// 像素扫描)输入卡片下方仍有 **51px** 空白带,其中 24px 是这里的滚动体内边距、
|
|
14410
|
-
// 6px 是下面 composerSeat 的内边距——两者都是 Tab 栏时代的遗留,在没有底栏的页面上
|
|
14411
|
-
// 纯属浪费。收窄到「只有安全区」后卡片下沿更贴近视口底,这 30px 直接变成会话区
|
|
14412
|
-
// 可显示的正文(滚动体内边距在 flex 容器里会把 composerSeat 连同消息区一起下移/增高)。
|
|
14413
|
-
// dsh 自带的 ~21px 底部间距(卡片 margin)保留,视觉上仍有呼吸感,不会贴死屏幕边缘。
|
|
14414
|
-
// ⚠️ 绝不能给滚动体加 justify-content:flex-end/center 贴底:内容会被挤到滚动体
|
|
14415
|
-
// 起点之外,Chrome 不把起点方向溢出算进 scrollHeight(手机视口实测
|
|
14416
|
-
// scrollHeight==clientHeight、maxScroll==0),会话记录彻底滚不动、首条消息永远看不到。
|
|
14417
|
-
// 宿主半部旧版注入里还留着那条 flex-end(要重启 dsh web 才消失),这里用更高优先级
|
|
14418
|
-
// 的选择器显式复位:刷新页面即修好,不必等重启。贴底只能用输入区自己的 margin-top:auto。
|
|
14419
|
-
'[class*="scrollBody"][data-conversation-scroll]{justify-content:flex-start !important;padding-bottom:env(safe-area-inset-bottom,0px) !important}',
|
|
14420
|
-
'html:not(.dsh-dock-kbd) [class*="scrollBody"]{padding-bottom:env(safe-area-inset-bottom,0px) !important}',
|
|
14421
|
-
'html.dsh-dock-kbd [class*="scrollBody"]{padding-bottom:env(safe-area-inset-bottom,0px) !important}',
|
|
14422
|
-
'[class*="scrollBody"]>[class*="composerSeat"]{margin-top:auto;padding-bottom:0}',
|
|
14423
|
-
// 输入区工具行上的 dsh-dock chip(用量/余额):窄屏下 28cqw 的宽度上限把它们挤成
|
|
14424
|
-
// 「…」「余..」(手机实测),既读不出数值又白占输入行空间。手机端整组收起,数值在
|
|
14425
|
-
// 功能坞(抽屉里进)看;桌面端不动。
|
|
14426
|
-
".dockchip-row{display:none}",
|
|
14427
|
-
'[class*="sidebarCol"]:has([class*="collapsed"]){visibility:hidden}',
|
|
14428
|
-
// ⚠️ 列级 visibility:hidden 在 dsh 0.2.0 上挡不住:工作区浏览器给自己的
|
|
14429
|
-
// headerActions/sectionLabel 显式声明 visibility:visible(展开/收拢动画用),visibility
|
|
14430
|
-
// 可被后代覆盖,轨道按钮会从隐藏列里「透」出来(实测手机截图左缘游离按钮)。
|
|
14431
|
-
// display:none 不可被后代翻转——但只能打在**轨道根节点**上(类名同时含 root 与
|
|
14432
|
-
// collapsed 两个语义后缀),绝不能打在列上:frame 是「侧栏 0px + 中列 1fr + 右轨 0px」
|
|
14433
|
-
// 的网格,列 display:none 会从网格流里摘掉,中列被自动放置顶进 0px 轨(实测整页空屏)。
|
|
14434
|
-
// 弹层打开时豁免(设置弹层挂在列内部,display:none 会连坐成空气弹层),此时列退回
|
|
14435
|
-
// visibility 机制(由下一条 [role=dialog] 强制可见),窄屏弹层全屏铺满盖住透出的轨道。
|
|
14436
|
-
'[class*="sidebarCol"]:has([class*="collapsed"]):not(:has([role="dialog"])) [class*="root"][class*="collapsed"]{display:none !important}',
|
|
14437
|
-
// 设置/插件管理弹层挂在侧栏列内部:上面隐藏整列会把它连坐隐藏(空气弹层)。
|
|
14438
|
-
// visibility 可被后代覆盖,弹层关闭态整体卸载,所以只在真正打开时命中。
|
|
14439
|
-
'[class*="sidebarCol"]:has([class*="collapsed"]) [role="dialog"]{visibility:visible}',
|
|
14440
|
-
"html.dsh-dock-kbd .dsh-mobile-burger{display:none !important}",
|
|
14441
|
-
// 功能坞面板在手机端抬到原生弹层之上:从抽屉进的官方插件管理页等原生弹层 z 序高于
|
|
14442
|
-
// 面板默认的 200,功能坞开在下面会被盖住。抽屉展开时从侧栏 rail 点功能坞图标进入。
|
|
14443
|
-
'[class*="dockm-backdrop"]{z-index:2000 !important}',
|
|
14444
|
-
"}"
|
|
14445
|
-
].join("\n");
|
|
14446
|
-
var feature13 = {
|
|
14447
|
-
id: "mobile",
|
|
14448
|
-
name: "\u624B\u673A\u9002\u914D",
|
|
14449
|
-
order: 170,
|
|
14450
|
-
accent: "#34d399",
|
|
14451
|
-
description: "\u624B\u673A/\u7A84\u5C4F\u6392\u7248\u4E0E\u89E6\u63A7\u515C\u5E95\uFF1A\u5DE6\u4E0A\u89D2\u6C49\u5821\u83DC\u5355 + \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",
|
|
14452
|
-
defaultEnabled: true,
|
|
14453
|
-
css: css6,
|
|
14454
|
-
Overlay: MobileOverlay,
|
|
14455
|
-
View: MobileView,
|
|
14456
|
-
HomeStat: MobileStat
|
|
14457
|
-
};
|
|
14458
|
-
|
|
14459
14205
|
// src/client.jsx
|
|
14460
|
-
var DOCK_VERSION = "0.
|
|
14461
|
-
var BUILTIN_FEATURES = [feature, feature2, feature3, feature4, feature5, feature6, feature7, feature8, feature9, feature10, feature11, feature12
|
|
14206
|
+
var DOCK_VERSION = "0.20.0";
|
|
14207
|
+
var BUILTIN_FEATURES = [feature, feature2, feature3, feature4, feature5, feature6, feature7, feature8, feature9, feature10, feature11, feature12];
|
|
14462
14208
|
var PLANNED_FEATURES = [];
|
|
14463
14209
|
var PLANNED_NOTES = {};
|
|
14464
14210
|
var externalDefs = [];
|
|
@@ -14665,8 +14411,8 @@ function ensureCss() {
|
|
|
14665
14411
|
}
|
|
14666
14412
|
}
|
|
14667
14413
|
function useExternalVersion() {
|
|
14668
|
-
const [, bump] =
|
|
14669
|
-
|
|
14414
|
+
const [, bump] = import_react24.default.useReducer((n) => n + 1, 0);
|
|
14415
|
+
import_react24.default.useEffect(() => {
|
|
14670
14416
|
externalListeners.add(bump);
|
|
14671
14417
|
return () => {
|
|
14672
14418
|
externalListeners.delete(bump);
|
|
@@ -14676,44 +14422,44 @@ function useExternalVersion() {
|
|
|
14676
14422
|
var lastGeom = { x: null, y: null, w: null, h: null };
|
|
14677
14423
|
function DockIcon(props) {
|
|
14678
14424
|
const size = props && props.size || 16;
|
|
14679
|
-
return
|
|
14425
|
+
return import_react24.default.createElement(
|
|
14680
14426
|
"svg",
|
|
14681
14427
|
{ width: size, height: size, viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: 1.3, "aria-hidden": true },
|
|
14682
|
-
|
|
14683
|
-
|
|
14684
|
-
|
|
14685
|
-
|
|
14428
|
+
import_react24.default.createElement("rect", { x: 2.5, y: 2.5, width: 4.4, height: 4.4, rx: 1.2 }),
|
|
14429
|
+
import_react24.default.createElement("rect", { x: 9, y: 2.5, width: 4.4, height: 4.4, rx: 1.2 }),
|
|
14430
|
+
import_react24.default.createElement("rect", { x: 2.5, y: 9, width: 4.4, height: 4.4, rx: 1.2 }),
|
|
14431
|
+
import_react24.default.createElement("rect", { x: 9, y: 9, width: 4.4, height: 4.4, rx: 1.2 })
|
|
14686
14432
|
);
|
|
14687
14433
|
}
|
|
14688
14434
|
function DockEntry(props) {
|
|
14689
14435
|
const wide = !!props.wide;
|
|
14690
|
-
const [open, setOpen] =
|
|
14691
|
-
|
|
14692
|
-
return
|
|
14436
|
+
const [open, setOpen] = import_react24.default.useState(panelNav.open);
|
|
14437
|
+
import_react24.default.useEffect(() => subscribePanel(() => setOpen(panelNav.open)), []);
|
|
14438
|
+
return import_react24.default.createElement("button", {
|
|
14693
14439
|
type: "button",
|
|
14694
14440
|
className: "docke2-btn" + (open ? " docke2-on" : "") + (wide ? "" : " docke2-rail"),
|
|
14695
14441
|
title: "\u529F\u80FD\u575E",
|
|
14696
14442
|
"aria-label": "\u529F\u80FD\u575E",
|
|
14697
14443
|
"aria-expanded": open,
|
|
14698
14444
|
onClick: () => setPanelOpen(!open)
|
|
14699
|
-
},
|
|
14445
|
+
}, import_react24.default.createElement(DockIcon, { size: wide ? 16 : 18 }), wide ? import_react24.default.createElement("span", { className: "docke2-label" }, "\u529F\u80FD\u575E") : null);
|
|
14700
14446
|
}
|
|
14701
14447
|
function DockModal() {
|
|
14702
|
-
const [nav, setNav] =
|
|
14703
|
-
|
|
14448
|
+
const [nav, setNav] = import_react24.default.useState({ open: panelNav.open, active: panelNav.active, params: panelNav.params });
|
|
14449
|
+
import_react24.default.useEffect(() => subscribePanel(() => setNav({ open: panelNav.open, active: panelNav.active, params: panelNav.params })), []);
|
|
14704
14450
|
const open = nav.open || typeof document === "undefined";
|
|
14705
14451
|
const active = nav.active;
|
|
14706
14452
|
const setActive = navigatePanel;
|
|
14707
14453
|
const navParams = nav.params;
|
|
14708
|
-
const [, force] =
|
|
14454
|
+
const [, force] = import_react24.default.useReducer((n) => n + 1, 0);
|
|
14709
14455
|
useExternalVersion();
|
|
14710
|
-
const [win, setWin] =
|
|
14711
|
-
const dlgRef =
|
|
14712
|
-
const contentRef =
|
|
14713
|
-
|
|
14456
|
+
const [win, setWin] = import_react24.default.useState(() => ({ mode: "normal", x: null, y: null, w: null, h: null }));
|
|
14457
|
+
const dlgRef = import_react24.default.useRef(null);
|
|
14458
|
+
const contentRef = import_react24.default.useRef(null);
|
|
14459
|
+
import_react24.default.useEffect(() => {
|
|
14714
14460
|
if (lastGeom.w) setWin({ mode: "normal", x: lastGeom.x, y: lastGeom.y, w: lastGeom.w, h: lastGeom.h });
|
|
14715
14461
|
}, []);
|
|
14716
|
-
|
|
14462
|
+
import_react24.default.useEffect(() => {
|
|
14717
14463
|
if (open && contentRef.current) contentRef.current.scrollTop = 0;
|
|
14718
14464
|
}, [active, open]);
|
|
14719
14465
|
function beginDrag(e, type) {
|
|
@@ -14751,13 +14497,13 @@ function DockModal() {
|
|
|
14751
14497
|
const mod = isHome ? null : MODULES.find((m) => m.id === active) || MODULES[0];
|
|
14752
14498
|
const st = mod ? stateOf(mod.id) : null;
|
|
14753
14499
|
const View = mod ? mod.View : null;
|
|
14754
|
-
const viewNode = mod && View ?
|
|
14500
|
+
const viewNode = mod && View ? import_react24.default.createElement(
|
|
14755
14501
|
"div",
|
|
14756
14502
|
{ className: "dockm-view" },
|
|
14757
|
-
|
|
14503
|
+
import_react24.default.createElement(
|
|
14758
14504
|
FeatureBoundary,
|
|
14759
14505
|
{ key: mod.id, label: mod.name },
|
|
14760
|
-
|
|
14506
|
+
import_react24.default.createElement(View, { ctx: ctxRef.current, feature: mod, params: navParams })
|
|
14761
14507
|
)
|
|
14762
14508
|
) : null;
|
|
14763
14509
|
const enabledCount = MODULES.filter((m) => {
|
|
@@ -14771,10 +14517,10 @@ function DockModal() {
|
|
|
14771
14517
|
width: win.w != null ? win.w : void 0,
|
|
14772
14518
|
height: win.mode === "min" ? "auto" : win.h != null ? win.h : void 0
|
|
14773
14519
|
} : null;
|
|
14774
|
-
return
|
|
14520
|
+
return import_react24.default.createElement(
|
|
14775
14521
|
"div",
|
|
14776
14522
|
{ className: "dockm-backdrop", onClick: () => setPanelOpen(false) },
|
|
14777
|
-
|
|
14523
|
+
import_react24.default.createElement(
|
|
14778
14524
|
"div",
|
|
14779
14525
|
{
|
|
14780
14526
|
className: "dockm-dialog" + (win.mode === "max" ? " dockm-max" : "") + (win.mode === "min" ? " dockm-min" : ""),
|
|
@@ -14782,41 +14528,41 @@ function DockModal() {
|
|
|
14782
14528
|
ref: dlgRef,
|
|
14783
14529
|
onClick: (e) => e.stopPropagation()
|
|
14784
14530
|
},
|
|
14785
|
-
|
|
14531
|
+
import_react24.default.createElement(
|
|
14786
14532
|
"div",
|
|
14787
14533
|
{
|
|
14788
14534
|
className: "dockm-head",
|
|
14789
14535
|
onPointerDown: (e) => beginDrag(e, "move"),
|
|
14790
14536
|
onDoubleClick: () => setWin((s) => Object.assign({}, s, { mode: s.mode === "max" ? "normal" : "max" }))
|
|
14791
14537
|
},
|
|
14792
|
-
|
|
14793
|
-
|
|
14794
|
-
|
|
14795
|
-
|
|
14538
|
+
import_react24.default.createElement(DockIcon, null),
|
|
14539
|
+
import_react24.default.createElement("span", { className: "dockm-title" }, "\u529F\u80FD\u575E"),
|
|
14540
|
+
import_react24.default.createElement("span", { className: "dockm-sub" }, "dsh-dock \xB7 \u4E5F\u53EF\u5728 \u8BBE\u7F6E \u2192 \u529F\u80FD\u575E \u6253\u5F00\u7BA1\u7406\u9875"),
|
|
14541
|
+
import_react24.default.createElement(
|
|
14796
14542
|
"span",
|
|
14797
14543
|
{ className: "dockm-ctrls" },
|
|
14798
|
-
|
|
14544
|
+
import_react24.default.createElement("button", {
|
|
14799
14545
|
type: "button",
|
|
14800
14546
|
className: "dockm-win",
|
|
14801
14547
|
title: win.mode === "min" ? "\u8FD8\u539F" : "\u6700\u5C0F\u5316",
|
|
14802
14548
|
onClick: () => setWin((s) => Object.assign({}, s, { mode: s.mode === "min" ? "normal" : "min" }))
|
|
14803
14549
|
}, "\u2581"),
|
|
14804
|
-
|
|
14550
|
+
import_react24.default.createElement("button", {
|
|
14805
14551
|
type: "button",
|
|
14806
14552
|
className: "dockm-win",
|
|
14807
14553
|
title: win.mode === "max" ? "\u8FD8\u539F" : "\u6700\u5927\u5316",
|
|
14808
14554
|
onClick: () => setWin((s) => Object.assign({}, s, { mode: s.mode === "max" ? "normal" : "max" }))
|
|
14809
14555
|
}, win.mode === "max" ? "\u2750" : "\u25A2"),
|
|
14810
|
-
|
|
14556
|
+
import_react24.default.createElement("button", { type: "button", className: "dockm-close", "aria-label": "\u5173\u95ED", title: "\u5173\u95ED", onClick: () => setPanelOpen(false) }, "\u2715")
|
|
14811
14557
|
)
|
|
14812
14558
|
),
|
|
14813
|
-
|
|
14559
|
+
import_react24.default.createElement(
|
|
14814
14560
|
"div",
|
|
14815
14561
|
{ className: "dockm-body" },
|
|
14816
|
-
|
|
14562
|
+
import_react24.default.createElement(
|
|
14817
14563
|
"nav",
|
|
14818
14564
|
{ className: "dockm-nav", "aria-label": "\u529F\u80FD\u6A21\u5757" },
|
|
14819
|
-
|
|
14565
|
+
import_react24.default.createElement(
|
|
14820
14566
|
"button",
|
|
14821
14567
|
{
|
|
14822
14568
|
type: "button",
|
|
@@ -14824,10 +14570,10 @@ function DockModal() {
|
|
|
14824
14570
|
className: "dockm-nav-item" + (isHome ? " on" : ""),
|
|
14825
14571
|
onClick: () => setActive("home")
|
|
14826
14572
|
},
|
|
14827
|
-
|
|
14828
|
-
|
|
14573
|
+
import_react24.default.createElement("span", { className: "dockm-navhome" }, import_react24.default.createElement(DockIcon, null)),
|
|
14574
|
+
import_react24.default.createElement("span", null, "\u9996\u9875")
|
|
14829
14575
|
),
|
|
14830
|
-
MODULES.map((m) =>
|
|
14576
|
+
MODULES.map((m) => import_react24.default.createElement(
|
|
14831
14577
|
"button",
|
|
14832
14578
|
{
|
|
14833
14579
|
type: "button",
|
|
@@ -14835,42 +14581,42 @@ function DockModal() {
|
|
|
14835
14581
|
className: "dockm-nav-item" + (m.id === active ? " on" : ""),
|
|
14836
14582
|
onClick: () => setActive(m.id)
|
|
14837
14583
|
},
|
|
14838
|
-
|
|
14839
|
-
|
|
14840
|
-
m.planned ?
|
|
14841
|
-
m.external ?
|
|
14584
|
+
import_react24.default.createElement("span", { className: "dockm-dot", style: { background: m.accent } }),
|
|
14585
|
+
import_react24.default.createElement("span", null, m.name),
|
|
14586
|
+
m.planned ? import_react24.default.createElement("span", { className: "dockm-badge" }, "\u89C4\u5212\u4E2D") : null,
|
|
14587
|
+
m.external ? import_react24.default.createElement("span", { className: "dockm-badge" }, "\u5916\u90E8") : null
|
|
14842
14588
|
))
|
|
14843
14589
|
),
|
|
14844
|
-
|
|
14590
|
+
import_react24.default.createElement(
|
|
14845
14591
|
"div",
|
|
14846
14592
|
{ className: "dockm-content", ref: contentRef },
|
|
14847
|
-
|
|
14593
|
+
import_react24.default.createElement(
|
|
14848
14594
|
"div",
|
|
14849
14595
|
{ className: "dockm-content-head" },
|
|
14850
|
-
|
|
14596
|
+
import_react24.default.createElement(
|
|
14851
14597
|
"div",
|
|
14852
14598
|
{ className: "dockm-name" },
|
|
14853
|
-
isHome ?
|
|
14599
|
+
isHome ? import_react24.default.createElement("span", { className: "dockm-navhome" }, import_react24.default.createElement(DockIcon, null)) : import_react24.default.createElement("span", { className: "dockm-dot", style: { background: mod.accent } }),
|
|
14854
14600
|
isHome ? "\u9996\u9875" : mod.name,
|
|
14855
|
-
!isHome && mod.planned ?
|
|
14856
|
-
!isHome && mod.external ?
|
|
14601
|
+
!isHome && mod.planned ? import_react24.default.createElement("span", { className: "dockm-badge" }, "\u89C4\u5212\u4E2D") : null,
|
|
14602
|
+
!isHome && mod.external ? import_react24.default.createElement("span", { className: "dockm-badge" }, "\u5916\u90E8\u5305" + (mod.package ? " \xB7 " + mod.package : "")) : null
|
|
14857
14603
|
),
|
|
14858
|
-
|
|
14604
|
+
import_react24.default.createElement(
|
|
14859
14605
|
"div",
|
|
14860
14606
|
{ className: "dockm-desc" },
|
|
14861
14607
|
isHome ? "\u6240\u6709\u5B50\u529F\u80FD\u603B\u63FD\uFF1A\u8FD0\u884C\u72B6\u6001\u3001\u6982\u8981\u4E0E\u5FEB\u6377\u5F00\u5173\uFF0C\u70B9\u51FB\u5361\u7247\u8FDB\u5165\u5BF9\u5E94\u529F\u80FD\u9875\u3002" : mod.description
|
|
14862
14608
|
)
|
|
14863
14609
|
),
|
|
14864
|
-
isHome ?
|
|
14865
|
-
|
|
14610
|
+
isHome ? import_react24.default.createElement("div", { className: "dockm-view" }, import_react24.default.createElement(HomeView, { ctx: ctxRef.current, onOpen: setActive, onToggle: force })) : mod.planned ? import_react24.default.createElement("div", { className: "dockm-note" }, PLANNED_NOTES[mod.id] || "\u5F85\u63A5\u5165\uFF1A\u89C1 README \u8DEF\u7EBF\u56FE") : st && st.enabled && viewNode ? viewNode : st && st.error ? import_react24.default.createElement("div", { className: "dockm-note dockm-err" }, "\u529F\u80FD\u51FA\u9519\uFF1A" + st.error) : import_react24.default.createElement("div", { className: "dockm-note" }, "\u8BE5\u529F\u80FD\u5F53\u524D\u4E3A\u505C\u7528\u72B6\u6001\uFF08\u5F00\u5173\u5DF2\u6301\u4E45\u5316\uFF0C\u91CD\u542F\u540E\u4FDD\u6301\uFF09"),
|
|
14611
|
+
import_react24.default.createElement(
|
|
14866
14612
|
"div",
|
|
14867
14613
|
{ className: "dockm-foot" },
|
|
14868
|
-
|
|
14869
|
-
!isHome && mod && !mod.planned && st ?
|
|
14614
|
+
import_react24.default.createElement("span", null, isHome ? "\u529F\u80FD\u575E v" + DOCK_VERSION + " \xB7 \u5171 " + MODULES.length + " \u4E2A\u529F\u80FD\u6A21\u5757\uFF0C" + enabledCount + " \u4E2A\u5DF2\u542F\u7528" : "\u529F\u80FD\u575E v" + DOCK_VERSION + " \xB7 \u65B0\u529F\u80FD\u6309\u8DEF\u7EBF\u56FE\u8FFD\u52A0"),
|
|
14615
|
+
!isHome && mod && !mod.planned && st ? import_react24.default.createElement(
|
|
14870
14616
|
"span",
|
|
14871
14617
|
{ className: "dockm-foot-sw" },
|
|
14872
|
-
|
|
14873
|
-
|
|
14618
|
+
import_react24.default.createElement("span", { className: "dockm-foot-swlabel" + (st.enabled ? " on" : "") }, st.enabled ? "\u5DF2\u542F\u7528" : "\u5DF2\u505C\u7528"),
|
|
14619
|
+
import_react24.default.createElement("button", {
|
|
14874
14620
|
type: "button",
|
|
14875
14621
|
className: "dock-sw" + (st.enabled ? " on" : ""),
|
|
14876
14622
|
role: "switch",
|
|
@@ -14883,11 +14629,11 @@ function DockModal() {
|
|
|
14883
14629
|
}
|
|
14884
14630
|
})
|
|
14885
14631
|
) : null,
|
|
14886
|
-
!isHome && mod && typeof mod.Chip === "function" ?
|
|
14632
|
+
!isHome && mod && typeof mod.Chip === "function" ? import_react24.default.createElement(
|
|
14887
14633
|
"span",
|
|
14888
14634
|
{ className: "dockm-foot-sw" },
|
|
14889
|
-
|
|
14890
|
-
|
|
14635
|
+
import_react24.default.createElement("span", { className: "dockm-foot-swlabel" + (chipShown(mod.id) ? " on" : "") }, "\u4F1A\u8BDD\u9875\u5C0F\u63A7\u4EF6"),
|
|
14636
|
+
import_react24.default.createElement("button", {
|
|
14891
14637
|
type: "button",
|
|
14892
14638
|
className: "dock-sw" + (chipShown(mod.id) ? " on" : ""),
|
|
14893
14639
|
role: "switch",
|
|
@@ -14903,30 +14649,30 @@ function DockModal() {
|
|
|
14903
14649
|
)
|
|
14904
14650
|
)
|
|
14905
14651
|
),
|
|
14906
|
-
win.mode === "normal" ?
|
|
14652
|
+
win.mode === "normal" ? import_react24.default.createElement("div", { className: "dockm-resize", onPointerDown: (e) => beginDrag(e, "size") }) : null
|
|
14907
14653
|
)
|
|
14908
14654
|
);
|
|
14909
14655
|
}
|
|
14910
14656
|
function HomeView(props) {
|
|
14911
14657
|
const ctx = props && props.ctx;
|
|
14912
|
-
const [, force] =
|
|
14658
|
+
const [, force] = import_react24.default.useReducer((n) => n + 1, 0);
|
|
14913
14659
|
useExternalVersion();
|
|
14914
14660
|
const open = (id) => {
|
|
14915
14661
|
if (props && typeof props.onOpen === "function") props.onOpen(id);
|
|
14916
14662
|
};
|
|
14917
|
-
return
|
|
14663
|
+
return import_react24.default.createElement(
|
|
14918
14664
|
"div",
|
|
14919
14665
|
{ className: "dockh-grid" },
|
|
14920
14666
|
allModules().map((m) => {
|
|
14921
14667
|
const st = stateOf(m.id);
|
|
14922
14668
|
const enabled = !!(st && st.enabled);
|
|
14923
14669
|
const Stat = m.HomeStat;
|
|
14924
|
-
const statNode = m.planned ?
|
|
14670
|
+
const statNode = m.planned ? import_react24.default.createElement("span", null, PLANNED_NOTES[m.id] || "\u5F85\u63A5\u5165\uFF1A\u89C1 README \u8DEF\u7EBF\u56FE") : enabled && Stat ? import_react24.default.createElement(
|
|
14925
14671
|
FeatureBoundary,
|
|
14926
14672
|
{ key: m.id, label: m.name },
|
|
14927
|
-
|
|
14928
|
-
) :
|
|
14929
|
-
return
|
|
14673
|
+
import_react24.default.createElement(Stat, { ctx })
|
|
14674
|
+
) : import_react24.default.createElement("span", null, "\u5DF2\u505C\u7528\uFF0C\u542F\u7528\u540E\u5728\u6B64\u5C55\u793A\u8FD0\u884C\u6982\u8981");
|
|
14675
|
+
return import_react24.default.createElement(
|
|
14930
14676
|
"div",
|
|
14931
14677
|
{
|
|
14932
14678
|
key: m.id,
|
|
@@ -14941,21 +14687,21 @@ function HomeView(props) {
|
|
|
14941
14687
|
}
|
|
14942
14688
|
}
|
|
14943
14689
|
},
|
|
14944
|
-
|
|
14690
|
+
import_react24.default.createElement(
|
|
14945
14691
|
"div",
|
|
14946
14692
|
{ className: "dockh-head" },
|
|
14947
|
-
|
|
14948
|
-
|
|
14949
|
-
m.external ?
|
|
14693
|
+
import_react24.default.createElement("span", { className: "dockm-dot", style: { background: m.accent } }),
|
|
14694
|
+
import_react24.default.createElement("span", { className: "dockh-name" }, m.name),
|
|
14695
|
+
m.external ? import_react24.default.createElement("span", { className: "dockh-badge", title: m.package || void 0 }, "\u5916\u90E8") : null,
|
|
14950
14696
|
// 状态标识:圆点 + 文字(纯展示,与开关视觉区分)
|
|
14951
|
-
|
|
14697
|
+
import_react24.default.createElement(
|
|
14952
14698
|
"span",
|
|
14953
14699
|
{ className: "dockh-status" + (m.planned ? " plan" : enabled ? "" : " off") },
|
|
14954
|
-
|
|
14955
|
-
|
|
14700
|
+
import_react24.default.createElement("span", { className: "dockh-sdot" }),
|
|
14701
|
+
import_react24.default.createElement("span", null, m.planned ? "\u89C4\u5212\u4E2D" : enabled ? "\u8FD0\u884C\u4E2D" : "\u5DF2\u505C\u7528")
|
|
14956
14702
|
),
|
|
14957
14703
|
// 启停开关(规划中的功能不显示)
|
|
14958
|
-
m.planned ? null :
|
|
14704
|
+
m.planned ? null : import_react24.default.createElement("button", {
|
|
14959
14705
|
type: "button",
|
|
14960
14706
|
className: "dock-sw" + (enabled ? " on" : ""),
|
|
14961
14707
|
role: "switch",
|
|
@@ -14970,12 +14716,12 @@ function HomeView(props) {
|
|
|
14970
14716
|
}
|
|
14971
14717
|
})
|
|
14972
14718
|
),
|
|
14973
|
-
|
|
14974
|
-
|
|
14975
|
-
|
|
14719
|
+
import_react24.default.createElement("div", { className: "dockh-desc" }, m.description),
|
|
14720
|
+
import_react24.default.createElement("div", { className: "dockh-stat" }, statNode),
|
|
14721
|
+
import_react24.default.createElement(
|
|
14976
14722
|
"div",
|
|
14977
14723
|
{ className: "dockh-foot" },
|
|
14978
|
-
|
|
14724
|
+
import_react24.default.createElement("span", { className: "dockh-go" }, "\u67E5\u770B\u8BE6\u60C5 \u2192")
|
|
14979
14725
|
)
|
|
14980
14726
|
);
|
|
14981
14727
|
})
|
|
@@ -14983,16 +14729,16 @@ function HomeView(props) {
|
|
|
14983
14729
|
}
|
|
14984
14730
|
function DockPanel(props) {
|
|
14985
14731
|
const ctx = ctxRef.current;
|
|
14986
|
-
const [, force] =
|
|
14732
|
+
const [, force] = import_react24.default.useReducer((n) => n + 1, 0);
|
|
14987
14733
|
useExternalVersion();
|
|
14988
14734
|
const toggle = (id) => {
|
|
14989
14735
|
toggleFeature(id);
|
|
14990
14736
|
force();
|
|
14991
14737
|
};
|
|
14992
|
-
return
|
|
14738
|
+
return import_react24.default.createElement(
|
|
14993
14739
|
"div",
|
|
14994
14740
|
{ className: "dock-root" },
|
|
14995
|
-
|
|
14741
|
+
import_react24.default.createElement(
|
|
14996
14742
|
"div",
|
|
14997
14743
|
{ className: "dock-intro" },
|
|
14998
14744
|
"\u529F\u80FD\u575E\uFF08dsh-dock\uFF09\xB7 \u6240\u6709\u5C0F\u529F\u80FD\u96C6\u4E2D\u5728\u8FD9\u4E00\u4E2A\u9762\u677F\u91CC\u7BA1\u7406\u3002v0.4.0 \u8D77\u6BCF\u4E2A\u529F\u80FD\u662F\u72EC\u7ACB\u6A21\u5757\uFF08features/<id>/\uFF09\uFF0C",
|
|
@@ -15001,25 +14747,25 @@ function DockPanel(props) {
|
|
|
15001
14747
|
allModules().map((f) => {
|
|
15002
14748
|
const st = stateOf(f.id);
|
|
15003
14749
|
const View = f.View;
|
|
15004
|
-
const viewNode = !f.planned && st.enabled && View ?
|
|
14750
|
+
const viewNode = !f.planned && st.enabled && View ? import_react24.default.createElement(
|
|
15005
14751
|
"div",
|
|
15006
14752
|
{ className: "dock-body" },
|
|
15007
|
-
|
|
14753
|
+
import_react24.default.createElement(
|
|
15008
14754
|
FeatureBoundary,
|
|
15009
14755
|
{ key: f.id, label: f.name },
|
|
15010
|
-
|
|
14756
|
+
import_react24.default.createElement(View, { ctx, feature: f, params: props && props.params })
|
|
15011
14757
|
)
|
|
15012
14758
|
) : null;
|
|
15013
|
-
return
|
|
14759
|
+
return import_react24.default.createElement(
|
|
15014
14760
|
"div",
|
|
15015
14761
|
{ className: "dock-card", key: f.id },
|
|
15016
|
-
|
|
14762
|
+
import_react24.default.createElement(
|
|
15017
14763
|
"div",
|
|
15018
14764
|
{ className: "dock-card-head" },
|
|
15019
|
-
|
|
15020
|
-
|
|
15021
|
-
|
|
15022
|
-
f.planned ?
|
|
14765
|
+
import_react24.default.createElement("span", { className: "dock-dot" + (st.error ? " err" : st.enabled ? " on" : "") }),
|
|
14766
|
+
import_react24.default.createElement("span", { className: "dock-name" }, f.name),
|
|
14767
|
+
import_react24.default.createElement("span", { className: "dock-desc" }, f.description + (f.external ? "\uFF08\u6765\u81EA\u5916\u90E8\u5305" + (f.package ? " " + f.package : "") + "\uFF09" : "")),
|
|
14768
|
+
f.planned ? import_react24.default.createElement("span", { className: "dock-badge" }, "\u89C4\u5212\u4E2D") : import_react24.default.createElement("button", {
|
|
15023
14769
|
type: "button",
|
|
15024
14770
|
className: "dock-sw" + (st.enabled ? " on" : ""),
|
|
15025
14771
|
role: "switch",
|
|
@@ -15028,11 +14774,11 @@ function DockPanel(props) {
|
|
|
15028
14774
|
title: st.enabled ? "\u505C\u7528\u300C" + f.name + "\u300D" : "\u542F\u7528\u300C" + f.name + "\u300D",
|
|
15029
14775
|
onClick: () => toggle(f.id)
|
|
15030
14776
|
}),
|
|
15031
|
-
!f.planned && typeof f.Chip === "function" ?
|
|
14777
|
+
!f.planned && typeof f.Chip === "function" ? import_react24.default.createElement(
|
|
15032
14778
|
"span",
|
|
15033
14779
|
{ className: "dockm-foot-sw" },
|
|
15034
|
-
|
|
15035
|
-
|
|
14780
|
+
import_react24.default.createElement("span", { className: "dockm-foot-swlabel" + (chipShown(f.id) ? " on" : "") }, "\u4F1A\u8BDD\u9875\u5C0F\u63A7\u4EF6"),
|
|
14781
|
+
import_react24.default.createElement("button", {
|
|
15036
14782
|
type: "button",
|
|
15037
14783
|
className: "dock-sw" + (chipShown(f.id) ? " on" : ""),
|
|
15038
14784
|
role: "switch",
|
|
@@ -15046,22 +14792,22 @@ function DockPanel(props) {
|
|
|
15046
14792
|
})
|
|
15047
14793
|
) : null
|
|
15048
14794
|
),
|
|
15049
|
-
f.planned ?
|
|
14795
|
+
f.planned ? import_react24.default.createElement("div", { className: "dock-body" }, PLANNED_NOTES[f.id] || "\u5F85\u63A5\u5165\uFF1A\u89C1 README \u8DEF\u7EBF\u56FE") : st.error ? import_react24.default.createElement("div", { className: "dock-body dockm-err" }, "\u529F\u80FD\u51FA\u9519\uFF1A" + st.error) : null,
|
|
15050
14796
|
viewNode
|
|
15051
14797
|
);
|
|
15052
14798
|
})
|
|
15053
14799
|
);
|
|
15054
14800
|
}
|
|
15055
14801
|
function DockChips(props) {
|
|
15056
|
-
const [, force] =
|
|
15057
|
-
|
|
14802
|
+
const [, force] = import_react24.default.useReducer((n) => n + 1, 0);
|
|
14803
|
+
import_react24.default.useEffect(() => subscribeFeatureState(() => force()), []);
|
|
15058
14804
|
const items = [];
|
|
15059
14805
|
for (const f of allModules()) {
|
|
15060
14806
|
if (f.planned || !stateOf(f.id).enabled || !chipShown(f.id) || typeof f.Chip !== "function") continue;
|
|
15061
|
-
items.push(
|
|
14807
|
+
items.push(import_react24.default.createElement(
|
|
15062
14808
|
FeatureBoundary,
|
|
15063
14809
|
{ key: f.id, label: f.name },
|
|
15064
|
-
|
|
14810
|
+
import_react24.default.createElement(f.Chip, {
|
|
15065
14811
|
ctx: props.ctx,
|
|
15066
14812
|
feature: f,
|
|
15067
14813
|
session: props.session,
|
|
@@ -15071,38 +14817,38 @@ function DockChips(props) {
|
|
|
15071
14817
|
));
|
|
15072
14818
|
}
|
|
15073
14819
|
if (items.length === 0) return null;
|
|
15074
|
-
return
|
|
14820
|
+
return import_react24.default.createElement("div", { className: "dockchip-row" }, items);
|
|
15075
14821
|
}
|
|
15076
14822
|
function FeatureOverlays() {
|
|
15077
|
-
const [, force] =
|
|
14823
|
+
const [, force] = import_react24.default.useReducer((n) => n + 1, 0);
|
|
15078
14824
|
useExternalVersion();
|
|
15079
|
-
|
|
14825
|
+
import_react24.default.useEffect(() => subscribeFeatureState(() => force()), []);
|
|
15080
14826
|
const items = [];
|
|
15081
14827
|
for (const f of allModules()) {
|
|
15082
14828
|
if (f.planned || !stateOf(f.id).enabled || typeof f.Overlay !== "function") continue;
|
|
15083
|
-
items.push(
|
|
14829
|
+
items.push(import_react24.default.createElement(
|
|
15084
14830
|
FeatureBoundary,
|
|
15085
14831
|
{ key: f.id, label: f.name },
|
|
15086
|
-
|
|
14832
|
+
import_react24.default.createElement(f.Overlay, { ctx: ctxRef.current, feature: f })
|
|
15087
14833
|
));
|
|
15088
14834
|
}
|
|
15089
14835
|
if (items.length === 0) return null;
|
|
15090
|
-
return
|
|
14836
|
+
return import_react24.default.createElement(import_react24.default.Fragment, null, items);
|
|
15091
14837
|
}
|
|
15092
14838
|
function FeatureTurnTail(props) {
|
|
15093
|
-
const [, force] =
|
|
15094
|
-
|
|
14839
|
+
const [, force] = import_react24.default.useReducer((n) => n + 1, 0);
|
|
14840
|
+
import_react24.default.useEffect(() => subscribeFeatureState(() => force()), []);
|
|
15095
14841
|
const items = [];
|
|
15096
14842
|
for (const f of allModules()) {
|
|
15097
14843
|
if (f.planned || !stateOf(f.id).enabled || typeof f.TurnTail !== "function") continue;
|
|
15098
|
-
items.push(
|
|
14844
|
+
items.push(import_react24.default.createElement(
|
|
15099
14845
|
FeatureBoundary,
|
|
15100
14846
|
{ key: f.id, label: f.name },
|
|
15101
|
-
|
|
14847
|
+
import_react24.default.createElement(f.TurnTail, Object.assign({}, props, { ctx: ctxRef.current, feature: f }))
|
|
15102
14848
|
));
|
|
15103
14849
|
}
|
|
15104
14850
|
if (items.length === 0) return null;
|
|
15105
|
-
return
|
|
14851
|
+
return import_react24.default.createElement(import_react24.default.Fragment, null, items);
|
|
15106
14852
|
}
|
|
15107
14853
|
var ctxRef = { current: null };
|
|
15108
14854
|
function apply(ctx) {
|
|
@@ -15113,27 +14859,27 @@ function apply(ctx) {
|
|
|
15113
14859
|
if (slots === void 0) return;
|
|
15114
14860
|
slots.inject("sidebar.footer.action", () => slots.register(
|
|
15115
14861
|
{ name: "sidebar.footer.action", id: "dsh-dock", order: 1, label: "\u529F\u80FD\u575E" },
|
|
15116
|
-
(props) =>
|
|
14862
|
+
(props) => import_react24.default.createElement(DockEntry, props)
|
|
15117
14863
|
));
|
|
15118
14864
|
slots.inject("shell.overlay", () => slots.register(
|
|
15119
14865
|
{ name: "shell.overlay", id: "dsh-dock-panel", order: 21, label: "\u529F\u80FD\u575E\u9762\u677F" },
|
|
15120
|
-
() =>
|
|
14866
|
+
() => import_react24.default.createElement(DockModal, null)
|
|
15121
14867
|
));
|
|
15122
14868
|
slots.inject("shell.overlay", () => slots.register(
|
|
15123
14869
|
{ name: "shell.overlay", id: "dsh-dock-feature-overlays", order: 22, label: "\u529F\u80FD\u575E\u5168\u5C40\u6D6E\u5C42" },
|
|
15124
|
-
() =>
|
|
14870
|
+
() => import_react24.default.createElement(FeatureOverlays, null)
|
|
15125
14871
|
));
|
|
15126
14872
|
slots.inject("settings.section", () => slots.register(
|
|
15127
14873
|
{ name: "settings.section", id: "dsh-dock", order: 90, label: "\u529F\u80FD\u575E" },
|
|
15128
|
-
(props) =>
|
|
14874
|
+
(props) => import_react24.default.createElement(DockPanel, props)
|
|
15129
14875
|
));
|
|
15130
14876
|
slots.inject("conversation.input.left", () => slots.register(
|
|
15131
14877
|
{ name: "conversation.input.left", id: "dsh-dock-chips", order: 10, label: "\u529F\u80FD\u575E" },
|
|
15132
|
-
(zone) =>
|
|
14878
|
+
(zone) => import_react24.default.createElement(DockChips, Object.assign({}, zone, { ctx: ctxRef.current }))
|
|
15133
14879
|
));
|
|
15134
14880
|
slots.inject("conversation.chat.turnTail", () => slots.register(
|
|
15135
14881
|
{ name: "conversation.chat.turnTail", id: "dsh-dock-turn-tail", order: 40, label: "\u529F\u80FD\u575E" },
|
|
15136
|
-
(owner) =>
|
|
14882
|
+
(owner) => import_react24.default.createElement(FeatureTurnTail, owner)
|
|
15137
14883
|
));
|
|
15138
14884
|
}
|
|
15139
14885
|
var inject = ["timer"];
|