dsh-dock 0.6.0 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -4
- package/client.js +620 -71
- package/features/animation/view.jsx +491 -18
- package/features/balance/view.js +25 -4
- package/features/games/games/breakout.jsx +225 -0
- package/features/games/games/gomoku.jsx +175 -0
- package/features/games/games/racer.jsx +171 -0
- package/features/games/games/snake.jsx +103 -0
- package/features/games/games/sokoban.jsx +153 -0
- package/features/games/games/tank.jsx +116 -0
- package/features/games/games/tetris.jsx +235 -0
- package/features/games/games/xiangqi.jsx +128 -0
- package/features/games/tank-core.js +152 -0
- package/features/games/view.jsx +632 -0
- package/features/games/xiangqi-core.js +270 -0
- package/features/mobile-relay/gateway.js +279 -0
- package/features/mobile-relay/host.js +328 -0
- package/features/mobile-relay/view.jsx +207 -0
- package/features/tokenlog/host.js +2 -2
- package/features/tokenlog/view.jsx +12 -21
- package/package.json +3 -2
- package/screenshots/dock-animation.png +0 -0
- package/screenshots/dock-modelconfig.png +0 -0
- package/src/client.jsx +45 -9
- package/src/host-core.js +4 -1
- package/screenshots/dock-robot.png +0 -0
|
@@ -37,13 +37,7 @@ function fmtCompact(n) {
|
|
|
37
37
|
if (n >= 1e3) return (n / 1e3).toFixed(1) + "K";
|
|
38
38
|
return String(Math.round(n));
|
|
39
39
|
}
|
|
40
|
-
|
|
41
|
-
const v = Number(n) || 0;
|
|
42
|
-
if (v >= 10) return "$" + v.toFixed(2);
|
|
43
|
-
if (v >= 0.01) return "$" + v.toFixed(4);
|
|
44
|
-
return "$" + v.toFixed(6);
|
|
45
|
-
}
|
|
46
|
-
// 人民币金额: USD 按汇率换算, 默认 7.2(host 返回 rateUsdCny 可覆盖)
|
|
40
|
+
// 金额记录在 RPC 中以 USD 传输;界面统一按人民币显示。
|
|
47
41
|
function fmtCostCny(usd, rate) {
|
|
48
42
|
const v = (Number(usd) || 0) * (Number(rate) > 0 ? Number(rate) : 7.2);
|
|
49
43
|
if (v >= 10000) return "¥" + (v / 10000).toFixed(2) + "万";
|
|
@@ -170,7 +164,7 @@ function Detail({ rec, onClose, rate }) {
|
|
|
170
164
|
["计费输入", fmtNum(rec.billedInput)],
|
|
171
165
|
["缓存命中率", rec.cacheHitPercent + "%"],
|
|
172
166
|
["总 Token", fmtNum(rec.totalTokens)],
|
|
173
|
-
["消耗金额(估算)",
|
|
167
|
+
["消耗金额(估算)", fmtCostCny(rec.cost, rateCny)],
|
|
174
168
|
["推理强度", rec.effort || "—"],
|
|
175
169
|
["耗时", fmtDuration(rec.llmMs)],
|
|
176
170
|
["Turn / Step", rec.turn + " / " + rec.step],
|
|
@@ -350,8 +344,7 @@ export function TokenLogView(props) {
|
|
|
350
344
|
{ v: fmtCompact(totals.cacheReadTokens), l: "缓存命中" },
|
|
351
345
|
{ v: totals.cacheHitPct + "%", l: "缓存命中率" },
|
|
352
346
|
{ v: fmtCompact(totals.outputTokens), l: "输出" },
|
|
353
|
-
{ v:
|
|
354
|
-
{ v: fmtCostCny(totals.cost, rateCny), l: "消耗金额(¥)" },
|
|
347
|
+
{ v: fmtCostCny(totals.cost, rateCny), l: "消耗金额(估算·人民币)" },
|
|
355
348
|
{ v: fmtDuration(totals.llmMs), l: "累计耗时" + (totals.timed ? " (" + totals.timed + "步)" : "") },
|
|
356
349
|
] : [];
|
|
357
350
|
|
|
@@ -368,7 +361,6 @@ export function TokenLogView(props) {
|
|
|
368
361
|
<td>{r.key}</td><td>{fmtNum(r.calls)}</td><td>{fmtCompact(r.inputTokens)}</td>
|
|
369
362
|
<td>{fmtCompact(r.cacheReadTokens)}</td><td>{r.cacheHitPct + "%"}</td><td>{fmtCompact(r.outputTokens)}</td>
|
|
370
363
|
<td>{fmtCompact(r.totalTokens)}</td>
|
|
371
|
-
<td>{fmtCost(r.cost)}</td>
|
|
372
364
|
<td>{fmtCostCny(r.cost, rateCny)}</td>
|
|
373
365
|
<td>{fmtDuration(r.llmMs)}</td>
|
|
374
366
|
</tr>
|
|
@@ -394,7 +386,6 @@ export function TokenLogView(props) {
|
|
|
394
386
|
<td>{fmtNum(r.outputTokens)}</td>
|
|
395
387
|
<td>{fmtNum(r.reasoningTokens)}</td>
|
|
396
388
|
<td>{fmtNum(r.totalTokens)}</td>
|
|
397
|
-
<td>{fmtCost(r.cost)}</td>
|
|
398
389
|
<td>{fmtCostCny(r.cost, rateCny)}</td>
|
|
399
390
|
<td>{r.effort || "—"}</td>
|
|
400
391
|
<td>
|
|
@@ -418,7 +409,7 @@ export function TokenLogView(props) {
|
|
|
418
409
|
<div key="sumtab" className="dtok-table-wrap">
|
|
419
410
|
<table className="dtok-table">
|
|
420
411
|
<thead><tr>
|
|
421
|
-
<th>维度</th><th>调用</th><th>输入</th><th>缓存</th><th>命中率</th><th>输出</th><th>总Token</th><th
|
|
412
|
+
<th>维度</th><th>调用</th><th>输入</th><th>缓存</th><th>命中率</th><th>输出</th><th>总Token</th><th>金额(人民币)</th><th>耗时</th>
|
|
422
413
|
</tr></thead>
|
|
423
414
|
<tbody>{summaryRows}</tbody>
|
|
424
415
|
</table>
|
|
@@ -451,7 +442,7 @@ export function TokenLogView(props) {
|
|
|
451
442
|
<thead><tr>
|
|
452
443
|
{sortTh("时间", "time")}{sortTh("会话ID", "sessionId")}{sortTh("提供商", "provider")}{sortTh("模型", "model")}
|
|
453
444
|
{sortTh("输入", "inputTokens")}{sortTh("缓存", "cacheReadTokens")}{sortTh("命中%", "cacheHitPercent")}{sortTh("输出", "outputTokens")}
|
|
454
|
-
{sortTh("推理", "reasoningTokens")}{sortTh("总额", "totalTokens")}{sortTh("
|
|
445
|
+
{sortTh("推理", "reasoningTokens")}{sortTh("总额", "totalTokens")}{sortTh("金额(人民币)", "cost")}{sortTh("强度", "effort")}
|
|
455
446
|
{sortTh("状态", "status")}{sortTh("耗时", "llmMs")}
|
|
456
447
|
</tr></thead>
|
|
457
448
|
<tbody>{detailRows}</tbody>
|
|
@@ -521,32 +512,32 @@ function TokenLogHomeStat() {
|
|
|
521
512
|
}, []);
|
|
522
513
|
if (!snap.totals) return <span>{snap.err ? "用量查询失败(点击进入查看)" : "正在拉取今日用量…"}</span>;
|
|
523
514
|
const t = snap.totals;
|
|
524
|
-
return <span>今日 {fmtNum(t.calls)} 次调用 · {fmtCompact(t.totalTokens)} Token · {
|
|
515
|
+
return <span>今日 {fmtNum(t.calls)} 次调用 · {fmtCompact(t.totalTokens)} Token · {fmtCostCny(t.cost, snap.rate)}</span>;
|
|
525
516
|
}
|
|
526
517
|
|
|
527
518
|
// ---------- 会话输入区 chip:显示当前会话总 Token(10s 静默刷新),点击打开功能坞并按该会话筛选 ----------
|
|
528
519
|
export function TokenLogChip(props) {
|
|
529
520
|
const sid = (props && props.sessionId) || (props && props.session && props.session.sessionId) || null;
|
|
530
|
-
const [snap, setSnap] = useState({ totals: null, err: "" });
|
|
521
|
+
const [snap, setSnap] = useState({ totals: null, rate: 7.2, err: "" });
|
|
531
522
|
useEffect(() => {
|
|
532
523
|
if (!sid) return;
|
|
533
524
|
let cancel = false;
|
|
534
525
|
const load = () => rpcCall("query", { sessionId: sid })
|
|
535
|
-
.then((d) => { if (!cancel) setSnap({ totals: d && d.totals, err: "" }); })
|
|
536
|
-
.catch((e) => { if (!cancel) setSnap((s) => ({ totals: s.totals, err: String((e && e.message) || e) })); });
|
|
526
|
+
.then((d) => { if (!cancel) setSnap({ totals: d && d.totals, rate: (d && d.rateUsdCny) || 7.2, err: "" }); })
|
|
527
|
+
.catch((e) => { if (!cancel) setSnap((s) => ({ totals: s.totals, rate: s.rate, err: String((e && e.message) || e) })); });
|
|
537
528
|
load();
|
|
538
529
|
const timer = setInterval(load, 10000);
|
|
539
530
|
return () => { cancel = true; clearInterval(timer); };
|
|
540
531
|
}, [sid]);
|
|
541
532
|
if (!sid) return null;
|
|
542
533
|
const t = snap.totals;
|
|
543
|
-
// chip
|
|
534
|
+
// chip 文案用紧凑人民币金额(2 位小数),避免撑爆输入卡工具行;
|
|
544
535
|
// 完整金额在 title 悬浮提示里。
|
|
545
536
|
const label = snap.err && !t
|
|
546
537
|
? (snap.err.includes("重启") ? "用量·需重启宿主" : "用量·失败")
|
|
547
|
-
: (t ? "⛁ " + fmtCompact(t.totalTokens) + (t.cost > 0 ? " ·
|
|
538
|
+
: (t ? "⛁ " + fmtCompact(t.totalTokens) + (t.cost > 0 ? " · " + fmtCostCny(t.cost, snap.rate) : "") : "⛁ …");
|
|
548
539
|
const title = t
|
|
549
|
-
? "本会话 " + fmtNum(t.calls) + " 次调用 · " + fmtNum(t.totalTokens) + " Token · " +
|
|
540
|
+
? "本会话 " + fmtNum(t.calls) + " 次调用 · " + fmtNum(t.totalTokens) + " Token · " + fmtCostCny(t.cost, snap.rate) + "(估算)\n点击在功能坞查看用量记录"
|
|
550
541
|
: (snap.err ? snap.err + "\n" : "") + "点击在功能坞查看用量记录";
|
|
551
542
|
return (
|
|
552
543
|
<button type="button" className={"dockchip" + (snap.err && !t ? " err" : "")} title={title} aria-label="会话用量"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-dock",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.1",
|
|
4
4
|
"description": "DeepSeek Harness 功能坞插件(dsh-dock):模块化功能中枢——每个功能一个 features/ 模块(可单独提取成包发布,又可经 dockBridge 装回面板)。含用量记录(LLM 调用记账/费用统计)、模型设置、图片理解代理、模型余额、任务动画(8 种氛围动效 + 桌面伙伴 3D 场景、完成通知与提示音、钉钉/飞书推送,开关独立、配置持久化);侧栏入口 + 可拖拽弹窗(最大化/最小化/缩放)。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -52,6 +52,7 @@
|
|
|
52
52
|
"@deepseek-ai/dsh-credentials": "^0.1.0-rc.6",
|
|
53
53
|
"@deepseek-ai/dsh-llm": "^0.1.1-rc.2",
|
|
54
54
|
"@deepseek-ai/dsh-settings": "^0.1.1-rc.2",
|
|
55
|
-
"@deepseek-ai/schemastery": "^3.18.1"
|
|
55
|
+
"@deepseek-ai/schemastery": "^3.18.1",
|
|
56
|
+
"qrcode": "^1.5.4"
|
|
56
57
|
}
|
|
57
58
|
}
|
|
Binary file
|
|
Binary file
|
package/src/client.jsx
CHANGED
|
@@ -26,7 +26,7 @@ import { feature as fBalance } from "../features/balance/view.js";
|
|
|
26
26
|
import { feature as fAnimation } from "../features/animation/view.jsx";
|
|
27
27
|
|
|
28
28
|
const name = "dsh-dock";
|
|
29
|
-
const DOCK_VERSION = "0.
|
|
29
|
+
const DOCK_VERSION = "0.7.1";
|
|
30
30
|
|
|
31
31
|
// ---- 内置功能注册表:新功能 = features/<id>/ 加模块 + 这里 import 一行 ----
|
|
32
32
|
const BUILTIN_FEATURES = [fTokenlog, fModelconfig, fHeartbeat, fTheme, fBalance, fAnimation];
|
|
@@ -172,7 +172,11 @@ const SHELL_CSS = [
|
|
|
172
172
|
// 弹层页脚:文字标签 + 开关 成组
|
|
173
173
|
".dockm-foot-sw{margin-left:auto;flex:none;display:inline-flex;align-items:center;gap:8px;}",
|
|
174
174
|
".dockm-foot-swlabel{font-size:11px;color:var(--dsw-alias-label-tertiary);}",
|
|
175
|
-
|
|
175
|
+
".dockm-foot-swlabel.on{color:var(--dsw-alias-state-success-primary);}",
|
|
176
|
+
// 窄屏:功能坞是一级工作台而不是被压扁的桌面弹窗。全屏承接安全区,导航改横向,
|
|
177
|
+
// 禁用桌面拖拽/缩放,所有导航和关闭动作保持至少 44px 的可点击面积。
|
|
178
|
+
"@media (max-width:680px){.dockm-backdrop{align-items:stretch;justify-content:stretch;background:var(--dsw-alias-bg-layer-2);backdrop-filter:none}.dockm-dialog,.dockm-dialog.dockm-max{position:fixed!important;left:0!important;top:0!important;right:auto!important;bottom:auto!important;width:100dvw!important;height:100dvh!important;min-height:100dvh;border:0;border-radius:0;box-shadow:none}.dockm-dialog.dockm-min .dockm-body{display:flex}.dockm-head{min-height:60px;box-sizing:border-box;padding:calc(env(safe-area-inset-top) + 8px) 12px 8px;cursor:default;touch-action:manipulation}.dockm-sub,.dockm-win,.dockm-resize{display:none}.dockm-title{font-size:16px}.dockm-close{width:44px;height:44px;font-size:17px}.dockm-body{flex-direction:column;min-height:0}.dockm-nav{box-sizing:border-box;width:auto;max-width:100%;min-height:56px;flex-direction:row;gap:6px;padding:6px 10px;overflow-x:auto;overflow-y:hidden;border-right:0;border-bottom:1px solid var(--dsw-alias-border-l1);scrollbar-width:none;overscroll-behavior-x:contain}.dockm-nav::-webkit-scrollbar{display:none}.dockm-nav-item{flex:none;min-height:44px;padding:0 12px;font-size:13px;touch-action:manipulation}.dockm-nav-item .dockm-badge{display:none}.dockm-content{padding:16px max(16px,env(safe-area-inset-right)) calc(20px + env(safe-area-inset-bottom)) max(16px,env(safe-area-inset-left));gap:14px;overscroll-behavior:contain}.dockm-content-head{gap:5px}.dockm-name{font-size:16px}.dockm-desc{font-size:13px;line-height:1.55}.dockm-foot{padding-top:12px;font-size:11px}.dockm-foot-sw{width:100%;margin-left:0;justify-content:space-between}.dock-sw{width:44px;height:26px}.dock-sw::after{top:3px;left:3px;width:18px;height:18px}.dock-sw.on::after{transform:translateX(18px)}.dockh-grid{grid-template-columns:1fr;gap:10px}.dockh-card{padding:12px}.dockh-desc{font-size:13px}.dockh-go{font-size:12px}}",
|
|
179
|
+
"@media (prefers-reduced-motion:reduce){.dockm-backdrop,.dockm-dialog{animation:none}.dockm-nav-item,.dockm-close,.dockm-win,.dock-sw{transition:none}}",
|
|
176
180
|
".dockh-desc{color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.5;}",
|
|
177
181
|
".dockh-stat{color:var(--dsw-alias-label-tertiary);font-size:12px;border-top:1px solid var(--dsw-alias-border-l1);padding-top:6px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}",
|
|
178
182
|
".dockh-foot{display:flex;align-items:center;gap:8px;}",
|
|
@@ -181,11 +185,16 @@ const SHELL_CSS = [
|
|
|
181
185
|
// 溢出兼容(两层防护,缺一不可):
|
|
182
186
|
// 1) 宽度上限:宿主 .row 是 flex-wrap:wrap 且换行优先于收缩,chips 一长 tools 整行变宽,
|
|
183
187
|
// 右侧模型选择器/发送键被挤到第二行(左右错位)。宿主 .row 带 container-type:inline-size,
|
|
184
|
-
// 用容器单位 cqw 让上限随输入卡宽度自适应(窄卡少占、宽卡多占);不支持 cqw
|
|
188
|
+
// 用容器单位 cqw 让上限随输入卡宽度自适应(窄卡少占、宽卡多占);不支持 cqw 的老内核退回固定值。
|
|
189
|
+
// 注意:旧上限 min(280px,36cqw) 仍偏宽——标准 780px 输入卡下(.row 内容约 762px),
|
|
190
|
+
// add 钮(28)+工作区选择器(~214)+chips(280) 已与右侧模型选择器+发送键(~345px)合计超宽,
|
|
191
|
+
// 即便 chips 未截断 .row 也会换行把模型选择器/发送键挤到第二行。实测把上限收到 189px
|
|
192
|
+
// (≈25cqw)并使 chips 内距收紧(padding 2px 6px、gap 2px)后,实测 4~6M 用量 + 余额
|
|
193
|
+
// 两 chip 可完整显示且不再换行;超限时仍被省略号截断,完整值在 title 悬浮提示里。
|
|
185
194
|
// 2) 截断:超限部分用省略号截断(完整数值在 title 悬浮提示里),防 chips 凸出输入卡圆角(悬空)。
|
|
186
|
-
".dockchip-row{display:inline-flex;align-items:center;gap:
|
|
187
|
-
"@supports (width:1cqw){.dockchip-row{max-width:min(
|
|
188
|
-
".dockchip{display:inline-flex;align-items:center;gap:5px;cursor:pointer;border:none;background:transparent;color:var(--dsw-alias-label-tertiary);border-radius:8px;padding:2px
|
|
195
|
+
".dockchip-row{display:inline-flex;align-items:center;gap:2px;min-width:0;flex:0 1 auto;overflow:hidden;max-width:189px;}",
|
|
196
|
+
"@supports (width:1cqw){.dockchip-row{max-width:min(189px,25cqw);}}",
|
|
197
|
+
".dockchip{display:inline-flex;align-items:center;gap:5px;cursor:pointer;border:none;background:transparent;color:var(--dsw-alias-label-tertiary);border-radius:8px;padding:2px 6px;font-family:inherit;font-size:11px;line-height:18px;white-space:nowrap;min-width:0;overflow:hidden;transition:background .15s var(--ds-ease-in-out),color .15s var(--ds-ease-in-out);}",
|
|
189
198
|
".dockchip > span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;}",
|
|
190
199
|
".dockchip:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary);}",
|
|
191
200
|
".dockchip .dockchip-dot{width:6px;height:6px;border-radius:50%;flex:none;}",
|
|
@@ -193,6 +202,13 @@ const SHELL_CSS = [
|
|
|
193
202
|
].join("\n");
|
|
194
203
|
|
|
195
204
|
let dockCssTag = null;
|
|
205
|
+
let initialCssSchedule = null;
|
|
206
|
+
function cancelInitialCssSchedule() {
|
|
207
|
+
if (!initialCssSchedule || typeof window === "undefined") return;
|
|
208
|
+
if (initialCssSchedule.type === "idle" && typeof window.cancelIdleCallback === "function") window.cancelIdleCallback(initialCssSchedule.id);
|
|
209
|
+
if (initialCssSchedule.type === "timer") window.clearTimeout(initialCssSchedule.id);
|
|
210
|
+
initialCssSchedule = null;
|
|
211
|
+
}
|
|
196
212
|
function fullDockCss() {
|
|
197
213
|
const parts = [SHELL_CSS];
|
|
198
214
|
for (const f of BUILTIN_FEATURES) if (f.css) parts.push(f.css);
|
|
@@ -204,6 +220,7 @@ function fullDockCss() {
|
|
|
204
220
|
// 外部功能注册携带样式时可重算更新(外部样式后到)。
|
|
205
221
|
function ensureCss() {
|
|
206
222
|
if (typeof document === "undefined") return;
|
|
223
|
+
cancelInitialCssSchedule();
|
|
207
224
|
try {
|
|
208
225
|
if (!dockCssTag || !dockCssTag.isConnected) {
|
|
209
226
|
if (document.querySelector('style[data-plugin-css="dsh-dock"]')) {
|
|
@@ -219,6 +236,20 @@ function ensureCss() {
|
|
|
219
236
|
console.error("[dsh-dock] ensureCss failed:", e && e.message ? e.message : String(e));
|
|
220
237
|
}
|
|
221
238
|
}
|
|
239
|
+
// 刷新页时宿主内容优先绘制:功能坞样式很大,首帧同步解析会让整页短暂停顿。
|
|
240
|
+
// 首次注入延后到浏览器空闲期;之后的外部模块注册仍走 ensureCss() 立即更新。
|
|
241
|
+
function scheduleInitialCss() {
|
|
242
|
+
if (typeof document === "undefined" || initialCssSchedule || (dockCssTag && dockCssTag.isConnected)) return;
|
|
243
|
+
const run = () => {
|
|
244
|
+
initialCssSchedule = null;
|
|
245
|
+
ensureCss();
|
|
246
|
+
};
|
|
247
|
+
if (typeof window !== "undefined" && typeof window.requestIdleCallback === "function") {
|
|
248
|
+
initialCssSchedule = { type: "idle", id: window.requestIdleCallback(run, { timeout: 350 }) };
|
|
249
|
+
} else {
|
|
250
|
+
initialCssSchedule = { type: "timer", id: setTimeout(run, 48) };
|
|
251
|
+
}
|
|
252
|
+
}
|
|
222
253
|
|
|
223
254
|
// ---- 外部功能变化订阅 hook(弹层/设置页重渲染用) ----
|
|
224
255
|
function useExternalVersion() {
|
|
@@ -272,9 +303,14 @@ function DockModal() {
|
|
|
272
303
|
// lastGeom 记住本页生命周期内最后一次几何,重开弹层时还原
|
|
273
304
|
const [win, setWin] = react.useState(() => ({ mode: "normal", x: null, y: null, w: null, h: null }));
|
|
274
305
|
const dlgRef = react.useRef(null);
|
|
306
|
+
const contentRef = react.useRef(null);
|
|
275
307
|
react.useEffect(() => {
|
|
276
308
|
if (lastGeom.w) setWin({ mode: "normal", x: lastGeom.x, y: lastGeom.y, w: lastGeom.w, h: lastGeom.h });
|
|
277
309
|
}, []);
|
|
310
|
+
// 切换左侧模块时总是从新页面顶部开始,避免把上一页的滚动位置带进小游戏等短页面。
|
|
311
|
+
react.useEffect(() => {
|
|
312
|
+
if (open && contentRef.current) contentRef.current.scrollTop = 0;
|
|
313
|
+
}, [active, open]);
|
|
278
314
|
function beginDrag(e, type) {
|
|
279
315
|
if (win.mode !== "normal" || e.button !== 0) return;
|
|
280
316
|
if (type === "move" && e.target && e.target.closest && e.target.closest("button,select,input")) return;
|
|
@@ -377,7 +413,7 @@ function DockModal() {
|
|
|
377
413
|
react.createElement("span", null, m.name),
|
|
378
414
|
m.planned ? react.createElement("span", { className: "dockm-badge" }, "规划中") : null,
|
|
379
415
|
m.external ? react.createElement("span", { className: "dockm-badge" }, "外部") : null))),
|
|
380
|
-
react.createElement("div", { className: "dockm-content" },
|
|
416
|
+
react.createElement("div", { className: "dockm-content", ref: contentRef },
|
|
381
417
|
react.createElement("div", { className: "dockm-content-head" },
|
|
382
418
|
react.createElement("div", { className: "dockm-name" },
|
|
383
419
|
isHome
|
|
@@ -589,7 +625,7 @@ const ctxRef = { current: null };
|
|
|
589
625
|
|
|
590
626
|
export function apply(ctx) {
|
|
591
627
|
ctxRef.current = ctx;
|
|
592
|
-
|
|
628
|
+
scheduleInitialCss();
|
|
593
629
|
initFeatureState(BUILTIN_FEATURES.concat(PLANNED_FEATURES));
|
|
594
630
|
const slots = ctx.get("slots");
|
|
595
631
|
if (slots === undefined) return;
|
|
@@ -614,4 +650,4 @@ export function apply(ctx) {
|
|
|
614
650
|
}
|
|
615
651
|
|
|
616
652
|
export const inject = ["timer"];
|
|
617
|
-
export { dockBridge };
|
|
653
|
+
export { dockBridge };
|
package/src/host-core.js
CHANGED
|
@@ -39,7 +39,10 @@ export const DockConfig = z.object({
|
|
|
39
39
|
})
|
|
40
40
|
|
|
41
41
|
/** 任务动画 effectMode 合法值(客户端动画模式)。 */
|
|
42
|
-
export const ANIMATION_MODES = [
|
|
42
|
+
export const ANIMATION_MODES = [
|
|
43
|
+
'flow', 'breathe', 'ring', 'orbit', 'robot', 'matrix', 'stars', 'aurora', 'space',
|
|
44
|
+
'nebula', 'warp', 'radar', 'constellation', 'fireflies', 'ocean', 'prism', 'circuit', 'gravity', 'lantern',
|
|
45
|
+
]
|
|
43
46
|
|
|
44
47
|
/** 提示音 soundEffect 合法值(客户端音效库键名)。 */
|
|
45
48
|
export const SOUND_EFFECTS = ['chime', 'ding', 'coin', 'bell', 'pulse', 'arp']
|
|
Binary file
|