@linxin666/dsh-remote-web-ui 0.1.17 → 0.1.19
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.i18n.yaml +2 -2
- package/README.md +5 -2
- package/README.zh.md +2 -2
- package/lib/client.js +82 -66
- package/lib/client.js.map +1 -1
- package/lib/index.js +18 -18
- package/lib/mobile.js +649 -45
- package/lib/mobile.js.map +1 -1
- package/lib/types/client/PluginSettingsCard.d.ts +11 -0
- package/lib/types/client/PluginSettingsCard.d.ts.map +1 -1
- package/lib/types/client/PluginSettingsCard.js +11 -5
- package/lib/types/client/RemoteSettingsCard.d.ts +5 -0
- package/lib/types/client/RemoteSettingsCard.d.ts.map +1 -1
- package/lib/types/client/RemoteSettingsCard.js +7 -0
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/client/index.js +13 -7
- package/lib/types/client/settings-form.d.ts +8 -0
- package/lib/types/client/settings-form.d.ts.map +1 -1
- package/lib/types/client/settings-form.js +15 -1
- package/lib/types/gate.d.ts +4 -9
- package/lib/types/gate.d.ts.map +1 -1
- package/lib/types/gate.js +5 -32
- package/lib/types/loopback.d.ts +25 -0
- package/lib/types/loopback.d.ts.map +1 -0
- package/lib/types/loopback.js +68 -0
- package/lib/types/mobile/markdown.d.ts +26 -0
- package/lib/types/mobile/markdown.d.ts.map +1 -0
- package/lib/types/mobile/markdown.js +272 -0
- package/lib/types/mobile/markdown.test.d.ts +2 -0
- package/lib/types/mobile/markdown.test.d.ts.map +1 -0
- package/lib/types/mobile/markdown.test.js +67 -0
- package/lib/types/mobile/messages.d.ts +14 -0
- package/lib/types/mobile/messages.d.ts.map +1 -1
- package/lib/types/mobile/messages.js +54 -2
- package/lib/types/mobile/messages.test.js +99 -0
- package/lib/types/mobile/mobile-styles.d.ts +1 -1
- package/lib/types/mobile/mobile-styles.d.ts.map +1 -1
- package/lib/types/mobile/mobile-styles.js +167 -0
- package/lib/types/mobile/views/ChatView.d.ts.map +1 -1
- package/lib/types/mobile/views/ChatView.js +81 -5
- package/lib/types/mobile/views/ChatView.test.js +105 -0
- package/package.json +1 -1
- package/src/client/PluginSettingsCard.tsx +50 -47
- package/src/client/RemoteSettingsCard.tsx +8 -0
- package/src/client/index.ts +13 -7
- package/src/client/settings-card.module.css +9 -0
- package/src/client/settings-form.ts +15 -1
- package/src/gate.ts +5 -30
- package/src/loopback.ts +63 -0
- package/src/mobile/markdown.test.ts +77 -0
- package/src/mobile/markdown.ts +278 -0
- package/src/mobile/messages.test.ts +106 -0
- package/src/mobile/messages.ts +66 -2
- package/src/mobile/mobile-styles.ts +167 -0
- package/src/mobile/views/ChatView.test.tsx +121 -0
- package/src/mobile/views/ChatView.tsx +164 -6
package/README.i18n.yaml
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
3
|
# after editing either side, bring the other along and re-record with:
|
|
4
4
|
# node scripts/verify-docs.mjs --write <dir>
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: 3a4ac70503ef6629ac456e3e86e0e429b90fd4b2
|
|
6
|
+
README.zh.md: e16a9bd530de74cff366fc23ae143254a198989b
|
package/README.md
CHANGED
|
@@ -140,13 +140,16 @@ mounts both halves.
|
|
|
140
140
|
- messages render with the desktop fold discipline: reasoning hides
|
|
141
141
|
behind a collapsed 深度思考 disclosure, tool calls behind a collapsed
|
|
142
142
|
工具 row (tap to see each call's arguments), very long answers behind
|
|
143
|
-
an explicit 展开全文 toggle,
|
|
143
|
+
an explicit 展开全文 toggle, each row carries its time, and assistant replies render as GFM Markdown (headings / bold / italic / inline code / code blocks / lists / tables / quotes / links / images; a zero-dependency renderer escapes first and allow-lists protocols, so the mobile bundle size barely moves; KaTeX is not supported yet and will be evaluated separately), while user messages stay plain text — and
|
|
144
144
|
- a composer toolbar carries the **model** picker (provider-grouped
|
|
145
145
|
catalog with a 思考强度 effort section per model) and the **权限**
|
|
146
146
|
picker (permission presets; 完全权限 requires an explicit confirm
|
|
147
147
|
step). Both ride the host's own `session.models` /
|
|
148
148
|
`session.selectModel` RPCs and the `/permission` command — the phone
|
|
149
|
-
changes the same session settings the desktop would
|
|
149
|
+
changes the same session settings the desktop would — plus a **显示**
|
|
150
|
+
sheet with persistent toggles for 工具调用 (tool-call disclosures) and
|
|
151
|
+
系统提示词 (injected system messages), and a 上下文 usage chip that
|
|
152
|
+
shows the latest assistant answer's context-fill percentage.
|
|
150
153
|
4. The desktop badge flips to 已连接 in real time; it falls back to
|
|
151
154
|
offline/断开 when the phone leaves.
|
|
152
155
|
5. 刷新二维码 invalidates the old link and issues a new one. 停止 revokes
|
package/README.zh.md
CHANGED
|
@@ -60,8 +60,8 @@ dsh plugin --profile web add link:$(pwd)/packages/dsh-remote-web-ui
|
|
|
60
60
|
- 打开会话**按需**抓取聊天内容(历史分页,"加载更早的消息"继续往回翻),
|
|
61
61
|
- 实时流随消息到达展示新消息,带发送自己消息的输入框(默认 **Enter 发送、Shift+Enter 换行**;设 `mobileEnterToSend: false` 后 Enter 改为换行,发送仅走「发送」按钮),
|
|
62
62
|
- **亮色优先主题**:界面默认亮色调色板;每个页头内的日/月切换翻到暗色调色板,选择跨访问持久(localStorage),
|
|
63
|
-
- 消息按桌面折叠纪律渲染:推理隐藏在被折叠的 深度思考 揭示下面,工具调用隐藏在被折叠的 工具 行下面(点击查看每个调用的参数),超长回答藏在显式 展开全文
|
|
64
|
-
- 输入栏工具条带 **模型** 选择器(provider 分组目录 + 每模型 思考强度 effort 区)与 **权限** 选择器(权限预设;完全权限 需要显式确认步骤)。两者都走 host 自己的 `session.models` / `session.selectModel` RPC 与 `/permission`
|
|
63
|
+
- 消息按桌面折叠纪律渲染:推理隐藏在被折叠的 深度思考 揭示下面,工具调用隐藏在被折叠的 工具 行下面(点击查看每个调用的参数),超长回答藏在显式 展开全文 切换下面,每行带时间,并且 assistant 回复按 GFM Markdown 渲染(标题 / 加粗 / 斜体 / 行内码 / 代码块 / 列表 / 表格 / 引用 / 链接 / 图片;零依赖自写渲染器,先转义再白名单协议,移动端 bundle 体积几乎不变;KaTeX 公式暂不支持,后续单独评估),用户消息保持纯文本,
|
|
64
|
+
- 输入栏工具条带 **模型** 选择器(provider 分组目录 + 每模型 思考强度 effort 区)与 **权限** 选择器(权限预设;完全权限 需要显式确认步骤)。两者都走 host 自己的 `session.models` / `session.selectModel` RPC 与 `/permission` 命令——手机改的与桌面改的是同一个会话设置——外加 **显示** 弹层(含 工具调用 与 系统提示词 两个持久开关)和一个 上下文 用量 chip(显示最近一次助手回答的上下文占用百分比)。
|
|
65
65
|
4. 桌面徽标实时翻到 已连接;手机离开时回落到离线/断开。
|
|
66
66
|
5. 刷新二维码 使旧链接失效并铸一枚新的。停止 撤销移动端访问:已配对设备下一次请求 403,包括其实时流。
|
|
67
67
|
|
package/lib/client.js
CHANGED
|
@@ -2219,7 +2219,7 @@ window.__ModuleLoader__.load({
|
|
|
2219
2219
|
}
|
|
2220
2220
|
//#endregion
|
|
2221
2221
|
//#region \0dsh-css:packages/dsh-remote-web-ui/src/client/settings-card.module.css.mjs
|
|
2222
|
-
const css = ".Kwoi6G_card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;list-style:none;transition:border-color .16s,background .16s}.Kwoi6G_card:hover{border-color:var(--dsw-alias-label-dimmed)}.Kwoi6G_cardOpen{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed)}.Kwoi6G_header{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:12px;padding:14px 16px;display:flex}.Kwoi6G_header:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}.Kwoi6G_headText{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}.Kwoi6G_name{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4}.Kwoi6G_description{color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}.Kwoi6G_pending{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;flex:none;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}.Kwoi6G_chevron{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s}.Kwoi6G_chevronOpen{transform:rotate(180deg)}.Kwoi6G_body{border-top:1px solid var(--dsw-alias-border-l2);margin:0 16px;padding-bottom:8px}.Kwoi6G_readOnly{color:var(--dsw-alias-label-tertiary);margin:12px 0 0;font-size:12px;line-height:1.5}.Kwoi6G_notExposed{color:var(--dsw-alias-state-warn-primary);margin:12px 0 0;font-size:12px;line-height:1.5}.Kwoi6G_footer{border-top:1px solid var(--dsw-alias-border-l2);justify-content:flex-end;align-items:center;gap:8px;padding:12px 0 4px;display:flex}.Kwoi6G_failed{min-width:0;color:var(--dsw-alias-label-error);text-overflow:ellipsis;white-space:nowrap;flex:1;margin:0;font-size:12px;line-height:1.5;overflow:hidden}.Kwoi6G_discard,.Kwoi6G_save{appearance:none;font:inherit;cursor:pointer;border:1px solid #0000;border-radius:8px;padding:5px 14px;font-size:13px;line-height:1.5}.Kwoi6G_discard{border-color:var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:0 0}.Kwoi6G_discard:hover:not(:disabled){color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-dimmed)}.Kwoi6G_save{background:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-3)}.Kwoi6G_discard:disabled,.Kwoi6G_save:disabled{opacity:.4;cursor:default}.Kwoi6G_discard:focus-visible,.Kwoi6G_save:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}.Kwoi6G_field{flex-direction:column;gap:6px;padding:12px 0;display:flex}.Kwoi6G_field+.Kwoi6G_field{border-top:1px solid var(--dsw-alias-border-l2)}.Kwoi6G_head{align-items:center;gap:8px;display:flex}.Kwoi6G_label{min-width:0;color:var(--dsw-alias-label-primary);flex:1;font-size:13px;font-weight:500;line-height:1.5}.Kwoi6G_badges{align-items:center;gap:8px;display:inline-flex}.Kwoi6G_badge{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}.Kwoi6G_reset{font:inherit;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;padding:0;font-size:12px;line-height:1.5}.Kwoi6G_reset:hover:not(:disabled){color:var(--dsw-alias-label-primary)}.Kwoi6G_reset:disabled{cursor:default}.Kwoi6G_reset:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px;outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}.Kwoi6G_input,.Kwoi6G_select{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);height:34px;font:inherit;color:var(--dsw-alias-label-primary);border-radius:8px;padding:0 12px;font-size:13px;line-height:1.5}.Kwoi6G_input:focus-visible,.Kwoi6G_select:focus-visible{border-color:var(--dsw-alias-brand-primary);outline:none}.Kwoi6G_input:disabled,.Kwoi6G_select:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.Kwoi6G_inputInvalid{border:1px solid var(--dsw-alias-label-error);background:var(--dsw-alias-bg-layer-3);height:34px;font:inherit;color:var(--dsw-alias-label-primary);border-radius:8px;padding:0 12px;font-size:13px;line-height:1.5}.Kwoi6G_inputInvalid:focus-visible{outline:2px solid var(--dsw-alias-label-error);outline-offset:1px;border-color:var(--dsw-alias-label-error)}.Kwoi6G_invalid{color:var(--dsw-alias-label-error);margin:0;font-size:12px;line-height:1.5}.Kwoi6G_hint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:1.5}@media (prefers-reduced-motion:reduce){.Kwoi6G_card,.Kwoi6G_header,.Kwoi6G_chevron,.Kwoi6G_chevronOpen,.Kwoi6G_discard,.Kwoi6G_save{transition:none}}";
|
|
2222
|
+
const css = ".Kwoi6G_card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;list-style:none;transition:border-color .16s,background .16s}.Kwoi6G_card:hover{border-color:var(--dsw-alias-label-dimmed)}.Kwoi6G_cardOpen{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed)}.Kwoi6G_header{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:12px;padding:14px 16px;display:flex}.Kwoi6G_header:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}.Kwoi6G_headerStatic{border-radius:12px;align-items:center;gap:12px;width:100%;padding:14px 16px;display:flex}.Kwoi6G_headText{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}.Kwoi6G_name{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4}.Kwoi6G_description{color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}.Kwoi6G_pending{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;flex:none;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}.Kwoi6G_chevron{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s}.Kwoi6G_chevronOpen{transform:rotate(180deg)}.Kwoi6G_body{border-top:1px solid var(--dsw-alias-border-l2);margin:0 16px;padding-bottom:8px}.Kwoi6G_readOnly{color:var(--dsw-alias-label-tertiary);margin:12px 0 0;font-size:12px;line-height:1.5}.Kwoi6G_notExposed{color:var(--dsw-alias-state-warn-primary);margin:12px 0 0;font-size:12px;line-height:1.5}.Kwoi6G_footer{border-top:1px solid var(--dsw-alias-border-l2);justify-content:flex-end;align-items:center;gap:8px;padding:12px 0 4px;display:flex}.Kwoi6G_failed{min-width:0;color:var(--dsw-alias-label-error);text-overflow:ellipsis;white-space:nowrap;flex:1;margin:0;font-size:12px;line-height:1.5;overflow:hidden}.Kwoi6G_discard,.Kwoi6G_save{appearance:none;font:inherit;cursor:pointer;border:1px solid #0000;border-radius:8px;padding:5px 14px;font-size:13px;line-height:1.5}.Kwoi6G_discard{border-color:var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:0 0}.Kwoi6G_discard:hover:not(:disabled){color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-dimmed)}.Kwoi6G_save{background:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-3)}.Kwoi6G_discard:disabled,.Kwoi6G_save:disabled{opacity:.4;cursor:default}.Kwoi6G_discard:focus-visible,.Kwoi6G_save:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}.Kwoi6G_field{flex-direction:column;gap:6px;padding:12px 0;display:flex}.Kwoi6G_field+.Kwoi6G_field{border-top:1px solid var(--dsw-alias-border-l2)}.Kwoi6G_head{align-items:center;gap:8px;display:flex}.Kwoi6G_label{min-width:0;color:var(--dsw-alias-label-primary);flex:1;font-size:13px;font-weight:500;line-height:1.5}.Kwoi6G_badges{align-items:center;gap:8px;display:inline-flex}.Kwoi6G_badge{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}.Kwoi6G_reset{font:inherit;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;padding:0;font-size:12px;line-height:1.5}.Kwoi6G_reset:hover:not(:disabled){color:var(--dsw-alias-label-primary)}.Kwoi6G_reset:disabled{cursor:default}.Kwoi6G_reset:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px;outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}.Kwoi6G_input,.Kwoi6G_select{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);height:34px;font:inherit;color:var(--dsw-alias-label-primary);border-radius:8px;padding:0 12px;font-size:13px;line-height:1.5}.Kwoi6G_input:focus-visible,.Kwoi6G_select:focus-visible{border-color:var(--dsw-alias-brand-primary);outline:none}.Kwoi6G_input:disabled,.Kwoi6G_select:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.Kwoi6G_inputInvalid{border:1px solid var(--dsw-alias-label-error);background:var(--dsw-alias-bg-layer-3);height:34px;font:inherit;color:var(--dsw-alias-label-primary);border-radius:8px;padding:0 12px;font-size:13px;line-height:1.5}.Kwoi6G_inputInvalid:focus-visible{outline:2px solid var(--dsw-alias-label-error);outline-offset:1px;border-color:var(--dsw-alias-label-error)}.Kwoi6G_invalid{color:var(--dsw-alias-label-error);margin:0;font-size:12px;line-height:1.5}.Kwoi6G_hint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:1.5}@media (prefers-reduced-motion:reduce){.Kwoi6G_card,.Kwoi6G_header,.Kwoi6G_chevron,.Kwoi6G_chevronOpen,.Kwoi6G_discard,.Kwoi6G_save{transition:none}}";
|
|
2223
2223
|
const tagId = "@linxin666/dsh-remote-web-ui/settings-card.module.css";
|
|
2224
2224
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
2225
2225
|
const tag = document.createElement("style");
|
|
@@ -2244,6 +2244,7 @@ window.__ModuleLoader__.load({
|
|
|
2244
2244
|
"head": "Kwoi6G_head",
|
|
2245
2245
|
"headText": "Kwoi6G_headText",
|
|
2246
2246
|
"header": "Kwoi6G_header",
|
|
2247
|
+
"headerStatic": "Kwoi6G_headerStatic",
|
|
2247
2248
|
"hint": "Kwoi6G_hint",
|
|
2248
2249
|
"input": "Kwoi6G_input",
|
|
2249
2250
|
"inputInvalid": "Kwoi6G_inputInvalid",
|
|
@@ -2273,24 +2274,42 @@ window.__ModuleLoader__.load({
|
|
|
2273
2274
|
* @returns the card, or nothing while the namespace is still loading.
|
|
2274
2275
|
*/
|
|
2275
2276
|
function PluginSettingsCard(props) {
|
|
2276
|
-
const [open, setOpen] = (0, react.useState)(
|
|
2277
|
-
const { state } = props;
|
|
2277
|
+
const [open, setOpen] = (0, react.useState)(props.defaultOpen ?? true);
|
|
2278
|
+
const { state, alwaysOpen } = props;
|
|
2278
2279
|
if (!state.available) return null;
|
|
2279
2280
|
const title = props.t(props.titleKey);
|
|
2280
2281
|
const description = props.t(props.descriptionKey);
|
|
2281
2282
|
const blocked = !state.dirty || state.invalid || state.saving;
|
|
2282
|
-
const
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
className: settings_card_module_css_default.
|
|
2288
|
-
"
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
},
|
|
2293
|
-
|
|
2283
|
+
const expanded = alwaysOpen === true || open;
|
|
2284
|
+
const cardClass = expanded ? `${settings_card_module_css_default.cardOpen} ${settings_card_module_css_default.card}` : settings_card_module_css_default.card;
|
|
2285
|
+
const header = alwaysOpen === true ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2286
|
+
className: settings_card_module_css_default.headerStatic,
|
|
2287
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
2288
|
+
className: settings_card_module_css_default.headText,
|
|
2289
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2290
|
+
className: settings_card_module_css_default.name,
|
|
2291
|
+
title,
|
|
2292
|
+
children: title
|
|
2293
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2294
|
+
className: settings_card_module_css_default.description,
|
|
2295
|
+
title: description,
|
|
2296
|
+
children: description
|
|
2297
|
+
})]
|
|
2298
|
+
}), state.dirty ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2299
|
+
className: settings_card_module_css_default.pending,
|
|
2300
|
+
title: props.t("settings.unsaved"),
|
|
2301
|
+
children: props.t("settings.unsaved")
|
|
2302
|
+
}) : null]
|
|
2303
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
2304
|
+
type: "button",
|
|
2305
|
+
className: settings_card_module_css_default.header,
|
|
2306
|
+
"aria-expanded": open,
|
|
2307
|
+
"aria-label": `${props.t(open ? "settings.collapse" : "settings.expand")}: ${title}`,
|
|
2308
|
+
onClick: () => {
|
|
2309
|
+
setOpen(!open);
|
|
2310
|
+
},
|
|
2311
|
+
children: [
|
|
2312
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
2294
2313
|
className: settings_card_module_css_default.headText,
|
|
2295
2314
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2296
2315
|
className: settings_card_module_css_default.name,
|
|
@@ -2301,7 +2320,13 @@ window.__ModuleLoader__.load({
|
|
|
2301
2320
|
title: description,
|
|
2302
2321
|
children: description
|
|
2303
2322
|
})]
|
|
2304
|
-
}),
|
|
2323
|
+
}),
|
|
2324
|
+
state.dirty ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2325
|
+
className: settings_card_module_css_default.pending,
|
|
2326
|
+
title: props.t("settings.unsaved"),
|
|
2327
|
+
children: props.t("settings.unsaved")
|
|
2328
|
+
}) : null,
|
|
2329
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
|
|
2305
2330
|
width: "14",
|
|
2306
2331
|
height: "14",
|
|
2307
2332
|
viewBox: "0 0 14 14",
|
|
@@ -2312,8 +2337,12 @@ window.__ModuleLoader__.load({
|
|
|
2312
2337
|
d: "M11.8486 5.5L11.4238 5.92383L8.69727 8.65137C8.44157 8.90706 8.21562 9.13382 8.01172 9.29785C7.79912 9.46883 7.55595 9.61756 7.25 9.66602C7.08435 9.69222 6.91565 9.69222 6.75 9.66602C6.44405 9.61756 6.20088 9.46883 5.98828 9.29785C5.78438 9.13382 5.55843 8.90706 5.30273 8.65137L2.57617 5.92383L2.15137 5.5L3 4.65137L3.42383 5.07617L6.15137 7.80273C6.42595 8.07732 6.59876 8.24849 6.74023 8.3623C6.87291 8.46904 6.92272 8.47813 6.9375 8.48047C6.97895 8.48703 7.02105 8.48703 7.0625 8.48047C7.07728 8.47813 7.12709 8.46904 7.25977 8.3623C7.40124 8.24849 7.57405 8.07732 7.84863 7.80273L10.5762 5.07617L11 4.65137L11.8486 5.5Z",
|
|
2313
2338
|
fill: "currentColor"
|
|
2314
2339
|
})
|
|
2315
|
-
})
|
|
2316
|
-
|
|
2340
|
+
})
|
|
2341
|
+
]
|
|
2342
|
+
});
|
|
2343
|
+
if (!state.exposed) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
2344
|
+
className: cardClass,
|
|
2345
|
+
children: [header, expanded ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2317
2346
|
className: settings_card_module_css_default.body,
|
|
2318
2347
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2319
2348
|
className: settings_card_module_css_default.notExposed,
|
|
@@ -2324,46 +2353,7 @@ window.__ModuleLoader__.load({
|
|
|
2324
2353
|
});
|
|
2325
2354
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
2326
2355
|
className: cardClass,
|
|
2327
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("
|
|
2328
|
-
type: "button",
|
|
2329
|
-
className: settings_card_module_css_default.header,
|
|
2330
|
-
"aria-expanded": open,
|
|
2331
|
-
"aria-label": `${props.t(open ? "settings.collapse" : "settings.expand")}: ${title}`,
|
|
2332
|
-
onClick: () => {
|
|
2333
|
-
setOpen(!open);
|
|
2334
|
-
},
|
|
2335
|
-
children: [
|
|
2336
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
2337
|
-
className: settings_card_module_css_default.headText,
|
|
2338
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2339
|
-
className: settings_card_module_css_default.name,
|
|
2340
|
-
title,
|
|
2341
|
-
children: title
|
|
2342
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2343
|
-
className: settings_card_module_css_default.description,
|
|
2344
|
-
title: description,
|
|
2345
|
-
children: description
|
|
2346
|
-
})]
|
|
2347
|
-
}),
|
|
2348
|
-
state.dirty ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2349
|
-
className: settings_card_module_css_default.pending,
|
|
2350
|
-
title: props.t("settings.unsaved"),
|
|
2351
|
-
children: props.t("settings.unsaved")
|
|
2352
|
-
}) : null,
|
|
2353
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
|
|
2354
|
-
width: "14",
|
|
2355
|
-
height: "14",
|
|
2356
|
-
viewBox: "0 0 14 14",
|
|
2357
|
-
fill: "none",
|
|
2358
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
2359
|
-
className: open ? `${settings_card_module_css_default.chevron} ${settings_card_module_css_default.chevronOpen}` : settings_card_module_css_default.chevron,
|
|
2360
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
2361
|
-
d: "M11.8486 5.5L11.4238 5.92383L8.69727 8.65137C8.44157 8.90706 8.21562 9.13382 8.01172 9.29785C7.79912 9.46883 7.55595 9.61756 7.25 9.66602C7.08435 9.69222 6.91565 9.69222 6.75 9.66602C6.44405 9.61756 6.20088 9.46883 5.98828 9.29785C5.78438 9.13382 5.55843 8.90706 5.30273 8.65137L2.57617 5.92383L2.15137 5.5L3 4.65137L3.42383 5.07617L6.15137 7.80273C6.42595 8.07732 6.59876 8.24849 6.74023 8.3623C6.87291 8.46904 6.92272 8.47813 6.9375 8.48047C6.97895 8.48703 7.02105 8.48703 7.0625 8.48047C7.07728 8.47813 7.12709 8.46904 7.25977 8.3623C7.40124 8.24849 7.57405 8.07732 7.84863 7.80273L10.5762 5.07617L11 4.65137L11.8486 5.5Z",
|
|
2362
|
-
fill: "currentColor"
|
|
2363
|
-
})
|
|
2364
|
-
})
|
|
2365
|
-
]
|
|
2366
|
-
}), open ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2356
|
+
children: [header, expanded ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2367
2357
|
className: settings_card_module_css_default.body,
|
|
2368
2358
|
children: [
|
|
2369
2359
|
!state.writable ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
@@ -2568,6 +2558,9 @@ window.__ModuleLoader__.load({
|
|
|
2568
2558
|
specs;
|
|
2569
2559
|
staged = /* @__PURE__ */ new Map();
|
|
2570
2560
|
listeners = /* @__PURE__ */ new Set();
|
|
2561
|
+
/** The scope subscription installed in the constructor; released by dispose(). */
|
|
2562
|
+
disposeScope;
|
|
2563
|
+
disposed = false;
|
|
2571
2564
|
saving = false;
|
|
2572
2565
|
failed = false;
|
|
2573
2566
|
failedReason;
|
|
@@ -2575,10 +2568,20 @@ window.__ModuleLoader__.load({
|
|
|
2575
2568
|
constructor(scope, specs) {
|
|
2576
2569
|
this.scope = scope;
|
|
2577
2570
|
this.specs = new Map(specs.map((spec) => [spec.field, spec]));
|
|
2578
|
-
scope.subscribe(() => {
|
|
2571
|
+
this.disposeScope = scope.subscribe(() => {
|
|
2579
2572
|
this.publish();
|
|
2580
2573
|
});
|
|
2581
2574
|
}
|
|
2575
|
+
/**
|
|
2576
|
+
* Release the scope subscription and every bound store listener. The card
|
|
2577
|
+
* must call this on teardown; later calls are no-ops.
|
|
2578
|
+
*/
|
|
2579
|
+
dispose() {
|
|
2580
|
+
if (this.disposed) return;
|
|
2581
|
+
this.disposed = true;
|
|
2582
|
+
this.disposeScope();
|
|
2583
|
+
this.listeners.clear();
|
|
2584
|
+
}
|
|
2582
2585
|
/** Publish a projection of this form, rebuilt whenever the scope or a draft changes. */
|
|
2583
2586
|
bind(project) {
|
|
2584
2587
|
const store = (0, _deepseek_ai_dsh_client_runtime_client.createSnapshotStore)(project());
|
|
@@ -2821,6 +2824,13 @@ window.__ModuleLoader__.load({
|
|
|
2821
2824
|
...this.form.actions()
|
|
2822
2825
|
};
|
|
2823
2826
|
}
|
|
2827
|
+
/**
|
|
2828
|
+
* Release the card's scope subscription and bound stores; the slot
|
|
2829
|
+
* disposer calls this on teardown.
|
|
2830
|
+
*/
|
|
2831
|
+
dispose() {
|
|
2832
|
+
this.form.dispose();
|
|
2833
|
+
}
|
|
2824
2834
|
};
|
|
2825
2835
|
/**
|
|
2826
2836
|
* Render the remote-control card.
|
|
@@ -3359,13 +3369,19 @@ window.__ModuleLoader__.load({
|
|
|
3359
3369
|
};
|
|
3360
3370
|
});
|
|
3361
3371
|
const remoteSettings = new RemoteSettingsCardController(settingsScope);
|
|
3362
|
-
ctx.slots.inject("web-ui.plugin.item", () =>
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
3372
|
+
ctx.slots.inject("web-ui.plugin.item", () => {
|
|
3373
|
+
const unregister = ctx.slots.register({
|
|
3374
|
+
name: "web-ui.plugin.item",
|
|
3375
|
+
id: "remote-web-ui",
|
|
3376
|
+
order: 90,
|
|
3377
|
+
locale: NS,
|
|
3378
|
+
inject: () => remoteSettings.inject()
|
|
3379
|
+
}, RemoteSettingsCard);
|
|
3380
|
+
return () => {
|
|
3381
|
+
remoteSettings.dispose();
|
|
3382
|
+
unregister();
|
|
3383
|
+
};
|
|
3384
|
+
});
|
|
3369
3385
|
let disposeRuntime;
|
|
3370
3386
|
const syncRuntime = () => {
|
|
3371
3387
|
if (enabled() && disposeRuntime === void 0) disposeRuntime = ctx.effect(() => {
|