dsh-session-manager 0.5.4 → 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 +23 -0
- package/README.local-workflow.md +52 -0
- package/README.md +11 -1
- package/README.zh.md +11 -3
- package/lib/annotation-store.js +1 -1
- package/lib/client.js +1481 -148
- package/lib/compat/dsh-adapter.js +55 -0
- package/lib/index.js +83 -2
- package/package.json +1 -1
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": "移出归档",
|
|
@@ -129,6 +147,38 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
129
147
|
"footer.label": "会话管理",
|
|
130
148
|
"panel.title": "会话管理",
|
|
131
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": "全部工作区",
|
|
@@ -303,6 +353,7 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
303
353
|
"marks.tags.clear": "Clear tags",
|
|
304
354
|
"marks.note.clear": "Clear note",
|
|
305
355
|
"header.aria": "Session actions",
|
|
356
|
+
"header.more": "More actions",
|
|
306
357
|
"menu.open": "Open",
|
|
307
358
|
"menu.archive": "Archive session",
|
|
308
359
|
"menu.unarchive": "Unarchive session",
|
|
@@ -313,6 +364,38 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
313
364
|
"footer.label": "Sessions",
|
|
314
365
|
"panel.title": "Session manager",
|
|
315
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",
|
|
316
399
|
"panel.search": "Search title, ID, tags or notes",
|
|
317
400
|
"panel.workspace": "Workspace",
|
|
318
401
|
"panel.workspace.all": "All workspaces",
|
|
@@ -469,17 +552,17 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
469
552
|
".sm-moveItem:hover{background:var(--dsw-alias-interactive-bg-hover)}",
|
|
470
553
|
".sm-moveItemSelected{border-color:var(--dsw-alias-accent-primary);background:var(--dsw-alias-accent-primary-bg)}",
|
|
471
554
|
".sm-moveItemName{color:var(--dsw-alias-label-primary);font-size:13px;line-height:18px}",
|
|
472
|
-
".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:
|
|
473
|
-
".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)}",
|
|
474
|
-
".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}",
|
|
475
558
|
|
|
476
559
|
// Theme colors are scoped to the plugin dialogs. DSH exposes its
|
|
477
560
|
// actual theme through `body[data-ds-dark-theme]` and color-scheme;
|
|
478
561
|
// keeping these values local avoids changing DSH's global variables.
|
|
479
|
-
"[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}",
|
|
480
|
-
"[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)}",
|
|
481
|
-
"[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}",
|
|
482
|
-
"[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}",
|
|
483
566
|
".sm-panelDialog{max-height:min(640px,calc(100vh - 32px))}.sm-panelDialog .sm-panel{min-width:0;overflow:hidden}",
|
|
484
567
|
".sm-panelTools{display:flex;flex-direction:column;gap:8px;flex:none;padding:2px 0 6px}",
|
|
485
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}",
|
|
@@ -491,13 +574,14 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
491
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)}",
|
|
492
575
|
"[data-sm-theme=dark] .sm-priority-1{color:#fdba74}[data-sm-theme=dark] .sm-priority-2{color:#fde68a}",
|
|
493
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)}",
|
|
494
|
-
".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}
|
|
495
|
-
".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)}",
|
|
496
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)}",
|
|
497
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}",
|
|
498
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}",
|
|
499
582
|
".sm-bulkSummary{color:var(--dsw-alias-label-primary,#111);font-size:12px;line-height:18px;font-weight:500}",
|
|
500
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}",
|
|
501
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}",
|
|
502
586
|
".sm-bulkBar .sm-bulkBtn:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary,#111)}",
|
|
503
587
|
".sm-bulkBar .sm-bulkBtn:disabled{opacity:.5;cursor:not-allowed}",
|
|
@@ -508,7 +592,7 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
508
592
|
".sm-bulkRowCheckbox input{width:14px;height:14px;cursor:pointer;margin:0}",
|
|
509
593
|
".sm-bulkRowCheckbox input:disabled{cursor:not-allowed}",
|
|
510
594
|
".sm-rowBulkSelected{border-color:var(--dsw-alias-accent-primary,#356ae6);background:var(--dsw-alias-accent-primary-bg,rgba(53,106,230,.06))}",
|
|
511
|
-
".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}",
|
|
512
596
|
".sm-bulkDialog .sm-nativeDialog{width:100%;max-height:min(640px,calc(100vh - 32px))}",
|
|
513
597
|
".sm-bulkDialogBody{display:flex;flex-direction:column;gap:12px;min-height:0}",
|
|
514
598
|
".sm-bulkDialogSummary{font-size:13px;line-height:20px;color:var(--dsw-alias-label-primary,#111)}",
|
|
@@ -526,13 +610,14 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
526
610
|
".sm-bulkResultItemReason{color:var(--dsw-alias-state-error-primary);font-size:11px;line-height:16px;word-break:break-word}",
|
|
527
611
|
".sm-bulkResultItemReasonSkip{color:var(--dsw-alias-label-tertiary,#888)}",
|
|
528
612
|
".sm-bulkResultFooter{display:flex;justify-content:space-between;align-items:center;gap:8px;flex-wrap:wrap}",
|
|
529
|
-
".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}",
|
|
530
614
|
".sm-footerBtn-wide:hover,.sm-footerBtn-wide:focus-visible{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover)}",
|
|
531
|
-
".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}",
|
|
532
616
|
".sm-footerBtn-rail:hover,.sm-footerBtn-rail:focus-visible{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover)}",
|
|
533
617
|
".sm-footerBtn-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;max-width:100%}",
|
|
534
|
-
".sm-
|
|
535
|
-
".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}",
|
|
536
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)}}",
|
|
537
622
|
].join("");
|
|
538
623
|
|
|
@@ -656,6 +741,268 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
656
741
|
try { installAnchor(); } catch (_) {}
|
|
657
742
|
|
|
658
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
|
+
|
|
659
1006
|
const callApi = (path, payload) => fetch(API + path, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify(payload || {}) }).then((r) => r.json());
|
|
660
1007
|
const fetchApi = (path, options) => fetch(API + path, options).then((r) => r.json());
|
|
661
1008
|
// Run a bulk action across many sessionIds. /batch already does per-id
|
|
@@ -743,12 +1090,30 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
743
1090
|
const annotationButtons = (id, title, t, state, className, onToggle, onEdit, disabled = false, editorOpen = false) => {
|
|
744
1091
|
const value = annotationOf(state, id);
|
|
745
1092
|
const busy = disabled || !state.loaded || !!state.error || state.pending.has(id);
|
|
746
|
-
const
|
|
747
|
-
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";
|
|
748
1098
|
return h(React.Fragment, null,
|
|
749
|
-
h("button", { type: "button", className: className + " sm-markIcon" + (value.favorite ? " sm-markOn" : ""), disabled: busy, "aria-label": favoriteLabel,
|
|
750
|
-
|
|
751
|
-
|
|
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
|
+
))
|
|
752
1117
|
);
|
|
753
1118
|
};
|
|
754
1119
|
|
|
@@ -1239,17 +1604,19 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
1239
1604
|
return "zh";
|
|
1240
1605
|
};
|
|
1241
1606
|
const activeLanguage = detectLanguage(t);
|
|
1242
|
-
const
|
|
1243
|
-
const
|
|
1244
|
-
const
|
|
1245
|
-
|
|
1246
|
-
|
|
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" : "");
|
|
1247
1613
|
const layerStyle = {
|
|
1248
1614
|
zIndex: zIndex || undefined,
|
|
1249
|
-
...(
|
|
1615
|
+
...(hasCoords ? { position: "fixed", top: computedTop + "px", left: computedLeft + "px", right: "auto", bottom: "auto", inset: `${computedTop}px auto auto ${computedLeft}px` } : {})
|
|
1250
1616
|
};
|
|
1251
|
-
return
|
|
1252
|
-
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 },
|
|
1253
1620
|
h("div", { className: "sm-nativeDialogHeader" }, h("h2", { id: "sm-annotation-title", className: "sm-nativeDialogTitle" }, t("marks.title"))),
|
|
1254
1621
|
h("div", { className: "sm-annotationBody" },
|
|
1255
1622
|
h("div", { className: "sm-annotationTarget", title: displayTitle || sessionId }, displayTitle || sessionId),
|
|
@@ -1284,7 +1651,7 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
1284
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"))
|
|
1285
1652
|
)
|
|
1286
1653
|
)
|
|
1287
|
-
);
|
|
1654
|
+
));
|
|
1288
1655
|
}
|
|
1289
1656
|
|
|
1290
1657
|
|
|
@@ -1351,24 +1718,31 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
1351
1718
|
window.addEventListener("keydown", handler);
|
|
1352
1719
|
return () => window.removeEventListener("keydown", handler);
|
|
1353
1720
|
}, [open]);
|
|
1354
|
-
// 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.
|
|
1355
1721
|
|
|
1722
|
+
const floatingCoords = useFloatingPosition(props.anchor, open, { placement: "bottom-end", dialogWidth: 360, dialogHeight: 180 });
|
|
1356
1723
|
|
|
1357
1724
|
if (!open) return null;
|
|
1358
1725
|
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
zIndex: zIndex || undefined,
|
|
1363
|
-
...(props.anchor && typeof props.anchor.top === "number"
|
|
1364
|
-
? { position: "fixed", top: props.anchor.top + "px", left: props.anchor.left + "px" }
|
|
1365
|
-
: {})
|
|
1366
|
-
},
|
|
1367
|
-
role: "presentation"
|
|
1368
|
-
},
|
|
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;
|
|
1369
1729
|
|
|
1370
|
-
|
|
1371
|
-
|
|
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" },
|
|
1372
1746
|
role: "dialog",
|
|
1373
1747
|
"aria-modal": "true",
|
|
1374
1748
|
"aria-labelledby": "sm-confirm-dialog-title"
|
|
@@ -1395,7 +1769,7 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
1395
1769
|
}, confirmLabel)
|
|
1396
1770
|
)
|
|
1397
1771
|
)
|
|
1398
|
-
);
|
|
1772
|
+
));
|
|
1399
1773
|
}
|
|
1400
1774
|
|
|
1401
1775
|
function MoveDialog(props) {
|
|
@@ -1476,20 +1850,27 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
1476
1850
|
onConfirm(selectedWorkspaceId);
|
|
1477
1851
|
}
|
|
1478
1852
|
};
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
...(props.anchor && typeof props.anchor.top === "number"
|
|
1484
|
-
? { position: "fixed", top: props.anchor.top + "px", left: props.anchor.left + "px" }
|
|
1485
|
-
: {})
|
|
1486
|
-
},
|
|
1487
|
-
role: "presentation",
|
|
1488
|
-
onKeyDown
|
|
1489
|
-
},
|
|
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;
|
|
1490
1857
|
|
|
1491
|
-
|
|
1492
|
-
|
|
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" },
|
|
1493
1874
|
role: "dialog",
|
|
1494
1875
|
"aria-modal": "true",
|
|
1495
1876
|
"aria-labelledby": "sm-move-dialog-title"
|
|
@@ -1513,7 +1894,7 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
1513
1894
|
}, confirmLabel)
|
|
1514
1895
|
)
|
|
1515
1896
|
)
|
|
1516
|
-
);
|
|
1897
|
+
));
|
|
1517
1898
|
}
|
|
1518
1899
|
|
|
1519
1900
|
function MigratePresetDialog(props) {
|
|
@@ -1610,14 +1991,15 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
1610
1991
|
target === currentPreset ? h("div", { className: "sm-migrateWarn" }, t("migrate.same")) : null
|
|
1611
1992
|
)
|
|
1612
1993
|
);
|
|
1613
|
-
return
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
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" },
|
|
1621
2003
|
role: "dialog",
|
|
1622
2004
|
"aria-modal": "true",
|
|
1623
2005
|
"aria-labelledby": "sm-migrate-dialog-title"
|
|
@@ -1641,9 +2023,274 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
1641
2023
|
}, busy ? t("busy.processing") : t("migrate.confirm"))
|
|
1642
2024
|
)
|
|
1643
2025
|
)
|
|
1644
|
-
);
|
|
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;
|
|
1645
2079
|
}
|
|
1646
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
|
+
|
|
1647
2294
|
const panelStore = {
|
|
1648
2295
|
open: false,
|
|
1649
2296
|
listeners: new Set(),
|
|
@@ -1661,6 +2308,7 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
1661
2308
|
setPendingMove(v) { this.pendingMove = v; this._emitPending(); },
|
|
1662
2309
|
consumePendingMove() { const v = this.pendingMove; this.pendingMove = null; return v; }
|
|
1663
2310
|
};
|
|
2311
|
+
const lastBatchContext = { action: null, ids: [] };
|
|
1664
2312
|
|
|
1665
2313
|
const DEFAULT_SORT = "updated-desc";
|
|
1666
2314
|
const SORT_ORDERS = ["updated-desc", "updated-asc", "created-desc", "created-asc", "priority"];
|
|
@@ -1716,6 +2364,11 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
1716
2364
|
const onMigrate = props.onMigrate;
|
|
1717
2365
|
const annotations = useAnnotations(true);
|
|
1718
2366
|
const marksReady = annotations.loaded && !annotations.error;
|
|
2367
|
+
const updateState = useSyncExternalStore(
|
|
2368
|
+
(cb) => updateStore.subscribe(cb),
|
|
2369
|
+
() => updateStore.getSnapshot(),
|
|
2370
|
+
() => updateStore.getSnapshot()
|
|
2371
|
+
);
|
|
1719
2372
|
const [onlyFavorite, setOnlyFavorite] = useState(false);
|
|
1720
2373
|
const [onlyReview, setOnlyReview] = useState(false);
|
|
1721
2374
|
const [tagFilter, setTagFilter] = useState("all");
|
|
@@ -1839,6 +2492,8 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
1839
2492
|
setBulkProgress(null);
|
|
1840
2493
|
setBulkResult({ action, actionLabel, items });
|
|
1841
2494
|
setBulkBusy(false);
|
|
2495
|
+
lastBatchContext.action = action;
|
|
2496
|
+
lastBatchContext.ids = ids;
|
|
1842
2497
|
try { await annotationStore.load(true); } catch (_) { /* ignore */ }
|
|
1843
2498
|
if (typeof props.onRefreshAfterBulk === "function") {
|
|
1844
2499
|
try { await props.onRefreshAfterBulk(action); } catch (_) { /* ignore */ }
|
|
@@ -1890,16 +2545,16 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
1890
2545
|
const onBulkTagApply = (tags) => {
|
|
1891
2546
|
const mode = bulkTagDraft && bulkTagDraft.mode;
|
|
1892
2547
|
setBulkTagDraft(null);
|
|
1893
|
-
if (mode === "add") onBulkAction("add-tags", { tags },
|
|
2548
|
+
if (mode === "add") onBulkAction("add-tags", { tags }, false);
|
|
1894
2549
|
};
|
|
1895
2550
|
const onBulkPriorityApply = (value) => {
|
|
1896
2551
|
const priority = Number(value);
|
|
1897
2552
|
setBulkTagDraft(null);
|
|
1898
|
-
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);
|
|
1899
2554
|
};
|
|
1900
2555
|
const onBulkMoveApply = (value) => {
|
|
1901
2556
|
setBulkTagDraft(null);
|
|
1902
|
-
if (value) onBulkAction("move", { targetWorkspaceId: value },
|
|
2557
|
+
if (value) onBulkAction("move", { targetWorkspaceId: value }, false);
|
|
1903
2558
|
};
|
|
1904
2559
|
const [bulkPresetDraft, setBulkPresetDraft] = useState(null);
|
|
1905
2560
|
const [bulkPresetOptions, setBulkPresetOptions] = useState([]);
|
|
@@ -1925,7 +2580,7 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
1925
2580
|
};
|
|
1926
2581
|
const onBulkPresetApply = (value) => {
|
|
1927
2582
|
setBulkPresetDraft(null);
|
|
1928
|
-
if (value) onBulkAction("preset-migrate", { toPreset: value },
|
|
2583
|
+
if (value) onBulkAction("preset-migrate", { toPreset: value }, false);
|
|
1929
2584
|
};
|
|
1930
2585
|
const bulkMoveOptions = useMemo(() => workspaces.map(ws => ({ value: ws.id, label: ws.title || ws.name || ws.id })), [workspaces]);
|
|
1931
2586
|
const bulkPriorityOptions = useMemo(() => [1, 2, 3, 4, 5].map(value => ({ value: String(value), label: t("marks.priority." + value) })), [t]);
|
|
@@ -2158,29 +2813,74 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
2158
2813
|
"aria-labelledby": "sm-panel-dialog-title"
|
|
2159
2814
|
},
|
|
2160
2815
|
h("div", { className: "sm-nativeDialogHeader" },
|
|
2161
|
-
h("
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
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
|
+
)),
|
|
2175
2874
|
),
|
|
2176
2875
|
h("h2", { id: "sm-panel-dialog-title", className: "sm-nativeDialogTitle" }, t("panel.title")),
|
|
2177
2876
|
h("div", { className: "sm-nativeDialogHeaderActions" },
|
|
2178
|
-
h("button", {
|
|
2877
|
+
renderTip(t("panel.close") || "关闭", h("button", {
|
|
2179
2878
|
type: "button",
|
|
2180
2879
|
className: "sm-panelHeaderClose",
|
|
2181
2880
|
disabled: busyId !== null || migrating,
|
|
2182
|
-
onClick: onPanelClose
|
|
2183
|
-
|
|
2881
|
+
onClick: onPanelClose,
|
|
2882
|
+
"aria-label": t("panel.close")
|
|
2883
|
+
}, h(CloseIcon, { size: 14 })))
|
|
2184
2884
|
)
|
|
2185
2885
|
),
|
|
2186
2886
|
h("div", { className: "sm-panel" },
|
|
@@ -2494,30 +3194,119 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
2494
3194
|
});
|
|
2495
3195
|
return () => { alive = false; };
|
|
2496
3196
|
}, [moveFor ? (moveFor.id || "x") : null]);
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
const
|
|
2501
|
-
|
|
2502
|
-
|
|
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
|
+
|
|
2503
3274
|
return {
|
|
2504
3275
|
top: Math.round(r.top + r.height + 6),
|
|
2505
|
-
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
|
+
}
|
|
2506
3293
|
};
|
|
2507
3294
|
};
|
|
2508
3295
|
const archiveLabelKey = isArchived ? "row.unarchive" : "row.archive";
|
|
2509
3296
|
return h(React.Fragment, null,
|
|
2510
3297
|
annotationFor ? h(AnnotationDialog, { key: annotationFor.id, sessionId: annotationFor.id, displayTitle: annotationFor.displayTitle, t, anchor: annotationAnchor, onClose: () => { setAnnotationFor(null); setAnnotationAnchor(null); } }) : null,
|
|
2511
|
-
h("div", { className: "sm-header" },
|
|
2512
|
-
h("button", {
|
|
3298
|
+
h("div", { className: "sm-header", ref: headerRef },
|
|
3299
|
+
(onArchive || onUnarchive) ? renderTip(t ? t(archiveLabelKey) : (isArchived ? "移出归档" : "归档会话"), h("button", {
|
|
2513
3300
|
type: "button",
|
|
2514
3301
|
className: "sm-headerBtn" + (isArchived ? " sm-headerBtnActive" : ""),
|
|
2515
3302
|
"aria-label": t ? t(archiveLabelKey) : (isArchived ? "移出归档" : "归档会话"),
|
|
2516
3303
|
onClick: () => runWithAlert("archive", () =>
|
|
2517
3304
|
isArchived ? onUnarchive(sessionId) : onArchive(sessionId)
|
|
2518
3305
|
)
|
|
2519
|
-
},
|
|
2520
|
-
|
|
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,
|
|
2521
3310
|
annotationButtons(sessionId, props.displayTitle || sessionId, t, annotations, "sm-headerBtn", patch => runWithAlert("annotations", () => annotationStore.save(sessionId, patch)), (e) => {
|
|
2522
3311
|
const nextOpen = !(annotationFor && annotationFor.id === sessionId);
|
|
2523
3312
|
// Do NOT clear moveFor / confirmFor here: the z-index counter
|
|
@@ -2525,51 +3314,143 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
2525
3314
|
// popup must not silently dismiss a previously opened move or
|
|
2526
3315
|
// delete popup on the same session.
|
|
2527
3316
|
if (nextOpen && e && e.currentTarget) {
|
|
2528
|
-
|
|
2529
|
-
setAnnotationAnchor({ top: Math.round(r.top + r.height + 6), left: Math.max(8, Math.round(r.right - 360)) });
|
|
3317
|
+
setAnnotationAnchor(anchorFor(e.currentTarget, "annotation"));
|
|
2530
3318
|
} else setAnnotationAnchor(null);
|
|
2531
3319
|
setAnnotationFor(current => current?.id === sessionId ? null : { id: sessionId, displayTitle });
|
|
2532
3320
|
}, false, annotationFor?.id === sessionId),
|
|
2533
|
-
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,
|
|
2534
3322
|
|
|
2535
|
-
h("
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
e
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
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
|
+
}
|
|
2551
3341
|
}
|
|
2552
|
-
}
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
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
|
+
}
|
|
2570
3363
|
}
|
|
2571
|
-
}
|
|
2572
|
-
|
|
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
|
+
)
|
|
2573
3454
|
),
|
|
2574
3455
|
confirmFor === null ? null : h(ConfirmDialog, {
|
|
2575
3456
|
open: true,
|
|
@@ -2626,8 +3507,8 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
2626
3507
|
// Bulk operations need to refresh ctx.sessions.list and the
|
|
2627
3508
|
// workspace projection after /batch mutates disk state so the
|
|
2628
3509
|
// panel reflects the new layout.
|
|
2629
|
-
onRefreshAfterBulk: async () => {
|
|
2630
|
-
try { await this.props.props.onBulkRefresh(); } catch (_) { /* ignore */ }
|
|
3510
|
+
onRefreshAfterBulk: async (...args) => {
|
|
3511
|
+
try { await this.props.props.onBulkRefresh?.(...args); } catch (_) { /* ignore */ }
|
|
2631
3512
|
},
|
|
2632
3513
|
onOpen: (id) => { try { this.props.panelStore.set(false); this.props.props.onOpen(id); } catch (_) {} },
|
|
2633
3514
|
onArchive: this.props.props.onArchive,
|
|
@@ -2653,10 +3534,14 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
2653
3534
|
() => panelStore.getSnapshot(),
|
|
2654
3535
|
() => panelStore.getSnapshot()
|
|
2655
3536
|
);
|
|
2656
|
-
const
|
|
3537
|
+
const updateState = useSyncExternalStore(
|
|
3538
|
+
(cb) => updateStore.subscribe(cb),
|
|
3539
|
+
() => updateStore.getSnapshot(),
|
|
3540
|
+
() => updateStore.getSnapshot()
|
|
3541
|
+
);
|
|
2657
3542
|
const btnClass = "sm-footerBtn" + (wide ? " sm-footerBtn-wide" : " sm-footerBtn-rail");
|
|
2658
3543
|
const btnLabel = t("footer.aria");
|
|
2659
|
-
return h(
|
|
3544
|
+
return h(React.Fragment, null,
|
|
2660
3545
|
h("button", {
|
|
2661
3546
|
type: "button",
|
|
2662
3547
|
className: btnClass,
|
|
@@ -2673,11 +3558,344 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
2673
3558
|
t: t,
|
|
2674
3559
|
useSessions: props.useSessions,
|
|
2675
3560
|
useWorkspaces: props.useWorkspaces,
|
|
2676
|
-
}) : 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
|
+
)
|
|
2677
3894
|
);
|
|
2678
3895
|
}
|
|
2679
3896
|
|
|
2680
3897
|
function apply(ctx) {
|
|
3898
|
+
activeClientCtx = ctx;
|
|
2681
3899
|
ctx.effect(() => {
|
|
2682
3900
|
const refresh = () => { if (annotationStore.hasSubscribers()) void annotationStore.load(true); };
|
|
2683
3901
|
window.addEventListener("focus", refresh);
|
|
@@ -2692,6 +3910,34 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
2692
3910
|
return () => { window.removeEventListener("focus", refresh); channel?.close(); annotationStore.notify = null; };
|
|
2693
3911
|
}, "session-manager: annotation synchronization");
|
|
2694
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
|
+
|
|
2695
3941
|
const actions = () => ({
|
|
2696
3942
|
// DSH 0.1.6+ removed ctx.sessions.open(); the navigation owner is
|
|
2697
3943
|
// `ctx.uiWorkspace.openSession()`, and the bare SessionController only
|
|
@@ -2713,18 +3959,28 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
2713
3959
|
}
|
|
2714
3960
|
throw new Error("session-manager: no Session open API on this DSH host");
|
|
2715
3961
|
},
|
|
2716
|
-
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
|
+
},
|
|
2717
3969
|
onUnarchive: async (sessionId) => {
|
|
2718
3970
|
const response = await callApi("/unarchive", { sessionId });
|
|
2719
3971
|
if (!response.ok) throw new Error(response.error || "unarchive failed");
|
|
2720
3972
|
},
|
|
2721
3973
|
onRemove: async (sessionId) => {
|
|
3974
|
+
const wasCurrent = isCurrentSession(sessionId);
|
|
2722
3975
|
const response = await callApi("/delete", { sessionId });
|
|
2723
3976
|
if (!response.ok) throw new Error(response.error || "delete failed");
|
|
2724
3977
|
await annotationStore.load(true);
|
|
2725
3978
|
if (response.result?.warning) window.alert(response.result.warning);
|
|
2726
|
-
|
|
2727
|
-
|
|
3979
|
+
if (wasCurrent || isCurrentSession(sessionId)) {
|
|
3980
|
+
clearCurrentSession();
|
|
3981
|
+
}
|
|
3982
|
+
try { await ctx.sessions?.refresh?.(); } catch (_) {}
|
|
3983
|
+
try { await ctx.workspaces?.refresh?.(); } catch (_) {}
|
|
2728
3984
|
},
|
|
2729
3985
|
onMove: async (sessionId, targetWorkspaceId) => {
|
|
2730
3986
|
const wasCurrent = ctx.sessions.list.getSnapshot().current === sessionId;
|
|
@@ -2754,7 +4010,6 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
2754
4010
|
if (!response.ok) throw new Error(response.error || "preset migration failed");
|
|
2755
4011
|
// The current DSH client session store derives agentPreset from
|
|
2756
4012
|
// the refreshed projection; older builds exposed noteAgentPreset,
|
|
2757
|
-
onOpenPanel: () => panelStore.toggle(),
|
|
2758
4013
|
await ctx.sessions.refresh();
|
|
2759
4014
|
// The migrate rewrite happens in-process on the live session, so
|
|
2760
4015
|
// we just need a delayed baseline to let the api-gateway's projection
|
|
@@ -2766,7 +4021,31 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
2766
4021
|
}, 250);
|
|
2767
4022
|
},
|
|
2768
4023
|
onOpenPanel: () => panelStore.toggle(),
|
|
2769
|
-
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
|
+
},
|
|
2770
4049
|
});
|
|
2771
4050
|
ctx.slots.inject("conversation.session.header.actions", () => ctx.slots.register({
|
|
2772
4051
|
name: "conversation.session.header.actions",
|
|
@@ -2782,12 +4061,66 @@ function nextDialogZ() { return ++dialogZStackCounter; }
|
|
|
2782
4061
|
locale: NS,
|
|
2783
4062
|
inject: () => actions()
|
|
2784
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");
|
|
2785
4109
|
}
|
|
2786
4110
|
|
|
2787
4111
|
const inject = ["slots", "sessions", "workspaces", "locale", "uiWorkspace"];
|
|
2788
4112
|
|
|
2789
4113
|
exports.apply = apply;
|
|
2790
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;
|
|
2791
4124
|
return module.exports;
|
|
2792
4125
|
}
|
|
2793
4126
|
});
|