dsh-session-manager 0.5.3 → 0.6.2
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/CHANGELOG.md +36 -9
- package/README.local-workflow.md +52 -0
- package/README.md +65 -32
- package/README.zh.md +64 -31
- package/lib/annotation-store.js +1 -1
- package/lib/client.js +1483 -151
- package/lib/compat/dsh-adapter.js +55 -0
- package/lib/index.js +83 -2
- package/package.json +9 -3
package/lib/client.js
CHANGED
|
@@ -21,7 +21,17 @@ window.__ModuleLoader__.load({
|
|
|
21
21
|
const P = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
22
22
|
if (typeof window !== "undefined") {
|
|
23
23
|
window.__smReact = React;
|
|
24
|
-
|
|
24
|
+
let rdomModule = null;
|
|
25
|
+
try { rdomModule = require("react-dom"); } catch (_) {}
|
|
26
|
+
if (!rdomModule) {
|
|
27
|
+
try { rdomModule = require("react-dom/client"); } catch (_) {}
|
|
28
|
+
}
|
|
29
|
+
if (!rdomModule && typeof window.ReactDOM !== "undefined") {
|
|
30
|
+
rdomModule = window.ReactDOM;
|
|
31
|
+
}
|
|
32
|
+
window.__smReactDOM = (rdomModule && typeof rdomModule.createPortal === "function")
|
|
33
|
+
? rdomModule
|
|
34
|
+
: (typeof React.createPortal === "function" ? React : null);
|
|
25
35
|
// Tiny imperative portal helper: takes a React element + a host
|
|
26
36
|
// DOM node, creates a React root on the host (lazily), and re-renders
|
|
27
37
|
// the element into it on each call. Used by ConfirmDialog to escape
|
|
@@ -48,9 +58,16 @@ window.__ModuleLoader__.load({
|
|
|
48
58
|
// this counter on mount, writes it to inline style.zIndex, and never
|
|
49
59
|
// recycles within a session, so the most-recently opened popup is
|
|
50
60
|
// always the topmost one.
|
|
51
|
-
let dialogZStackCounter =
|
|
61
|
+
let dialogZStackCounter = 100000;
|
|
52
62
|
function nextDialogZ() { return ++dialogZStackCounter; }
|
|
53
63
|
|
|
64
|
+
function renderTip(label, node, side = "bottom", portal = true) {
|
|
65
|
+
if (!label || !node) return node;
|
|
66
|
+
if (P && typeof P.Tooltip === "function") {
|
|
67
|
+
return h(P.Tooltip, { label, side, portal, align: "center" }, node);
|
|
68
|
+
}
|
|
69
|
+
return node;
|
|
70
|
+
}
|
|
54
71
|
|
|
55
72
|
const NS = "session-manager";
|
|
56
73
|
const API = "/session-manager/api";
|
|
@@ -119,6 +136,7 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
119
136
|
"marks.tags.clear": "清空标签",
|
|
120
137
|
"marks.note.clear": "清空备注",
|
|
121
138
|
"header.aria": "会话操作",
|
|
139
|
+
"header.more": "更多操作",
|
|
122
140
|
"menu.open": "打开",
|
|
123
141
|
"menu.archive": "归档会话",
|
|
124
142
|
"menu.unarchive": "移出归档",
|
|
@@ -128,7 +146,39 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
128
146
|
"footer.aria": "会话管理",
|
|
129
147
|
"footer.label": "会话管理",
|
|
130
148
|
"panel.title": "会话管理",
|
|
131
|
-
"panel.github.title": "欢迎Star
|
|
149
|
+
"panel.github.title": "欢迎Star和提交Issue",
|
|
150
|
+
"panel.update.title": "检查更新",
|
|
151
|
+
"panel.update.badge": "有新版本可用",
|
|
152
|
+
"update.title": "检查更新",
|
|
153
|
+
"update.newVersion": "发现新版本",
|
|
154
|
+
"update.currentVersion": "当前版本",
|
|
155
|
+
"update.latestVersion": "最新版本",
|
|
156
|
+
"update.isLatest": "当前已是最新版本",
|
|
157
|
+
"update.checking": "正在检查更新…",
|
|
158
|
+
"update.installing": "正在通过插件管理器安装新版本…",
|
|
159
|
+
"update.btn.check": "检查更新",
|
|
160
|
+
"update.btn.update": "更新到 v{version}",
|
|
161
|
+
"update.btn.updating": "更新中…",
|
|
162
|
+
"update.btn.later": "稍后",
|
|
163
|
+
"update.btn.done": "好的",
|
|
164
|
+
"update.btn.retry": "重试",
|
|
165
|
+
"update.btn.close": "关闭",
|
|
166
|
+
"update.done.restart": "更新已安装(v{from} → v{to}),重启 DSH 后生效。",
|
|
167
|
+
"update.done.applied": "更新已应用!",
|
|
168
|
+
"update.error": "更新遇到问题",
|
|
169
|
+
"update.autoCheck": "自动检查更新",
|
|
170
|
+
"update.autoCheck.enable": "开启",
|
|
171
|
+
"settings.registry": "安装源",
|
|
172
|
+
"settings.registry.npm": "npm 官方源 registry.npmjs.org",
|
|
173
|
+
"settings.registry.china": "中国大陆镜像源 registry.npmmirror.com",
|
|
174
|
+
"settings.title": "会话管理",
|
|
175
|
+
"settings.pluginName": "dsh-session-manager",
|
|
176
|
+
"settings.versionSection": "插件版本",
|
|
177
|
+
"settings.prefSection": "偏好设置",
|
|
178
|
+
"settings.projectSection": "项目",
|
|
179
|
+
"settings.github": "GitHub 仓库",
|
|
180
|
+
"settings.star": "感谢Star",
|
|
181
|
+
"settings.feedback": "欢迎反馈",
|
|
132
182
|
"panel.search": "搜索标题、ID、标签或备注",
|
|
133
183
|
"panel.workspace": "工作区",
|
|
134
184
|
"panel.workspace.all": "全部工作区",
|
|
@@ -285,7 +335,6 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
285
335
|
"marks.discard": "Discard unsaved annotation changes?",
|
|
286
336
|
"marks.note.exists": "Has note",
|
|
287
337
|
"marks.sort": "Priority (1 → 5)",
|
|
288
|
-
"marks.note.exists": "Has note",
|
|
289
338
|
"marks.import.copy": "Copy Prompt",
|
|
290
339
|
"marks.import.copy.copied": "Copied. Paste it into the current conversation to generate the result.",
|
|
291
340
|
"marks.import.copy.failed": "Copy failed: {message}",
|
|
@@ -304,6 +353,7 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
304
353
|
"marks.tags.clear": "Clear tags",
|
|
305
354
|
"marks.note.clear": "Clear note",
|
|
306
355
|
"header.aria": "Session actions",
|
|
356
|
+
"header.more": "More actions",
|
|
307
357
|
"menu.open": "Open",
|
|
308
358
|
"menu.archive": "Archive session",
|
|
309
359
|
"menu.unarchive": "Unarchive session",
|
|
@@ -313,7 +363,39 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
313
363
|
"footer.aria": "Session manager",
|
|
314
364
|
"footer.label": "Sessions",
|
|
315
365
|
"panel.title": "Session manager",
|
|
316
|
-
"panel.github.title": "Star or open an issue",
|
|
366
|
+
"panel.github.title": "Star the project or open an issue",
|
|
367
|
+
"panel.update.title": "Check for updates",
|
|
368
|
+
"panel.update.badge": "New version available",
|
|
369
|
+
"update.title": "Check for Updates",
|
|
370
|
+
"update.newVersion": "New Version Available",
|
|
371
|
+
"update.currentVersion": "Current Version",
|
|
372
|
+
"update.latestVersion": "Latest Version",
|
|
373
|
+
"update.isLatest": "Up to date",
|
|
374
|
+
"update.checking": "Checking for updates…",
|
|
375
|
+
"update.installing": "Installing update via plugin manager…",
|
|
376
|
+
"update.btn.check": "Check for Updates",
|
|
377
|
+
"update.btn.update": "Update to v{version}",
|
|
378
|
+
"update.btn.updating": "Updating…",
|
|
379
|
+
"update.btn.later": "Later",
|
|
380
|
+
"update.btn.done": "OK",
|
|
381
|
+
"update.btn.retry": "Retry",
|
|
382
|
+
"update.btn.close": "Close",
|
|
383
|
+
"update.done.restart": "Update installed (v{from} → v{to}). Please restart DSH.",
|
|
384
|
+
"update.done.applied": "Update applied successfully!",
|
|
385
|
+
"update.error": "Update Error",
|
|
386
|
+
"update.autoCheck": "Automatically check for updates",
|
|
387
|
+
"update.autoCheck.enable": "Enable",
|
|
388
|
+
"settings.registry": "Install Source",
|
|
389
|
+
"settings.registry.npm": "npm official registry.npmjs.org",
|
|
390
|
+
"settings.registry.china": "China mainland mirror registry.npmmirror.com",
|
|
391
|
+
"settings.title": "Session Manager",
|
|
392
|
+
"settings.pluginName": "dsh-session-manager",
|
|
393
|
+
"settings.versionSection": "Plugin Version",
|
|
394
|
+
"settings.prefSection": "Preferences",
|
|
395
|
+
"settings.projectSection": "Project",
|
|
396
|
+
"settings.github": "GitHub Repository",
|
|
397
|
+
"settings.star": "Star on GitHub",
|
|
398
|
+
"settings.feedback": "Feedback / Issues",
|
|
317
399
|
"panel.search": "Search title, ID, tags or notes",
|
|
318
400
|
"panel.workspace": "Workspace",
|
|
319
401
|
"panel.workspace.all": "All workspaces",
|
|
@@ -470,17 +552,17 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
470
552
|
".sm-moveItem:hover{background:var(--dsw-alias-interactive-bg-hover)}",
|
|
471
553
|
".sm-moveItemSelected{border-color:var(--dsw-alias-accent-primary);background:var(--dsw-alias-accent-primary-bg)}",
|
|
472
554
|
".sm-moveItemName{color:var(--dsw-alias-label-primary);font-size:13px;line-height:18px}",
|
|
473
|
-
".sm-moveItemMeta{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:16px}.sm-panelModal{width:760px;max-width:92vw}.sm-panelModal .sm-rowActions{flex-wrap:wrap;justify-content:flex-end}.sm-headerMenu{position:absolute;right:0;top:100%;z-index:50;display:flex;flex-direction:column;min-width:
|
|
474
|
-
".sm-panelDialog{position:fixed;left:50%;top:50%;transform:translate(-50%,-50%);width:600px;max-width:calc(100vw - 32px);max-height:560px;height:auto;box-sizing:border-box;display:flex;flex-direction:column;gap:0;background:var(--dsw-alias-surface-l1,#fff);color:var(--dsw-alias-label-primary,#111);border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:12px;box-shadow:0 16px 48px rgba(0,0,0,.25);overflow:hidden;z-index:9999;opacity:1}.sm-panelDialog .sm-nativeDialogHeader{display:flex;align-items:center;gap:8px;padding:10px 16px;border-bottom:1px solid var(--dsw-alias-border-l2,#eee);flex:none}.sm-panelDialog .sm-nativeDialogTitle{margin:0;font-size:14px;line-height:20px;font-weight:600;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:center;flex:1 1 auto}.sm-panelDialog .sm-nativeDialogHeaderActions{display:flex;align-items:center;gap:6px;flex:none}.sm-panelDialog .sm-nativeDialogTitle{margin:0;font-size:14px;line-height:20px;font-weight:600;text-align:center;flex:1 1 auto}.sm-nativeDialogFooter,.sm-bulkDialog .sm-nativeDialogFooter,.sm-confirmDialog .sm-nativeDialogFooter,.sm-migrateDialog .sm-nativeDialogFooter{display:flex;padding:10px 16px;border-top:1px solid var(--dsw-alias-border-l2,#eee);flex:none;flex-wrap:wrap;justify-content:space-between;gap:6px;margin-top:0}.sm-panelDialog .sm-panel{display:flex;flex-direction:column;gap:6px;min-height:0;flex:1 1 auto;overflow:auto;padding:8px 12px}.sm-panelDialog .sm-list{display:flex;flex-direction:column;gap:2px;flex:1 1 auto;min-height:0;overflow:auto}.sm-panelDialog .sm-row{display:flex;align-items:center;gap:8px;padding:6px 10px;min-height:36px;border:1px solid transparent;border-radius:8px;background:transparent;flex-shrink:0}.sm-panelDialog .sm-row:hover{background:var(--dsw-alias-interactive-bg-hover)}.sm-panelDialog .sm-rowCurrent{background:var(--dsw-alias-fill-l2);border-color:var(--dsw-alias-accent-primary,#356ae6)}.sm-panelDialog .sm-rowMain{display:flex;align-items:stretch!important;gap:8px;min-width:0;flex:1 1 auto;overflow:visible;text-align:left!important}.sm-panelDialog .sm-rowTitle{min-width:0;flex:1 1 0%;width:100%;align-self:stretch;display:flex;align-items:center;justify-content:flex-start;gap:6px;font-size:12px;line-height:16px;overflow:hidden;text-align:left!important;direction:ltr!important}.sm-confirmDialog{z-index:10000}.sm-confirmDialog.sm-nativeDialogLayer{position:fixed;left:calc(50vw + 184px);top:calc(50vh - 90px);width:360px;max-width:calc(100vw - 32px);max-height:none;display:block;align-items:initial;justify-content:initial;box-sizing:border-box;background:transparent;border:0;box-shadow:none;padding:0;inset:calc(50vh - 90px) auto auto calc(50vw + 308px)}.sm-confirmDialog.sm-nativeDialogLayer .sm-nativeDialogBackdrop{display:none}.sm-confirmDialog.sm-nativeDialogLayer .sm-nativeDialog{position:relative;left:auto;top:auto;transform:none;width:auto;box-sizing:border-box;background:var(--dsw-alias-surface-l1,#fff);color:var(--dsw-alias-label-primary,#111);border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:12px;box-shadow:0 16px 48px rgba(0,0,0,.25);padding:0;overflow:hidden;animation:sm-confirmPop .14s ease-out}.sm-confirmDialog .sm-nativeDialogHeader{padding:12px 16px;border-bottom:1px solid var(--dsw-alias-border-l2,#eee)}.sm-confirmDialog .sm-nativeDialogTitle{margin:0;font-size:14px;line-height:20px;font-weight:600;text-align:center;width:100%}.sm-confirmDialog .sm-nativeDialogBody{padding:10px 16px;display:flex;flex-direction:column;gap:8px;min-height:0}.sm-confirmDialog .sm-nativeDialogDescription{font-size:12px;line-height:18px;color:var(--dsw-alias-label-secondary);white-space:pre-wrap}.sm-confirmDialog .sm-warn{padding:6px 10px;font-size:12px;line-height:16px;margin-top:0}.sm-confirmDialog .sm-nativeDialogFooter{padding:10px 16px;border-top:1px solid var(--dsw-alias-border-l2,#eee);flex-wrap:wrap;justify-content:space-between;gap:6px;margin-top:0}.sm-confirmDialog .sm-nativeDialogButton{min-height:28px;padding:3px 14px;font-size:12px;line-height:20px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;cursor:pointer;background:transparent;color:var(--dsw-alias-label-primary);text-align:center}.sm-confirmDialog .sm-nativeDialogCancel:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.sm-confirmDialog .sm-nativeDialogConfirm{background:var(--dsw-alias-accent-primary,#356ae6);color:#fff;border-color:var(--dsw-alias-accent-primary,#356ae6)}.sm-confirmDialog .sm-nativeDialogConfirm:hover:not(:disabled){filter:brightness(.94)}@keyframes sm-confirmPop{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.sm-confirmDialog.sm-nativeDialog{padding:0;width:auto;max-width:none}.sm-panelDialog .sm-rowTitle>span:first-child{display:block;min-width:0;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;flex:1 1 auto;width:auto;text-align:left!important;direction:ltr!important;unicode-bidi:plaintext}.sm-panelDialog .sm-rowMeta{display:none}.sm-panelDialog .sm-rowActions{display:flex;gap:2px;flex:none;justify-content:flex-end}.sm-panelDialog .sm-rowActions .sm-rowBtn{min-height:22px;padding:0 7px;font-size:11px;line-height:18px;border-radius:6px;border:1px solid transparent;background:transparent;color:var(--dsw-alias-label-secondary);cursor:pointer;white-space:nowrap}.sm-rowBtn.sm-markIcon{padding:0 6px;font-size:13px;line-height:18px}.sm-panelDialog .sm-rowActions .sm-rowBtn:hover{background:var(--dsw-alias-fill-l2);color:var(--dsw-alias-label-primary)}.sm-panelDialog .sm-rowActions .sm-rowBtnDanger{color:var(--dsw-alias-state-error-primary)}.sm-panelDialog .sm-filter{flex:none;padding:6px 12px 4px;gap:4px;display:flex;flex-wrap:wrap}.sm-panelDialog .sm-filterBtn{min-height:24px;padding:2px 10px;font-size:11px;line-height:16px;border-radius:4px;border:1px solid var(--dsw-alias-border-l2);background:transparent;color:var(--dsw-alias-label-secondary);cursor:pointer}.sm-panelDialog .sm-filterBtn.sm-on{background:var(--dsw-alias-fill-l2);color:var(--dsw-alias-label-primary)}.sm-panelDialog .sm-badge{font-size:10px;line-height:14px;padding:0 5px;border-radius:6px;flex:none}.sm-panelDialog .sm-error{padding:6px 10px;margin:0;font-size:12px;line-height:16px}.sm-panelDialog .sm-nativeDialogButton{min-height:28px;padding:3px 12px;font-size:12px;line-height:18px;border:1px solid var(--dsw-alias-border-l2);border-radius:6px;background:transparent;color:var(--dsw-alias-label-primary);cursor:pointer}.sm-panelDialog .sm-nativeDialogCancel{background:transparent}.sm-panelDialog .sm-nativeDialogGhost{background:transparent;border-color:var(--dsw-alias-border-l2)}.sm-panelDialog .sm-nativeDialogConfirm{background:var(--dsw-alias-accent-primary,#356ae6);color:#fff;border-color:var(--dsw-alias-accent-primary,#356ae6)}.sm-nativeDialogDanger{background:var(--dsw-alias-state-error-primary,#d92d20);color:#fff;border-color:var(--dsw-alias-state-error-primary,#d92d20)}.sm-nativeDialogDanger:hover:not(:disabled){filter:brightness(.92)}.sm-confirmDialog .sm-nativeDialogDanger,.sm-migrateDialog .sm-nativeDialogDanger,.sm-bulkDialog .sm-nativeDialogDanger{background:var(--dsw-alias-state-error-primary,#d92d20);color:#fff;border-color:var(--dsw-alias-state-error-primary,#d92d20)}.sm-confirmDialog .sm-nativeDialogDanger:hover:not(:disabled),.sm-migrateDialog .sm-nativeDialogDanger:hover:not(:disabled),.sm-bulkDialog .sm-nativeDialogDanger:hover:not(:disabled){filter:brightness(.92)}.sm-panelDialog .sm-empty{padding:18px 0;font-size:12px;color:var(--dsw-alias-label-tertiary);text-align:center}.sm-panelDialog .sm-footError{font-size:11px;color:var(--dsw-alias-state-error-primary);margin-right:auto;line-height:20px}.sm-panelDialog .sm-moveLabel{font-size:12px;line-height:18px;color:var(--dsw-alias-label-secondary)}.sm-migrateDialog .sm-nativeDialogFooter{flex-wrap:wrap;justify-content:space-between;gap:6px;margin-top:0}.sm-migrateDialog .sm-migrateChip{cursor:pointer;pointer-events:auto;position:relative;z-index:1}.sm-migrateDialog .sm-migrateChip[disabled]{opacity:.5;cursor:not-allowed}.sm-migrateDialog.sm-nativeDialogLayer{position:fixed;left:50vw;top:auto;bottom:48px;transform:translateX(-50%);width:min(560px,calc(100vw - 32px));max-height:none;display:block;align-items:initial;justify-content:initial;box-sizing:border-box;background:transparent;border:0;box-shadow:none;padding:0;inset:auto;z-index:10001}.sm-migrateDialog.sm-nativeDialogLayer .sm-nativeDialogBackdrop{display:none}.sm-migrateDialog.sm-nativeDialogLayer .sm-nativeDialog{position:relative;left:auto;top:auto;transform:none;width:360px;max-width:calc(100vw - 32px);max-height:min(70vh,520px);box-sizing:border-box;background-color:#ffffff;background-color:var(--dsw-alias-surface-l1,#fff);color:var(--dsw-alias-label-primary,#111);border:1px solid #d4d4d8;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:12px;box-shadow:0 16px 48px rgba(0,0,0,.45);overflow:hidden;padding:0;display:flex;flex-direction:column;gap:0;opacity:1}.sm-migrateDialog{position:fixed;left:50vw;top:auto;bottom:48px;transform:translateX(-50%);width:min(560px,calc(100vw - 32px));max-height:min(70vh,520px);box-sizing:border-box;display:flex;flex-direction:column;gap:0;background-color:#ffffff;background-color:var(--dsw-alias-surface-l1,#fff);color:var(--dsw-alias-label-primary,#111);border:1px solid #d4d4d8;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:12px;box-shadow:0 16px 48px rgba(0,0,0,.45);overflow:hidden;opacity:1;z-index:10001;backdrop-filter:none;-webkit-backdrop-filter:none}.sm-migrateDialog .sm-nativeDialogHeader{padding:12px 18px;border-bottom:1px solid #eee;border-bottom:1px solid var(--dsw-alias-border-l2,#eee);flex:none;background-color:#fff;background-color:var(--dsw-alias-surface-l1,#fff)}.sm-migrateDialog .sm-nativeDialogTitle{margin:0;font-size:14px;line-height:20px;font-weight:600;color:#111;color:var(--dsw-alias-label-primary,#111);text-align:center;width:100%}.sm-migrateDialog .sm-migratePanel{padding:12px 18px;display:flex;flex-direction:column;gap:14px;background-color:#fff;background-color:var(--dsw-alias-surface-l1,#fff)}.sm-migrateDialog .sm-nativeDialogBody{padding:0;background-color:#fff;background-color:var(--dsw-alias-surface-l1,#fff)}.sm-migrateDialog .sm-nativeDialogFooter{padding:10px 16px;border-top:1px solid var(--dsw-alias-border-l2,#eee);flex:none;flex-wrap:wrap;justify-content:space-between;gap:6px;margin-top:0;gap:8px;background-color:#fff;background-color:var(--dsw-alias-surface-l1,#fff)}.sm-migrateDialog .sm-migrateRow>label{color:#444;color:var(--dsw-alias-label-secondary,#444)}.sm-migrateDialog .sm-migrateChip{padding:6px 12px;border-radius:999px;border:1px solid #d4d4d8;border:1px solid var(--dsw-alias-border-l2,#ddd);background-color:#f5f5f5;background-color:var(--dsw-alias-fill-l2,#f5f5f5);color:#111;color:var(--dsw-alias-label-primary,#111);font-size:13px;line-height:18px;cursor:pointer;pointer-events:auto;position:relative;z-index:1;white-space:nowrap}.sm-migrateDialog .sm-migrateChip:hover:not(:disabled){background-color:#e8e8e8;background-color:var(--dsw-alias-interactive-bg-hover,#e8e8e8)}.sm-migrateDialog .sm-migrateChipOn{background-color:#356ae6;background-color:var(--dsw-alias-accent-primary,#356ae6);color:#fff;border-color:#356ae6;border-color:var(--dsw-alias-accent-primary,#356ae6)}.sm-migrateDialog .sm-migrateChip.sm-migrateChipOn:hover:not(:disabled){background-color:#4576f0;background-color:var(--dsw-alias-accent-primary-hover,#4576f0);color:#fff;border-color:#4576f0;border-color:var(--dsw-alias-accent-primary-hover,#4576f0);filter:none}.sm-migrateDialog .sm-migrateChipOn:hover:not(:disabled){filter:brightness(.92)}.sm-migrateDialog .sm-migrateChip[disabled]{opacity:.5;cursor:not-allowed}.sm-migrateDialog .sm-migrateEmpty{color:#888;color:var(--dsw-alias-label-tertiary,#888)}.sm-migrateDialog .sm-migratePreview{padding:10px 12px;border:1px solid #d4d4d8;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:8px;background-color:#f5f5f5;background-color:var(--dsw-alias-fill-l2,#f5f5f5);color:#111;color:var(--dsw-alias-label-primary,#111);font-size:13px;line-height:18px}.sm-migrateDialog .sm-migrateWarn{padding:10px 12px;border:1px solid rgba(217,119,6,.25);border-radius:8px;background-color:rgba(217,119,6,.08);color:#444;color:var(--dsw-alias-label-secondary,#444);font-size:13px;line-height:18px}.sm-migrateDialog .sm-nativeDialogButton{min-height:28px;padding:3px 14px;font-size:12px;line-height:20px;border:1px solid #d4d4d8;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:8px;cursor:pointer;background-color:#fff;background-color:var(--dsw-alias-fill-l2,#fff);color:#111;color:var(--dsw-alias-label-primary,#111);text-align:center}.sm-migrateDialog .sm-nativeDialogButton:hover:not(:disabled){background-color:#e8e8e8;background-color:var(--dsw-alias-interactive-bg-hover,#e8e8e8)}.sm-migrateDialog .sm-nativeDialogConfirm{background-color:#356ae6;background-color:var(--dsw-alias-accent-primary,#356ae6);color:#fff;border-color:#356ae6;border-color:var(--dsw-alias-accent-primary,#356ae6)}.sm-migrateDialog .sm-nativeDialogConfirm:hover:not(:disabled){filter:brightness(.94)}",
|
|
475
|
-
".sm-panelDialog .sm-nativeDialogHeader{display:flex;align-items:center;gap:8px}.sm-panelHeaderClose{min-height:26px;padding:2px 9px;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:7px;background:transparent;color:var(--dsw-alias-label-secondary,#555);cursor:pointer;font-size:12px;line-height:18px;flex:none}.sm-panelHeaderGithub{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;border-radius:6px;color:var(--dsw-alias-label-secondary,#555);text-decoration:none;flex:none;transition:background .15s,color .15s;cursor:pointer}.sm-panelHeaderGithub:hover{background:var(--dsw-alias-interactive-bg-hover,#eee);color:var(--dsw-alias-label-primary,#111)}.sm-panelHeaderGithub svg{display:block;width:16px;height:16px;fill:currentColor}.sm-panelHeaderClose:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,#eee);color:var(--dsw-alias-label-primary,#111)}.sm-panelHeaderClose:disabled{opacity:.5;cursor:not-allowed}.sm-panelHeaderSelect{min-height:26px;padding:2px 9px;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:7px;background:transparent;color:var(--dsw-alias-label-secondary,#555);cursor:pointer;font-size:12px;line-height:18px;display:inline-flex;align-items:center;gap:4px}.sm-panelHeaderSelect:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,#eee);color:var(--dsw-alias-label-primary,#111)}.sm-panelHeaderSelect:disabled{opacity:.5;cursor:not-allowed}.sm-panelHeaderSelect.sm-on{background:var(--dsw-alias-accent-primary-bg,rgba(53,106,230,.12));border-color:var(--dsw-alias-accent-primary,#356ae6);color:var(--dsw-alias-accent-primary,#356ae6)}.sm-migrateCurrent{padding:8px 10px;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:8px;background:var(--dsw-alias-fill-l2,#f5f5f5);font-size:13px;line-height:18px;color:var(--dsw-alias-label-primary,#111)}.sm-migrateConfirmLayer.sm-confirmDialog.sm-nativeDialogLayer{width:360px;inset:calc(50vh - 90px) auto auto calc(50vw + 308px)}.sm-migrateConfirmLayer.sm-confirmDialog.sm-nativeDialogLayer .sm-migrateDialog{position:relative;left:auto;top:auto;bottom:auto;transform:none;width:100%;max-width:none;max-height:min(70vh,520px);z-index:auto}.sm-migrateConfirmLayer .sm-migratePanel{min-width:0}.sm-migrateConfirmLayer .sm-nativeDialogButton.sm-nativeDialogConfirm:hover:not(:disabled){background-color:#4576f0;background-color:var(--dsw-alias-accent-primary-hover,#4576f0);color:#fff;border-color:#4576f0;border-color:var(--dsw-alias-accent-primary-hover,#4576f0);filter:none}",
|
|
555
|
+
".sm-moveItemMeta{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:16px}.sm-panelModal{width:760px;max-width:92vw}.sm-panelModal .sm-rowActions{flex-wrap:wrap;justify-content:flex-end}.sm-headerMenu{position:absolute;right:0;top:100%;margin-top:4px;z-index:50;display:flex;flex-direction:column;min-width:140px;padding:4px;background:var(--dsw-alias-surface-l1,#fff);border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:8px;box-shadow:0 4px 16px rgba(0,0,0,.15)}.sm-headerMenuItem{display:flex;align-items:center;gap:8px;width:100%;text-align:left;background:0 0;border:0;border-radius:6px;color:var(--dsw-alias-label-primary,#111);cursor:pointer;padding:6px 10px;font-size:13px;line-height:18px;white-space:nowrap}.sm-headerMenuItem:hover{background:var(--dsw-alias-interactive-bg-hover)}.sm-headerMenuItem .sm-headerBtnIcon{width:20px;min-width:20px;text-align:center;flex-shrink:0}.sm-headerMenuItemDanger{color:var(--dsw-alias-state-error-primary,#d92d20)}.sm-headerMenuItemDanger:hover{background:rgba(217,45,32,.08)}.sm-headerBtn{display:inline-flex;align-items:center;justify-content:center;gap:6px;min-height:32px;height:32px;box-sizing:border-box;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-surface-l1,#fff);border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:8px;cursor:pointer;padding:0 10px;font-size:13px;line-height:1;white-space:nowrap;transition:background .15s,color .15s,border-color .15s;flex-shrink:0}.sm-headerBtn:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-border-l1)}.sm-headerBtn:focus-visible{outline:2px solid var(--dsw-alias-accent-primary);outline-offset:1px}.sm-headerBtn svg{width:16px;height:16px;display:block;margin:auto;flex-shrink:0}.sm-migratePanel{display:flex;flex-direction:column;gap:14px;min-width:480px}.sm-migrateRow{display:flex;flex-direction:column;gap:8px}.sm-migrateRow>label{color:var(--dsw-alias-label-secondary);font-size:12px;line-height:16px;font-weight:500}.sm-migrateChips{display:flex;flex-wrap:wrap;gap:6px}.sm-migrateChip{padding:6px 12px;border-radius:999px;border:1px solid var(--dsw-alias-border-l2);background:transparent;cursor:pointer;font-size:13px;line-height:18px;color:var(--dsw-alias-label-primary);white-space:nowrap}.sm-migrateChip:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.sm-migrateChip:disabled{opacity:.5;cursor:not-allowed}.sm-migrateChipOn{background:var(--dsw-alias-accent-primary);color:#fff;border-color:var(--dsw-alias-accent-primary)}.sm-migrateEmpty{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}.sm-migratePreview{padding:10px 12px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:var(--dsw-alias-fill-l2);color:var(--dsw-alias-label-primary);font-size:13px;line-height:18px}.sm-migrateWarn{padding:10px 12px;border:1px solid rgba(217,119,6,.25);border-radius:8px;background:rgba(217,119,6,.08);color:var(--dsw-alias-label-secondary);font-size:13px;line-height:18px}.sm-migrateList{max-height:200px;overflow:auto;border:1px solid var(--dsw-alias-border-l2);border-radius:8px}.sm-headerBtnDanger{background:var(--dsw-alias-surface-l1,#fff);color:var(--dsw-alias-state-error-primary,#d92d20);border-color:var(--dsw-alias-state-error-primary,#d92d20);font-weight:500}.sm-headerBtnDanger:hover:not(:disabled){background:var(--dsw-alias-state-error-primary,#d92d20)!important;color:#fff!important;border-color:var(--dsw-alias-state-error-primary,#d92d20)!important}.sm-header{display:inline-flex;align-items:center;gap:6px;flex-wrap:nowrap}.sm-headerSecondaryActions{display:inline-flex;align-items:center;gap:6px;flex-wrap:nowrap}.sm-headerCompactMenu{display:none;position:relative}.sm-headerCompactMenuBtn{width:32px;min-width:32px;height:32px;padding:0;justify-content:center;font-size:16px;line-height:1}.sm-headerBtnIcon{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;font-size:14px;line-height:1;vertical-align:middle;flex-shrink:0}.sm-headerBtn.sm-markIcon{width:32px;min-width:32px;height:32px;padding:0;justify-content:center}.sm-headerBtn.sm-markIcon .sm-headerBtnIcon{width:16px;height:16px;font-size:15px;line-height:1}.sm-headerCompactMenuBtn .sm-headerBtnIcon{width:16px;height:16px;font-size:16px;line-height:1}.sm-annotationToggleOpen{position:relative;z-index:100004}.sm-headerBtnActive{background:var(--dsw-alias-fill-l3);color:var(--dsw-alias-label-primary)}@container (max-width:720px){.sm-headerBtn{width:32px;min-width:32px;height:32px;padding:0;justify-content:center}.sm-headerBtnLabel,.sm-priorityText,.sm-priorityBadge{display:none}.sm-headerBtn.sm-headerBtn-withBadge{width:auto;min-width:32px;padding:0 6px}}@container (max-width:520px){.sm-headerSecondaryActions,.sm-headerSecondaryAction{display:none!important}.sm-headerCompactMenu{display:inline-flex}}",
|
|
556
|
+
".sm-panelDialog{position:fixed;left:50%;top:50%;transform:translate(-50%,-50%);width:600px;max-width:calc(100vw - 32px);max-height:560px;height:auto;box-sizing:border-box;display:flex;flex-direction:column;gap:0;background:var(--dsw-alias-surface-l1,#fff);color:var(--dsw-alias-label-primary,#111);border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:12px;box-shadow:0 16px 48px rgba(0,0,0,.25);overflow:hidden;z-index:9999;opacity:1}.sm-panelDialog .sm-nativeDialogHeader{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:10px 16px;border-bottom:1px solid var(--dsw-alias-border-l2,#eee);flex:none;position:relative;min-height:46px;box-sizing:border-box}.sm-panelDialog .sm-nativeDialogTitle{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);margin:0;font-size:14px;line-height:20px;font-weight:600;min-width:0;max-width:calc(100% - 140px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:center;pointer-events:auto;z-index:0}.sm-panelDialog .sm-nativeDialogHeaderActions{display:flex;align-items:center;gap:6px;flex:none;position:relative;z-index:1;margin-left:auto}.sm-nativeDialogFooter,.sm-bulkDialog .sm-nativeDialogFooter,.sm-confirmDialog .sm-nativeDialogFooter,.sm-migrateDialog .sm-nativeDialogFooter{display:flex;padding:10px 16px;border-top:1px solid var(--dsw-alias-border-l2,#eee);flex:none;flex-wrap:wrap;justify-content:space-between;gap:6px;margin-top:0}.sm-panelDialog .sm-panel{display:flex;flex-direction:column;gap:6px;min-height:0;flex:1 1 auto;overflow:auto;padding:8px 12px}.sm-panelDialog .sm-list{display:flex;flex-direction:column;gap:2px;flex:1 1 auto;min-height:0;overflow:auto}.sm-panelDialog .sm-row{display:flex;align-items:center;gap:8px;padding:6px 10px;min-height:36px;border:1px solid transparent;border-radius:8px;background:transparent;flex-shrink:0}.sm-panelDialog .sm-row:hover{background:var(--dsw-alias-interactive-bg-hover)}.sm-panelDialog .sm-rowCurrent{background:var(--dsw-alias-fill-l2);border-color:var(--dsw-alias-accent-primary,#356ae6)}.sm-panelDialog .sm-rowMain{display:flex;align-items:stretch!important;gap:8px;min-width:0;flex:1 1 auto;overflow:visible;text-align:left!important}.sm-panelDialog .sm-rowTitle{min-width:0;flex:1 1 0%;width:100%;align-self:stretch;display:flex;align-items:center;justify-content:flex-start;gap:6px;font-size:12px;line-height:16px;overflow:hidden;text-align:left!important;direction:ltr!important}.sm-confirmDialog{z-index:10000}.sm-confirmDialog.sm-nativeDialogLayer{position:fixed;left:calc(50vw + 184px);top:calc(50vh - 90px);width:360px;max-width:calc(100vw - 32px);max-height:none;display:block;align-items:initial;justify-content:initial;box-sizing:border-box;background:transparent;border:0;box-shadow:none;padding:0;inset:calc(50vh - 90px) auto auto calc(50vw + 308px)}.sm-confirmDialog.sm-nativeDialogLayer .sm-nativeDialogBackdrop{display:none}.sm-confirmDialog.sm-nativeDialogLayer .sm-nativeDialog{position:relative;left:auto;top:auto;transform:none;width:auto;box-sizing:border-box;background:var(--dsw-alias-surface-l1,#fff);color:var(--dsw-alias-label-primary,#111);border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:12px;box-shadow:0 16px 48px rgba(0,0,0,.25);padding:0;overflow:hidden;animation:sm-confirmPop .14s ease-out}.sm-confirmDialog .sm-nativeDialogHeader{position:relative;padding:12px 16px;border-bottom:1px solid var(--dsw-alias-border-l2,#eee);display:flex;align-items:center;justify-content:center;min-height:44px;box-sizing:border-box}.sm-confirmDialog .sm-nativeDialogTitle{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);margin:0;font-size:14px;line-height:20px;font-weight:600;text-align:center;width:auto;max-width:calc(100% - 32px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sm-confirmDialog .sm-nativeDialogBody{padding:10px 16px;display:flex;flex-direction:column;gap:8px;min-height:0}.sm-confirmDialog .sm-nativeDialogDescription{font-size:12px;line-height:18px;color:var(--dsw-alias-label-secondary);white-space:pre-wrap}.sm-confirmDialog .sm-warn{padding:6px 10px;font-size:12px;line-height:16px;margin-top:0}.sm-confirmDialog .sm-nativeDialogFooter{padding:10px 16px;border-top:1px solid var(--dsw-alias-border-l2,#eee);flex-wrap:wrap;justify-content:space-between;gap:6px;margin-top:0}.sm-confirmDialog .sm-nativeDialogButton{min-height:28px;padding:3px 14px;font-size:12px;line-height:20px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;cursor:pointer;background:transparent;color:var(--dsw-alias-label-primary);text-align:center}.sm-confirmDialog .sm-nativeDialogCancel:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.sm-confirmDialog .sm-nativeDialogConfirm{background:var(--dsw-alias-accent-primary,#356ae6);color:#fff;border-color:var(--dsw-alias-accent-primary,#356ae6)}.sm-confirmDialog .sm-nativeDialogConfirm:hover:not(:disabled){filter:brightness(.94)}@keyframes sm-confirmPop{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.sm-confirmDialog.sm-nativeDialog{padding:0;width:auto;max-width:none}.sm-panelDialog .sm-rowTitle>span:first-child{display:block;min-width:0;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;flex:1 1 auto;width:auto;text-align:left!important;direction:ltr!important;unicode-bidi:plaintext}.sm-panelDialog .sm-rowMeta{display:none}.sm-panelDialog .sm-rowActions{display:flex;gap:2px;flex:none;justify-content:flex-end}.sm-panelDialog .sm-rowActions .sm-rowBtn{min-height:22px;padding:0 7px;font-size:11px;line-height:18px;border-radius:6px;border:1px solid transparent;background:transparent;color:var(--dsw-alias-label-secondary);cursor:pointer;white-space:nowrap}.sm-rowBtn.sm-markIcon{padding:0 6px;font-size:13px;line-height:18px}.sm-panelDialog .sm-rowActions .sm-rowBtn:hover{background:var(--dsw-alias-fill-l2);color:var(--dsw-alias-label-primary)}.sm-panelDialog .sm-rowActions .sm-rowBtnDanger{color:var(--dsw-alias-state-error-primary)}.sm-panelDialog .sm-filter{flex:none;padding:6px 12px 4px;gap:4px;display:flex;flex-wrap:wrap}.sm-panelDialog .sm-filterBtn{min-height:24px;padding:2px 10px;font-size:11px;line-height:16px;border-radius:4px;border:1px solid var(--dsw-alias-border-l2);background:transparent;color:var(--dsw-alias-label-secondary);cursor:pointer}.sm-panelDialog .sm-filterBtn.sm-on{background:var(--dsw-alias-fill-l2);color:var(--dsw-alias-label-primary)}.sm-panelDialog .sm-badge{font-size:10px;line-height:14px;padding:0 5px;border-radius:6px;flex:none}.sm-panelDialog .sm-error{padding:6px 10px;margin:0;font-size:12px;line-height:16px}.sm-panelDialog .sm-nativeDialogButton{min-height:28px;padding:3px 12px;font-size:12px;line-height:18px;border:1px solid var(--dsw-alias-border-l2);border-radius:6px;background:transparent;color:var(--dsw-alias-label-primary);cursor:pointer}.sm-panelDialog .sm-nativeDialogCancel{background:transparent}.sm-panelDialog .sm-nativeDialogGhost{background:transparent;border-color:var(--dsw-alias-border-l2)}.sm-panelDialog .sm-nativeDialogConfirm{background:var(--dsw-alias-accent-primary,#356ae6);color:#fff;border-color:var(--dsw-alias-accent-primary,#356ae6)}.sm-nativeDialogDanger{background:var(--dsw-alias-state-error-primary,#d92d20);color:#fff;border-color:var(--dsw-alias-state-error-primary,#d92d20)}.sm-nativeDialogDanger:hover:not(:disabled){filter:brightness(.92)}.sm-confirmDialog .sm-nativeDialogDanger,.sm-migrateDialog .sm-nativeDialogDanger,.sm-bulkDialog .sm-nativeDialogDanger{background:var(--dsw-alias-state-error-primary,#d92d20);color:#fff;border-color:var(--dsw-alias-state-error-primary,#d92d20)}.sm-confirmDialog .sm-nativeDialogDanger:hover:not(:disabled),.sm-migrateDialog .sm-nativeDialogDanger:hover:not(:disabled),.sm-bulkDialog .sm-nativeDialogDanger:hover:not(:disabled){filter:brightness(.92)}.sm-panelDialog .sm-empty{padding:18px 0;font-size:12px;color:var(--dsw-alias-label-tertiary);text-align:center}.sm-panelDialog .sm-footError{font-size:11px;color:var(--dsw-alias-state-error-primary);margin-right:auto;line-height:20px}.sm-panelDialog .sm-moveLabel{font-size:12px;line-height:18px;color:var(--dsw-alias-label-secondary)}.sm-migrateDialog .sm-nativeDialogFooter{flex-wrap:wrap;justify-content:space-between;gap:6px;margin-top:0}.sm-migrateDialog .sm-migrateChip{cursor:pointer;pointer-events:auto;position:relative;z-index:1}.sm-migrateDialog .sm-migrateChip[disabled]{opacity:.5;cursor:not-allowed}.sm-migrateDialog.sm-nativeDialogLayer{position:fixed;left:50vw;top:auto;bottom:48px;transform:translateX(-50%);width:min(560px,calc(100vw - 32px));max-height:none;display:block;align-items:initial;justify-content:initial;box-sizing:border-box;background:transparent;border:0;box-shadow:none;padding:0;inset:auto;z-index:10001}.sm-migrateDialog.sm-nativeDialogLayer .sm-nativeDialogBackdrop{display:none}.sm-migrateDialog.sm-nativeDialogLayer .sm-nativeDialog{position:relative;left:auto;top:auto;transform:none;width:360px;max-width:calc(100vw - 32px);max-height:min(70vh,520px);box-sizing:border-box;background-color:#ffffff;background-color:var(--dsw-alias-surface-l1,#fff);color:var(--dsw-alias-label-primary,#111);border:1px solid #d4d4d8;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:12px;box-shadow:0 16px 48px rgba(0,0,0,.45);overflow:hidden;padding:0;display:flex;flex-direction:column;gap:0;opacity:1}.sm-migrateDialog{position:fixed;left:50vw;top:auto;bottom:48px;transform:translateX(-50%);width:min(560px,calc(100vw - 32px));max-height:min(70vh,520px);box-sizing:border-box;display:flex;flex-direction:column;gap:0;background-color:#ffffff;background-color:var(--dsw-alias-surface-l1,#fff);color:var(--dsw-alias-label-primary,#111);border:1px solid #d4d4d8;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:12px;box-shadow:0 16px 48px rgba(0,0,0,.45);overflow:hidden;opacity:1;z-index:10001;backdrop-filter:none;-webkit-backdrop-filter:none}.sm-migrateDialog .sm-nativeDialogHeader{padding:12px 18px;border-bottom:1px solid #eee;border-bottom:1px solid var(--dsw-alias-border-l2,#eee);flex:none;background-color:#fff;background-color:var(--dsw-alias-surface-l1,#fff);position:relative;display:flex;align-items:center;justify-content:center;min-height:44px;box-sizing:border-box}.sm-migrateDialog .sm-nativeDialogTitle{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);margin:0;font-size:14px;line-height:20px;font-weight:600;color:#111;color:var(--dsw-alias-label-primary,#111);text-align:center;width:auto;max-width:calc(100% - 36px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sm-migrateDialog .sm-migratePanel{padding:12px 18px;display:flex;flex-direction:column;gap:14px;background-color:#fff;background-color:var(--dsw-alias-surface-l1,#fff)}.sm-migrateDialog .sm-nativeDialogBody{padding:0;background-color:#fff;background-color:var(--dsw-alias-surface-l1,#fff)}.sm-migrateDialog .sm-nativeDialogFooter{padding:10px 16px;border-top:1px solid var(--dsw-alias-border-l2,#eee);flex:none;flex-wrap:wrap;justify-content:space-between;gap:6px;margin-top:0;gap:8px;background-color:#fff;background-color:var(--dsw-alias-surface-l1,#fff)}.sm-migrateDialog .sm-migrateRow>label{color:#444;color:var(--dsw-alias-label-secondary,#444)}.sm-migrateDialog .sm-migrateChip{padding:6px 12px;border-radius:999px;border:1px solid #d4d4d8;border:1px solid var(--dsw-alias-border-l2,#ddd);background-color:#f5f5f5;background-color:var(--dsw-alias-fill-l2,#f5f5f5);color:#111;color:var(--dsw-alias-label-primary,#111);font-size:13px;line-height:18px;cursor:pointer;pointer-events:auto;position:relative;z-index:1;white-space:nowrap}.sm-migrateDialog .sm-migrateChip:hover:not(:disabled){background-color:#e8e8e8;background-color:var(--dsw-alias-interactive-bg-hover,#e8e8e8)}.sm-migrateDialog .sm-migrateChipOn{background-color:#356ae6;background-color:var(--dsw-alias-accent-primary,#356ae6);color:#fff;border-color:#356ae6;border-color:var(--dsw-alias-accent-primary,#356ae6)}.sm-migrateDialog .sm-migrateChip.sm-migrateChipOn:hover:not(:disabled){background-color:#4576f0;background-color:var(--dsw-alias-accent-primary-hover,#4576f0);color:#fff;border-color:#4576f0;border-color:var(--dsw-alias-accent-primary-hover,#4576f0);filter:none}.sm-migrateDialog .sm-migrateChipOn:hover:not(:disabled){filter:brightness(.92)}.sm-migrateDialog .sm-migrateChip[disabled]{opacity:.5;cursor:not-allowed}.sm-migrateDialog .sm-migrateEmpty{color:#888;color:var(--dsw-alias-label-tertiary,#888)}.sm-migrateDialog .sm-migratePreview{padding:10px 12px;border:1px solid #d4d4d8;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:8px;background-color:#f5f5f5;background-color:var(--dsw-alias-fill-l2,#f5f5f5);color:#111;color:var(--dsw-alias-label-primary,#111);font-size:13px;line-height:18px}.sm-migrateDialog .sm-migrateWarn{padding:10px 12px;border:1px solid rgba(217,119,6,.25);border-radius:8px;background-color:rgba(217,119,6,.08);color:#444;color:var(--dsw-alias-label-secondary,#444);font-size:13px;line-height:18px}.sm-migrateDialog .sm-nativeDialogButton{min-height:28px;padding:3px 14px;font-size:12px;line-height:20px;border:1px solid #d4d4d8;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:8px;cursor:pointer;background-color:#fff;background-color:var(--dsw-alias-fill-l2,#fff);color:#111;color:var(--dsw-alias-label-primary,#111);text-align:center}.sm-migrateDialog .sm-nativeDialogButton:hover:not(:disabled){background-color:#e8e8e8;background-color:var(--dsw-alias-interactive-bg-hover,#e8e8e8)}.sm-migrateDialog .sm-nativeDialogConfirm{background-color:#356ae6;background-color:var(--dsw-alias-accent-primary,#356ae6);color:#fff;border-color:#356ae6;border-color:var(--dsw-alias-accent-primary,#356ae6)}.sm-migrateDialog .sm-nativeDialogConfirm:hover:not(:disabled){filter:brightness(.94)}",
|
|
557
|
+
".sm-panelHeaderClose{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;min-height:26px;padding:0;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:7px;background:transparent;color:var(--dsw-alias-label-secondary,#555);cursor:pointer;flex:none;box-sizing:border-box;outline:none}.sm-panelHeaderClose:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,#eee);color:var(--dsw-alias-label-primary,#111)}.sm-panelHeaderClose svg{display:block;width:14px;height:14px;margin:auto}.sm-panelHeaderGithub{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;border-radius:6px;color:var(--dsw-alias-label-secondary,#555);text-decoration:none;flex:none;transition:background .15s,color .15s;cursor:pointer}.sm-panelHeaderGithub:hover{background:var(--dsw-alias-interactive-bg-hover,#eee);color:var(--dsw-alias-label-primary,#111)}.sm-panelHeaderGithub svg{display:block;width:16px;height:16px;fill:currentColor}.sm-panelHeaderLeft{display:flex;align-items:center;gap:4px;flex:none;position:relative;z-index:1}.sm-panelHeaderWhale{display:inline-flex;align-items:center;justify-content:center;position:relative;width:26px;height:26px;border-radius:6px;color:var(--dsw-alias-label-secondary,#555);text-decoration:none;flex:none;transition:background .15s,color .15s;cursor:pointer}.sm-panelHeaderWhale:hover{background:var(--dsw-alias-interactive-bg-hover,#eee);color:var(--dsw-alias-label-primary,#111)}.sm-panelHeaderWhale svg{display:block;width:16px;height:16px;margin:auto}.sm-panelHeaderWhale .sm-updateDot{position:absolute;top:2px;right:2px;width:7px;height:7px;border-radius:50%;background:#e53e3e;border:1.5px solid var(--dsw-alias-surface-l1,#fff)}.sm-panelHeaderWhale .sm-updateSpinner{position:absolute;inset:2px;border:2px solid transparent;border-top-color:var(--dsw-alias-accent-primary,#356ae6);border-radius:50%;animation:sm-spin .8s linear infinite}@keyframes sm-spin{to{transform:rotate(360deg)}}.sm-updateDialogLayer{display:flex!important;align-items:center!important;justify-content:center!important;position:fixed;inset:0;padding:16px;box-sizing:border-box;background:transparent;border:0;box-shadow:none;z-index:10010;pointer-events:none}.sm-updateDialogLayer .sm-nativeDialog{position:relative;width:380px;max-width:calc(100vw - 32px);box-sizing:border-box;background:var(--dsw-alias-surface-l1,#fff);color:var(--dsw-alias-label-primary,#111);border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:12px;box-shadow:0 16px 48px rgba(0,0,0,.25);overflow:hidden;animation:sm-confirmPop .14s ease-out;pointer-events:auto}.sm-updateDialog .sm-nativeDialogHeader{position:relative;display:flex;align-items:center;justify-content:space-between;gap:8px;padding:12px 16px;border-bottom:1px solid var(--dsw-alias-border-l2,#eee);flex:none;min-height:46px;box-sizing:border-box}.sm-updateDialog .sm-nativeDialogTitle{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);margin:0;font-size:15px;line-height:20px;font-weight:600;text-align:center;width:auto;max-width:calc(100% - 80px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;z-index:0}.sm-updateDialog .sm-nativeDialogHeader .sm-panelHeaderClose{position:relative;z-index:1;margin-left:auto}.sm-updateDialog .sm-nativeDialogBody{padding:14px 16px;display:flex;flex-direction:column;gap:10px;font-size:13px;line-height:20px;color:var(--dsw-alias-label-primary,#111)}.sm-updateDialog .sm-nativeDialogFooter{display:flex;padding:10px 16px;border-top:1px solid var(--dsw-alias-border-l2,#eee);flex:none;flex-wrap:wrap;justify-content:space-between;gap:8px;margin-top:0}.sm-updateDialog .sm-nativeDialogFooter .sm-nativeDialogConfirm:only-child{margin-left:auto}.sm-updateDialog .sm-nativeDialogButton{min-height:28px;padding:3px 14px;font-size:12px;line-height:20px;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:8px;cursor:pointer;background:transparent;color:var(--dsw-alias-label-primary,#111);text-align:center}.sm-updateDialog .sm-nativeDialogButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.sm-updateDialog .sm-nativeDialogConfirm{background:var(--dsw-alias-accent-primary,#356ae6);color:#fff;border-color:var(--dsw-alias-accent-primary,#356ae6)}.sm-updateDialog .sm-nativeDialogConfirm:hover:not(:disabled){filter:brightness(.94)}.sm-updateVersionGrid{display:grid;grid-template-columns:auto 1fr;gap:6px 12px;padding:12px;background:var(--dsw-alias-fill-l2,#f5f5f5);border:1px solid var(--dsw-alias-border-l2,#eee);border-radius:8px;font-size:13px;line-height:20px}.sm-updateVersionLabel{color:var(--dsw-alias-label-secondary,#666);font-weight:500}.sm-updateVersionValue{color:var(--dsw-alias-label-primary,#111);font-family:monospace;font-size:13px}.sm-updateStatusBox{margin-top:10px;font-size:13px;line-height:20px;color:var(--dsw-alias-label-primary,#111)}.sm-updateStatusBox.sm-warn{color:#d97706;background:rgba(217,119,6,.08);padding:8px 10px;border-radius:6px;border:1px solid rgba(217,119,6,.2)}.sm-updateStatusBox.sm-error{color:#dc2626;background:rgba(220,38,38,.08);padding:8px 10px;border-radius:6px;border:1px solid rgba(220,38,38,.2)}.sm-updateStatusBox.sm-success{color:#16a34a;background:rgba(22,163,74,.08);padding:8px 10px;border-radius:6px;border:1px solid rgba(22,163,74,.2)}.sm-settingsCard{background:var(--dsw-alias-surface-l1,#fff);border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:12px;padding:16px 20px;font-size:13px;line-height:20px;color:var(--dsw-alias-label-primary,#111);box-sizing:border-box;width:100%}.sm-settingsHeader{display:flex;align-items:center;justify-content:space-between;margin-bottom:14px;padding-bottom:10px;border-bottom:1px solid var(--dsw-alias-border-l2,#eee)}.sm-settingsTitle{margin:0;font-size:16px;line-height:22px;font-weight:600;display:flex;align-items:center;gap:8px}.sm-settingsTag{font-size:12px;padding:2px 8px;border-radius:999px;background:var(--dsw-alias-fill-l2,#f0f0f0);color:var(--dsw-alias-label-secondary,#666);font-family:monospace}.sm-settingsSection{margin-top:14px;padding-top:12px;border-top:1px solid var(--dsw-alias-border-l2,#eee)}.sm-settingsSectionTitle{font-size:13px;font-weight:600;color:var(--dsw-alias-label-secondary,#666);margin-bottom:8px;text-transform:uppercase;letter-spacing:.5px}.sm-settingsRow{display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:32px}.sm-settingsActions{display:flex;align-items:center;gap:8px;margin-top:10px}.sm-settingsLink{color:var(--dsw-alias-accent-primary,#356ae6);text-decoration:none}.sm-settingsLink:hover{text-decoration:underline}.sm-settingsCheckbox{display:inline-flex;align-items:center;gap:6px;cursor:pointer}.sm-settingsSelect{min-height:28px;padding:3px 8px;font-size:12px;line-height:20px;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:6px;background:var(--dsw-alias-surface-l1,#fff);color:var(--dsw-alias-label-primary,#111);cursor:pointer;outline:none}.sm-panelHeaderClose:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,#eee);color:var(--dsw-alias-label-primary,#111)}.sm-panelHeaderClose:disabled{opacity:.5;cursor:not-allowed}.sm-panelHeaderSelect{min-height:26px;padding:2px 9px;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:7px;background:transparent;color:var(--dsw-alias-label-secondary,#555);cursor:pointer;font-size:12px;line-height:18px;display:inline-flex;align-items:center;gap:4px}.sm-panelHeaderSelect:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,#eee);color:var(--dsw-alias-label-primary,#111)}.sm-panelHeaderSelect:disabled{opacity:.5;cursor:not-allowed}.sm-panelHeaderSelect.sm-on{background:var(--dsw-alias-accent-primary-bg,rgba(53,106,230,.12));border-color:var(--dsw-alias-accent-primary,#356ae6);color:var(--dsw-alias-accent-primary,#356ae6)}.sm-migrateCurrent{padding:8px 10px;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:8px;background:var(--dsw-alias-fill-l2,#f5f5f5);font-size:13px;line-height:18px;color:var(--dsw-alias-label-primary,#111)}.sm-migrateConfirmLayer.sm-confirmDialog.sm-nativeDialogLayer{width:360px;inset:calc(50vh - 90px) auto auto calc(50vw + 308px)}.sm-migrateConfirmLayer.sm-confirmDialog.sm-nativeDialogLayer .sm-migrateDialog{position:relative;left:auto;top:auto;bottom:auto;transform:none;width:100%;max-width:none;max-height:min(70vh,520px);z-index:auto}.sm-migrateConfirmLayer .sm-migratePanel{min-width:0}.sm-migrateConfirmLayer .sm-nativeDialogButton.sm-nativeDialogConfirm:hover:not(:disabled){background-color:#4576f0;background-color:var(--dsw-alias-accent-primary-hover,#4576f0);color:#fff;border-color:#4576f0;border-color:var(--dsw-alias-accent-primary-hover,#4576f0);filter:none}.sm-settingsSectionHeader{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:8px}.sm-settingsSectionHeader .sm-settingsSectionTitle{margin-bottom:0}.sm-settingsVersionActions{display:flex;align-items:center;gap:8px}.sm-settingsCheckBtn{min-height:26px;padding:2px 12px;font-size:12px;line-height:18px;border-radius:6px;border:1px solid var(--dsw-alias-border-l2,#ddd);background:transparent;color:var(--dsw-alias-label-primary,#111);cursor:pointer;white-space:nowrap}.sm-settingsCheckBtn:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.sm-settingsRowInline{justify-content:flex-start;flex-wrap:wrap;gap:8px;align-items:center}.sm-settingsBadgeLink{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:6px;border:1px solid var(--dsw-alias-border-l2,#ddd);background:var(--dsw-alias-fill-l2,#f5f5f5);color:var(--dsw-alias-label-secondary,#555);font-size:12px;line-height:18px;text-decoration:none;cursor:pointer;transition:all .15s}.sm-settingsBadgeLink:hover{background:var(--dsw-alias-interactive-bg-hover,#eee);color:var(--dsw-alias-accent-primary,#356ae6);border-color:var(--dsw-alias-accent-primary,#356ae6)}.sm-settingsBadgeLink svg{flex:none}[data-sm-theme=dark] .sm-settingsBadgeLink{background:#2a2a30!important;color:#b3b3b3!important;border-color:#3a3a40!important}[data-sm-theme=dark] .sm-settingsBadgeLink:hover{background:rgba(255,255,255,.06)!important;color:#5d8aff!important;border-color:#5d8aff!important}.sm-tooltip{z-index:1100!important;box-shadow:none!important;border:1px solid var(--dsw-alias-border-l2,rgba(0,0,0,.15))!important;filter:none!important}",
|
|
476
558
|
|
|
477
559
|
// Theme colors are scoped to the plugin dialogs. DSH exposes its
|
|
478
560
|
// actual theme through `body[data-ds-dark-theme]` and color-scheme;
|
|
479
561
|
// keeping these values local avoids changing DSH's global variables.
|
|
480
|
-
"[data-sm-theme=light] .sm-panelDialog,[data-sm-theme=light] .sm-confirmDialog.sm-nativeDialogLayer .sm-nativeDialog,[data-sm-theme=light] .sm-migrateDialog.sm-nativeDialogLayer .sm-nativeDialog{--dsw-alias-surface-l1:#fff;--dsw-alias-label-primary:#1f1f1f;--dsw-alias-label-secondary:#555;--dsw-alias-label-tertiary:#888;--dsw-alias-border-l1:#d4d4d8;--dsw-alias-border-l2:#e5e5e5;--dsw-alias-fill-l2:#f5f5f5;--dsw-alias-interactive-bg-hover:#eee;--dsw-alias-state-error-primary:#d92d20;--dsw-alias-state-warning-primary:#d97706;--dsw-alias-accent-primary:#356ae6;--dsw-alias-accent-primary-bg:rgba(53,106,230,.12);background:#fff!important;background-color:#fff!important;color:#1f1f1f!important;border-color:#e5e5e5!important}",
|
|
481
|
-
"[data-sm-theme=dark] .sm-panelDialog,[data-sm-theme=dark] .sm-confirmDialog.sm-nativeDialogLayer .sm-nativeDialog,[data-sm-theme=dark] .sm-migrateDialog.sm-nativeDialogLayer .sm-nativeDialog,[data-sm-theme=dark] .sm-bulkDialog.sm-nativeDialogLayer .sm-nativeDialog{--dsw-alias-surface-l1:#1f1f23;--dsw-alias-label-primary:#ececec;--dsw-alias-label-secondary:#b3b3b3;--dsw-alias-label-tertiary:#999;--dsw-alias-border-l1:#555;--dsw-alias-border-l2:#3a3a40;--dsw-alias-fill-l1:#1a1a1e;--dsw-alias-fill-l2:#2a2a30;--dsw-alias-interactive-bg-hover:rgba(255,255,255,.06);--dsw-alias-state-error-primary:#f47171;--dsw-alias-state-warning-primary:#f0a040;--dsw-alias-accent-primary:#5d8aff;--dsw-alias-accent-primary-bg:rgba(93,138,255,.18);background:#1f1f23!important;background-color:#1f1f23!important;color:#ececec!important;border-color:#3a3a40!important}","[data-sm-theme=dark] .sm-header{--dsw-alias-surface-l1:#1f1f23;--dsw-alias-label-primary:#ececec;--dsw-alias-label-secondary:#b3b3b3;--dsw-alias-label-tertiary:#999;--dsw-alias-border-l1:#555;--dsw-alias-border-l2:#3a3a40;--dsw-alias-fill-l1:#1a1a1e;--dsw-alias-fill-l2:#2a2a30;--dsw-alias-interactive-bg-hover:rgba(255,255,255,.06);--dsw-alias-accent-primary:#5d8aff;--dsw-alias-accent-primary-bg:rgba(93,138,255,.18)}",
|
|
482
|
-
"[data-sm-theme=light] .sm-panelDialog .sm-nativeDialogHeader,[data-sm-theme=light] .sm-panelDialog .sm-nativeDialogFooter,[data-sm-theme=light] .sm-confirmDialog .sm-nativeDialogHeader,[data-sm-theme=light] .sm-confirmDialog .sm-nativeDialogFooter,[data-sm-theme=light] .sm-migrateDialog .sm-nativeDialogHeader,[data-sm-theme=light] .sm-migrateDialog .sm-nativeDialogBody,[data-sm-theme=light] .sm-migrateDialog .sm-nativeDialogFooter{background:#fff!important;background-color:#fff!important;border-color:#e5e5e5!important}",
|
|
483
|
-
"[data-sm-theme=dark] .sm-panelDialog .sm-nativeDialogHeader,[data-sm-theme=dark] .sm-panelDialog .sm-nativeDialogFooter,[data-sm-theme=dark] .sm-confirmDialog .sm-nativeDialogHeader,[data-sm-theme=dark] .sm-confirmDialog .sm-nativeDialogFooter,[data-sm-theme=dark] .sm-migrateDialog .sm-nativeDialogHeader,[data-sm-theme=dark] .sm-migrateDialog .sm-nativeDialogBody,[data-sm-theme=dark] .sm-migrateDialog .sm-nativeDialogFooter,[data-sm-theme=dark] .sm-bulkDialog .sm-nativeDialogHeader,[data-sm-theme=dark] .sm-bulkDialog .sm-nativeDialogBody,[data-sm-theme=dark] .sm-bulkDialog .sm-nativeDialogFooter{background:#1f1f23!important;background-color:#1f1f23!important;border-color:#3a3a40!important}[data-sm-theme=dark] .sm-bulkDialog .sm-bulkSessionList,[data-sm-theme=dark] .sm-bulkDialog .sm-bulkResultList,[data-sm-theme=dark] .sm-bulkDialog .sm-bulkProgressBar{background:#1a1a1e!important;background-color:#1a1a1e!important;border-color:#3a3a40!important;color:var(--dsw-alias-label-primary,#ececec)}[data-sm-theme=dark] .sm-bulkDialog .sm-bulkSessionItem,[data-sm-theme=dark] .sm-bulkDialog .sm-bulkResultItemTitle,[data-sm-theme=dark] .sm-bulkDialog .sm-bulkResultItem{color:var(--dsw-alias-label-primary,#ececec)}",
|
|
562
|
+
"[data-sm-theme=light] .sm-panelDialog,[data-sm-theme=light] .sm-confirmDialog.sm-nativeDialogLayer .sm-nativeDialog,[data-sm-theme=light] .sm-migrateDialog.sm-nativeDialogLayer .sm-nativeDialog,[data-sm-theme=light] .sm-updateDialogLayer .sm-nativeDialog,[data-sm-theme=light] .sm-settingsCard{--dsw-alias-surface-l1:#fff;--dsw-alias-label-primary:#1f1f1f;--dsw-alias-label-secondary:#555;--dsw-alias-label-tertiary:#888;--dsw-alias-border-l1:#d4d4d8;--dsw-alias-border-l2:#e5e5e5;--dsw-alias-fill-l2:#f5f5f5;--dsw-alias-interactive-bg-hover:#eee;--dsw-alias-state-error-primary:#d92d20;--dsw-alias-state-warning-primary:#d97706;--dsw-alias-accent-primary:#356ae6;--dsw-alias-accent-primary-bg:rgba(53,106,230,.12);background:#fff!important;background-color:#fff!important;color:#1f1f1f!important;border-color:#e5e5e5!important}",
|
|
563
|
+
"[data-sm-theme=dark] .sm-panelDialog,[data-sm-theme=dark] .sm-confirmDialog.sm-nativeDialogLayer .sm-nativeDialog,[data-sm-theme=dark] .sm-migrateDialog.sm-nativeDialogLayer .sm-nativeDialog,[data-sm-theme=dark] .sm-updateDialogLayer .sm-nativeDialog,[data-sm-theme=dark] .sm-settingsCard,[data-sm-theme=dark] .sm-bulkDialog.sm-nativeDialogLayer .sm-nativeDialog{--dsw-alias-surface-l1:#1f1f23;--dsw-alias-label-primary:#ececec;--dsw-alias-label-secondary:#b3b3b3;--dsw-alias-label-tertiary:#999;--dsw-alias-border-l1:#555;--dsw-alias-border-l2:#3a3a40;--dsw-alias-fill-l1:#1a1a1e;--dsw-alias-fill-l2:#2a2a30;--dsw-alias-interactive-bg-hover:rgba(255,255,255,.06);--dsw-alias-state-error-primary:#f47171;--dsw-alias-state-warning-primary:#f0a040;--dsw-alias-accent-primary:#5d8aff;--dsw-alias-accent-primary-bg:rgba(93,138,255,.18);background:#1f1f23!important;background-color:#1f1f23!important;color:#ececec!important;border-color:#3a3a40!important}","[data-sm-theme=dark] .sm-header{--dsw-alias-surface-l1:#1f1f23;--dsw-alias-label-primary:#ececec;--dsw-alias-label-secondary:#b3b3b3;--dsw-alias-label-tertiary:#999;--dsw-alias-border-l1:#555;--dsw-alias-border-l2:#3a3a40;--dsw-alias-fill-l1:#1a1a1e;--dsw-alias-fill-l2:#2a2a30;--dsw-alias-interactive-bg-hover:rgba(255,255,255,.06);--dsw-alias-state-error-primary:#f47171;--dsw-alias-accent-primary:#5d8aff;--dsw-alias-accent-primary-bg:rgba(93,138,255,.18)}",
|
|
564
|
+
"[data-sm-theme=light] .sm-panelDialog .sm-nativeDialogHeader,[data-sm-theme=light] .sm-panelDialog .sm-nativeDialogFooter,[data-sm-theme=light] .sm-confirmDialog .sm-nativeDialogHeader,[data-sm-theme=light] .sm-confirmDialog .sm-nativeDialogFooter,[data-sm-theme=light] .sm-migrateDialog .sm-nativeDialogHeader,[data-sm-theme=light] .sm-migrateDialog .sm-nativeDialogBody,[data-sm-theme=light] .sm-migrateDialog .sm-nativeDialogFooter,[data-sm-theme=light] .sm-updateDialog .sm-nativeDialogHeader,[data-sm-theme=light] .sm-updateDialog .sm-nativeDialogFooter{background:#fff!important;background-color:#fff!important;border-color:#e5e5e5!important}",
|
|
565
|
+
"[data-sm-theme=dark] .sm-panelDialog .sm-nativeDialogHeader,[data-sm-theme=dark] .sm-panelDialog .sm-nativeDialogFooter,[data-sm-theme=dark] .sm-confirmDialog .sm-nativeDialogHeader,[data-sm-theme=dark] .sm-confirmDialog .sm-nativeDialogFooter,[data-sm-theme=dark] .sm-migrateDialog .sm-nativeDialogHeader,[data-sm-theme=dark] .sm-migrateDialog .sm-nativeDialogBody,[data-sm-theme=dark] .sm-migrateDialog .sm-nativeDialogFooter,[data-sm-theme=dark] .sm-bulkDialog .sm-nativeDialogHeader,[data-sm-theme=dark] .sm-bulkDialog .sm-nativeDialogBody,[data-sm-theme=dark] .sm-bulkDialog .sm-nativeDialogFooter,[data-sm-theme=dark] .sm-updateDialog .sm-nativeDialogHeader,[data-sm-theme=dark] .sm-updateDialog .sm-nativeDialogFooter{background:#1f1f23!important;background-color:#1f1f23!important;border-color:#3a3a40!important}[data-sm-theme=dark] .sm-updateVersionGrid{background:#1a1a1e!important;background-color:#1a1a1e!important;border-color:#3a3a40!important}[data-sm-theme=dark] .sm-updateVersionLabel{color:#b3b3b3!important}[data-sm-theme=dark] .sm-updateVersionValue{color:#ececec!important}[data-sm-theme=dark] .sm-settingsHeader,[data-sm-theme=dark] .sm-settingsSection{border-color:#3a3a40!important}[data-sm-theme=dark] .sm-settingsTag{background:#2a2a30!important;color:#b3b3b3!important}[data-sm-theme=dark] .sm-bulkDialog .sm-bulkSessionList,[data-sm-theme=dark] .sm-bulkDialog .sm-bulkResultList,[data-sm-theme=dark] .sm-bulkDialog .sm-bulkProgressBar{background:#1a1a1e!important;background-color:#1a1a1e!important;border-color:#3a3a40!important;color:var(--dsw-alias-label-primary,#ececec)}[data-sm-theme=dark] .sm-bulkDialog .sm-bulkSessionItem,[data-sm-theme=dark] .sm-bulkDialog .sm-bulkResultItemTitle,[data-sm-theme=dark] .sm-bulkDialog .sm-bulkResultItem{color:var(--dsw-alias-label-primary,#ececec)}[data-sm-theme=dark] .sm-settingsSelect{background:#2a2a30!important;color:#ececec!important;border-color:#3a3a40!important}",
|
|
484
566
|
".sm-panelDialog{max-height:min(640px,calc(100vh - 32px))}.sm-panelDialog .sm-panel{min-width:0;overflow:hidden}",
|
|
485
567
|
".sm-panelTools{display:flex;flex-direction:column;gap:8px;flex:none;padding:2px 0 6px}",
|
|
486
568
|
".sm-queryInput,.sm-viewSelect{box-sizing:border-box;width:100%;min-width:0;height:32px;padding:5px 9px;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:7px;background:var(--dsw-alias-surface-l1,#fff);color:var(--dsw-alias-label-primary,#111);font:inherit;font-size:12px;line-height:20px}",
|
|
@@ -492,13 +574,14 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
492
574
|
".sm-markIcon{min-width:25px;padding-left:5px;padding-right:5px;font-size:15px}.sm-markIcon.sm-markOn{color:var(--dsw-alias-accent-primary,#356ae6)!important;background:var(--dsw-alias-fill-l2,#eee)}.sm-priorityBadge{padding:0 5px;border-radius:4px;background:var(--dsw-alias-fill-l2,#eee);color:var(--dsw-alias-label-secondary,#666)}.sm-priority-1{color:#c2410c;background:rgba(234,88,12,.12)}.sm-priority-2{color:#a16207;background:rgba(202,138,4,.12)}",
|
|
493
575
|
"[data-sm-theme=dark] .sm-priority-1{color:#fdba74}[data-sm-theme=dark] .sm-priority-2{color:#fde68a}",
|
|
494
576
|
".sm-tagChip,.sm-noteBadge{max-width:88px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;border:0;border-radius:4px;background:var(--dsw-alias-fill-l2,#eee);color:var(--dsw-alias-label-secondary,#666);font:inherit;line-height:16px;padding:0 5px;cursor:pointer}.sm-noteBadge{background:transparent}.sm-tagChip:hover,.sm-noteBadge:hover{color:var(--dsw-alias-accent-primary,#356ae6)}",
|
|
495
|
-
".sm-markFilters{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.sm-markFiltersGroup{display:flex;flex-wrap:wrap;align-items:center;gap:6px}.sm-markFiltersSpacer{flex:1 1 auto;min-width:12px}.sm-markFilterToggle{height:28px;padding:3px 10px;white-space:nowrap}.sm-markFilterToggle:disabled{opacity:.5;cursor:not-allowed}.sm-bulkSelectBtn{height:28px;padding:3px 10px;white-space:nowrap}.sm-bulkSelectBtn:disabled{opacity:.5;cursor:not-allowed}
|
|
496
|
-
".sm-annotationDialog.sm-nativeDialogLayer{position:fixed;display:block;pointer-events:none;z-index:
|
|
577
|
+
".sm-markFilters{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.sm-markFiltersGroup{display:flex;flex-wrap:wrap;align-items:center;gap:6px}.sm-markFiltersSpacer{flex:1 1 auto;min-width:12px}.sm-markFilterToggle{height:28px;padding:3px 10px;white-space:nowrap}.sm-markFilterToggle:disabled{opacity:.5;cursor:not-allowed}.sm-bulkSelectBtn{height:28px;padding:3px 10px;white-space:nowrap}.sm-bulkSelectBtn:disabled{opacity:.5;cursor:not-allowed}",
|
|
578
|
+
"#dsh-session-manager-overlay-root{position:fixed!important;inset:0!important;width:100%!important;height:100%!important;z-index:99999!important;pointer-events:none!important;overflow:visible!important}.sm-annotationDialog.sm-nativeDialogLayer{position:fixed;display:block;pointer-events:none;z-index:100002;background:transparent}.sm-annotationDialog .sm-nativeDialogBackdrop{display:none}.sm-annotationDialog.sm-annotationDialog-anchored.sm-nativeDialogLayer,.sm-confirmDialog.sm-confirmDialog-anchored.sm-nativeDialogLayer{inset:auto;background:transparent}.sm-annotationDialog.sm-confirmDialog.sm-nativeDialogLayer:not(.sm-annotationDialog-anchored){inset:50% auto auto calc(50vw + 308px);transform:translateY(-50%);max-height:calc(100vh - 32px)}.sm-panelDialog.sm-annotationSurface{position:absolute;width:360px;max-height:min(680px,calc(100vh - 32px));pointer-events:auto;z-index:100003;box-shadow:0 16px 48px rgba(0,0,0,.25)}.sm-panelDialog.sm-annotationSurface.sm-annotationSurface-anchored{position:relative;transform:none;left:auto;top:auto;margin:0}.sm-annotationCloseHint{margin:0 16px 8px;font-size:11px;line-height:16px;color:var(--dsw-alias-label-tertiary)}",
|
|
497
579
|
".sm-annotationBody{padding:14px 16px;display:flex;flex-direction:column;gap:12px;min-height:0;overflow:auto;flex:1 1 auto}.sm-annotationTarget{font-size:12px;line-height:18px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--dsw-alias-label-secondary,#666)}.sm-annotationChecks{display:grid;grid-template-columns:auto 1fr;column-gap:14px;row-gap:4px;align-items:center;font-size:13px}.sm-annotationChecks>label{display:flex;gap:6px;align-items:center;cursor:pointer}.sm-annotationChecks .sm-annotationPriority{display:inline-flex;align-items:center;gap:6px;font-size:13px;line-height:18px;color:inherit}.sm-annotationChecks .sm-prioritySelectInline{height:24px;padding:2px 6px;font-size:12px;line-height:18px;min-width:104px;width:auto;border-radius:6px;color:var(--dsw-alias-label-primary,#111)}.sm-annotationChecks>small{font-size:11px;line-height:16px;color:var(--dsw-alias-label-tertiary,#888);justify-self:start}.sm-annotationHint,.sm-annotationBody small{font-size:11px;line-height:16px;color:var(--dsw-alias-label-tertiary,#888)}",
|
|
498
580
|
".sm-noteInput{box-sizing:border-box;width:100%;min-height:60px;resize:vertical;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:7px;padding:8px;background:var(--dsw-alias-surface-l1,#fff);color:var(--dsw-alias-label-primary,#111);font:inherit;font-size:13px;line-height:19px}.sm-noteInput:focus-visible{outline:2px solid var(--dsw-alias-accent-primary,#356ae6);outline-offset:2px}.sm-markConflict{display:flex;flex-direction:column;gap:5px;font-size:12px;padding:8px;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:6px}.sm-fieldWithClear .sm-fieldRow{position:relative;display:flex;align-items:flex-start;gap:4px}.sm-fieldRow .sm-queryInput{flex:1 1 auto;min-width:0}.sm-fieldRowNote{align-items:stretch}.sm-fieldClear{position:absolute;top:5px;right:6px;width:22px;height:22px;border:0;background:transparent;color:var(--dsw-alias-label-tertiary);cursor:pointer;border-radius:4px;font-size:14px;line-height:18px;display:inline-flex;align-items:center;justify-content:center;padding:0}.sm-fieldClear:hover,.sm-fieldClear:focus-visible{color:var(--dsw-alias-accent-primary);background:var(--dsw-alias-interactive-bg-hover);outline:none}.sm-fieldClearNote{top:6px}.sm-importGroup{display:flex;flex-direction:column;gap:8px;padding:10px 16px;border-top:1px solid var(--dsw-alias-border-l2,#eee);background:var(--dsw-alias-fill-l1,#fafbfc)}.sm-importGroupButtons{display:flex;justify-content:space-between;align-items:center;gap:8px}.sm-importBtn{cursor:pointer;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-surface-l1,#fff);border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:8px;padding:5px 12px;font-size:12px;line-height:18px}.sm-importBtn:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.sm-importBtn:disabled{opacity:.5;cursor:not-allowed}.sm-importStatus{margin:0 16px;padding:8px 10px;font-size:12px;line-height:18px;background:var(--dsw-alias-accent-primary-bg,rgba(53,106,230,.08));color:var(--dsw-alias-label-secondary);border-radius:6px;white-space:pre-wrap;word-break:break-word}",
|
|
499
581
|
".sm-bulkBar{box-sizing:border-box;display:grid;grid-template-columns:repeat(6,minmax(0,1fr));align-items:stretch;gap:6px;padding:8px 10px;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:10px;background:var(--dsw-alias-fill-l1,#fafbfc)}.sm-bulkBar .sm-bulkSummary{grid-column:1/-1;color:var(--dsw-alias-label-primary,#111);font-size:12px;line-height:18px;font-weight:500;margin:0 0 2px}",
|
|
500
582
|
".sm-bulkSummary{color:var(--dsw-alias-label-primary,#111);font-size:12px;line-height:18px;font-weight:500}",
|
|
501
583
|
"",
|
|
584
|
+
".sm-panelDialog button,.sm-panelDialog a,.sm-panelHeaderGithub,.sm-panelHeaderWhale,.sm-panelHeaderClose,.sm-headerBtn,.sm-headerMenuItem,.sm-updateDialog button,.sm-settingsCard button,.sm-settingsCard a,.sm-rowBtn,.sm-bulkBtn{outline:none;box-shadow:none;-webkit-appearance:none;-moz-appearance:none;appearance:none}.sm-panelDialog button:hover,.sm-panelDialog a:hover,.sm-panelHeaderGithub:hover,.sm-panelHeaderWhale:hover,.sm-panelHeaderClose:hover,.sm-headerBtn:hover,.sm-headerMenuItem:hover,.sm-updateDialog button:hover,.sm-settingsCard button:hover,.sm-rowBtn:hover,.sm-bulkBtn:hover{outline:none;box-shadow:none}",
|
|
502
585
|
".sm-bulkBar .sm-bulkBtn{cursor:pointer;color:var(--dsw-alias-label-secondary,#666);background:var(--dsw-alias-surface-l1,#fff);border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:8px;padding:4px 10px;font-size:12px;line-height:18px;display:inline-flex;align-items:center;justify-content:center;gap:4px;white-space:nowrap;text-align:center}",
|
|
503
586
|
".sm-bulkBar .sm-bulkBtn:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary,#111)}",
|
|
504
587
|
".sm-bulkBar .sm-bulkBtn:disabled{opacity:.5;cursor:not-allowed}",
|
|
@@ -509,7 +592,7 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
509
592
|
".sm-bulkRowCheckbox input{width:14px;height:14px;cursor:pointer;margin:0}",
|
|
510
593
|
".sm-bulkRowCheckbox input:disabled{cursor:not-allowed}",
|
|
511
594
|
".sm-rowBulkSelected{border-color:var(--dsw-alias-accent-primary,#356ae6);background:var(--dsw-alias-accent-primary-bg,rgba(53,106,230,.06))}",
|
|
512
|
-
".sm-bulkDialog.sm-nativeDialogLayer{position:fixed;left:calc(50vw + 184px);top:calc(50vh - 90px);width:360px;max-width:calc(100vw - 32px);max-height:none;display:block;align-items:initial;justify-content:initial;box-sizing:border-box;background:transparent;border:0;box-shadow:none;padding:0;inset:calc(50vh - 90px) auto auto calc(50vw + 308px);z-index:10002}.sm-bulkDialog.sm-nativeDialogLayer .sm-nativeDialogBackdrop{display:none}.sm-bulkDialog.sm-nativeDialogLayer .sm-nativeDialog{position:relative;left:auto;top:auto;transform:none;width:auto;box-sizing:border-box;background:var(--dsw-alias-surface-l1,#fff);color:var(--dsw-alias-label-primary,#111);border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:12px;box-shadow:0 16px 48px rgba(0,0,0,.25);padding:0;overflow:hidden;animation:sm-confirmPop .14s ease-out}.sm-bulkDialog .sm-nativeDialogHeader{padding:10px 16px;border-bottom:1px solid var(--dsw-alias-border-l2,#eee);flex:none;display:flex;align-items:center;
|
|
595
|
+
".sm-bulkDialog.sm-nativeDialogLayer{position:fixed;left:calc(50vw + 184px);top:calc(50vh - 90px);width:360px;max-width:calc(100vw - 32px);max-height:none;display:block;align-items:initial;justify-content:initial;box-sizing:border-box;background:transparent;border:0;box-shadow:none;padding:0;inset:calc(50vh - 90px) auto auto calc(50vw + 308px);z-index:10002}.sm-bulkDialog.sm-nativeDialogLayer .sm-nativeDialogBackdrop{display:none}.sm-bulkDialog.sm-nativeDialogLayer .sm-nativeDialog{position:relative;left:auto;top:auto;transform:none;width:auto;box-sizing:border-box;background:var(--dsw-alias-surface-l1,#fff);color:var(--dsw-alias-label-primary,#111);border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:12px;box-shadow:0 16px 48px rgba(0,0,0,.25);padding:0;overflow:hidden;animation:sm-confirmPop .14s ease-out}.sm-bulkDialog .sm-nativeDialogHeader{padding:10px 16px;border-bottom:1px solid var(--dsw-alias-border-l2,#eee);flex:none;position:relative;display:flex;align-items:center;justify-content:center;min-height:44px;box-sizing:border-box}.sm-bulkDialog .sm-nativeDialogTitle{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);margin:0;font-size:14px;line-height:20px;font-weight:600;text-align:center;width:auto;max-width:calc(100% - 32px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sm-bulkDialog .sm-nativeDialogBody{padding:12px 16px;display:flex;flex-direction:column;gap:10px;font-size:13px;line-height:20px;color:var(--dsw-alias-label-primary,#111)}.sm-bulkDialog .sm-nativeDialogFooter{padding:10px 16px;display:flex;flex-wrap:wrap;justify-content:space-between;gap:6px}.sm-bulkDialog .sm-nativeDialogButton{min-height:28px;padding:3px 14px;font-size:12px;line-height:20px;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:8px;cursor:pointer;background:transparent;color:var(--dsw-alias-label-primary,#111);text-align:center}.sm-bulkDialog .sm-nativeDialogConfirm{background:var(--dsw-alias-accent-primary,#356ae6);color:#fff;border-color:var(--dsw-alias-accent-primary,#356ae6)}.sm-bulkDialog .sm-nativeDialogConfirm:hover:not(:disabled){filter:brightness(.94)}.sm-bulkDialog .sm-nativeDialogDanger{background:var(--dsw-alias-state-error-primary,#d92d20);color:#fff;border-color:var(--dsw-alias-state-error-primary,#d92d20)}.sm-bulkDialog .sm-nativeDialogDanger:hover:not(:disabled){filter:brightness(.92)}.sm-bulkDialog .sm-nativeDialog select.sm-viewSelect{font-size:13px;line-height:20px;height:32px;padding:5px 9px}",
|
|
513
596
|
".sm-bulkDialog .sm-nativeDialog{width:100%;max-height:min(640px,calc(100vh - 32px))}",
|
|
514
597
|
".sm-bulkDialogBody{display:flex;flex-direction:column;gap:12px;min-height:0}",
|
|
515
598
|
".sm-bulkDialogSummary{font-size:13px;line-height:20px;color:var(--dsw-alias-label-primary,#111)}",
|
|
@@ -527,13 +610,14 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
527
610
|
".sm-bulkResultItemReason{color:var(--dsw-alias-state-error-primary);font-size:11px;line-height:16px;word-break:break-word}",
|
|
528
611
|
".sm-bulkResultItemReasonSkip{color:var(--dsw-alias-label-tertiary,#888)}",
|
|
529
612
|
".sm-bulkResultFooter{display:flex;justify-content:space-between;align-items:center;gap:8px;flex-wrap:wrap}",
|
|
530
|
-
".sm-footerBtn-wide{flex:
|
|
613
|
+
".sm-footerBtn-wide{flex:none;display:flex;align-items:center;gap:8px;width:calc(100% + 8px);height:34px;margin:4px -4px 4px;padding:6px 2px 6px 10px;box-sizing:border-box;border:none;border-radius:12px;cursor:pointer;overflow:hidden;font-size:14px;line-height:22px}",
|
|
531
614
|
".sm-footerBtn-wide:hover,.sm-footerBtn-wide:focus-visible{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover)}",
|
|
532
|
-
".sm-footerBtn-rail{width:36px;height:36px;padding:0;justify-content:center;border-radius:12px;color:var(--dsw-alias-label-secondary)}",
|
|
615
|
+
".sm-footerBtn-rail{width:36px;height:36px;padding:0;justify-content:center;border-radius:12px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;display:inline-flex;align-items:center}",
|
|
533
616
|
".sm-footerBtn-rail:hover,.sm-footerBtn-rail:focus-visible{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover)}",
|
|
534
617
|
".sm-footerBtn-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;max-width:100%}",
|
|
535
|
-
".sm-
|
|
536
|
-
".sm-
|
|
618
|
+
".sm-overlayLayer{position:fixed;inset:0;pointer-events:none}",
|
|
619
|
+
".sm-overlayLayer>*{pointer-events:auto}",
|
|
620
|
+
".sm-overlayBackdrop{position:fixed;inset:0;background:transparent;pointer-events:auto}",
|
|
537
621
|
"@media(max-width:720px){.sm-panelSelects{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}.sm-panelDialog .sm-row{flex-wrap:wrap}.sm-panelDialog .sm-rowMain{flex-basis:100%}.sm-panelDialog .sm-rowActions{width:100%;min-width:0;flex:1 1 100%;justify-content:flex-start}}@media(max-width:540px){.sm-panelSelects{grid-template-columns:minmax(0,1fr)}}",
|
|
538
622
|
].join("");
|
|
539
623
|
|
|
@@ -657,6 +741,268 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
657
741
|
try { installAnchor(); } catch (_) {}
|
|
658
742
|
|
|
659
743
|
const h = (type, props, ...children) => React.createElement(type, props, ...children);
|
|
744
|
+
|
|
745
|
+
let overlayRootElement = null;
|
|
746
|
+
function getOverlayRoot() {
|
|
747
|
+
if (typeof document === "undefined" || !document.body) return null;
|
|
748
|
+
if (typeof document.createElement !== "function") return null;
|
|
749
|
+
const contains = typeof document.body.contains === "function" ? (el) => document.body.contains(el) : () => true;
|
|
750
|
+
if (!overlayRootElement || !contains(overlayRootElement)) {
|
|
751
|
+
let el = typeof document.getElementById === "function"
|
|
752
|
+
? document.getElementById("dsh-session-manager-overlay-root")
|
|
753
|
+
: (typeof document.querySelector === "function" ? document.querySelector("#dsh-session-manager-overlay-root") : null);
|
|
754
|
+
if (!el) {
|
|
755
|
+
el = document.createElement("div");
|
|
756
|
+
el.id = "dsh-session-manager-overlay-root";
|
|
757
|
+
el.style.position = "fixed";
|
|
758
|
+
el.style.top = "0";
|
|
759
|
+
el.style.left = "0";
|
|
760
|
+
el.style.width = "100%";
|
|
761
|
+
el.style.height = "100%";
|
|
762
|
+
el.style.zIndex = "99999";
|
|
763
|
+
el.style.overflow = "visible";
|
|
764
|
+
el.style.pointerEvents = "none";
|
|
765
|
+
if (typeof document.body.appendChild === "function") {
|
|
766
|
+
document.body.appendChild(el);
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
overlayRootElement = el;
|
|
770
|
+
}
|
|
771
|
+
try {
|
|
772
|
+
if (document.documentElement && typeof document.documentElement.getAttribute === "function") {
|
|
773
|
+
const currentTheme = document.documentElement.getAttribute(SM_THEME_ATTR);
|
|
774
|
+
if (currentTheme && overlayRootElement && typeof overlayRootElement.setAttribute === "function") {
|
|
775
|
+
if (overlayRootElement.getAttribute(SM_THEME_ATTR) !== currentTheme) {
|
|
776
|
+
overlayRootElement.setAttribute(SM_THEME_ATTR, currentTheme);
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
} catch (_) {}
|
|
781
|
+
return overlayRootElement;
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
function getPortalFn() {
|
|
785
|
+
if (typeof React.createPortal === "function") return React.createPortal;
|
|
786
|
+
if (typeof window !== "undefined") {
|
|
787
|
+
if (window.__smReactDOM && typeof window.__smReactDOM.createPortal === "function") return window.__smReactDOM.createPortal;
|
|
788
|
+
if (window.ReactDOM && typeof window.ReactDOM.createPortal === "function") return window.ReactDOM.createPortal;
|
|
789
|
+
if (window.React && typeof window.React.createPortal === "function") return window.React.createPortal;
|
|
790
|
+
}
|
|
791
|
+
try {
|
|
792
|
+
const RDOM = require("react-dom");
|
|
793
|
+
if (RDOM && typeof RDOM.createPortal === "function") return RDOM.createPortal;
|
|
794
|
+
} catch (_) {}
|
|
795
|
+
try {
|
|
796
|
+
const RDOMC = require("react-dom/client");
|
|
797
|
+
if (RDOMC && typeof RDOMC.createPortal === "function") return RDOMC.createPortal;
|
|
798
|
+
} catch (_) {}
|
|
799
|
+
return null;
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
function renderInOverlay(vnode) {
|
|
803
|
+
if (!vnode) return null;
|
|
804
|
+
const root = getOverlayRoot();
|
|
805
|
+
const portal = getPortalFn();
|
|
806
|
+
if (portal && root) {
|
|
807
|
+
return portal(vnode, root);
|
|
808
|
+
}
|
|
809
|
+
return vnode;
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
function OverlayLayer({ children, className, style, onBackdropClick, role = "presentation", onKeyDown }) {
|
|
813
|
+
const zRef = useRef(null);
|
|
814
|
+
if (zRef.current === null) {
|
|
815
|
+
zRef.current = nextDialogZ();
|
|
816
|
+
}
|
|
817
|
+
const root = getOverlayRoot();
|
|
818
|
+
const portal = getPortalFn();
|
|
819
|
+
|
|
820
|
+
const layerStyle = {
|
|
821
|
+
position: "fixed",
|
|
822
|
+
inset: "0",
|
|
823
|
+
zIndex: zRef.current,
|
|
824
|
+
pointerEvents: "none",
|
|
825
|
+
...(style || {})
|
|
826
|
+
};
|
|
827
|
+
|
|
828
|
+
const content = h("div", {
|
|
829
|
+
className: "sm-overlayLayer " + (className || ""),
|
|
830
|
+
style: layerStyle,
|
|
831
|
+
role: role,
|
|
832
|
+
onKeyDown: onKeyDown
|
|
833
|
+
},
|
|
834
|
+
onBackdropClick ? h("div", {
|
|
835
|
+
className: "sm-nativeDialogBackdrop sm-overlayBackdrop",
|
|
836
|
+
style: {
|
|
837
|
+
position: "fixed",
|
|
838
|
+
inset: "0",
|
|
839
|
+
background: "transparent",
|
|
840
|
+
pointerEvents: "auto",
|
|
841
|
+
zIndex: -1
|
|
842
|
+
},
|
|
843
|
+
onClick: (e) => {
|
|
844
|
+
if (e.target === e.currentTarget && onBackdropClick) {
|
|
845
|
+
onBackdropClick(e);
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
}) : null,
|
|
849
|
+
children
|
|
850
|
+
);
|
|
851
|
+
|
|
852
|
+
if (portal && root) {
|
|
853
|
+
return portal(content, root);
|
|
854
|
+
}
|
|
855
|
+
return content;
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
const raf = typeof requestAnimationFrame === "function" ? requestAnimationFrame : (fn) => setTimeout(fn, 16);
|
|
859
|
+
const caf = typeof cancelAnimationFrame === "function" ? cancelAnimationFrame : (id) => clearTimeout(id);
|
|
860
|
+
|
|
861
|
+
function useFloatingPosition(anchor, open, options = {}) {
|
|
862
|
+
const {
|
|
863
|
+
placement = "bottom-end",
|
|
864
|
+
dialogWidth = 360,
|
|
865
|
+
dialogHeight = 220,
|
|
866
|
+
gap = 8,
|
|
867
|
+
margin = 16
|
|
868
|
+
} = options;
|
|
869
|
+
|
|
870
|
+
const [coords, setCoords] = useState(() => {
|
|
871
|
+
if (anchor && typeof anchor.top === "number" && typeof anchor.left === "number") {
|
|
872
|
+
return { top: anchor.top, left: anchor.left };
|
|
873
|
+
}
|
|
874
|
+
return null;
|
|
875
|
+
});
|
|
876
|
+
|
|
877
|
+
const anchorRef = useRef(anchor);
|
|
878
|
+
anchorRef.current = anchor;
|
|
879
|
+
|
|
880
|
+
useEffect(() => {
|
|
881
|
+
if (!open) return;
|
|
882
|
+
const currentAnchor = anchorRef.current;
|
|
883
|
+
if (!currentAnchor) return;
|
|
884
|
+
|
|
885
|
+
if (typeof currentAnchor.top === "number" && typeof currentAnchor.getBoundingClientRect !== "function") {
|
|
886
|
+
setCoords({ top: currentAnchor.top, left: currentAnchor.left });
|
|
887
|
+
return;
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
const getEl = () => {
|
|
891
|
+
const a = anchorRef.current;
|
|
892
|
+
if (!a) return null;
|
|
893
|
+
if (typeof a.getBoundingClientRect === "function") return a;
|
|
894
|
+
if (a.current && typeof a.current.getBoundingClientRect === "function") return a.current;
|
|
895
|
+
if (a.nodeType === 1) return a;
|
|
896
|
+
return null;
|
|
897
|
+
};
|
|
898
|
+
|
|
899
|
+
const targetEl = getEl();
|
|
900
|
+
if (!targetEl) return;
|
|
901
|
+
|
|
902
|
+
let frameId = 0;
|
|
903
|
+
const update = () => {
|
|
904
|
+
caf(frameId);
|
|
905
|
+
frameId = raf(() => {
|
|
906
|
+
const el = getEl();
|
|
907
|
+
if (!el) return;
|
|
908
|
+
const r = el.getBoundingClientRect();
|
|
909
|
+
if (!r || (r.width === 0 && r.height === 0 && r.top === 0 && r.bottom === 0)) {
|
|
910
|
+
return;
|
|
911
|
+
}
|
|
912
|
+
const winW = typeof window !== "undefined" && window.innerWidth ? window.innerWidth : 1024;
|
|
913
|
+
const winH = typeof window !== "undefined" && window.innerHeight ? window.innerHeight : 768;
|
|
914
|
+
|
|
915
|
+
let left;
|
|
916
|
+
if (placement.endsWith("-end")) {
|
|
917
|
+
left = r.right - dialogWidth;
|
|
918
|
+
} else if (placement.endsWith("-start")) {
|
|
919
|
+
left = r.left;
|
|
920
|
+
} else {
|
|
921
|
+
left = r.left + (r.width - dialogWidth) / 2;
|
|
922
|
+
}
|
|
923
|
+
left = Math.max(margin, Math.min(left, winW - dialogWidth - margin));
|
|
924
|
+
|
|
925
|
+
let top;
|
|
926
|
+
const fitsBelow = (r.bottom + gap + dialogHeight) <= (winH - margin);
|
|
927
|
+
const fitsAbove = (r.top - gap - dialogHeight) >= margin;
|
|
928
|
+
|
|
929
|
+
if (placement.startsWith("top")) {
|
|
930
|
+
if (fitsAbove || !fitsBelow) {
|
|
931
|
+
top = r.top - dialogHeight - gap;
|
|
932
|
+
} else {
|
|
933
|
+
top = r.bottom + gap;
|
|
934
|
+
}
|
|
935
|
+
top = Math.max(margin, Math.min(top, winH - dialogHeight - margin));
|
|
936
|
+
} else {
|
|
937
|
+
// For anchors near viewport top (like title bar actions), default to below.
|
|
938
|
+
// Never jump upward over the header when there is insufficient space above.
|
|
939
|
+
if (!fitsBelow && fitsAbove && r.top > dialogHeight + gap + margin) {
|
|
940
|
+
top = r.top - dialogHeight - gap;
|
|
941
|
+
} else {
|
|
942
|
+
top = r.bottom + gap;
|
|
943
|
+
}
|
|
944
|
+
top = Math.max(margin, top);
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
setCoords({ top: Math.round(top), left: Math.round(left) });
|
|
948
|
+
});
|
|
949
|
+
};
|
|
950
|
+
|
|
951
|
+
update();
|
|
952
|
+
|
|
953
|
+
if (typeof window !== "undefined") {
|
|
954
|
+
window.addEventListener("resize", update);
|
|
955
|
+
window.addEventListener("scroll", update, true);
|
|
956
|
+
if (window.visualViewport) {
|
|
957
|
+
window.visualViewport.addEventListener("resize", update);
|
|
958
|
+
window.visualViewport.addEventListener("scroll", update);
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
const pollTimer = setInterval(update, 100);
|
|
963
|
+
|
|
964
|
+
let ro = null;
|
|
965
|
+
const getRealEl = (target) => {
|
|
966
|
+
if (!target) return null;
|
|
967
|
+
if (typeof Element !== "undefined" && target instanceof Element) return target;
|
|
968
|
+
if (target.current && typeof Element !== "undefined" && target.current instanceof Element) return target.current;
|
|
969
|
+
if (typeof target.resolveActiveEl === "function") {
|
|
970
|
+
const resolved = target.resolveActiveEl();
|
|
971
|
+
if (resolved && typeof Element !== "undefined" && resolved instanceof Element) return resolved;
|
|
972
|
+
}
|
|
973
|
+
if (target.nodeType === 1 && typeof target.addEventListener === "function") return target;
|
|
974
|
+
return null;
|
|
975
|
+
};
|
|
976
|
+
const domEl = getRealEl(targetEl);
|
|
977
|
+
if (typeof ResizeObserver === "function" && domEl) {
|
|
978
|
+
try {
|
|
979
|
+
ro = new ResizeObserver(update);
|
|
980
|
+
ro.observe(domEl);
|
|
981
|
+
if (domEl.parentElement) ro.observe(domEl.parentElement);
|
|
982
|
+
const headerAncestor = typeof domEl.closest === "function" ? domEl.closest(".sm-header") : null;
|
|
983
|
+
if (headerAncestor) ro.observe(headerAncestor);
|
|
984
|
+
if (document.body) ro.observe(document.body);
|
|
985
|
+
} catch (_) {}
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
return () => {
|
|
989
|
+
caf(frameId);
|
|
990
|
+
clearInterval(pollTimer);
|
|
991
|
+
if (typeof window !== "undefined") {
|
|
992
|
+
window.removeEventListener("resize", update);
|
|
993
|
+
window.removeEventListener("scroll", update, true);
|
|
994
|
+
if (window.visualViewport) {
|
|
995
|
+
window.visualViewport.removeEventListener("resize", update);
|
|
996
|
+
window.visualViewport.removeEventListener("scroll", update);
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
if (ro) ro.disconnect();
|
|
1000
|
+
};
|
|
1001
|
+
}, [open, placement, dialogWidth, dialogHeight, gap, margin]);
|
|
1002
|
+
|
|
1003
|
+
return coords;
|
|
1004
|
+
}
|
|
1005
|
+
|
|
660
1006
|
const callApi = (path, payload) => fetch(API + path, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify(payload || {}) }).then((r) => r.json());
|
|
661
1007
|
const fetchApi = (path, options) => fetch(API + path, options).then((r) => r.json());
|
|
662
1008
|
// Run a bulk action across many sessionIds. /batch already does per-id
|
|
@@ -744,12 +1090,30 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
744
1090
|
const annotationButtons = (id, title, t, state, className, onToggle, onEdit, disabled = false, editorOpen = false) => {
|
|
745
1091
|
const value = annotationOf(state, id);
|
|
746
1092
|
const busy = disabled || !state.loaded || !!state.error || state.pending.has(id);
|
|
747
|
-
const
|
|
748
|
-
const
|
|
1093
|
+
const favoriteDesc = t(value.favorite ? "marks.favorite.remove" : "marks.favorite.add");
|
|
1094
|
+
const reviewDesc = t(value.reviewLater ? "marks.review.remove" : "marks.review.add");
|
|
1095
|
+
const favoriteLabel = favoriteDesc + ": " + title;
|
|
1096
|
+
const reviewLabel = reviewDesc + ": " + title;
|
|
1097
|
+
const isHeader = className === "sm-headerBtn";
|
|
749
1098
|
return h(React.Fragment, null,
|
|
750
|
-
h("button", { type: "button", className: className + " sm-markIcon" + (value.favorite ? " sm-markOn" : ""), disabled: busy, "aria-label": favoriteLabel,
|
|
751
|
-
|
|
752
|
-
|
|
1099
|
+
renderTip(favoriteDesc, h("button", { type: "button", className: className + " sm-markIcon" + (value.favorite ? " sm-markOn" : ""), disabled: busy, "aria-label": favoriteLabel, "aria-pressed": value.favorite, onClick: () => onToggle({ favorite: !value.favorite }) },
|
|
1100
|
+
h("span", { className: "sm-headerBtnIcon" }, value.favorite ? "★" : "☆")
|
|
1101
|
+
)),
|
|
1102
|
+
renderTip(reviewDesc, h("button", { type: "button", className: className + " sm-markIcon" + (value.reviewLater ? " sm-markOn" : ""), disabled: busy, "aria-label": reviewLabel, "aria-pressed": value.reviewLater, onClick: () => onToggle({ reviewLater: !value.reviewLater }) },
|
|
1103
|
+
h("span", { className: "sm-headerBtnIcon" }, "◷")
|
|
1104
|
+
)),
|
|
1105
|
+
renderTip(t("marks.edit.aria"), h("button", {
|
|
1106
|
+
type: "button",
|
|
1107
|
+
className: className + (isHeader ? " sm-headerSecondaryAction" : "") + (editorOpen ? " sm-annotationToggleOpen sm-headerBtnActive" : ""),
|
|
1108
|
+
disabled: busy,
|
|
1109
|
+
"aria-label": t("marks.edit.aria") + ": " + title,
|
|
1110
|
+
...(isHeader ? { "aria-expanded": editorOpen } : {}),
|
|
1111
|
+
onClick: e => onEdit(e)
|
|
1112
|
+
},
|
|
1113
|
+
isHeader ? h("span", { className: "sm-headerBtnIcon" }, "🏷") : null,
|
|
1114
|
+
isHeader ? h("span", { className: "sm-headerBtnLabel" }, t("marks.header.edit")) : t("marks.edit"),
|
|
1115
|
+
isHeader ? h("span", { className: "sm-priorityBadge sm-priority-" + (value.priority ?? 3) }, "P" + (value.priority ?? 3)) : null
|
|
1116
|
+
))
|
|
753
1117
|
);
|
|
754
1118
|
};
|
|
755
1119
|
|
|
@@ -1240,17 +1604,19 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
1240
1604
|
return "zh";
|
|
1241
1605
|
};
|
|
1242
1606
|
const activeLanguage = detectLanguage(t);
|
|
1243
|
-
const
|
|
1244
|
-
const
|
|
1245
|
-
const
|
|
1246
|
-
|
|
1247
|
-
|
|
1607
|
+
const floatingCoords = useFloatingPosition(anchor, true, { placement: "bottom-end", dialogWidth: 360, dialogHeight: 460 });
|
|
1608
|
+
const hasCoords = floatingCoords !== null || (anchor && typeof anchor.top === "number" && typeof anchor.left === "number");
|
|
1609
|
+
const computedTop = floatingCoords ? floatingCoords.top : (anchor && typeof anchor.top === "number" ? anchor.top : null);
|
|
1610
|
+
const computedLeft = floatingCoords ? floatingCoords.left : (anchor && typeof anchor.left === "number" ? anchor.left : null);
|
|
1611
|
+
const layerClass = "sm-nativeDialogLayer sm-annotationDialog sm-confirmDialog" + (hasCoords ? " sm-annotationDialog-anchored" : "");
|
|
1612
|
+
const surfaceClass = "sm-nativeDialog sm-panelDialog sm-annotationSurface" + (hasCoords ? " sm-annotationSurface-anchored" : "");
|
|
1248
1613
|
const layerStyle = {
|
|
1249
1614
|
zIndex: zIndex || undefined,
|
|
1250
|
-
...(
|
|
1615
|
+
...(hasCoords ? { position: "fixed", top: computedTop + "px", left: computedLeft + "px", right: "auto", bottom: "auto", inset: `${computedTop}px auto auto ${computedLeft}px` } : {})
|
|
1251
1616
|
};
|
|
1252
|
-
return
|
|
1253
|
-
h("
|
|
1617
|
+
return renderInOverlay(
|
|
1618
|
+
h("div", { className: layerClass, style: layerStyle, role: "presentation" },
|
|
1619
|
+
h("section", { className: surfaceClass, style: { pointerEvents: "auto" }, role: "dialog", "aria-labelledby": "sm-annotation-title", ref: dialogRef, onKeyDown },
|
|
1254
1620
|
h("div", { className: "sm-nativeDialogHeader" }, h("h2", { id: "sm-annotation-title", className: "sm-nativeDialogTitle" }, t("marks.title"))),
|
|
1255
1621
|
h("div", { className: "sm-annotationBody" },
|
|
1256
1622
|
h("div", { className: "sm-annotationTarget", title: displayTitle || sessionId }, displayTitle || sessionId),
|
|
@@ -1285,7 +1651,7 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
1285
1651
|
h("button", { type: "button", className: "sm-nativeDialogButton sm-nativeDialogConfirm", disabled: busy || !annotations.loaded || !!annotations.error || latest.revision !== base.revision, onClick: save }, t(busy ? "marks.saving" : "marks.save"))
|
|
1286
1652
|
)
|
|
1287
1653
|
)
|
|
1288
|
-
);
|
|
1654
|
+
));
|
|
1289
1655
|
}
|
|
1290
1656
|
|
|
1291
1657
|
|
|
@@ -1352,24 +1718,31 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
1352
1718
|
window.addEventListener("keydown", handler);
|
|
1353
1719
|
return () => window.removeEventListener("keydown", handler);
|
|
1354
1720
|
}, [open]);
|
|
1355
|
-
// Render inline as a sibling of the panel; createPortal to document.body broke under some hosts. Migrate and AnnotationDialog render inline; do the same here.
|
|
1356
1721
|
|
|
1722
|
+
const floatingCoords = useFloatingPosition(props.anchor, open, { placement: "bottom-end", dialogWidth: 360, dialogHeight: 180 });
|
|
1357
1723
|
|
|
1358
1724
|
if (!open) return null;
|
|
1359
1725
|
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
zIndex: zIndex || undefined,
|
|
1364
|
-
...(props.anchor && typeof props.anchor.top === "number"
|
|
1365
|
-
? { position: "fixed", top: props.anchor.top + "px", left: props.anchor.left + "px" }
|
|
1366
|
-
: {})
|
|
1367
|
-
},
|
|
1368
|
-
role: "presentation"
|
|
1369
|
-
},
|
|
1726
|
+
const topPx = floatingCoords ? floatingCoords.top : (props.anchor && typeof props.anchor.top === "number" ? props.anchor.top : null);
|
|
1727
|
+
const leftPx = floatingCoords ? floatingCoords.left : (props.anchor && typeof props.anchor.left === "number" ? props.anchor.left : null);
|
|
1728
|
+
const hasCoords = topPx !== null && leftPx !== null;
|
|
1370
1729
|
|
|
1371
|
-
|
|
1372
|
-
|
|
1730
|
+
const layerStyle = {
|
|
1731
|
+
zIndex: zIndex || undefined,
|
|
1732
|
+
...(hasCoords
|
|
1733
|
+
? { position: "fixed", top: topPx + "px", left: leftPx + "px", right: "auto", bottom: "auto", inset: `${topPx}px auto auto ${leftPx}px` }
|
|
1734
|
+
: {})
|
|
1735
|
+
};
|
|
1736
|
+
|
|
1737
|
+
return renderInOverlay(
|
|
1738
|
+
h("div", {
|
|
1739
|
+
className: "sm-nativeDialogLayer sm-confirmDialog" + (hasCoords ? " sm-confirmDialog-anchored" : ""),
|
|
1740
|
+
style: layerStyle,
|
|
1741
|
+
role: "presentation"
|
|
1742
|
+
},
|
|
1743
|
+
h("section", {
|
|
1744
|
+
className: "sm-nativeDialog",
|
|
1745
|
+
style: { pointerEvents: "auto" },
|
|
1373
1746
|
role: "dialog",
|
|
1374
1747
|
"aria-modal": "true",
|
|
1375
1748
|
"aria-labelledby": "sm-confirm-dialog-title"
|
|
@@ -1396,7 +1769,7 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
1396
1769
|
}, confirmLabel)
|
|
1397
1770
|
)
|
|
1398
1771
|
)
|
|
1399
|
-
);
|
|
1772
|
+
));
|
|
1400
1773
|
}
|
|
1401
1774
|
|
|
1402
1775
|
function MoveDialog(props) {
|
|
@@ -1477,20 +1850,27 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
1477
1850
|
onConfirm(selectedWorkspaceId);
|
|
1478
1851
|
}
|
|
1479
1852
|
};
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
...(props.anchor && typeof props.anchor.top === "number"
|
|
1485
|
-
? { position: "fixed", top: props.anchor.top + "px", left: props.anchor.left + "px" }
|
|
1486
|
-
: {})
|
|
1487
|
-
},
|
|
1488
|
-
role: "presentation",
|
|
1489
|
-
onKeyDown
|
|
1490
|
-
},
|
|
1853
|
+
const floatingCoords = useFloatingPosition(props.anchor, open, { placement: "bottom-end", dialogWidth: 360, dialogHeight: 320 });
|
|
1854
|
+
const topPx = floatingCoords ? floatingCoords.top : (props.anchor && typeof props.anchor.top === "number" ? props.anchor.top : null);
|
|
1855
|
+
const leftPx = floatingCoords ? floatingCoords.left : (props.anchor && typeof props.anchor.left === "number" ? props.anchor.left : null);
|
|
1856
|
+
const hasCoords = topPx !== null && leftPx !== null;
|
|
1491
1857
|
|
|
1492
|
-
|
|
1493
|
-
|
|
1858
|
+
const layerStyle = {
|
|
1859
|
+
zIndex: zIndex || undefined,
|
|
1860
|
+
...(hasCoords
|
|
1861
|
+
? { position: "fixed", top: topPx + "px", left: leftPx + "px", right: "auto", bottom: "auto", inset: `${topPx}px auto auto ${leftPx}px` }
|
|
1862
|
+
: {})
|
|
1863
|
+
};
|
|
1864
|
+
return renderInOverlay(
|
|
1865
|
+
h("div", {
|
|
1866
|
+
className: "sm-nativeDialogLayer sm-confirmDialog" + (hasCoords ? " sm-confirmDialog-anchored" : ""),
|
|
1867
|
+
style: layerStyle,
|
|
1868
|
+
role: "presentation",
|
|
1869
|
+
onKeyDown
|
|
1870
|
+
},
|
|
1871
|
+
h("section", {
|
|
1872
|
+
className: "sm-nativeDialog",
|
|
1873
|
+
style: { pointerEvents: "auto" },
|
|
1494
1874
|
role: "dialog",
|
|
1495
1875
|
"aria-modal": "true",
|
|
1496
1876
|
"aria-labelledby": "sm-move-dialog-title"
|
|
@@ -1514,7 +1894,7 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
1514
1894
|
}, confirmLabel)
|
|
1515
1895
|
)
|
|
1516
1896
|
)
|
|
1517
|
-
);
|
|
1897
|
+
));
|
|
1518
1898
|
}
|
|
1519
1899
|
|
|
1520
1900
|
function MigratePresetDialog(props) {
|
|
@@ -1611,14 +1991,15 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
1611
1991
|
target === currentPreset ? h("div", { className: "sm-migrateWarn" }, t("migrate.same")) : null
|
|
1612
1992
|
)
|
|
1613
1993
|
);
|
|
1614
|
-
return
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1994
|
+
return renderInOverlay(
|
|
1995
|
+
h("div", {
|
|
1996
|
+
className: "sm-nativeDialogLayer sm-confirmDialog sm-migrateConfirmLayer",
|
|
1997
|
+
role: "presentation",
|
|
1998
|
+
style: { zIndex: zIndex || undefined }
|
|
1999
|
+
},
|
|
2000
|
+
h("section", {
|
|
2001
|
+
className: "sm-nativeDialog sm-migrateDialog",
|
|
2002
|
+
style: { pointerEvents: "auto" },
|
|
1622
2003
|
role: "dialog",
|
|
1623
2004
|
"aria-modal": "true",
|
|
1624
2005
|
"aria-labelledby": "sm-migrate-dialog-title"
|
|
@@ -1642,9 +2023,274 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
1642
2023
|
}, busy ? t("busy.processing") : t("migrate.confirm"))
|
|
1643
2024
|
)
|
|
1644
2025
|
)
|
|
1645
|
-
);
|
|
2026
|
+
));
|
|
2027
|
+
}
|
|
2028
|
+
|
|
2029
|
+
const CURRENT_VERSION = "0.6.2";
|
|
2030
|
+
|
|
2031
|
+
function compareSemver(v1, v2) {
|
|
2032
|
+
if (typeof v1 !== "string" || typeof v2 !== "string") return 0;
|
|
2033
|
+
const parse = (v) => {
|
|
2034
|
+
// Strip build metadata (+...)
|
|
2035
|
+
const noBuild = v.trim().replace(/^[vV]/, "").split("+")[0];
|
|
2036
|
+
const hyphenIdx = noBuild.indexOf("-");
|
|
2037
|
+
const core = hyphenIdx === -1 ? noBuild : noBuild.slice(0, hyphenIdx);
|
|
2038
|
+
const prerelease = hyphenIdx === -1 ? undefined : noBuild.slice(hyphenIdx + 1);
|
|
2039
|
+
const parts = (core || "").split(".").map(n => parseInt(n, 10) || 0);
|
|
2040
|
+
while (parts.length < 3) parts.push(0);
|
|
2041
|
+
return { parts, prerelease: prerelease !== undefined ? prerelease.trim() : undefined };
|
|
2042
|
+
};
|
|
2043
|
+
const p1 = parse(v1);
|
|
2044
|
+
const p2 = parse(v2);
|
|
2045
|
+
for (let i = 0; i < 3; i++) {
|
|
2046
|
+
if (p1.parts[i] > p2.parts[i]) return 1;
|
|
2047
|
+
if (p1.parts[i] < p2.parts[i]) return -1;
|
|
2048
|
+
}
|
|
2049
|
+
// When major, minor, patch match: version without prerelease is higher
|
|
2050
|
+
if (p1.prerelease && !p2.prerelease) return -1;
|
|
2051
|
+
if (!p1.prerelease && p2.prerelease) return 1;
|
|
2052
|
+
if (p1.prerelease && p2.prerelease) {
|
|
2053
|
+
if (p1.prerelease === p2.prerelease) return 0;
|
|
2054
|
+
const id1 = p1.prerelease.split(".");
|
|
2055
|
+
const id2 = p2.prerelease.split(".");
|
|
2056
|
+
const maxLen = Math.max(id1.length, id2.length);
|
|
2057
|
+
for (let i = 0; i < maxLen; i++) {
|
|
2058
|
+
if (i >= id1.length) return -1;
|
|
2059
|
+
if (i >= id2.length) return 1;
|
|
2060
|
+
const part1 = id1[i];
|
|
2061
|
+
const part2 = id2[i];
|
|
2062
|
+
if (part1 === part2) continue;
|
|
2063
|
+
const num1 = /^\d+$/.test(part1) ? parseInt(part1, 10) : null;
|
|
2064
|
+
const num2 = /^\d+$/.test(part2) ? parseInt(part2, 10) : null;
|
|
2065
|
+
if (num1 !== null && num2 !== null) {
|
|
2066
|
+
if (num1 > num2) return 1;
|
|
2067
|
+
if (num1 < num2) return -1;
|
|
2068
|
+
} else if (num1 !== null && num2 === null) {
|
|
2069
|
+
return -1;
|
|
2070
|
+
} else if (num1 === null && num2 !== null) {
|
|
2071
|
+
return 1;
|
|
2072
|
+
} else {
|
|
2073
|
+
if (part1 > part2) return 1;
|
|
2074
|
+
if (part1 < part2) return -1;
|
|
2075
|
+
}
|
|
2076
|
+
}
|
|
2077
|
+
}
|
|
2078
|
+
return 0;
|
|
1646
2079
|
}
|
|
1647
2080
|
|
|
2081
|
+
let activeClientCtx = null;
|
|
2082
|
+
|
|
2083
|
+
const updateStore = {
|
|
2084
|
+
state: {
|
|
2085
|
+
status: "idle",
|
|
2086
|
+
currentVersion: CURRENT_VERSION,
|
|
2087
|
+
latestVersion: null,
|
|
2088
|
+
error: null,
|
|
2089
|
+
application: null,
|
|
2090
|
+
dialogOpen: false,
|
|
2091
|
+
checkedAt: null,
|
|
2092
|
+
},
|
|
2093
|
+
listeners: new Set(),
|
|
2094
|
+
getSnapshot() { return this.state; },
|
|
2095
|
+
subscribe(cb) {
|
|
2096
|
+
this.listeners.add(cb);
|
|
2097
|
+
return () => this.listeners.delete(cb);
|
|
2098
|
+
},
|
|
2099
|
+
_notify() {
|
|
2100
|
+
this.state = { ...this.state };
|
|
2101
|
+
for (const fn of [...this.listeners]) fn();
|
|
2102
|
+
},
|
|
2103
|
+
openDialog() {
|
|
2104
|
+
this.state.dialogOpen = true;
|
|
2105
|
+
this._notify();
|
|
2106
|
+
},
|
|
2107
|
+
closeDialog() {
|
|
2108
|
+
this.state.dialogOpen = false;
|
|
2109
|
+
this._notify();
|
|
2110
|
+
},
|
|
2111
|
+
getAutoCheck() {
|
|
2112
|
+
try {
|
|
2113
|
+
if (typeof localStorage !== "undefined") {
|
|
2114
|
+
return localStorage.getItem("dsh-session-manager-auto-check") !== "false";
|
|
2115
|
+
}
|
|
2116
|
+
} catch (_) {}
|
|
2117
|
+
return true;
|
|
2118
|
+
},
|
|
2119
|
+
setAutoCheck(enabled) {
|
|
2120
|
+
try {
|
|
2121
|
+
if (typeof localStorage !== "undefined") {
|
|
2122
|
+
localStorage.setItem("dsh-session-manager-auto-check", enabled ? "true" : "false");
|
|
2123
|
+
}
|
|
2124
|
+
} catch (_) {}
|
|
2125
|
+
this._notify();
|
|
2126
|
+
},
|
|
2127
|
+
REGISTRY_OPTIONS: {
|
|
2128
|
+
"registry.npmjs.org": "https://registry.npmjs.org",
|
|
2129
|
+
"registry.npmmirror.com": "https://registry.npmmirror.com",
|
|
2130
|
+
},
|
|
2131
|
+
DEFAULT_REGISTRY: "registry.npmjs.org",
|
|
2132
|
+
getRegistry() {
|
|
2133
|
+
try {
|
|
2134
|
+
if (typeof localStorage !== "undefined") {
|
|
2135
|
+
const v = localStorage.getItem("dsh-session-manager-registry");
|
|
2136
|
+
if (v && this.REGISTRY_OPTIONS[v]) return v;
|
|
2137
|
+
}
|
|
2138
|
+
} catch (_) {}
|
|
2139
|
+
return this.DEFAULT_REGISTRY;
|
|
2140
|
+
},
|
|
2141
|
+
setRegistry(key) {
|
|
2142
|
+
try {
|
|
2143
|
+
if (typeof localStorage !== "undefined") {
|
|
2144
|
+
if (this.REGISTRY_OPTIONS[key]) {
|
|
2145
|
+
localStorage.setItem("dsh-session-manager-registry", key);
|
|
2146
|
+
} else {
|
|
2147
|
+
localStorage.setItem("dsh-session-manager-registry", this.DEFAULT_REGISTRY);
|
|
2148
|
+
}
|
|
2149
|
+
}
|
|
2150
|
+
} catch (_) {}
|
|
2151
|
+
this._notify();
|
|
2152
|
+
},
|
|
2153
|
+
getRegistryUrl() {
|
|
2154
|
+
return this.REGISTRY_OPTIONS[this.getRegistry()] || this.REGISTRY_OPTIONS[this.DEFAULT_REGISTRY];
|
|
2155
|
+
},
|
|
2156
|
+
async checkForUpdate(options = {}) {
|
|
2157
|
+
const { silent = false, openOnFound = true, manual = false } = options;
|
|
2158
|
+
const shouldOpenDialog = options.openDialog ?? (manual && !silent && options.openOnFound !== false);
|
|
2159
|
+
if (this.state.status === "checking" || this.state.status === "updating") return this.state;
|
|
2160
|
+
|
|
2161
|
+
this.state.status = "checking";
|
|
2162
|
+
this.state.error = null;
|
|
2163
|
+
if (shouldOpenDialog) {
|
|
2164
|
+
this.state.dialogOpen = true;
|
|
2165
|
+
}
|
|
2166
|
+
this._notify();
|
|
2167
|
+
|
|
2168
|
+
try {
|
|
2169
|
+
let res = null;
|
|
2170
|
+
if (typeof window !== "undefined" && window.__DSH_SM_TEST_UPDATE__) {
|
|
2171
|
+
const testOverride = window.__DSH_SM_TEST_UPDATE__;
|
|
2172
|
+
if (testOverride.error) {
|
|
2173
|
+
throw new Error(testOverride.error);
|
|
2174
|
+
}
|
|
2175
|
+
const cur = testOverride.currentVersion || this.state.currentVersion;
|
|
2176
|
+
const lat = testOverride.latestVersion || "9.9.9";
|
|
2177
|
+
const hasUpdate = compareSemver(lat, cur) > 0;
|
|
2178
|
+
res = { ok: true, result: { currentVersion: cur, latestVersion: lat, hasUpdate } };
|
|
2179
|
+
} else {
|
|
2180
|
+
const registryUrl = this.getRegistryUrl();
|
|
2181
|
+
const registryParam = encodeURIComponent(registryUrl);
|
|
2182
|
+
try {
|
|
2183
|
+
res = await fetchApi("/update/check?registry=" + registryParam);
|
|
2184
|
+
} catch (fetchErr) {
|
|
2185
|
+
try {
|
|
2186
|
+
const base = registryUrl.endsWith("/") ? registryUrl : registryUrl + "/";
|
|
2187
|
+
const npmRes = await fetch(base + "dsh-session-manager/latest");
|
|
2188
|
+
if (npmRes.ok) {
|
|
2189
|
+
const npmData = await npmRes.json();
|
|
2190
|
+
if (npmData && npmData.version) {
|
|
2191
|
+
const cur = this.state.currentVersion;
|
|
2192
|
+
const lat = npmData.version;
|
|
2193
|
+
const hasUpdate = compareSemver(lat, cur) > 0;
|
|
2194
|
+
res = { ok: true, result: { currentVersion: cur, latestVersion: lat, hasUpdate } };
|
|
2195
|
+
}
|
|
2196
|
+
}
|
|
2197
|
+
} catch (_) {}
|
|
2198
|
+
if (!res) throw fetchErr;
|
|
2199
|
+
}
|
|
2200
|
+
}
|
|
2201
|
+
|
|
2202
|
+
if (!res || !res.ok) {
|
|
2203
|
+
throw new Error(res?.error || "检查更新失败");
|
|
2204
|
+
}
|
|
2205
|
+
|
|
2206
|
+
const result = res.result || {};
|
|
2207
|
+
const currentVersion = result.currentVersion || this.state.currentVersion;
|
|
2208
|
+
const latestVersion = result.latestVersion || currentVersion;
|
|
2209
|
+
const hasUpdate = !!result.hasUpdate || compareSemver(latestVersion, currentVersion) > 0;
|
|
2210
|
+
|
|
2211
|
+
this.state.currentVersion = currentVersion;
|
|
2212
|
+
this.state.latestVersion = latestVersion;
|
|
2213
|
+
this.state.checkedAt = Date.now();
|
|
2214
|
+
|
|
2215
|
+
if (hasUpdate) {
|
|
2216
|
+
this.state.status = "available";
|
|
2217
|
+
if (openOnFound && !silent) {
|
|
2218
|
+
this.state.dialogOpen = true;
|
|
2219
|
+
}
|
|
2220
|
+
} else {
|
|
2221
|
+
this.state.status = "idle";
|
|
2222
|
+
if (shouldOpenDialog) {
|
|
2223
|
+
this.state.dialogOpen = true;
|
|
2224
|
+
}
|
|
2225
|
+
}
|
|
2226
|
+
this._notify();
|
|
2227
|
+
return this.state;
|
|
2228
|
+
} catch (err) {
|
|
2229
|
+
this.state.status = "error";
|
|
2230
|
+
this.state.error = err.message || "检查更新失败";
|
|
2231
|
+
if (shouldOpenDialog) {
|
|
2232
|
+
this.state.dialogOpen = true;
|
|
2233
|
+
}
|
|
2234
|
+
this._notify();
|
|
2235
|
+
return this.state;
|
|
2236
|
+
}
|
|
2237
|
+
},
|
|
2238
|
+
async startUpdate(options = {}) {
|
|
2239
|
+
const { openDialog = false } = options;
|
|
2240
|
+
if (this.state.status === "updating") return this.state;
|
|
2241
|
+
this.state.status = "updating";
|
|
2242
|
+
this.state.error = null;
|
|
2243
|
+
if (openDialog) {
|
|
2244
|
+
this.state.dialogOpen = true;
|
|
2245
|
+
}
|
|
2246
|
+
this._notify();
|
|
2247
|
+
|
|
2248
|
+
const targetVersion = this.state.latestVersion || "latest";
|
|
2249
|
+
const spec = "dsh-session-manager@" + targetVersion;
|
|
2250
|
+
|
|
2251
|
+
try {
|
|
2252
|
+
let outcome = null;
|
|
2253
|
+
if (typeof window !== "undefined" && window.__DSH_SM_TEST_UPDATE__) {
|
|
2254
|
+
const testOverride = window.__DSH_SM_TEST_UPDATE__;
|
|
2255
|
+
if (testOverride.error) {
|
|
2256
|
+
throw new Error(testOverride.error);
|
|
2257
|
+
}
|
|
2258
|
+
if (typeof testOverride.installBundle === "function") {
|
|
2259
|
+
outcome = await testOverride.installBundle(spec);
|
|
2260
|
+
} else {
|
|
2261
|
+
await new Promise(r => setTimeout(r, 100));
|
|
2262
|
+
outcome = { application: testOverride.application || "restart-required" };
|
|
2263
|
+
}
|
|
2264
|
+
} else {
|
|
2265
|
+
const remotePm = activeClientCtx?.remote?.pluginManager || activeClientCtx?.pluginManager;
|
|
2266
|
+
if (remotePm && typeof remotePm.installBundle === "function") {
|
|
2267
|
+
outcome = await remotePm.installBundle(spec);
|
|
2268
|
+
} else {
|
|
2269
|
+
const res = await callApi("/update/install", { version: targetVersion, registry: this.getRegistryUrl() });
|
|
2270
|
+
if (!res || !res.ok) {
|
|
2271
|
+
throw new Error(res?.error || "安装更新失败");
|
|
2272
|
+
}
|
|
2273
|
+
outcome = res.result;
|
|
2274
|
+
}
|
|
2275
|
+
}
|
|
2276
|
+
|
|
2277
|
+
const application = outcome?.application || "restart-required";
|
|
2278
|
+
this.state.status = "done";
|
|
2279
|
+
this.state.application = application;
|
|
2280
|
+
this._notify();
|
|
2281
|
+
return outcome;
|
|
2282
|
+
} catch (err) {
|
|
2283
|
+
this.state.status = "error";
|
|
2284
|
+
this.state.error = err.message || "更新安装失败";
|
|
2285
|
+
if (openDialog) {
|
|
2286
|
+
this.state.dialogOpen = true;
|
|
2287
|
+
}
|
|
2288
|
+
this._notify();
|
|
2289
|
+
return { ok: false, error: this.state.error };
|
|
2290
|
+
}
|
|
2291
|
+
}
|
|
2292
|
+
};
|
|
2293
|
+
|
|
1648
2294
|
const panelStore = {
|
|
1649
2295
|
open: false,
|
|
1650
2296
|
listeners: new Set(),
|
|
@@ -1662,6 +2308,7 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
1662
2308
|
setPendingMove(v) { this.pendingMove = v; this._emitPending(); },
|
|
1663
2309
|
consumePendingMove() { const v = this.pendingMove; this.pendingMove = null; return v; }
|
|
1664
2310
|
};
|
|
2311
|
+
const lastBatchContext = { action: null, ids: [] };
|
|
1665
2312
|
|
|
1666
2313
|
const DEFAULT_SORT = "updated-desc";
|
|
1667
2314
|
const SORT_ORDERS = ["updated-desc", "updated-asc", "created-desc", "created-asc", "priority"];
|
|
@@ -1717,6 +2364,11 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
1717
2364
|
const onMigrate = props.onMigrate;
|
|
1718
2365
|
const annotations = useAnnotations(true);
|
|
1719
2366
|
const marksReady = annotations.loaded && !annotations.error;
|
|
2367
|
+
const updateState = useSyncExternalStore(
|
|
2368
|
+
(cb) => updateStore.subscribe(cb),
|
|
2369
|
+
() => updateStore.getSnapshot(),
|
|
2370
|
+
() => updateStore.getSnapshot()
|
|
2371
|
+
);
|
|
1720
2372
|
const [onlyFavorite, setOnlyFavorite] = useState(false);
|
|
1721
2373
|
const [onlyReview, setOnlyReview] = useState(false);
|
|
1722
2374
|
const [tagFilter, setTagFilter] = useState("all");
|
|
@@ -1840,6 +2492,8 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
1840
2492
|
setBulkProgress(null);
|
|
1841
2493
|
setBulkResult({ action, actionLabel, items });
|
|
1842
2494
|
setBulkBusy(false);
|
|
2495
|
+
lastBatchContext.action = action;
|
|
2496
|
+
lastBatchContext.ids = ids;
|
|
1843
2497
|
try { await annotationStore.load(true); } catch (_) { /* ignore */ }
|
|
1844
2498
|
if (typeof props.onRefreshAfterBulk === "function") {
|
|
1845
2499
|
try { await props.onRefreshAfterBulk(action); } catch (_) { /* ignore */ }
|
|
@@ -1891,16 +2545,16 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
1891
2545
|
const onBulkTagApply = (tags) => {
|
|
1892
2546
|
const mode = bulkTagDraft && bulkTagDraft.mode;
|
|
1893
2547
|
setBulkTagDraft(null);
|
|
1894
|
-
if (mode === "add") onBulkAction("add-tags", { tags },
|
|
2548
|
+
if (mode === "add") onBulkAction("add-tags", { tags }, false);
|
|
1895
2549
|
};
|
|
1896
2550
|
const onBulkPriorityApply = (value) => {
|
|
1897
2551
|
const priority = Number(value);
|
|
1898
2552
|
setBulkTagDraft(null);
|
|
1899
|
-
if (Number.isInteger(priority) && priority >= 1 && priority <= 5) onBulkAction("set-priority", { priority },
|
|
2553
|
+
if (Number.isInteger(priority) && priority >= 1 && priority <= 5) onBulkAction("set-priority", { priority }, false);
|
|
1900
2554
|
};
|
|
1901
2555
|
const onBulkMoveApply = (value) => {
|
|
1902
2556
|
setBulkTagDraft(null);
|
|
1903
|
-
if (value) onBulkAction("move", { targetWorkspaceId: value },
|
|
2557
|
+
if (value) onBulkAction("move", { targetWorkspaceId: value }, false);
|
|
1904
2558
|
};
|
|
1905
2559
|
const [bulkPresetDraft, setBulkPresetDraft] = useState(null);
|
|
1906
2560
|
const [bulkPresetOptions, setBulkPresetOptions] = useState([]);
|
|
@@ -1926,7 +2580,7 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
1926
2580
|
};
|
|
1927
2581
|
const onBulkPresetApply = (value) => {
|
|
1928
2582
|
setBulkPresetDraft(null);
|
|
1929
|
-
if (value) onBulkAction("preset-migrate", { toPreset: value },
|
|
2583
|
+
if (value) onBulkAction("preset-migrate", { toPreset: value }, false);
|
|
1930
2584
|
};
|
|
1931
2585
|
const bulkMoveOptions = useMemo(() => workspaces.map(ws => ({ value: ws.id, label: ws.title || ws.name || ws.id })), [workspaces]);
|
|
1932
2586
|
const bulkPriorityOptions = useMemo(() => [1, 2, 3, 4, 5].map(value => ({ value: String(value), label: t("marks.priority." + value) })), [t]);
|
|
@@ -2159,29 +2813,74 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
2159
2813
|
"aria-labelledby": "sm-panel-dialog-title"
|
|
2160
2814
|
},
|
|
2161
2815
|
h("div", { className: "sm-nativeDialogHeader" },
|
|
2162
|
-
h("
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2816
|
+
h("div", { className: "sm-panelHeaderLeft" },
|
|
2817
|
+
renderTip(t("panel.github.title"), h("a", {
|
|
2818
|
+
href: "https://github.com/hkkz9522/dsh-session-manager",
|
|
2819
|
+
target: "_blank",
|
|
2820
|
+
rel: "noopener noreferrer",
|
|
2821
|
+
className: "sm-panelHeaderGithub",
|
|
2822
|
+
"aria-label": t("panel.github.title")
|
|
2823
|
+
},
|
|
2824
|
+
h("svg", { viewBox: "0 0 16 16", width: 16, height: 16, "aria-hidden": "true" },
|
|
2825
|
+
h("path", {
|
|
2826
|
+
fill: "currentColor",
|
|
2827
|
+
d: "M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"
|
|
2828
|
+
})
|
|
2829
|
+
)
|
|
2830
|
+
)),
|
|
2831
|
+
renderTip(updateState.status === "available"
|
|
2832
|
+
? t("panel.update.badge")
|
|
2833
|
+
: updateState.status === "checking"
|
|
2834
|
+
? t("update.checking")
|
|
2835
|
+
: updateState.status === "done"
|
|
2836
|
+
? t("update.done.applied")
|
|
2837
|
+
: updateState.status === "error"
|
|
2838
|
+
? (updateState.error || t("update.error"))
|
|
2839
|
+
: t("panel.update.title"),
|
|
2840
|
+
h("a", {
|
|
2841
|
+
role: "button",
|
|
2842
|
+
tabIndex: 0,
|
|
2843
|
+
className: "sm-panelHeaderGithub sm-panelHeaderWhale" + (updateState.status === "available" ? " sm-hasUpdate" : ""),
|
|
2844
|
+
"aria-label": updateState.status === "available"
|
|
2845
|
+
? t("panel.update.badge")
|
|
2846
|
+
: updateState.status === "checking"
|
|
2847
|
+
? t("update.checking")
|
|
2848
|
+
: t("panel.update.title"),
|
|
2849
|
+
onClick: (e) => {
|
|
2850
|
+
if (e && typeof e.preventDefault === "function") e.preventDefault();
|
|
2851
|
+
if (updateState.status === "available" || updateState.status === "done" || updateState.status === "updating") {
|
|
2852
|
+
updateStore.openDialog();
|
|
2853
|
+
} else {
|
|
2854
|
+
updateStore.openDialog();
|
|
2855
|
+
updateStore.checkForUpdate({ manual: true, silent: false, openDialog: true });
|
|
2856
|
+
}
|
|
2857
|
+
},
|
|
2858
|
+
onKeyDown: (e) => {
|
|
2859
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
2860
|
+
if (e && typeof e.preventDefault === "function") e.preventDefault();
|
|
2861
|
+
if (updateState.status === "available" || updateState.status === "done" || updateState.status === "updating") {
|
|
2862
|
+
updateStore.openDialog();
|
|
2863
|
+
} else {
|
|
2864
|
+
updateStore.openDialog();
|
|
2865
|
+
updateStore.checkForUpdate({ manual: true, silent: false, openDialog: true });
|
|
2866
|
+
}
|
|
2867
|
+
}
|
|
2868
|
+
}
|
|
2869
|
+
},
|
|
2870
|
+
h(NpmIcon, { size: 16 }),
|
|
2871
|
+
updateState.status === "available" ? h("span", { className: "sm-updateDot", "aria-hidden": "true" }) : null,
|
|
2872
|
+
updateState.status === "checking" ? h("span", { className: "sm-updateSpinner", "aria-hidden": "true" }) : null
|
|
2873
|
+
)),
|
|
2176
2874
|
),
|
|
2177
2875
|
h("h2", { id: "sm-panel-dialog-title", className: "sm-nativeDialogTitle" }, t("panel.title")),
|
|
2178
2876
|
h("div", { className: "sm-nativeDialogHeaderActions" },
|
|
2179
|
-
h("button", {
|
|
2877
|
+
renderTip(t("panel.close") || "关闭", h("button", {
|
|
2180
2878
|
type: "button",
|
|
2181
2879
|
className: "sm-panelHeaderClose",
|
|
2182
2880
|
disabled: busyId !== null || migrating,
|
|
2183
|
-
onClick: onPanelClose
|
|
2184
|
-
|
|
2881
|
+
onClick: onPanelClose,
|
|
2882
|
+
"aria-label": t("panel.close")
|
|
2883
|
+
}, h(CloseIcon, { size: 14 })))
|
|
2185
2884
|
)
|
|
2186
2885
|
),
|
|
2187
2886
|
h("div", { className: "sm-panel" },
|
|
@@ -2495,30 +3194,119 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
2495
3194
|
});
|
|
2496
3195
|
return () => { alive = false; };
|
|
2497
3196
|
}, [moveFor ? (moveFor.id || "x") : null]);
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
const
|
|
2502
|
-
|
|
2503
|
-
|
|
3197
|
+
const [moreOpen, setMoreOpen] = useState(false);
|
|
3198
|
+
const headerRef = useRef(null);
|
|
3199
|
+
const moreBtnRef = useRef(null);
|
|
3200
|
+
const moreBtnElRef = useRef(null);
|
|
3201
|
+
useEffect(() => {
|
|
3202
|
+
if (!moreOpen) return;
|
|
3203
|
+
const onDocClick = (e) => {
|
|
3204
|
+
if (moreBtnRef.current && moreBtnRef.current.contains(e.target)) return;
|
|
3205
|
+
setMoreOpen(false);
|
|
3206
|
+
};
|
|
3207
|
+
const onKey = (e) => {
|
|
3208
|
+
if (e.key === "Escape") setMoreOpen(false);
|
|
3209
|
+
};
|
|
3210
|
+
window.addEventListener("click", onDocClick, true);
|
|
3211
|
+
window.addEventListener("keydown", onKey, true);
|
|
3212
|
+
return () => {
|
|
3213
|
+
window.removeEventListener("click", onDocClick, true);
|
|
3214
|
+
window.removeEventListener("keydown", onKey, true);
|
|
3215
|
+
};
|
|
3216
|
+
}, [moreOpen]);
|
|
3217
|
+
|
|
3218
|
+
const getMoreBtn = () => {
|
|
3219
|
+
if (moreBtnElRef.current && moreBtnElRef.current.nodeType === 1) return moreBtnElRef.current;
|
|
3220
|
+
if (moreBtnRef.current) {
|
|
3221
|
+
const btn = moreBtnRef.current.querySelector(".sm-headerCompactMenuBtn");
|
|
3222
|
+
if (btn) return btn;
|
|
3223
|
+
}
|
|
3224
|
+
if (headerRef.current) {
|
|
3225
|
+
const btn = headerRef.current.querySelector(".sm-headerCompactMenuBtn");
|
|
3226
|
+
if (btn) return btn;
|
|
3227
|
+
}
|
|
3228
|
+
return null;
|
|
3229
|
+
};
|
|
3230
|
+
|
|
3231
|
+
const isVisible = (element) => {
|
|
3232
|
+
if (!element || typeof element.getBoundingClientRect !== "function") return false;
|
|
3233
|
+
if (typeof element.isConnected === "boolean" && !element.isConnected) return false;
|
|
3234
|
+
const rect = element.getBoundingClientRect();
|
|
3235
|
+
if (rect.width === 0 && rect.height === 0) return false;
|
|
3236
|
+
if (typeof element.offsetParent !== "undefined" && element.offsetParent === null && element.style?.position !== "fixed") return false;
|
|
3237
|
+
return true;
|
|
3238
|
+
};
|
|
3239
|
+
|
|
3240
|
+
const resolveActiveAnchorEl = (targetEl, actionType) => {
|
|
3241
|
+
if (isVisible(targetEl)) return targetEl;
|
|
3242
|
+
const moreBtn = getMoreBtn();
|
|
3243
|
+
if (isVisible(moreBtn)) return moreBtn;
|
|
3244
|
+
if (headerRef.current) {
|
|
3245
|
+
if (actionType === "annotation") {
|
|
3246
|
+
const btn = headerRef.current.querySelector(".sm-headerSecondaryAction")
|
|
3247
|
+
|| headerRef.current.querySelector(".sm-annotationToggleOpen")
|
|
3248
|
+
|| headerRef.current.querySelector("[aria-label*='marks']")
|
|
3249
|
+
|| headerRef.current.querySelector("[aria-label*='标签']");
|
|
3250
|
+
if (isVisible(btn)) return btn;
|
|
3251
|
+
} else if (actionType === "move") {
|
|
3252
|
+
const btn = headerRef.current.querySelector(".sm-headerSecondaryActions button:first-child")
|
|
3253
|
+
|| headerRef.current.querySelector("[aria-label*='move']")
|
|
3254
|
+
|| headerRef.current.querySelector("[aria-label*='移动']");
|
|
3255
|
+
if (isVisible(btn)) return btn;
|
|
3256
|
+
} else if (actionType === "delete") {
|
|
3257
|
+
const btn = headerRef.current.querySelector(".sm-headerSecondaryActions button:last-child")
|
|
3258
|
+
|| headerRef.current.querySelector(".sm-headerBtnDanger");
|
|
3259
|
+
if (isVisible(btn)) return btn;
|
|
3260
|
+
}
|
|
3261
|
+
if (isVisible(headerRef.current)) return headerRef.current;
|
|
3262
|
+
}
|
|
3263
|
+
return moreBtn || targetEl || null;
|
|
3264
|
+
};
|
|
3265
|
+
|
|
3266
|
+
// Anchor dialogs to the trigger button with dynamic tracking (issue #19 / #20).
|
|
3267
|
+
const anchorFor = (el, actionType) => {
|
|
3268
|
+
const domEl = el?.nodeType === 1 ? el : (el?.currentTarget || el?.target || el?.current || el);
|
|
3269
|
+
if (!domEl || typeof domEl.getBoundingClientRect !== "function") return domEl || null;
|
|
3270
|
+
|
|
3271
|
+
const activeEl = resolveActiveAnchorEl(domEl, actionType);
|
|
3272
|
+
const r = (activeEl && isVisible(activeEl) ? activeEl : domEl).getBoundingClientRect();
|
|
3273
|
+
|
|
2504
3274
|
return {
|
|
2505
3275
|
top: Math.round(r.top + r.height + 6),
|
|
2506
|
-
left: Math.max(8, Math.round(r.right - 360))
|
|
3276
|
+
left: Math.max(8, Math.round(r.right - 360)),
|
|
3277
|
+
current: domEl,
|
|
3278
|
+
nodeType: domEl.nodeType,
|
|
3279
|
+
actionType: actionType,
|
|
3280
|
+
resolveActiveEl: () => resolveActiveAnchorEl(domEl, actionType),
|
|
3281
|
+
getBoundingClientRect: () => {
|
|
3282
|
+
const currentEl = resolveActiveAnchorEl(domEl, actionType);
|
|
3283
|
+
if (currentEl && typeof currentEl.getBoundingClientRect === "function") {
|
|
3284
|
+
const curR = currentEl.getBoundingClientRect();
|
|
3285
|
+
if (curR.width > 0 || curR.height > 0) return curR;
|
|
3286
|
+
}
|
|
3287
|
+
if (headerRef.current && typeof headerRef.current.getBoundingClientRect === "function") {
|
|
3288
|
+
const hr = headerRef.current.getBoundingClientRect();
|
|
3289
|
+
if (hr.width > 0 || hr.height > 0) return hr;
|
|
3290
|
+
}
|
|
3291
|
+
return r;
|
|
3292
|
+
}
|
|
2507
3293
|
};
|
|
2508
3294
|
};
|
|
2509
3295
|
const archiveLabelKey = isArchived ? "row.unarchive" : "row.archive";
|
|
2510
3296
|
return h(React.Fragment, null,
|
|
2511
3297
|
annotationFor ? h(AnnotationDialog, { key: annotationFor.id, sessionId: annotationFor.id, displayTitle: annotationFor.displayTitle, t, anchor: annotationAnchor, onClose: () => { setAnnotationFor(null); setAnnotationAnchor(null); } }) : null,
|
|
2512
|
-
h("div", { className: "sm-header" },
|
|
2513
|
-
h("button", {
|
|
3298
|
+
h("div", { className: "sm-header", ref: headerRef },
|
|
3299
|
+
(onArchive || onUnarchive) ? renderTip(t ? t(archiveLabelKey) : (isArchived ? "移出归档" : "归档会话"), h("button", {
|
|
2514
3300
|
type: "button",
|
|
2515
3301
|
className: "sm-headerBtn" + (isArchived ? " sm-headerBtnActive" : ""),
|
|
2516
3302
|
"aria-label": t ? t(archiveLabelKey) : (isArchived ? "移出归档" : "归档会话"),
|
|
2517
3303
|
onClick: () => runWithAlert("archive", () =>
|
|
2518
3304
|
isArchived ? onUnarchive(sessionId) : onArchive(sessionId)
|
|
2519
3305
|
)
|
|
2520
|
-
},
|
|
2521
|
-
|
|
3306
|
+
},
|
|
3307
|
+
h("span", { className: "sm-headerBtnIcon" }, isArchived ? "📤" : "📥"),
|
|
3308
|
+
h("span", { className: "sm-headerBtnLabel" }, isArchived ? (t ? t("row.unarchive") : "移出归档") : (t ? t("row.archive") : "归档"))
|
|
3309
|
+
)) : null,
|
|
2522
3310
|
annotationButtons(sessionId, props.displayTitle || sessionId, t, annotations, "sm-headerBtn", patch => runWithAlert("annotations", () => annotationStore.save(sessionId, patch)), (e) => {
|
|
2523
3311
|
const nextOpen = !(annotationFor && annotationFor.id === sessionId);
|
|
2524
3312
|
// Do NOT clear moveFor / confirmFor here: the z-index counter
|
|
@@ -2526,51 +3314,143 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
2526
3314
|
// popup must not silently dismiss a previously opened move or
|
|
2527
3315
|
// delete popup on the same session.
|
|
2528
3316
|
if (nextOpen && e && e.currentTarget) {
|
|
2529
|
-
|
|
2530
|
-
setAnnotationAnchor({ top: Math.round(r.top + r.height + 6), left: Math.max(8, Math.round(r.right - 360)) });
|
|
3317
|
+
setAnnotationAnchor(anchorFor(e.currentTarget, "annotation"));
|
|
2531
3318
|
} else setAnnotationAnchor(null);
|
|
2532
3319
|
setAnnotationFor(current => current?.id === sessionId ? null : { id: sessionId, displayTitle });
|
|
2533
3320
|
}, false, annotationFor?.id === sessionId),
|
|
2534
|
-
annotations.error ? h("button", { type: "button", className: "sm-headerBtn",
|
|
3321
|
+
annotations.error ? renderTip(t("marks.error", { message: annotations.error }), h("button", { type: "button", className: "sm-headerBtn", "aria-label": t("marks.retry"), onClick: () => annotationStore.load(true) }, "!")) : null,
|
|
2535
3322
|
|
|
2536
|
-
h("
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
e
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
3323
|
+
h("div", { className: "sm-headerSecondaryActions" },
|
|
3324
|
+
renderTip(t ? t("row.move") : "移动至工作区", h("button", {
|
|
3325
|
+
type: "button",
|
|
3326
|
+
className: "sm-headerBtn" + (moveFor ? " sm-headerBtnActive" : ""),
|
|
3327
|
+
"aria-label": t ? t("row.move") : "移动至工作区",
|
|
3328
|
+
onClick: (e) => {
|
|
3329
|
+
if (e && typeof e.stopPropagation === "function") e.stopPropagation();
|
|
3330
|
+
// Do NOT clear confirmFor / confirmAnchor here: opening the
|
|
3331
|
+
// move popup must not silently dismiss a previously opened
|
|
3332
|
+
// delete popup on the same session. The z-index counter
|
|
3333
|
+
// (see nextDialogZ) handles stacking.
|
|
3334
|
+
if (moveFor && moveFor.id === sessionId) {
|
|
3335
|
+
setMoveFor(null);
|
|
3336
|
+
setMoveAnchor(null);
|
|
3337
|
+
} else {
|
|
3338
|
+
setMoveAnchor(anchorFor(e?.currentTarget, "move"));
|
|
3339
|
+
setMoveFor({ id: sessionId, displayTitle, workspaceId: "" });
|
|
3340
|
+
}
|
|
2552
3341
|
}
|
|
2553
|
-
}
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
3342
|
+
},
|
|
3343
|
+
h("span", { className: "sm-headerBtnIcon" }, "↔"),
|
|
3344
|
+
h("span", { className: "sm-headerBtnLabel" }, t ? t("row.move") : "移动至工作区")
|
|
3345
|
+
)),
|
|
3346
|
+
renderTip(t ? t("row.delete") : "删除会话", h("button", {
|
|
3347
|
+
type: "button",
|
|
3348
|
+
className: "sm-headerBtn sm-headerBtnDanger" + (confirmFor ? " sm-headerBtnActive" : ""),
|
|
3349
|
+
"aria-label": t ? t("row.delete") : "删除会话",
|
|
3350
|
+
onClick: (e) => {
|
|
3351
|
+
if (e && typeof e.stopPropagation === "function") e.stopPropagation();
|
|
3352
|
+
// Do NOT clear moveFor / moveAnchor here: opening the delete
|
|
3353
|
+
// popup must not silently dismiss a previously opened move
|
|
3354
|
+
// popup on the same session. The z-index counter (see
|
|
3355
|
+
// nextDialogZ) handles stacking.
|
|
3356
|
+
if (confirmFor && confirmFor.id === sessionId) {
|
|
3357
|
+
setConfirmFor(null);
|
|
3358
|
+
setConfirmAnchor(null);
|
|
3359
|
+
} else {
|
|
3360
|
+
setConfirmAnchor(anchorFor(e?.currentTarget, "delete"));
|
|
3361
|
+
setConfirmFor({ id: sessionId, displayTitle });
|
|
3362
|
+
}
|
|
2571
3363
|
}
|
|
2572
|
-
}
|
|
2573
|
-
|
|
3364
|
+
},
|
|
3365
|
+
h("span", { className: "sm-headerBtnIcon" }, "🗑"),
|
|
3366
|
+
h("span", { className: "sm-headerBtnLabel" }, t ? t("row.delete") : "删除会话")
|
|
3367
|
+
))
|
|
3368
|
+
),
|
|
3369
|
+
h("div", { className: "sm-headerCompactMenu", ref: moreBtnRef },
|
|
3370
|
+
renderTip((t && t("header.more")) || "更多操作", h("button", {
|
|
3371
|
+
ref: moreBtnElRef,
|
|
3372
|
+
type: "button",
|
|
3373
|
+
className: "sm-headerBtn sm-headerCompactMenuBtn" + (moreOpen ? " sm-headerBtnActive" : ""),
|
|
3374
|
+
"aria-label": (t && t("header.more")) || "更多操作",
|
|
3375
|
+
"aria-haspopup": "menu",
|
|
3376
|
+
"aria-expanded": moreOpen,
|
|
3377
|
+
onClick: (e) => {
|
|
3378
|
+
if (e && typeof e.stopPropagation === "function") e.stopPropagation();
|
|
3379
|
+
setMoreOpen(v => !v);
|
|
3380
|
+
}
|
|
3381
|
+
},
|
|
3382
|
+
h("span", { className: "sm-headerBtnIcon" }, "⋯")
|
|
3383
|
+
)),
|
|
3384
|
+
moreOpen ? h("div", { className: "sm-headerMenu", role: "menu" },
|
|
3385
|
+
h("button", {
|
|
3386
|
+
type: "button",
|
|
3387
|
+
className: "sm-headerMenuItem",
|
|
3388
|
+
role: "menuitem",
|
|
3389
|
+
onClick: () => {
|
|
3390
|
+
const anchorEl = getMoreBtn() || moreBtnRef.current;
|
|
3391
|
+
setMoreOpen(false);
|
|
3392
|
+
const nextOpen = !(annotationFor && annotationFor.id === sessionId);
|
|
3393
|
+
if (nextOpen && anchorEl) {
|
|
3394
|
+
setAnnotationAnchor(anchorFor(anchorEl, "annotation"));
|
|
3395
|
+
} else setAnnotationAnchor(null);
|
|
3396
|
+
setAnnotationFor(curr => (curr?.id === sessionId ? null : { id: sessionId, displayTitle }));
|
|
3397
|
+
}
|
|
3398
|
+
},
|
|
3399
|
+
h("span", { className: "sm-headerBtnIcon" }, "🏷"),
|
|
3400
|
+
h("span", null, t ? t("marks.header.edit") : "标签/备注")
|
|
3401
|
+
),
|
|
3402
|
+
h("button", {
|
|
3403
|
+
type: "button",
|
|
3404
|
+
className: "sm-headerMenuItem",
|
|
3405
|
+
role: "menuitem",
|
|
3406
|
+
onClick: () => {
|
|
3407
|
+
const anchorEl = getMoreBtn() || moreBtnRef.current;
|
|
3408
|
+
setMoreOpen(false);
|
|
3409
|
+
if (moveFor && moveFor.id === sessionId) {
|
|
3410
|
+
setMoveFor(null);
|
|
3411
|
+
setMoveAnchor(null);
|
|
3412
|
+
} else {
|
|
3413
|
+
setMoveAnchor(anchorFor(anchorEl, "move"));
|
|
3414
|
+
setMoveFor({ id: sessionId, displayTitle, workspaceId: "" });
|
|
3415
|
+
}
|
|
3416
|
+
}
|
|
3417
|
+
},
|
|
3418
|
+
h("span", { className: "sm-headerBtnIcon" }, "↔"),
|
|
3419
|
+
h("span", null, t ? t("row.move") : "移动至工作区")
|
|
3420
|
+
),
|
|
3421
|
+
(onArchive || onUnarchive) ? h("button", {
|
|
3422
|
+
type: "button",
|
|
3423
|
+
className: "sm-headerMenuItem",
|
|
3424
|
+
role: "menuitem",
|
|
3425
|
+
onClick: () => {
|
|
3426
|
+
setMoreOpen(false);
|
|
3427
|
+
runWithAlert("archive", () => isArchived ? onUnarchive(sessionId) : onArchive(sessionId));
|
|
3428
|
+
}
|
|
3429
|
+
},
|
|
3430
|
+
h("span", { className: "sm-headerBtnIcon" }, isArchived ? "📤" : "📥"),
|
|
3431
|
+
h("span", null, isArchived ? (t ? t("row.unarchive") : "移出归档") : (t ? t("row.archive") : "归档"))
|
|
3432
|
+
) : null,
|
|
3433
|
+
h("button", {
|
|
3434
|
+
type: "button",
|
|
3435
|
+
className: "sm-headerMenuItem sm-headerMenuItemDanger",
|
|
3436
|
+
role: "menuitem",
|
|
3437
|
+
onClick: () => {
|
|
3438
|
+
const anchorEl = getMoreBtn() || moreBtnRef.current;
|
|
3439
|
+
setMoreOpen(false);
|
|
3440
|
+
if (confirmFor && confirmFor.id === sessionId) {
|
|
3441
|
+
setConfirmFor(null);
|
|
3442
|
+
setConfirmAnchor(null);
|
|
3443
|
+
} else {
|
|
3444
|
+
setConfirmAnchor(anchorFor(anchorEl, "delete"));
|
|
3445
|
+
setConfirmFor({ id: sessionId, displayTitle });
|
|
3446
|
+
}
|
|
3447
|
+
}
|
|
3448
|
+
},
|
|
3449
|
+
h("span", { className: "sm-headerBtnIcon" }, "🗑"),
|
|
3450
|
+
h("span", null, t ? t("row.delete") : "删除会话")
|
|
3451
|
+
)
|
|
3452
|
+
) : null
|
|
3453
|
+
)
|
|
2574
3454
|
),
|
|
2575
3455
|
confirmFor === null ? null : h(ConfirmDialog, {
|
|
2576
3456
|
open: true,
|
|
@@ -2627,8 +3507,8 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
2627
3507
|
// Bulk operations need to refresh ctx.sessions.list and the
|
|
2628
3508
|
// workspace projection after /batch mutates disk state so the
|
|
2629
3509
|
// panel reflects the new layout.
|
|
2630
|
-
onRefreshAfterBulk: async () => {
|
|
2631
|
-
try { await this.props.props.onBulkRefresh(); } catch (_) { /* ignore */ }
|
|
3510
|
+
onRefreshAfterBulk: async (...args) => {
|
|
3511
|
+
try { await this.props.props.onBulkRefresh?.(...args); } catch (_) { /* ignore */ }
|
|
2632
3512
|
},
|
|
2633
3513
|
onOpen: (id) => { try { this.props.panelStore.set(false); this.props.props.onOpen(id); } catch (_) {} },
|
|
2634
3514
|
onArchive: this.props.props.onArchive,
|
|
@@ -2654,10 +3534,14 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
2654
3534
|
() => panelStore.getSnapshot(),
|
|
2655
3535
|
() => panelStore.getSnapshot()
|
|
2656
3536
|
);
|
|
2657
|
-
const
|
|
3537
|
+
const updateState = useSyncExternalStore(
|
|
3538
|
+
(cb) => updateStore.subscribe(cb),
|
|
3539
|
+
() => updateStore.getSnapshot(),
|
|
3540
|
+
() => updateStore.getSnapshot()
|
|
3541
|
+
);
|
|
2658
3542
|
const btnClass = "sm-footerBtn" + (wide ? " sm-footerBtn-wide" : " sm-footerBtn-rail");
|
|
2659
3543
|
const btnLabel = t("footer.aria");
|
|
2660
|
-
return h(
|
|
3544
|
+
return h(React.Fragment, null,
|
|
2661
3545
|
h("button", {
|
|
2662
3546
|
type: "button",
|
|
2663
3547
|
className: btnClass,
|
|
@@ -2674,11 +3558,344 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
2674
3558
|
t: t,
|
|
2675
3559
|
useSessions: props.useSessions,
|
|
2676
3560
|
useWorkspaces: props.useWorkspaces,
|
|
2677
|
-
}) : null
|
|
3561
|
+
}) : null,
|
|
3562
|
+
updateState.dialogOpen ? h(UpdateDialog, { t: t }) : null
|
|
3563
|
+
);
|
|
3564
|
+
}
|
|
3565
|
+
|
|
3566
|
+
function NpmIcon(props) {
|
|
3567
|
+
const size = props.size || 16;
|
|
3568
|
+
return h("svg", {
|
|
3569
|
+
viewBox: "0 0 16 16",
|
|
3570
|
+
width: size,
|
|
3571
|
+
height: size,
|
|
3572
|
+
fill: "currentColor",
|
|
3573
|
+
"aria-hidden": "true",
|
|
3574
|
+
style: { display: "block" }
|
|
3575
|
+
},
|
|
3576
|
+
h("path", {
|
|
3577
|
+
fillRule: "evenodd",
|
|
3578
|
+
d: "M0 0v16h16V0H0zm13 13h-2V5H8v8H3V3h10v10z"
|
|
3579
|
+
})
|
|
3580
|
+
);
|
|
3581
|
+
}
|
|
3582
|
+
const WhaleIcon = NpmIcon;
|
|
3583
|
+
|
|
3584
|
+
function CloseIcon(props) {
|
|
3585
|
+
const size = props.size || 14;
|
|
3586
|
+
return h("svg", {
|
|
3587
|
+
viewBox: "0 0 16 16",
|
|
3588
|
+
width: size,
|
|
3589
|
+
height: size,
|
|
3590
|
+
fill: "none",
|
|
3591
|
+
stroke: "currentColor",
|
|
3592
|
+
strokeWidth: "1.8",
|
|
3593
|
+
strokeLinecap: "round",
|
|
3594
|
+
strokeLinejoin: "round",
|
|
3595
|
+
"aria-hidden": "true",
|
|
3596
|
+
style: { display: "block" }
|
|
3597
|
+
},
|
|
3598
|
+
h("path", { d: "M3.5 3.5l9 9M12.5 3.5l-9 9" })
|
|
3599
|
+
);
|
|
3600
|
+
}
|
|
3601
|
+
|
|
3602
|
+
function StarIcon(props) {
|
|
3603
|
+
const size = props.size || 14;
|
|
3604
|
+
return h("svg", {
|
|
3605
|
+
viewBox: "0 0 16 16",
|
|
3606
|
+
width: size,
|
|
3607
|
+
height: size,
|
|
3608
|
+
fill: "#eac54f",
|
|
3609
|
+
"aria-hidden": "true",
|
|
3610
|
+
style: { display: "block" }
|
|
3611
|
+
},
|
|
3612
|
+
h("path", {
|
|
3613
|
+
d: "M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.75.75 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25z"
|
|
3614
|
+
})
|
|
3615
|
+
);
|
|
3616
|
+
}
|
|
3617
|
+
|
|
3618
|
+
function IssueIcon(props) {
|
|
3619
|
+
const size = props.size || 14;
|
|
3620
|
+
return h("svg", {
|
|
3621
|
+
viewBox: "0 0 16 16",
|
|
3622
|
+
width: size,
|
|
3623
|
+
height: size,
|
|
3624
|
+
fill: "currentColor",
|
|
3625
|
+
"aria-hidden": "true",
|
|
3626
|
+
style: { display: "block" }
|
|
3627
|
+
},
|
|
3628
|
+
h("path", {
|
|
3629
|
+
fillRule: "evenodd",
|
|
3630
|
+
d: "M8 1.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13zM0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8zm9 3a1 1 0 1 1-2 0 1 1 0 0 1 2 0zm-.25-6.25a.75.75 0 0 0-1.5 0v3.5a.75.75 0 0 0 1.5 0v-3.5z"
|
|
3631
|
+
})
|
|
3632
|
+
);
|
|
3633
|
+
}
|
|
3634
|
+
|
|
3635
|
+
function UpdateDialog(props) {
|
|
3636
|
+
const t = props.t || ((k) => k);
|
|
3637
|
+
const updateState = useSyncExternalStore(
|
|
3638
|
+
(cb) => updateStore.subscribe(cb),
|
|
3639
|
+
() => updateStore.getSnapshot(),
|
|
3640
|
+
() => updateStore.getSnapshot()
|
|
3641
|
+
);
|
|
3642
|
+
|
|
3643
|
+
const status = updateState.status;
|
|
3644
|
+
const isUpdating = status === "updating";
|
|
3645
|
+
const isDone = status === "done";
|
|
3646
|
+
const isError = status === "error";
|
|
3647
|
+
const isAvailable = status === "available";
|
|
3648
|
+
const isChecking = status === "checking";
|
|
3649
|
+
const isIdle = status === "idle";
|
|
3650
|
+
|
|
3651
|
+
let dialogTitle = t("update.title");
|
|
3652
|
+
if (isAvailable) dialogTitle = t("update.newVersion");
|
|
3653
|
+
else if (isUpdating) dialogTitle = t("update.installing");
|
|
3654
|
+
else if (isDone) dialogTitle = t("update.title");
|
|
3655
|
+
else if (isError) dialogTitle = t("update.error");
|
|
3656
|
+
|
|
3657
|
+
const handleClose = () => {
|
|
3658
|
+
if (!isUpdating) {
|
|
3659
|
+
updateStore.closeDialog();
|
|
3660
|
+
}
|
|
3661
|
+
};
|
|
3662
|
+
|
|
3663
|
+
return h(OverlayLayer, {
|
|
3664
|
+
className: "sm-updateDialogLayer",
|
|
3665
|
+
onBackdropClick: handleClose,
|
|
3666
|
+
onKeyDown: (e) => {
|
|
3667
|
+
if (e.key === "Escape" && !isUpdating) handleClose();
|
|
3668
|
+
}
|
|
3669
|
+
},
|
|
3670
|
+
h("section", {
|
|
3671
|
+
className: "sm-nativeDialog sm-updateDialog",
|
|
3672
|
+
style: { pointerEvents: "auto" },
|
|
3673
|
+
role: "dialog",
|
|
3674
|
+
"aria-modal": "true",
|
|
3675
|
+
"aria-labelledby": "sm-update-dialog-title"
|
|
3676
|
+
},
|
|
3677
|
+
h("div", { className: "sm-nativeDialogHeader" },
|
|
3678
|
+
h("h3", { id: "sm-update-dialog-title", className: "sm-nativeDialogTitle" }, dialogTitle),
|
|
3679
|
+
!isUpdating ? renderTip(t("update.btn.close"), h("button", {
|
|
3680
|
+
type: "button",
|
|
3681
|
+
className: "sm-panelHeaderClose",
|
|
3682
|
+
"aria-label": t("update.btn.close"),
|
|
3683
|
+
onClick: handleClose
|
|
3684
|
+
}, h(CloseIcon, { size: 14 }))) : null
|
|
3685
|
+
),
|
|
3686
|
+
h("div", { className: "sm-nativeDialogBody" },
|
|
3687
|
+
h("div", { className: "sm-updateVersionGrid" },
|
|
3688
|
+
h("span", { className: "sm-updateVersionLabel" }, t("update.currentVersion")),
|
|
3689
|
+
h("span", { className: "sm-updateVersionValue" }, "v" + updateState.currentVersion),
|
|
3690
|
+
h("span", { className: "sm-updateVersionLabel" }, t("update.latestVersion")),
|
|
3691
|
+
h("span", { className: "sm-updateVersionValue" }, updateState.latestVersion ? "v" + updateState.latestVersion : (isChecking ? t("update.checking") : "-"))
|
|
3692
|
+
),
|
|
3693
|
+
isChecking ? h("div", { className: "sm-updateStatusBox" }, t("update.checking")) : null,
|
|
3694
|
+
isAvailable ? h("div", { className: "sm-updateStatusBox sm-warn" }, t("update.newVersion") + " (v" + updateState.latestVersion + ")") : null,
|
|
3695
|
+
isUpdating ? h("div", { className: "sm-updateStatusBox sm-warn" }, t("update.installing")) : null,
|
|
3696
|
+
isDone ? h("div", { className: "sm-updateStatusBox sm-success" },
|
|
3697
|
+
updateState.application === "applied"
|
|
3698
|
+
? t("update.done.applied")
|
|
3699
|
+
: t("update.done.restart", { from: updateState.currentVersion, to: updateState.latestVersion || updateState.currentVersion })
|
|
3700
|
+
) : null,
|
|
3701
|
+
isError ? h("div", { className: "sm-updateStatusBox sm-error" }, (updateState.error || t("update.error"))) : null,
|
|
3702
|
+
(isIdle && updateState.latestVersion && !isAvailable) ? h("div", { className: "sm-updateStatusBox sm-success" }, t("update.isLatest")) : null
|
|
3703
|
+
),
|
|
3704
|
+
h("div", { className: "sm-nativeDialogFooter" },
|
|
3705
|
+
isAvailable ? h(React.Fragment, null,
|
|
3706
|
+
h("button", {
|
|
3707
|
+
type: "button",
|
|
3708
|
+
className: "sm-nativeDialogButton sm-nativeDialogCancel",
|
|
3709
|
+
onClick: handleClose
|
|
3710
|
+
}, t("update.btn.later")),
|
|
3711
|
+
h("button", {
|
|
3712
|
+
type: "button",
|
|
3713
|
+
className: "sm-nativeDialogButton sm-nativeDialogConfirm",
|
|
3714
|
+
onClick: () => updateStore.startUpdate()
|
|
3715
|
+
}, t("update.btn.update", { version: updateState.latestVersion }))
|
|
3716
|
+
) : null,
|
|
3717
|
+
isUpdating ? h("button", {
|
|
3718
|
+
type: "button",
|
|
3719
|
+
className: "sm-nativeDialogButton sm-nativeDialogConfirm",
|
|
3720
|
+
disabled: true
|
|
3721
|
+
}, t("update.btn.updating")) : null,
|
|
3722
|
+
isDone ? h("button", {
|
|
3723
|
+
type: "button",
|
|
3724
|
+
className: "sm-nativeDialogButton sm-nativeDialogConfirm",
|
|
3725
|
+
onClick: handleClose
|
|
3726
|
+
}, t("update.btn.done")) : null,
|
|
3727
|
+
isError ? h(React.Fragment, null,
|
|
3728
|
+
h("button", {
|
|
3729
|
+
type: "button",
|
|
3730
|
+
className: "sm-nativeDialogButton sm-nativeDialogCancel",
|
|
3731
|
+
onClick: handleClose
|
|
3732
|
+
}, t("update.btn.close")),
|
|
3733
|
+
h("button", {
|
|
3734
|
+
type: "button",
|
|
3735
|
+
className: "sm-nativeDialogButton sm-nativeDialogConfirm",
|
|
3736
|
+
onClick: () => {
|
|
3737
|
+
if (updateState.latestVersion && compareSemver(updateState.latestVersion, updateState.currentVersion) > 0) {
|
|
3738
|
+
updateStore.startUpdate();
|
|
3739
|
+
} else {
|
|
3740
|
+
updateStore.checkForUpdate({ manual: true, openDialog: true });
|
|
3741
|
+
}
|
|
3742
|
+
}
|
|
3743
|
+
}, t("update.btn.retry"))
|
|
3744
|
+
) : null,
|
|
3745
|
+
(isIdle || isChecking) ? h(React.Fragment, null,
|
|
3746
|
+
h("button", {
|
|
3747
|
+
type: "button",
|
|
3748
|
+
className: "sm-nativeDialogButton sm-nativeDialogCancel",
|
|
3749
|
+
onClick: handleClose
|
|
3750
|
+
}, t("update.btn.close")),
|
|
3751
|
+
!isChecking ? h("button", {
|
|
3752
|
+
type: "button",
|
|
3753
|
+
className: "sm-nativeDialogButton",
|
|
3754
|
+
onClick: () => updateStore.checkForUpdate({ manual: true, openDialog: true })
|
|
3755
|
+
}, t("update.btn.check")) : null
|
|
3756
|
+
) : null
|
|
3757
|
+
)
|
|
3758
|
+
)
|
|
3759
|
+
);
|
|
3760
|
+
}
|
|
3761
|
+
|
|
3762
|
+
function SessionManagerSettingsCard(props) {
|
|
3763
|
+
const t = props.t || ((k, v) => {
|
|
3764
|
+
const dict = zh[k] || en[k] || k;
|
|
3765
|
+
return dict.replace(/\{(\w+)\}/g, (_, name) => String(v?.[name] ?? ""));
|
|
3766
|
+
});
|
|
3767
|
+
const updateState = useSyncExternalStore(
|
|
3768
|
+
(cb) => updateStore.subscribe(cb),
|
|
3769
|
+
() => updateStore.getSnapshot(),
|
|
3770
|
+
() => updateStore.getSnapshot()
|
|
3771
|
+
);
|
|
3772
|
+
const autoCheck = updateStore.getAutoCheck();
|
|
3773
|
+
|
|
3774
|
+
const isChecking = updateState.status === "checking";
|
|
3775
|
+
const isUpdating = updateState.status === "updating";
|
|
3776
|
+
const isAvailable = updateState.status === "available";
|
|
3777
|
+
|
|
3778
|
+
const onToggleAutoCheck = (e) => {
|
|
3779
|
+
updateStore.setAutoCheck(e.target.checked);
|
|
3780
|
+
};
|
|
3781
|
+
const currentRegistry = updateStore.getRegistry();
|
|
3782
|
+
const onRegistryChange = (e) => {
|
|
3783
|
+
updateStore.setRegistry(e.target.value);
|
|
3784
|
+
};
|
|
3785
|
+
|
|
3786
|
+
return h("div", { className: "sm-settingsCard" },
|
|
3787
|
+
h("div", { className: "sm-settingsHeader" },
|
|
3788
|
+
h("h3", { className: "sm-settingsTitle" },
|
|
3789
|
+
h(NpmIcon, { size: 18 }),
|
|
3790
|
+
h("span", null, t("settings.title")),
|
|
3791
|
+
h("span", { className: "sm-settingsTag" }, "v" + updateState.currentVersion)
|
|
3792
|
+
)
|
|
3793
|
+
),
|
|
3794
|
+
h("div", { className: "sm-settingsSection" },
|
|
3795
|
+
h("div", { className: "sm-settingsSectionHeader" },
|
|
3796
|
+
h("div", { className: "sm-settingsSectionTitle" }, t("settings.versionSection")),
|
|
3797
|
+
h("div", { className: "sm-settingsVersionActions" },
|
|
3798
|
+
h("button", {
|
|
3799
|
+
type: "button",
|
|
3800
|
+
className: "sm-nativeDialogButton sm-settingsCheckBtn",
|
|
3801
|
+
disabled: isChecking || isUpdating,
|
|
3802
|
+
onClick: () => updateStore.checkForUpdate({ manual: true, openOnFound: false, openDialog: false })
|
|
3803
|
+
}, isChecking ? t("update.checking") : t("update.btn.check")),
|
|
3804
|
+
isAvailable ? h("button", {
|
|
3805
|
+
type: "button",
|
|
3806
|
+
className: "sm-nativeDialogButton sm-nativeDialogConfirm sm-settingsCheckBtn",
|
|
3807
|
+
disabled: isUpdating,
|
|
3808
|
+
onClick: () => updateStore.startUpdate({ openDialog: false })
|
|
3809
|
+
}, isUpdating ? t("update.btn.updating") : t("update.btn.update", { version: updateState.latestVersion })) : null
|
|
3810
|
+
)
|
|
3811
|
+
),
|
|
3812
|
+
h("div", { className: "sm-settingsRow" },
|
|
3813
|
+
h("span", null, t("update.currentVersion")),
|
|
3814
|
+
h("span", { style: { fontFamily: "monospace" } }, "v" + updateState.currentVersion)
|
|
3815
|
+
),
|
|
3816
|
+
h("div", { className: "sm-settingsRow" },
|
|
3817
|
+
h("span", null, t("update.latestVersion")),
|
|
3818
|
+
h("span", { style: { fontFamily: "monospace" } },
|
|
3819
|
+
updateState.latestVersion ? "v" + updateState.latestVersion : (isChecking ? t("update.checking") : "-")
|
|
3820
|
+
)
|
|
3821
|
+
),
|
|
3822
|
+
updateState.status === "available" ? h("div", { className: "sm-updateStatusBox sm-warn" },
|
|
3823
|
+
t("update.newVersion") + " (v" + updateState.latestVersion + ")"
|
|
3824
|
+
) : null,
|
|
3825
|
+
updateState.status === "updating" ? h("div", { className: "sm-updateStatusBox sm-warn" },
|
|
3826
|
+
t("update.installing")
|
|
3827
|
+
) : null,
|
|
3828
|
+
updateState.status === "done" ? h("div", { className: "sm-updateStatusBox sm-success" },
|
|
3829
|
+
updateState.application === "applied" ? t("update.done.applied") : t("update.done.restart", { from: updateState.currentVersion, to: updateState.latestVersion || updateState.currentVersion })
|
|
3830
|
+
) : null,
|
|
3831
|
+
updateState.status === "error" ? h("div", { className: "sm-updateStatusBox sm-error" },
|
|
3832
|
+
updateState.error || t("update.error")
|
|
3833
|
+
) : null
|
|
3834
|
+
),
|
|
3835
|
+
h("div", { className: "sm-settingsSection" },
|
|
3836
|
+
h("div", { className: "sm-settingsSectionTitle" }, t("settings.prefSection")),
|
|
3837
|
+
h("div", { className: "sm-settingsRow" },
|
|
3838
|
+
h("span", null, t("settings.registry")),
|
|
3839
|
+
h("select", {
|
|
3840
|
+
className: "sm-settingsSelect",
|
|
3841
|
+
value: currentRegistry,
|
|
3842
|
+
onChange: onRegistryChange,
|
|
3843
|
+
"aria-label": t("settings.registry")
|
|
3844
|
+
},
|
|
3845
|
+
h("option", { value: "registry.npmjs.org" }, t("settings.registry.npm")),
|
|
3846
|
+
h("option", { value: "registry.npmmirror.com" }, t("settings.registry.china"))
|
|
3847
|
+
)
|
|
3848
|
+
),
|
|
3849
|
+
h("div", { className: "sm-settingsRow" },
|
|
3850
|
+
h("span", null, t("update.autoCheck")),
|
|
3851
|
+
h("label", { className: "sm-settingsCheckbox" },
|
|
3852
|
+
h("input", {
|
|
3853
|
+
type: "checkbox",
|
|
3854
|
+
checked: autoCheck,
|
|
3855
|
+
onChange: onToggleAutoCheck,
|
|
3856
|
+
"aria-label": t("update.autoCheck")
|
|
3857
|
+
}),
|
|
3858
|
+
h("span", null, t("update.autoCheck.enable"))
|
|
3859
|
+
)
|
|
3860
|
+
)
|
|
3861
|
+
),
|
|
3862
|
+
h("div", { className: "sm-settingsSection" },
|
|
3863
|
+
h("div", { className: "sm-settingsSectionTitle" }, t("settings.projectSection")),
|
|
3864
|
+
h("div", { className: "sm-settingsRow sm-settingsRowInline" },
|
|
3865
|
+
h("span", null, t("settings.github")),
|
|
3866
|
+
h("a", {
|
|
3867
|
+
href: "https://github.com/hkkz9522/dsh-session-manager",
|
|
3868
|
+
target: "_blank",
|
|
3869
|
+
rel: "noopener noreferrer",
|
|
3870
|
+
className: "sm-settingsLink"
|
|
3871
|
+
}, "hkkz9522/dsh-session-manager"),
|
|
3872
|
+
h("a", {
|
|
3873
|
+
href: "https://github.com/hkkz9522/dsh-session-manager",
|
|
3874
|
+
target: "_blank",
|
|
3875
|
+
rel: "noopener noreferrer",
|
|
3876
|
+
className: "sm-settingsBadgeLink",
|
|
3877
|
+
title: "Star on GitHub"
|
|
3878
|
+
},
|
|
3879
|
+
h(StarIcon, { size: 14 }),
|
|
3880
|
+
h("span", null, t("settings.star"))
|
|
3881
|
+
),
|
|
3882
|
+
h("a", {
|
|
3883
|
+
href: "https://github.com/hkkz9522/dsh-session-manager/issues",
|
|
3884
|
+
target: "_blank",
|
|
3885
|
+
rel: "noopener noreferrer",
|
|
3886
|
+
className: "sm-settingsBadgeLink",
|
|
3887
|
+
title: "GitHub Issues"
|
|
3888
|
+
},
|
|
3889
|
+
h(IssueIcon, { size: 14 }),
|
|
3890
|
+
h("span", null, t("settings.feedback"))
|
|
3891
|
+
)
|
|
3892
|
+
)
|
|
3893
|
+
)
|
|
2678
3894
|
);
|
|
2679
3895
|
}
|
|
2680
3896
|
|
|
2681
3897
|
function apply(ctx) {
|
|
3898
|
+
activeClientCtx = ctx;
|
|
2682
3899
|
ctx.effect(() => {
|
|
2683
3900
|
const refresh = () => { if (annotationStore.hasSubscribers()) void annotationStore.load(true); };
|
|
2684
3901
|
window.addEventListener("focus", refresh);
|
|
@@ -2693,6 +3910,34 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
2693
3910
|
return () => { window.removeEventListener("focus", refresh); channel?.close(); annotationStore.notify = null; };
|
|
2694
3911
|
}, "session-manager: annotation synchronization");
|
|
2695
3912
|
ctx.effect(() => ctx.locale.register(NS, { zh, en }), "session-manager: dictionaries");
|
|
3913
|
+
const getCurrentSessionId = () => {
|
|
3914
|
+
try {
|
|
3915
|
+
const id = ctx.uiWorkspace?.mainReference?.sessionId
|
|
3916
|
+
|| ctx.uiWorkspace?.selection?.getSnapshot?.()?.sessionId
|
|
3917
|
+
|| ctx.sessions?.list?.getSnapshot?.()?.current;
|
|
3918
|
+
return typeof id === "string" && id ? id : null;
|
|
3919
|
+
} catch (_) {
|
|
3920
|
+
return null;
|
|
3921
|
+
}
|
|
3922
|
+
};
|
|
3923
|
+
|
|
3924
|
+
const isCurrentSession = (id) => {
|
|
3925
|
+
if (!id) return false;
|
|
3926
|
+
return getCurrentSessionId() === id;
|
|
3927
|
+
};
|
|
3928
|
+
|
|
3929
|
+
const clearCurrentSession = () => {
|
|
3930
|
+
const uiWorkspace = ctx.uiWorkspace;
|
|
3931
|
+
if (uiWorkspace && typeof uiWorkspace.clearMain === "function") {
|
|
3932
|
+
try { uiWorkspace.clearMain(); } catch (_) {}
|
|
3933
|
+
} else if (uiWorkspace && typeof uiWorkspace.startSession === "function") {
|
|
3934
|
+
try { uiWorkspace.startSession(); } catch (_) {}
|
|
3935
|
+
}
|
|
3936
|
+
if (ctx.sessions && typeof ctx.sessions.clear === "function") {
|
|
3937
|
+
try { ctx.sessions.clear(); } catch (_) {}
|
|
3938
|
+
}
|
|
3939
|
+
};
|
|
3940
|
+
|
|
2696
3941
|
const actions = () => ({
|
|
2697
3942
|
// DSH 0.1.6+ removed ctx.sessions.open(); the navigation owner is
|
|
2698
3943
|
// `ctx.uiWorkspace.openSession()`, and the bare SessionController only
|
|
@@ -2714,18 +3959,28 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
2714
3959
|
}
|
|
2715
3960
|
throw new Error("session-manager: no Session open API on this DSH host");
|
|
2716
3961
|
},
|
|
2717
|
-
onArchive: async (sessionId) => {
|
|
3962
|
+
onArchive: async (sessionId) => {
|
|
3963
|
+
if (ctx.uiWorkspace && typeof ctx.uiWorkspace.archiveSession === "function") {
|
|
3964
|
+
await ctx.uiWorkspace.archiveSession(sessionId);
|
|
3965
|
+
} else {
|
|
3966
|
+
await ctx.workspaces.archiveSession(sessionId);
|
|
3967
|
+
}
|
|
3968
|
+
},
|
|
2718
3969
|
onUnarchive: async (sessionId) => {
|
|
2719
3970
|
const response = await callApi("/unarchive", { sessionId });
|
|
2720
3971
|
if (!response.ok) throw new Error(response.error || "unarchive failed");
|
|
2721
3972
|
},
|
|
2722
3973
|
onRemove: async (sessionId) => {
|
|
3974
|
+
const wasCurrent = isCurrentSession(sessionId);
|
|
2723
3975
|
const response = await callApi("/delete", { sessionId });
|
|
2724
3976
|
if (!response.ok) throw new Error(response.error || "delete failed");
|
|
2725
3977
|
await annotationStore.load(true);
|
|
2726
3978
|
if (response.result?.warning) window.alert(response.result.warning);
|
|
2727
|
-
|
|
2728
|
-
|
|
3979
|
+
if (wasCurrent || isCurrentSession(sessionId)) {
|
|
3980
|
+
clearCurrentSession();
|
|
3981
|
+
}
|
|
3982
|
+
try { await ctx.sessions?.refresh?.(); } catch (_) {}
|
|
3983
|
+
try { await ctx.workspaces?.refresh?.(); } catch (_) {}
|
|
2729
3984
|
},
|
|
2730
3985
|
onMove: async (sessionId, targetWorkspaceId) => {
|
|
2731
3986
|
const wasCurrent = ctx.sessions.list.getSnapshot().current === sessionId;
|
|
@@ -2755,7 +4010,6 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
2755
4010
|
if (!response.ok) throw new Error(response.error || "preset migration failed");
|
|
2756
4011
|
// The current DSH client session store derives agentPreset from
|
|
2757
4012
|
// the refreshed projection; older builds exposed noteAgentPreset,
|
|
2758
|
-
onOpenPanel: () => panelStore.toggle(),
|
|
2759
4013
|
await ctx.sessions.refresh();
|
|
2760
4014
|
// The migrate rewrite happens in-process on the live session, so
|
|
2761
4015
|
// we just need a delayed baseline to let the api-gateway's projection
|
|
@@ -2767,7 +4021,31 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
2767
4021
|
}, 250);
|
|
2768
4022
|
},
|
|
2769
4023
|
onOpenPanel: () => panelStore.toggle(),
|
|
2770
|
-
onBulkRefresh: async () => {
|
|
4024
|
+
onBulkRefresh: async (action, meta) => {
|
|
4025
|
+
const currentBefore = getCurrentSessionId();
|
|
4026
|
+
if (action === "delete" || action === "archive") {
|
|
4027
|
+
const items = meta?.items || meta?.result?.items || [];
|
|
4028
|
+
const successIds = items
|
|
4029
|
+
.filter(item => item && (item.status === "success" || item.ok === true))
|
|
4030
|
+
.map(item => item.sessionId);
|
|
4031
|
+
const batchIds = (lastBatchContext.action === action && Array.isArray(lastBatchContext.ids)) ? lastBatchContext.ids : [];
|
|
4032
|
+
const candidateIds = successIds.length > 0 ? successIds : (meta?.ids || batchIds);
|
|
4033
|
+
if (candidateIds.some(isCurrentSession)) {
|
|
4034
|
+
clearCurrentSession();
|
|
4035
|
+
}
|
|
4036
|
+
}
|
|
4037
|
+
try { await ctx.sessions?.refresh?.(); } catch (_) { /* ignore */ }
|
|
4038
|
+
try { await ctx.workspaces?.refresh?.(); } catch (_) { /* ignore */ }
|
|
4039
|
+
if (currentBefore && (action === "delete" || action === "archive")) {
|
|
4040
|
+
const sessionsSnapshot = ctx.sessions?.list?.getSnapshot?.();
|
|
4041
|
+
const workspacesSnapshot = ctx.workspaces?.list?.getSnapshot?.();
|
|
4042
|
+
const deleted = sessionsSnapshot?.byId && sessionsSnapshot.byId[currentBefore] === undefined;
|
|
4043
|
+
const archived = Array.isArray(workspacesSnapshot?.archivedSessionIds) && workspacesSnapshot.archivedSessionIds.includes(currentBefore);
|
|
4044
|
+
if (deleted || archived) {
|
|
4045
|
+
clearCurrentSession();
|
|
4046
|
+
}
|
|
4047
|
+
}
|
|
4048
|
+
},
|
|
2771
4049
|
});
|
|
2772
4050
|
ctx.slots.inject("conversation.session.header.actions", () => ctx.slots.register({
|
|
2773
4051
|
name: "conversation.session.header.actions",
|
|
@@ -2783,12 +4061,66 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
2783
4061
|
locale: NS,
|
|
2784
4062
|
inject: () => actions()
|
|
2785
4063
|
}, FooterAction));
|
|
4064
|
+
ctx.slots.inject("plugins.bundle.config", () => ctx.slots.register({
|
|
4065
|
+
name: "plugins.bundle.config",
|
|
4066
|
+
id: "dsh-session-manager-bundle-config",
|
|
4067
|
+
key: "dsh-session-manager",
|
|
4068
|
+
locale: NS,
|
|
4069
|
+
inject: () => actions()
|
|
4070
|
+
}, (ownerProps = {}) => (ownerProps?.view === "summary" ? null : h(SessionManagerSettingsCard, ownerProps))));
|
|
4071
|
+
|
|
4072
|
+
try {
|
|
4073
|
+
if (typeof ctx.inject === "function") {
|
|
4074
|
+
ctx.inject(["settingsScope"], (scoped) => {
|
|
4075
|
+
if (scoped && scoped.slots) {
|
|
4076
|
+
scoped.slots.inject("settings.plugin.item", () => scoped.slots.register({
|
|
4077
|
+
name: "settings.plugin.item",
|
|
4078
|
+
id: "session-manager-settings-scoped",
|
|
4079
|
+
key: "dsh-session-manager",
|
|
4080
|
+
locale: NS,
|
|
4081
|
+
inject: () => actions()
|
|
4082
|
+
}, SessionManagerSettingsCard));
|
|
4083
|
+
}
|
|
4084
|
+
});
|
|
4085
|
+
}
|
|
4086
|
+
} catch (_) {}
|
|
4087
|
+
|
|
4088
|
+
ctx.slots.inject("settings.plugin.item", () => ctx.slots.register({
|
|
4089
|
+
name: "settings.plugin.item",
|
|
4090
|
+
id: "session-manager-settings",
|
|
4091
|
+
key: "dsh-session-manager",
|
|
4092
|
+
order: 50,
|
|
4093
|
+
locale: NS,
|
|
4094
|
+
inject: () => actions()
|
|
4095
|
+
}, SessionManagerSettingsCard));
|
|
4096
|
+
|
|
4097
|
+
ctx.effect(() => {
|
|
4098
|
+
if (!updateStore.getAutoCheck()) return;
|
|
4099
|
+
const timer = setTimeout(() => {
|
|
4100
|
+
updateStore.checkForUpdate({ silent: true, openOnFound: false, openDialog: false }).catch(() => {});
|
|
4101
|
+
}, 1500);
|
|
4102
|
+
return () => {
|
|
4103
|
+
try {
|
|
4104
|
+
if (typeof clearTimeout === "function") clearTimeout(timer);
|
|
4105
|
+
else if (typeof window !== "undefined" && typeof window.clearTimeout === "function") window.clearTimeout(timer);
|
|
4106
|
+
} catch (_) {}
|
|
4107
|
+
};
|
|
4108
|
+
}, "session-manager: auto update check");
|
|
2786
4109
|
}
|
|
2787
4110
|
|
|
2788
4111
|
const inject = ["slots", "sessions", "workspaces", "locale", "uiWorkspace"];
|
|
2789
4112
|
|
|
2790
4113
|
exports.apply = apply;
|
|
2791
4114
|
exports.inject = inject;
|
|
4115
|
+
exports.updateStore = updateStore;
|
|
4116
|
+
exports.compareSemver = compareSemver;
|
|
4117
|
+
exports.UpdateDialog = UpdateDialog;
|
|
4118
|
+
exports.SessionManagerSettingsCard = SessionManagerSettingsCard;
|
|
4119
|
+
exports.WhaleIcon = WhaleIcon;
|
|
4120
|
+
exports.NpmIcon = NpmIcon;
|
|
4121
|
+
exports.CloseIcon = CloseIcon;
|
|
4122
|
+
exports.StarIcon = StarIcon;
|
|
4123
|
+
exports.IssueIcon = IssueIcon;
|
|
2792
4124
|
return module.exports;
|
|
2793
4125
|
}
|
|
2794
4126
|
});
|