dsh-session-manager 0.7.1 → 0.7.3
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 +19 -0
- package/README.md +22 -20
- package/README.zh.md +20 -18
- package/lib/client.js +429 -95
- package/lib/compat/dsh-adapter.js +177 -7
- package/lib/index.js +946 -39
- package/lib/session-files.js +73 -6
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -181,8 +181,11 @@ function isTopmostDialog(z) {
|
|
|
181
181
|
"panel.update.title": "检查更新",
|
|
182
182
|
"panel.update.badge": "有新版本可用",
|
|
183
183
|
"update.title": "检查更新",
|
|
184
|
+
"update.done.title": "升级成功",
|
|
184
185
|
"update.newVersion": "发现新版本",
|
|
185
186
|
"update.currentVersion": "当前版本",
|
|
187
|
+
"update.runningVersion": "当前运行版本",
|
|
188
|
+
"update.installedVersion": "已安装版本",
|
|
186
189
|
"update.latestVersion": "最新版本",
|
|
187
190
|
"update.isLatest": "当前已是最新版本",
|
|
188
191
|
"update.checking": "正在检查更新…",
|
|
@@ -192,16 +195,26 @@ function isTopmostDialog(z) {
|
|
|
192
195
|
"update.btn.updating": "更新中…",
|
|
193
196
|
"update.btn.later": "稍后",
|
|
194
197
|
"update.btn.done": "好的",
|
|
195
|
-
"update.btn.retry": "重试",
|
|
196
198
|
"update.btn.close": "关闭",
|
|
197
|
-
"update.
|
|
198
|
-
"update.done.
|
|
199
|
+
"update.btn.retry": "重试",
|
|
200
|
+
"update.done.restart": "升级成功!已安装 v{to}(当前运行 v{from})。请重启 DSH 使新版本生效。",
|
|
201
|
+
"update.done.refresh": "升级成功!已安装 v{to}。请刷新界面使新版本生效。",
|
|
202
|
+
"update.done.applied": "升级成功!新版本已立即生效。",
|
|
203
|
+
"update.rolledBack.title": "已安全回滚",
|
|
204
|
+
"update.rolledBack": "升级未成功,已安全回滚至旧版本 v{version}。",
|
|
205
|
+
"update.rolledBack.reason": "原因:{reason}",
|
|
206
|
+
"update.source.linked": "开发模式(本地链接),请手动修改或拉取代码。",
|
|
207
|
+
"update.source.github": "通过 Git/GitHub 安装,请通过 DSH 插件市场或 git 更新。",
|
|
208
|
+
"update.source.installation": "系统内置插件,无法独立更新。",
|
|
209
|
+
"update.source.unknown": "无法确认插件安装来源,为保证安全已禁止自动更新。",
|
|
210
|
+
"update.hmrUnsupported": "当前处于 HMR 开发环境,无法在运行中直接自我更新。请使用 DSH 插件市场或命令行执行更新。",
|
|
199
211
|
"update.error": "更新遇到问题",
|
|
200
212
|
"update.autoCheck": "自动检查更新",
|
|
201
213
|
"update.autoCheck.enable": "开启",
|
|
202
214
|
"settings.registry": "安装源",
|
|
203
215
|
"settings.registry.npm": "npm 官方源 (npmjs.org)",
|
|
204
216
|
"settings.registry.china": "国内镜像源 (npmmirror.com)",
|
|
217
|
+
"settings.registry.local": "本地测试源 (127.0.0.1:4873)",
|
|
205
218
|
"settings.title": "会话管理",
|
|
206
219
|
"settings.pluginName": "dsh-session-manager",
|
|
207
220
|
"settings.versionSection": "插件版本",
|
|
@@ -452,8 +465,11 @@ function isTopmostDialog(z) {
|
|
|
452
465
|
"panel.update.title": "Check for updates",
|
|
453
466
|
"panel.update.badge": "New version available",
|
|
454
467
|
"update.title": "Check for Updates",
|
|
468
|
+
"update.done.title": "Upgrade Succeeded",
|
|
455
469
|
"update.newVersion": "New Version Available",
|
|
456
470
|
"update.currentVersion": "Current Version",
|
|
471
|
+
"update.runningVersion": "Running Version",
|
|
472
|
+
"update.installedVersion": "Installed Version",
|
|
457
473
|
"update.latestVersion": "Latest Version",
|
|
458
474
|
"update.isLatest": "Up to date",
|
|
459
475
|
"update.checking": "Checking for updates…",
|
|
@@ -463,16 +479,26 @@ function isTopmostDialog(z) {
|
|
|
463
479
|
"update.btn.updating": "Updating…",
|
|
464
480
|
"update.btn.later": "Later",
|
|
465
481
|
"update.btn.done": "OK",
|
|
466
|
-
"update.btn.retry": "Retry",
|
|
467
482
|
"update.btn.close": "Close",
|
|
468
|
-
"update.
|
|
469
|
-
"update.done.
|
|
483
|
+
"update.btn.retry": "Retry",
|
|
484
|
+
"update.done.restart": "Upgrade succeeded! Installed v{to} (running v{from}). Please restart DSH to apply.",
|
|
485
|
+
"update.done.refresh": "Upgrade succeeded! Installed v{to}. Please refresh the UI to apply.",
|
|
486
|
+
"update.done.applied": "Upgrade succeeded! Update applied and active now.",
|
|
487
|
+
"update.rolledBack.title": "Safely Rolled Back",
|
|
488
|
+
"update.rolledBack": "Upgrade was not completed. Safely rolled back to previous version v{version}.",
|
|
489
|
+
"update.rolledBack.reason": "Reason: {reason}",
|
|
490
|
+
"update.source.linked": "Development mode (linked package). Please update local code directly.",
|
|
491
|
+
"update.source.github": "Installed via Git/GitHub. Please update via DSH Market or git.",
|
|
492
|
+
"update.source.installation": "Built-in package. Cannot be updated independently.",
|
|
493
|
+
"update.source.unknown": "Unknown installation source. Self-update disabled for safety.",
|
|
494
|
+
"update.hmrUnsupported": "Running under HMR development mode; self-update cannot proceed while active. Please update via DSH Market or CLI.",
|
|
470
495
|
"update.error": "Update Error",
|
|
471
496
|
"update.autoCheck": "Automatically check for updates",
|
|
472
497
|
"update.autoCheck.enable": "Enable",
|
|
473
498
|
"settings.registry": "Install Source",
|
|
474
499
|
"settings.registry.npm": "Official npm (npmjs.org)",
|
|
475
500
|
"settings.registry.china": "China mirror (npmmirror.com)",
|
|
501
|
+
"settings.registry.local": "Local test registry (127.0.0.1:4873)",
|
|
476
502
|
"settings.title": "Session Manager",
|
|
477
503
|
"settings.pluginName": "dsh-session-manager",
|
|
478
504
|
"settings.versionSection": "Plugin Version",
|
|
@@ -732,7 +758,7 @@ function isTopmostDialog(z) {
|
|
|
732
758
|
// applied). Tooltip visibility is governed by the layering contract
|
|
733
759
|
// above, not by this rule; it is kept as the scoped replacement for the
|
|
734
760
|
// unscoped selector Issue #21 removed.
|
|
735
|
-
".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:var(--dsw-alias-state-error-primary,#e53e3e);border:1.5px solid var(--dsw-alias-bg-layer-1,#fff)}.sm-panelHeaderWhale .sm-updateSpinner{position:absolute;inset:2px;border:2px solid transparent;border-top-color:var(--dsw-alias-state-business-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(--sm-dialog-fill);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-state-business-primary,#356ae6);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-state-business-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-bg-layer-2,#fff);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:var(--dsw-alias-state-warn-label,#dd8629);background:var(--dsw-alias-state-warn-tertiary,#fef5e7);padding:8px 10px;border-radius:6px;border:1px solid color-mix(in srgb,var(--dsw-alias-state-warn-primary,#f59e0b) 25%,transparent)}.sm-updateStatusBox.sm-error{color:var(--dsw-alias-state-error-primary,#ec1313);background:color-mix(in srgb,var(--dsw-alias-state-error-primary,#ec1313) 8%,transparent);padding:8px 10px;border-radius:6px;border:1px solid color-mix(in srgb,var(--dsw-alias-state-error-primary,#ec1313) 22%,transparent)}.sm-updateStatusBox.sm-success{color:var(--dsw-alias-state-success-primary,#22c55e);background:var(--dsw-alias-state-success-tertiary,#e6faed);padding:8px 10px;border-radius:6px;border:1px solid color-mix(in srgb,var(--dsw-alias-state-success-primary,#22c55e) 25%,transparent)}.sm-settingsCard{background:var(--sm-dialog-surface);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-markdown-tag,#f1f3f5);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:16px;min-height:36px;margin-top:8px}.sm-settingsRow:first-of-type{margin-top:0}.sm-settingsRow>span:first-child{white-space:nowrap;flex-shrink:0}.sm-settingsActions{display:flex;align-items:center;gap:8px;margin-top:10px}.sm-settingsLink{color:var(--dsw-alias-state-business-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:30px;height:30px;width:280px;min-width:280px;max-width:280px;flex:0 0 280px;box-sizing:border-box;font-size:12px;line-height:20px;padding:4px 26px 4px 10px;border-radius:8px;background:var(--dsw-alias-bg-layer-2,#fff);color:var(--dsw-alias-label-primary,#111);cursor:pointer}.sm-settingsRowLeft{display:flex;flex-direction:column;align-items:flex-start;justify-content:center;gap:2px;min-width:0;flex:1 1 auto}.sm-settingsRowLeft>span:first-child{white-space:nowrap;flex-shrink:0}.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-migrateCurrent{padding:8px 10px;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:8px;background:var(--dsw-alias-bg-layer-2,#fff);font-size:13px;line-height:18px;color:var(--dsw-alias-label-primary,#111)}.sm-migrateConfirmLayer.sm-confirmDialog.sm-nativeDialogLayer{width:360px;max-width:calc(100vw - 32px);max-height:calc(100vh - 32px);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:calc(100vw - 32px);max-height:min(70vh,calc(100vh - 32px));z-index:auto;display:flex;flex-direction:column;overflow:hidden}.sm-migrateConfirmLayer .sm-migratePanel{min-width:0;max-height:calc(100vh - 120px);overflow-y:auto}.sm-migrateConfirmLayer .sm-nativeDialogButton.sm-nativeDialogConfirm:hover:not(:disabled){background-color:var(--dsw-alias-button-info-hover,#4576f0);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-button-info-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-settingsProjectLeft{display:flex;align-items:center;gap:8px;min-width:0;flex-wrap:nowrap}.sm-settingsProjectLabel{color:var(--dsw-alias-label-primary,#111);white-space:nowrap;flex-shrink:0}.sm-settingsBadgeActions{display:flex;align-items:center;gap:8px;margin-left:auto;flex:0 0 280px;width:280px;min-width:280px;max-width:280px;box-sizing:border-box;justify-content:flex-end}.sm-settingsBadgeActions>*{display:inline-flex;flex:1 1 0;min-width:0}.sm-settingsBadgeLink{display:inline-flex;align-items:center;justify-content:center;gap:6px;width:100%;padding:4px 10px;min-height:28px;height:28px;box-sizing:border-box;border-radius:6px;border:1px solid var(--dsw-alias-border-l2,#ddd);background:var(--dsw-alias-markdown-tag,#f1f3f5);color:var(--dsw-alias-label-secondary,#555);font-size:12px;line-height:18px;text-decoration:none;cursor:pointer;white-space:nowrap;transition:all .15s}.sm-settingsBadgeLink:hover{background:var(--dsw-alias-interactive-bg-hover,#eee);color:var(--dsw-alias-state-business-primary,#356ae6);border-color:var(--dsw-alias-state-business-primary,#356ae6)}.sm-settingsBadgeLink svg{flex:none}.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}",
|
|
761
|
+
".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:var(--dsw-alias-state-error-primary,#e53e3e);border:1.5px solid var(--dsw-alias-bg-layer-1,#fff)}.sm-panelHeaderWhale .sm-updateSpinner{position:absolute;inset:2px;border:2px solid transparent;border-top-color:var(--dsw-alias-state-business-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);height:248px!important;min-height:248px!important;max-height:248px!important;box-sizing:border-box;background:var(--sm-dialog-fill);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:none!important;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;height:46px;min-height:46px;max-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;height:152px!important;min-height:152px!important;max-height:152px!important;box-sizing:border-box;font-size:13px;line-height:20px;color:var(--dsw-alias-label-primary,#111);overflow:hidden}.sm-updateDialog .sm-nativeDialogFooter{display:flex;padding:10px 16px;border-top:1px solid var(--dsw-alias-border-l2,#eee);flex:none;height:50px;min-height:50px;max-height:50px;box-sizing:border-box;flex-wrap:nowrap;justify-content:space-between;align-items:center;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;white-space:nowrap}.sm-nativeDialogButton:disabled{opacity:.5!important;cursor:not-allowed!important}.sm-updateDialog .sm-nativeDialogButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.sm-updateDialog .sm-nativeDialogConfirm,.sm-updateDialog .sm-nativeDialogButton.sm-nativeDialogConfirm,.sm-settingsCard .sm-nativeDialogConfirm,.sm-settingsCard .sm-nativeDialogButton.sm-nativeDialogConfirm{background:var(--dsw-alias-state-business-primary,#356ae6)!important;color:var(--dsw-alias-label-primary-foreground,#fff)!important;border-color:var(--dsw-alias-state-business-primary,#356ae6)!important}.sm-updateDialog .sm-nativeDialogCancel,.sm-updateDialog .sm-nativeDialogButton.sm-nativeDialogCancel{background:transparent!important;color:var(--dsw-alias-label-primary,#111)!important;border-color:var(--dsw-alias-border-l2,#ddd)!important}.sm-updateDialog .sm-nativeDialogConfirm:hover:not(:disabled),.sm-updateDialog .sm-nativeDialogButton.sm-nativeDialogConfirm:hover:not(:disabled),.sm-settingsCard .sm-nativeDialogConfirm:hover:not(:disabled),.sm-settingsCard .sm-nativeDialogButton.sm-nativeDialogConfirm:hover:not(:disabled){background:var(--dsw-alias-state-business-primary,#356ae6)!important;color:var(--dsw-alias-label-primary-foreground,#fff)!important;border-color:var(--dsw-alias-state-business-primary,#356ae6)!important;filter:brightness(.94)!important}.sm-updateDialog .sm-nativeDialogCancel:hover:not(:disabled),.sm-updateDialog .sm-nativeDialogButton.sm-nativeDialogCancel:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)!important;color:var(--dsw-alias-label-primary,#111)!important}.sm-updateVersionGrid{display:grid;grid-template-columns:auto 1fr;gap:6px 12px;padding:12px;background:var(--dsw-alias-bg-layer-2,#fff);border:1px solid var(--dsw-alias-border-l2,#eee);border-radius:8px;font-size:13px;line-height:20px;box-sizing:border-box;flex:none}.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;box-sizing:border-box;min-height:38px;height:38px;padding:8px 10px;border-radius:6px;border:1px solid transparent;font-size:13px;line-height:20px;color:var(--dsw-alias-label-primary,#111);display:flex;align-items:center;flex:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sm-updateDialog .sm-updateStatusBox{margin-top:0}.sm-updateStatusBox.sm-checking{color:var(--dsw-alias-label-secondary,#666);background:var(--dsw-alias-bg-layer-2,#f5f5f5);border:1px solid var(--dsw-alias-border-l2,#eee)}.sm-updateStatusBox.sm-warn{color:var(--dsw-alias-state-warn-label,#dd8629);background:var(--dsw-alias-state-warn-tertiary,#fef5e7);padding:8px 10px;border-radius:6px;border:1px solid color-mix(in srgb,var(--dsw-alias-state-warn-primary,#f59e0b) 25%,transparent)}.sm-updateStatusBox.sm-error{color:var(--dsw-alias-state-error-primary,#ec1313);background:color-mix(in srgb,var(--dsw-alias-state-error-primary,#ec1313) 8%,transparent);padding:8px 10px;border-radius:6px;border:1px solid color-mix(in srgb,var(--dsw-alias-state-error-primary,#ec1313) 22%,transparent)}.sm-updateStatusBox.sm-success{color:var(--dsw-alias-state-success-primary,#22c55e);background:var(--dsw-alias-state-success-tertiary,#e6faed);padding:8px 10px;border-radius:6px;border:1px solid color-mix(in srgb,var(--dsw-alias-state-success-primary,#22c55e) 25%,transparent)}.sm-settingsCard{background:var(--sm-dialog-surface);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-markdown-tag,#f1f3f5);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:16px;min-height:36px;margin-top:8px}.sm-settingsRow:first-of-type{margin-top:0}.sm-settingsRow>span:first-child{white-space:nowrap;flex-shrink:0}.sm-settingsActions{display:flex;align-items:center;gap:8px;margin-top:10px}.sm-settingsLink{color:var(--dsw-alias-state-business-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:30px;height:30px;width:280px;min-width:280px;max-width:280px;flex:0 0 280px;box-sizing:border-box;font-size:12px;line-height:20px;padding:4px 26px 4px 10px;border-radius:8px;background:var(--dsw-alias-bg-layer-2,#fff);color:var(--dsw-alias-label-primary,#111);cursor:pointer}.sm-settingsRowLeft{display:flex;flex-direction:column;align-items:flex-start;justify-content:center;gap:2px;min-width:0;flex:1 1 auto}.sm-settingsRowLeft>span:first-child{white-space:nowrap;flex-shrink:0}.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-migrateCurrent{padding:8px 10px;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:8px;background:var(--dsw-alias-bg-layer-2,#fff);font-size:13px;line-height:18px;color:var(--dsw-alias-label-primary,#111)}.sm-migrateConfirmLayer.sm-confirmDialog.sm-nativeDialogLayer{width:360px;max-width:calc(100vw - 32px);max-height:calc(100vh - 32px);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:calc(100vw - 32px);max-height:min(70vh,calc(100vh - 32px));z-index:auto;display:flex;flex-direction:column;overflow:hidden}.sm-migrateConfirmLayer .sm-migratePanel{min-width:0;max-height:calc(100vh - 120px);overflow-y:auto}.sm-migrateConfirmLayer .sm-nativeDialogButton.sm-nativeDialogConfirm:hover:not(:disabled){background-color:var(--dsw-alias-state-business-primary,#356ae6);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-state-business-primary,#356ae6);filter:brightness(.94)}.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-settingsProjectLeft{display:flex;align-items:center;gap:8px;min-width:0;flex-wrap:nowrap}.sm-settingsProjectLabel{color:var(--dsw-alias-label-primary,#111);white-space:nowrap;flex-shrink:0}.sm-settingsBadgeActions{display:flex;align-items:center;gap:8px;margin-left:auto;flex:0 0 280px;width:280px;min-width:280px;max-width:280px;box-sizing:border-box;justify-content:flex-end}.sm-settingsBadgeActions>*{display:inline-flex;flex:1 1 0;min-width:0}.sm-settingsBadgeLink{display:inline-flex;align-items:center;justify-content:center;gap:6px;width:100%;padding:4px 10px;min-height:28px;height:28px;box-sizing:border-box;border-radius:6px;border:1px solid var(--dsw-alias-border-l2,#ddd);background:var(--dsw-alias-markdown-tag,#f1f3f5);color:var(--dsw-alias-label-secondary,#555);font-size:12px;line-height:18px;text-decoration:none;cursor:pointer;white-space:nowrap;transition:all .15s}.sm-settingsBadgeLink:hover{background:var(--dsw-alias-interactive-bg-hover,#eee);color:var(--dsw-alias-state-business-primary,#356ae6);border-color:var(--dsw-alias-state-business-primary,#356ae6)}.sm-settingsBadgeLink svg{flex:none}.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}",
|
|
736
762
|
|
|
737
763
|
// Issue #23 — dialog opacity.
|
|
738
764
|
//
|
|
@@ -862,7 +888,8 @@ function isTopmostDialog(z) {
|
|
|
862
888
|
".sm-bulkResultItemReason{color:var(--dsw-alias-state-error-primary);font-size:11px;line-height:16px;word-break:break-word}",
|
|
863
889
|
".sm-bulkResultItemReasonSkip{color:var(--dsw-alias-label-tertiary,#888)}",
|
|
864
890
|
".sm-bulkResultFooter{display:flex;justify-content:space-between;align-items:center;gap:8px;flex-wrap:wrap}",
|
|
865
|
-
".sm-footerBtn-wide
|
|
891
|
+
"[class*=footerActions]:has(.sm-footerBtn-wide),[class*=footer-actions]:has(.sm-footerBtn-wide),[class*=footer]:has(> .sm-footerBtn-wide),[class*=footer] > div:has(> .sm-footerBtn-wide){flex-wrap:wrap;align-content:flex-start;height:auto}",
|
|
892
|
+
".sm-footerBtn-wide{flex:1 1 100%;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}",
|
|
866
893
|
".sm-footerBtn-wide:hover,.sm-footerBtn-wide:focus-visible{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover)}",
|
|
867
894
|
".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}",
|
|
868
895
|
".sm-footerBtn-rail:hover,.sm-footerBtn-rail:focus-visible{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover)}",
|
|
@@ -2100,6 +2127,18 @@ function isTopmostDialog(z) {
|
|
|
2100
2127
|
}
|
|
2101
2128
|
}
|
|
2102
2129
|
|
|
2130
|
+
function getTargetSmSelect(target) {
|
|
2131
|
+
if (!target || typeof target.closest !== "function") return null;
|
|
2132
|
+
const direct = target.closest(SM_SELECT_SELECTOR);
|
|
2133
|
+
if (direct && direct.tagName === "SELECT") return direct;
|
|
2134
|
+
const container = target.closest(".sm-wsSortField, .sm-annotationPriority, .sm-viewField, .sm-moveSection, .sm-settingsRow, .sm-customSelectWrapper");
|
|
2135
|
+
if (container) {
|
|
2136
|
+
const sel = container.querySelector("select");
|
|
2137
|
+
if (sel && sel.tagName === "SELECT") return sel;
|
|
2138
|
+
}
|
|
2139
|
+
return null;
|
|
2140
|
+
}
|
|
2141
|
+
|
|
2103
2142
|
function installCustomDropdownInterceptor() {
|
|
2104
2143
|
if (typeof document === "undefined" || typeof document.addEventListener !== "function") {
|
|
2105
2144
|
return () => {};
|
|
@@ -2113,24 +2152,8 @@ function isTopmostDialog(z) {
|
|
|
2113
2152
|
if (activeCustomMenu && activeCustomMenu.contains(e.target)) return;
|
|
2114
2153
|
if (e.target?.closest?.("button, input, textarea, a")) return;
|
|
2115
2154
|
|
|
2116
|
-
|
|
2117
|
-
if (
|
|
2118
|
-
select = e.target;
|
|
2119
|
-
} else if (e.target?.closest?.("select")) {
|
|
2120
|
-
select = e.target.closest("select");
|
|
2121
|
-
} else {
|
|
2122
|
-
const container = e.target?.closest?.(".sm-wsSortField, .sm-annotationPriority, .sm-viewField, .sm-moveSection, .sm-settingsRow, .sm-customSelectWrapper");
|
|
2123
|
-
if (container) {
|
|
2124
|
-
select = container.querySelector("select");
|
|
2125
|
-
} else {
|
|
2126
|
-
const nearest = e.target?.closest?.(SM_SELECT_SELECTOR);
|
|
2127
|
-
if (nearest && nearest.tagName === "SELECT") {
|
|
2128
|
-
select = nearest;
|
|
2129
|
-
}
|
|
2130
|
-
}
|
|
2131
|
-
}
|
|
2132
|
-
|
|
2133
|
-
if (select && select.tagName === "SELECT") {
|
|
2155
|
+
const select = getTargetSmSelect(e.target);
|
|
2156
|
+
if (select) {
|
|
2134
2157
|
e.preventDefault();
|
|
2135
2158
|
e.stopPropagation();
|
|
2136
2159
|
if (select.disabled) return;
|
|
@@ -2146,14 +2169,8 @@ function isTopmostDialog(z) {
|
|
|
2146
2169
|
|
|
2147
2170
|
const onClick = (e) => {
|
|
2148
2171
|
if (e.target?.closest?.("button, input, textarea, a")) return;
|
|
2149
|
-
|
|
2150
|
-
if (
|
|
2151
|
-
select = e.target;
|
|
2152
|
-
} else {
|
|
2153
|
-
const container = e.target?.closest?.(".sm-wsSortField, .sm-annotationPriority, .sm-viewField, .sm-moveSection, .sm-settingsRow, .sm-customSelectWrapper");
|
|
2154
|
-
if (container) select = container.querySelector("select");
|
|
2155
|
-
}
|
|
2156
|
-
if (select && select.tagName === "SELECT") {
|
|
2172
|
+
const select = getTargetSmSelect(e.target);
|
|
2173
|
+
if (select) {
|
|
2157
2174
|
e.preventDefault();
|
|
2158
2175
|
e.stopPropagation();
|
|
2159
2176
|
}
|
|
@@ -2170,7 +2187,7 @@ function isTopmostDialog(z) {
|
|
|
2170
2187
|
}
|
|
2171
2188
|
|
|
2172
2189
|
const focused = document.activeElement;
|
|
2173
|
-
const targetSelect = activeCustomSelect || (focused
|
|
2190
|
+
const targetSelect = activeCustomSelect || getTargetSmSelect(focused);
|
|
2174
2191
|
if (!targetSelect || targetSelect.tagName !== "SELECT") return;
|
|
2175
2192
|
|
|
2176
2193
|
if (e.key === "Enter" || e.key === " ") {
|
|
@@ -2196,7 +2213,14 @@ function isTopmostDialog(z) {
|
|
|
2196
2213
|
}
|
|
2197
2214
|
};
|
|
2198
2215
|
|
|
2199
|
-
const onResizeOrScroll = () => {
|
|
2216
|
+
const onResizeOrScroll = (e) => {
|
|
2217
|
+
// Ignore scrolls that originate inside the open menu: the listener is bound on
|
|
2218
|
+
// window with capture=true, so scrolling the menu's own option list (wheel or
|
|
2219
|
+
// scrollbar drag) would otherwise close it immediately.
|
|
2220
|
+
// Reference: PR #37
|
|
2221
|
+
if (activeCustomMenu && e && e.type === "scroll" && e.target && typeof activeCustomMenu.contains === "function" && activeCustomMenu.contains(e.target)) {
|
|
2222
|
+
return;
|
|
2223
|
+
}
|
|
2200
2224
|
if (activeCustomMenu) closeCustomSelect();
|
|
2201
2225
|
};
|
|
2202
2226
|
|
|
@@ -3749,7 +3773,7 @@ function isTopmostDialog(z) {
|
|
|
3749
3773
|
));
|
|
3750
3774
|
}
|
|
3751
3775
|
|
|
3752
|
-
const CURRENT_VERSION = "0.7.
|
|
3776
|
+
const CURRENT_VERSION = "0.7.3";
|
|
3753
3777
|
|
|
3754
3778
|
function compareSemver(v1, v2) {
|
|
3755
3779
|
if (typeof v1 !== "string" || typeof v2 !== "string") return 0;
|
|
@@ -3805,17 +3829,25 @@ function isTopmostDialog(z) {
|
|
|
3805
3829
|
state: {
|
|
3806
3830
|
status: "idle",
|
|
3807
3831
|
currentVersion: CURRENT_VERSION,
|
|
3832
|
+
runningVersion: CURRENT_VERSION,
|
|
3833
|
+
installedVersion: null,
|
|
3808
3834
|
latestVersion: null,
|
|
3809
3835
|
error: null,
|
|
3810
3836
|
application: null,
|
|
3811
3837
|
dialogOpen: false,
|
|
3812
3838
|
checkedAt: null,
|
|
3813
3839
|
lastAttemptAt: null,
|
|
3840
|
+
source: null,
|
|
3841
|
+
notes: null,
|
|
3842
|
+
channelSwitch: null,
|
|
3843
|
+
rollbackInfo: null,
|
|
3844
|
+
taskId: null,
|
|
3814
3845
|
},
|
|
3815
3846
|
CHECK_INTERVAL_MS: 6 * 60 * 60 * 1000,
|
|
3816
3847
|
RETRY_COOLDOWN_MS: 30 * 60 * 1000,
|
|
3817
3848
|
lastFailedAt: null,
|
|
3818
3849
|
listeners: new Set(),
|
|
3850
|
+
_statusPromise: null,
|
|
3819
3851
|
getSnapshot() { return this.state; },
|
|
3820
3852
|
subscribe(cb) {
|
|
3821
3853
|
this.listeners.add(cb);
|
|
@@ -3830,9 +3862,92 @@ function isTopmostDialog(z) {
|
|
|
3830
3862
|
this._notify();
|
|
3831
3863
|
},
|
|
3832
3864
|
closeDialog() {
|
|
3865
|
+
try {
|
|
3866
|
+
if (typeof localStorage !== "undefined") {
|
|
3867
|
+
const currentTaskId = this.state.taskId || this.state.rollbackInfo?.taskId;
|
|
3868
|
+
if (currentTaskId && this.state.status !== "updating") {
|
|
3869
|
+
localStorage.setItem("dsh-sm-ack-task", currentTaskId);
|
|
3870
|
+
}
|
|
3871
|
+
}
|
|
3872
|
+
} catch (_) {}
|
|
3833
3873
|
this.state.dialogOpen = false;
|
|
3874
|
+
if (this.state.status !== "updating") {
|
|
3875
|
+
this.state.status = "idle";
|
|
3876
|
+
}
|
|
3834
3877
|
this._notify();
|
|
3835
3878
|
},
|
|
3879
|
+
async checkRecentStatus() {
|
|
3880
|
+
if (this._statusPromise) return this._statusPromise;
|
|
3881
|
+
if (this.state.status === "updating") return;
|
|
3882
|
+
this._statusPromise = (async () => {
|
|
3883
|
+
try {
|
|
3884
|
+
const statusData = await fetchApi("/update/status");
|
|
3885
|
+
if (statusData && statusData.ok && statusData.result) {
|
|
3886
|
+
const r = statusData.result;
|
|
3887
|
+
const ackTaskId = (typeof localStorage !== "undefined") ? localStorage.getItem("dsh-sm-ack-task") : null;
|
|
3888
|
+
if (r.taskId && r.taskId === ackTaskId) return;
|
|
3889
|
+
if (this.state.taskId === r.taskId && (this.state.status === "done" || this.state.status === "error")) return;
|
|
3890
|
+
|
|
3891
|
+
const runningV = r.runningVersion || r.currentVersion || this.state.runningVersion || this.state.currentVersion || CURRENT_VERSION;
|
|
3892
|
+
const installedV = r.installedVersion || (r.status === "completed" ? (r.targetVersion || runningV) : runningV);
|
|
3893
|
+
this.state.runningVersion = runningV;
|
|
3894
|
+
this.state.currentVersion = runningV;
|
|
3895
|
+
if (compareSemver(installedV, runningV) > 0) {
|
|
3896
|
+
this.state.installedVersion = installedV;
|
|
3897
|
+
}
|
|
3898
|
+
|
|
3899
|
+
if (r.status === "rolled-back" || (r.status === "failed" && r.rolledBack)) {
|
|
3900
|
+
this.state.status = "error";
|
|
3901
|
+
this.state.taskId = r.taskId;
|
|
3902
|
+
this.state.rollbackInfo = {
|
|
3903
|
+
rolledBack: true,
|
|
3904
|
+
currentVersion: r.currentVersion || runningV,
|
|
3905
|
+
reason: r.error || "未知原因",
|
|
3906
|
+
taskId: r.taskId
|
|
3907
|
+
};
|
|
3908
|
+
this.state.error = (r.error || "升级未成功") + "(已安全回滚至旧版本 v" + (r.currentVersion || runningV) + ")";
|
|
3909
|
+
this.state.dialogOpen = true;
|
|
3910
|
+
this._notify();
|
|
3911
|
+
} else if (r.status === "completed") {
|
|
3912
|
+
const targetV = r.targetVersion || this.state.latestVersion || installedV;
|
|
3913
|
+
this.state.taskId = r.taskId;
|
|
3914
|
+
this.state.latestVersion = targetV;
|
|
3915
|
+
this.state.installedVersion = targetV;
|
|
3916
|
+
|
|
3917
|
+
// If DSH was restarted and already running targetV or higher, do not popup again!
|
|
3918
|
+
if (compareSemver(runningV, targetV) >= 0) {
|
|
3919
|
+
try {
|
|
3920
|
+
if (typeof localStorage !== "undefined" && r.taskId) {
|
|
3921
|
+
localStorage.setItem("dsh-sm-ack-task", r.taskId);
|
|
3922
|
+
}
|
|
3923
|
+
} catch (_) {}
|
|
3924
|
+
return;
|
|
3925
|
+
}
|
|
3926
|
+
|
|
3927
|
+
if (r.application === "applied") {
|
|
3928
|
+
this.state.runningVersion = targetV;
|
|
3929
|
+
this.state.currentVersion = targetV;
|
|
3930
|
+
}
|
|
3931
|
+
|
|
3932
|
+
this.state.status = "done";
|
|
3933
|
+
this.state.application = r.application || "restart-required";
|
|
3934
|
+
this.state.dialogOpen = true;
|
|
3935
|
+
this._notify();
|
|
3936
|
+
} else if (r.status === "recovery-required") {
|
|
3937
|
+
this.state.status = "error";
|
|
3938
|
+
this.state.taskId = r.taskId;
|
|
3939
|
+
this.state.error = "更新失败且自动恢复旧版本失败: " + (r.rollbackError || r.error) + "。请手动重新安装插件。";
|
|
3940
|
+
this.state.dialogOpen = true;
|
|
3941
|
+
this._notify();
|
|
3942
|
+
}
|
|
3943
|
+
}
|
|
3944
|
+
} catch (_) {}
|
|
3945
|
+
finally {
|
|
3946
|
+
this._statusPromise = null;
|
|
3947
|
+
}
|
|
3948
|
+
})();
|
|
3949
|
+
return this._statusPromise;
|
|
3950
|
+
},
|
|
3836
3951
|
getAutoCheck() {
|
|
3837
3952
|
try {
|
|
3838
3953
|
if (typeof localStorage !== "undefined") {
|
|
@@ -3853,6 +3968,9 @@ function isTopmostDialog(z) {
|
|
|
3853
3968
|
if (!this.getAutoCheck()) return false;
|
|
3854
3969
|
if (this.state.status === "checking" || this.state.status === "updating") return false;
|
|
3855
3970
|
if (this.state.status === "available") return false;
|
|
3971
|
+
if (this.state.installedVersion && compareSemver(this.state.installedVersion, this.state.currentVersion) > 0) {
|
|
3972
|
+
return false;
|
|
3973
|
+
}
|
|
3856
3974
|
if (this.lastFailedAt && (now - this.lastFailedAt < this.RETRY_COOLDOWN_MS)) {
|
|
3857
3975
|
return false;
|
|
3858
3976
|
}
|
|
@@ -3896,13 +4014,14 @@ function isTopmostDialog(z) {
|
|
|
3896
4014
|
REGISTRY_OPTIONS: {
|
|
3897
4015
|
"registry.npmjs.org": "https://registry.npmjs.org",
|
|
3898
4016
|
"registry.npmmirror.com": "https://registry.npmmirror.com",
|
|
4017
|
+
"127.0.0.1:4873": "http://127.0.0.1:4873",
|
|
3899
4018
|
},
|
|
3900
4019
|
DEFAULT_REGISTRY: "registry.npmjs.org",
|
|
3901
4020
|
getRegistry() {
|
|
3902
4021
|
try {
|
|
3903
4022
|
if (typeof localStorage !== "undefined") {
|
|
3904
4023
|
const v = localStorage.getItem("dsh-session-manager-registry");
|
|
3905
|
-
if (v && this.REGISTRY_OPTIONS[v]) return v;
|
|
4024
|
+
if (v && (this.REGISTRY_OPTIONS[v] || /^https?:\/\//i.test(v))) return v;
|
|
3906
4025
|
}
|
|
3907
4026
|
} catch (_) {}
|
|
3908
4027
|
return this.DEFAULT_REGISTRY;
|
|
@@ -3910,7 +4029,7 @@ function isTopmostDialog(z) {
|
|
|
3910
4029
|
setRegistry(key) {
|
|
3911
4030
|
try {
|
|
3912
4031
|
if (typeof localStorage !== "undefined") {
|
|
3913
|
-
if (this.REGISTRY_OPTIONS[key]) {
|
|
4032
|
+
if (this.REGISTRY_OPTIONS[key] || (key && /^https?:\/\//i.test(key))) {
|
|
3914
4033
|
localStorage.setItem("dsh-session-manager-registry", key);
|
|
3915
4034
|
} else {
|
|
3916
4035
|
localStorage.setItem("dsh-session-manager-registry", this.DEFAULT_REGISTRY);
|
|
@@ -3920,7 +4039,9 @@ function isTopmostDialog(z) {
|
|
|
3920
4039
|
this._notify();
|
|
3921
4040
|
},
|
|
3922
4041
|
getRegistryUrl() {
|
|
3923
|
-
|
|
4042
|
+
const reg = this.getRegistry();
|
|
4043
|
+
if (/^https?:\/\//i.test(reg)) return reg;
|
|
4044
|
+
return this.REGISTRY_OPTIONS[reg] || this.REGISTRY_OPTIONS[this.DEFAULT_REGISTRY];
|
|
3924
4045
|
},
|
|
3925
4046
|
async checkForUpdate(options = {}) {
|
|
3926
4047
|
const { silent = false, openOnFound = true, manual = false } = options;
|
|
@@ -3929,6 +4050,7 @@ function isTopmostDialog(z) {
|
|
|
3929
4050
|
|
|
3930
4051
|
this.state.status = "checking";
|
|
3931
4052
|
this.state.error = null;
|
|
4053
|
+
this.state.notes = null;
|
|
3932
4054
|
if (shouldOpenDialog) {
|
|
3933
4055
|
this.state.dialogOpen = true;
|
|
3934
4056
|
}
|
|
@@ -3953,12 +4075,15 @@ function isTopmostDialog(z) {
|
|
|
3953
4075
|
}
|
|
3954
4076
|
const cur = testOverride.currentVersion || this.state.currentVersion;
|
|
3955
4077
|
const lat = testOverride.latestVersion || "9.9.9";
|
|
3956
|
-
const
|
|
3957
|
-
|
|
4078
|
+
const src = testOverride.source || "npm";
|
|
4079
|
+
const hasUpdate = typeof testOverride.hasUpdate === "boolean"
|
|
4080
|
+
? testOverride.hasUpdate
|
|
4081
|
+
: (src === "npm" && compareSemver(lat, cur) > 0);
|
|
4082
|
+
res = { ok: true, result: { currentVersion: cur, latestVersion: lat, hasUpdate, source: src } };
|
|
3958
4083
|
} else {
|
|
4084
|
+
const fetchOpts = abortController ? { signal: abortController.signal } : undefined;
|
|
3959
4085
|
const registryUrl = this.getRegistryUrl();
|
|
3960
4086
|
const registryParam = encodeURIComponent(registryUrl);
|
|
3961
|
-
const fetchOpts = abortController ? { signal: abortController.signal } : undefined;
|
|
3962
4087
|
try {
|
|
3963
4088
|
res = await fetchApi("/update/check?registry=" + registryParam, fetchOpts);
|
|
3964
4089
|
} catch (fetchErr) {
|
|
@@ -3974,7 +4099,7 @@ function isTopmostDialog(z) {
|
|
|
3974
4099
|
const cur = this.state.currentVersion;
|
|
3975
4100
|
const lat = npmData.version;
|
|
3976
4101
|
const hasUpdate = compareSemver(lat, cur) > 0;
|
|
3977
|
-
res = { ok: true, result: { currentVersion: cur, latestVersion: lat, hasUpdate } };
|
|
4102
|
+
res = { ok: true, result: { currentVersion: cur, latestVersion: lat, hasUpdate, source: "npm" } };
|
|
3978
4103
|
}
|
|
3979
4104
|
}
|
|
3980
4105
|
} catch (_) {
|
|
@@ -3991,24 +4116,51 @@ function isTopmostDialog(z) {
|
|
|
3991
4116
|
}
|
|
3992
4117
|
|
|
3993
4118
|
const result = res.result || {};
|
|
3994
|
-
const
|
|
3995
|
-
const
|
|
3996
|
-
const
|
|
3997
|
-
|
|
3998
|
-
|
|
4119
|
+
const runningVersion = result.runningVersion || result.currentVersion || this.state.runningVersion || CURRENT_VERSION;
|
|
4120
|
+
const installedVersion = result.installedVersion || (this.state.installedVersion && compareSemver(this.state.installedVersion, runningVersion) > 0 ? this.state.installedVersion : runningVersion);
|
|
4121
|
+
const latestVersion = result.latestVersion || installedVersion;
|
|
4122
|
+
const source = result.source || "npm";
|
|
4123
|
+
const hasUpdate = typeof result.hasUpdate === "boolean" ? result.hasUpdate : compareSemver(latestVersion, installedVersion) > 0;
|
|
4124
|
+
|
|
4125
|
+
this.state.runningVersion = runningVersion;
|
|
4126
|
+
this.state.currentVersion = runningVersion;
|
|
4127
|
+
this.state.installedVersion = installedVersion;
|
|
3999
4128
|
this.state.latestVersion = latestVersion;
|
|
4129
|
+
this.state.source = source;
|
|
4130
|
+
this.state.channelSwitch = result.channelSwitch || null;
|
|
4000
4131
|
const now = Date.now();
|
|
4001
4132
|
this.state.checkedAt = now;
|
|
4002
4133
|
this.state.lastAttemptAt = now;
|
|
4003
4134
|
this.lastFailedAt = null;
|
|
4004
4135
|
|
|
4005
|
-
if (
|
|
4136
|
+
if (source === "linked") {
|
|
4137
|
+
this.state.notes = "update.source.linked";
|
|
4138
|
+
this.state.status = "idle";
|
|
4139
|
+
} else if (source === "github" && !hasUpdate) {
|
|
4140
|
+
this.state.notes = "update.source.github";
|
|
4141
|
+
this.state.status = "idle";
|
|
4142
|
+
} else if (source === "installation") {
|
|
4143
|
+
this.state.notes = "update.source.installation";
|
|
4144
|
+
this.state.status = "idle";
|
|
4145
|
+
} else if (source === "unknown") {
|
|
4146
|
+
this.state.notes = "update.source.unknown";
|
|
4147
|
+
this.state.status = "idle";
|
|
4148
|
+
} else if (compareSemver(installedVersion, runningVersion) > 0) {
|
|
4149
|
+
this.state.status = "done";
|
|
4150
|
+
this.state.application = "restart-required";
|
|
4151
|
+
this.state.notes = null;
|
|
4152
|
+
if (shouldOpenDialog) {
|
|
4153
|
+
this.state.dialogOpen = true;
|
|
4154
|
+
}
|
|
4155
|
+
} else if (hasUpdate) {
|
|
4006
4156
|
this.state.status = "available";
|
|
4157
|
+
this.state.notes = null;
|
|
4007
4158
|
if (openOnFound && !silent) {
|
|
4008
4159
|
this.state.dialogOpen = true;
|
|
4009
4160
|
}
|
|
4010
4161
|
} else {
|
|
4011
4162
|
this.state.status = "idle";
|
|
4163
|
+
this.state.notes = null;
|
|
4012
4164
|
if (shouldOpenDialog) {
|
|
4013
4165
|
this.state.dialogOpen = true;
|
|
4014
4166
|
}
|
|
@@ -4031,7 +4183,7 @@ function isTopmostDialog(z) {
|
|
|
4031
4183
|
}
|
|
4032
4184
|
},
|
|
4033
4185
|
async startUpdate(options = {}) {
|
|
4034
|
-
const { openDialog =
|
|
4186
|
+
const { openDialog = true } = options;
|
|
4035
4187
|
if (this.state.status === "updating") return this.state;
|
|
4036
4188
|
this.state.status = "updating";
|
|
4037
4189
|
this.state.error = null;
|
|
@@ -4042,6 +4194,10 @@ function isTopmostDialog(z) {
|
|
|
4042
4194
|
|
|
4043
4195
|
const targetVersion = this.state.latestVersion || "latest";
|
|
4044
4196
|
const spec = "dsh-session-manager@" + targetVersion;
|
|
4197
|
+
const registryUrl = this.getRegistryUrl();
|
|
4198
|
+
const clientTaskId = "update-" + Date.now() + "-" + Math.random().toString(36).slice(2, 8);
|
|
4199
|
+
let activeTaskId = clientTaskId;
|
|
4200
|
+
this.state.taskId = activeTaskId;
|
|
4045
4201
|
|
|
4046
4202
|
try {
|
|
4047
4203
|
let outcome = null;
|
|
@@ -4057,31 +4213,127 @@ function isTopmostDialog(z) {
|
|
|
4057
4213
|
outcome = { application: testOverride.application || "restart-required" };
|
|
4058
4214
|
}
|
|
4059
4215
|
} else {
|
|
4060
|
-
|
|
4061
|
-
|
|
4062
|
-
|
|
4063
|
-
|
|
4064
|
-
|
|
4065
|
-
|
|
4066
|
-
|
|
4067
|
-
|
|
4216
|
+
let res = null;
|
|
4217
|
+
let shouldPoll = false;
|
|
4218
|
+
let callError = null;
|
|
4219
|
+
try {
|
|
4220
|
+
res = await callApi("/update/install", { version: targetVersion, registry: registryUrl, taskId: clientTaskId });
|
|
4221
|
+
} catch (err) {
|
|
4222
|
+
shouldPoll = true;
|
|
4223
|
+
callError = err;
|
|
4224
|
+
}
|
|
4225
|
+
|
|
4226
|
+
if (res && res.ok) {
|
|
4068
4227
|
outcome = res.result;
|
|
4228
|
+
} else if (res && !res.ok) {
|
|
4229
|
+
if (res.code === "update-in-progress" && res.taskId) {
|
|
4230
|
+
// Another update task is already running: adopt its taskId and poll
|
|
4231
|
+
activeTaskId = res.taskId;
|
|
4232
|
+
this.state.taskId = activeTaskId;
|
|
4233
|
+
shouldPoll = true;
|
|
4234
|
+
} else {
|
|
4235
|
+
const errObj = new Error(res.error || "安装更新失败");
|
|
4236
|
+
if (res.rolledBack) {
|
|
4237
|
+
errObj.rolledBack = true;
|
|
4238
|
+
errObj.reason = res.error;
|
|
4239
|
+
errObj.currentVersion = this.state.currentVersion;
|
|
4240
|
+
}
|
|
4241
|
+
throw errObj;
|
|
4242
|
+
}
|
|
4243
|
+
}
|
|
4244
|
+
|
|
4245
|
+
if (shouldPoll) {
|
|
4246
|
+
const pollStart = Date.now();
|
|
4247
|
+
const maxPollMs = (typeof window !== "undefined" && typeof window.__DSH_SM_POLL_TIMEOUT_MS__ === "number")
|
|
4248
|
+
? window.__DSH_SM_POLL_TIMEOUT_MS__
|
|
4249
|
+
: 90000;
|
|
4250
|
+
let reconciled = false;
|
|
4251
|
+
while (Date.now() - pollStart < maxPollMs) {
|
|
4252
|
+
await new Promise((resolve) => {
|
|
4253
|
+
const timer = setTimeout(resolve, 1500);
|
|
4254
|
+
if (typeof timer === "number" && timer === 1) {
|
|
4255
|
+
Promise.resolve().then(resolve);
|
|
4256
|
+
}
|
|
4257
|
+
});
|
|
4258
|
+
|
|
4259
|
+
let statusData = null;
|
|
4260
|
+
try {
|
|
4261
|
+
statusData = await fetchApi("/update/status?taskId=" + encodeURIComponent(activeTaskId));
|
|
4262
|
+
} catch (netErr) {
|
|
4263
|
+
// Only network or HTTP transport errors during status fetching allow polling retry
|
|
4264
|
+
continue;
|
|
4265
|
+
}
|
|
4266
|
+
|
|
4267
|
+
if (statusData && statusData.ok && statusData.result) {
|
|
4268
|
+
const r = statusData.result;
|
|
4269
|
+
if (r.status === "completed") {
|
|
4270
|
+
outcome = {
|
|
4271
|
+
application: r.application || "restart-required",
|
|
4272
|
+
spec,
|
|
4273
|
+
version: r.targetVersion || targetVersion,
|
|
4274
|
+
taskId: activeTaskId,
|
|
4275
|
+
alreadyInstalled: !!r.alreadyInstalled
|
|
4276
|
+
};
|
|
4277
|
+
reconciled = true;
|
|
4278
|
+
break;
|
|
4279
|
+
} else if (r.status === "rolled-back" || (r.status === "failed" && r.rolledBack)) {
|
|
4280
|
+
const rollErr = new Error((r.error || "安装更新失败") + "(已自动恢复旧版本 v" + (r.currentVersion || "") + ")");
|
|
4281
|
+
rollErr.rolledBack = true;
|
|
4282
|
+
rollErr.currentVersion = r.currentVersion || this.state.currentVersion;
|
|
4283
|
+
rollErr.reason = r.error;
|
|
4284
|
+
throw rollErr;
|
|
4285
|
+
} else if (r.status === "recovery-required") {
|
|
4286
|
+
throw new Error("更新失败且自动恢复旧版本失败: " + (r.rollbackError || r.error || "未知原因") + "。请手动重新安装插件。");
|
|
4287
|
+
} else if (r.status === "failed") {
|
|
4288
|
+
throw new Error(r.error || "安装更新失败");
|
|
4289
|
+
} else if (r.status === "superseded") {
|
|
4290
|
+
throw new Error("更新任务已被其他操作覆盖,请重新检查更新");
|
|
4291
|
+
}
|
|
4292
|
+
}
|
|
4293
|
+
}
|
|
4294
|
+
|
|
4295
|
+
if (!reconciled) {
|
|
4296
|
+
throw new Error("更新结果尚未确认,请刷新页面或重启 DSH 查看状态");
|
|
4297
|
+
}
|
|
4069
4298
|
}
|
|
4070
4299
|
}
|
|
4071
4300
|
|
|
4072
4301
|
const application = outcome?.application || "restart-required";
|
|
4073
4302
|
this.state.status = "done";
|
|
4074
4303
|
this.state.application = application;
|
|
4304
|
+
this.state.taskId = activeTaskId;
|
|
4305
|
+
const installedV = outcome?.version || targetVersion;
|
|
4306
|
+
this.state.installedVersion = installedV;
|
|
4307
|
+
this.state.latestVersion = installedV;
|
|
4308
|
+
// Running version is NOT modified before restart/reload!
|
|
4309
|
+
this.state.runningVersion = CURRENT_VERSION;
|
|
4310
|
+
this.state.currentVersion = CURRENT_VERSION;
|
|
4311
|
+
this.state.rollbackInfo = null;
|
|
4312
|
+
this.state.error = null;
|
|
4313
|
+
if (openDialog || this.state.dialogOpen) {
|
|
4314
|
+
this.state.dialogOpen = true;
|
|
4315
|
+
}
|
|
4075
4316
|
this._notify();
|
|
4076
4317
|
return outcome;
|
|
4077
4318
|
} catch (err) {
|
|
4078
4319
|
this.state.status = "error";
|
|
4079
|
-
|
|
4080
|
-
|
|
4320
|
+
if (err.rolledBack) {
|
|
4321
|
+
this.state.rollbackInfo = {
|
|
4322
|
+
rolledBack: true,
|
|
4323
|
+
currentVersion: err.currentVersion || this.state.currentVersion,
|
|
4324
|
+
reason: err.reason || err.message,
|
|
4325
|
+
taskId: activeTaskId
|
|
4326
|
+
};
|
|
4327
|
+
this.state.error = err.message || ("安装更新失败(已自动恢复旧版本 v" + (err.currentVersion || this.state.currentVersion) + ")");
|
|
4328
|
+
} else {
|
|
4329
|
+
this.state.rollbackInfo = null;
|
|
4330
|
+
this.state.error = err.message || "更新安装失败";
|
|
4331
|
+
}
|
|
4332
|
+
if (openDialog || this.state.dialogOpen) {
|
|
4081
4333
|
this.state.dialogOpen = true;
|
|
4082
4334
|
}
|
|
4083
4335
|
this._notify();
|
|
4084
|
-
return { ok: false, error: this.state.error };
|
|
4336
|
+
return { ok: false, error: this.state.error, rolledBack: !!err.rolledBack };
|
|
4085
4337
|
}
|
|
4086
4338
|
}
|
|
4087
4339
|
};
|
|
@@ -6142,6 +6394,9 @@ function isTopmostDialog(z) {
|
|
|
6142
6394
|
() => updateStore.getSnapshot(),
|
|
6143
6395
|
() => updateStore.getSnapshot()
|
|
6144
6396
|
);
|
|
6397
|
+
useEffect(() => {
|
|
6398
|
+
try { updateStore.checkRecentStatus().catch(() => {}); } catch (_) {}
|
|
6399
|
+
}, []);
|
|
6145
6400
|
const btnClass = "sm-footerBtn" + (wide ? " sm-footerBtn-wide" : " sm-footerBtn-rail");
|
|
6146
6401
|
const btnLabel = t("footer.aria");
|
|
6147
6402
|
return h(React.Fragment, null,
|
|
@@ -6255,8 +6510,8 @@ function isTopmostDialog(z) {
|
|
|
6255
6510
|
let dialogTitle = t("update.title");
|
|
6256
6511
|
if (isAvailable) dialogTitle = t("update.newVersion");
|
|
6257
6512
|
else if (isUpdating) dialogTitle = t("update.installing");
|
|
6258
|
-
else if (isDone) dialogTitle = t("update.title");
|
|
6259
|
-
else if (isError) dialogTitle = t("update.error");
|
|
6513
|
+
else if (isDone) dialogTitle = t("update.done.title");
|
|
6514
|
+
else if (isError) dialogTitle = updateState.rollbackInfo ? t("update.rolledBack.title") : t("update.error");
|
|
6260
6515
|
|
|
6261
6516
|
const handleClose = () => {
|
|
6262
6517
|
if (!isUpdating) {
|
|
@@ -6288,22 +6543,64 @@ function isTopmostDialog(z) {
|
|
|
6288
6543
|
}, h(CloseIcon, { size: 14 }))) : null
|
|
6289
6544
|
),
|
|
6290
6545
|
h("div", { className: "sm-nativeDialogBody" },
|
|
6291
|
-
|
|
6292
|
-
|
|
6293
|
-
|
|
6294
|
-
|
|
6295
|
-
h("
|
|
6296
|
-
|
|
6297
|
-
|
|
6298
|
-
|
|
6299
|
-
|
|
6300
|
-
|
|
6301
|
-
|
|
6302
|
-
|
|
6303
|
-
|
|
6304
|
-
)
|
|
6305
|
-
|
|
6306
|
-
|
|
6546
|
+
(() => {
|
|
6547
|
+
const runningV = updateState.currentVersion || updateState.runningVersion || CURRENT_VERSION;
|
|
6548
|
+
const hasInstalledDiff = !!(updateState.installedVersion && compareSemver(updateState.installedVersion, runningV) > 0);
|
|
6549
|
+
const targetV = hasInstalledDiff ? updateState.installedVersion : (updateState.latestVersion || runningV);
|
|
6550
|
+
return h("div", { className: "sm-updateVersionGrid" },
|
|
6551
|
+
h("span", { className: "sm-updateVersionLabel" }, hasInstalledDiff ? t("update.runningVersion") : t("update.currentVersion")),
|
|
6552
|
+
h("span", { className: "sm-updateVersionValue" }, "v" + runningV),
|
|
6553
|
+
h("span", { className: "sm-updateVersionLabel" }, hasInstalledDiff ? t("update.installedVersion") : t("update.latestVersion")),
|
|
6554
|
+
h("span", { className: "sm-updateVersionValue" }, hasInstalledDiff
|
|
6555
|
+
? ("v" + updateState.installedVersion)
|
|
6556
|
+
: (updateState.latestVersion ? "v" + updateState.latestVersion : (isChecking ? t("update.checking") : "-")))
|
|
6557
|
+
);
|
|
6558
|
+
})(),
|
|
6559
|
+
(() => {
|
|
6560
|
+
const runningV = updateState.currentVersion || updateState.runningVersion || CURRENT_VERSION;
|
|
6561
|
+
const hasInstalledDiff = !!(updateState.installedVersion && compareSemver(updateState.installedVersion, runningV) > 0);
|
|
6562
|
+
const targetV = hasInstalledDiff ? updateState.installedVersion : (updateState.latestVersion || runningV);
|
|
6563
|
+
let statusBox = null;
|
|
6564
|
+
if (isChecking) {
|
|
6565
|
+
statusBox = h("div", { className: "sm-updateStatusBox sm-checking" }, t("update.checking"));
|
|
6566
|
+
} else if (isUpdating) {
|
|
6567
|
+
statusBox = h("div", { className: "sm-updateStatusBox sm-warn" }, t("update.installing"));
|
|
6568
|
+
} else if (isDone) {
|
|
6569
|
+
statusBox = h("div", { className: "sm-updateStatusBox sm-success", style: { textAlign: "left", whiteSpace: "pre-wrap" } },
|
|
6570
|
+
updateState.application === "applied" && runningV === targetV
|
|
6571
|
+
? t("update.done.applied", { to: targetV, version: targetV })
|
|
6572
|
+
: (updateState.application === "refresh-required"
|
|
6573
|
+
? t("update.done.refresh", { from: runningV, to: targetV })
|
|
6574
|
+
: t("update.done.restart", { from: runningV, to: targetV })
|
|
6575
|
+
)
|
|
6576
|
+
);
|
|
6577
|
+
} else if (isError) {
|
|
6578
|
+
if (updateState.rollbackInfo) {
|
|
6579
|
+
statusBox = h("div", { className: "sm-updateStatusBox sm-warn", style: { textAlign: "left", whiteSpace: "pre-wrap" } },
|
|
6580
|
+
h("div", { style: { fontWeight: "bold", marginBottom: "4px" } },
|
|
6581
|
+
t("update.rolledBack.title")
|
|
6582
|
+
),
|
|
6583
|
+
h("div", null,
|
|
6584
|
+
t("update.rolledBack", { version: updateState.rollbackInfo.currentVersion })
|
|
6585
|
+
),
|
|
6586
|
+
h("div", { style: { marginTop: "4px", opacity: 0.9, fontSize: "12px" } },
|
|
6587
|
+
t("update.rolledBack.reason", { reason: updateState.rollbackInfo.reason })
|
|
6588
|
+
)
|
|
6589
|
+
);
|
|
6590
|
+
} else {
|
|
6591
|
+
statusBox = h("div", { className: "sm-updateStatusBox sm-error", style: { textAlign: "left", whiteSpace: "pre-wrap" } },
|
|
6592
|
+
(updateState.error || t("update.error"))
|
|
6593
|
+
);
|
|
6594
|
+
}
|
|
6595
|
+
} else if (isAvailable) {
|
|
6596
|
+
statusBox = h("div", { className: "sm-updateStatusBox sm-warn" }, t("update.newVersion") + " (v" + updateState.latestVersion + ")");
|
|
6597
|
+
} else if (updateState.notes) {
|
|
6598
|
+
statusBox = h("div", { className: "sm-updateStatusBox sm-warn" }, t(updateState.notes));
|
|
6599
|
+
} else if (isIdle && updateState.latestVersion) {
|
|
6600
|
+
statusBox = h("div", { className: "sm-updateStatusBox sm-success" }, t("update.isLatest"));
|
|
6601
|
+
}
|
|
6602
|
+
return statusBox || h("div", { className: "sm-updateStatusBox sm-placeholder", style: { visibility: "hidden" } }, "-");
|
|
6603
|
+
})()
|
|
6307
6604
|
),
|
|
6308
6605
|
h("div", { className: "sm-nativeDialogFooter" },
|
|
6309
6606
|
isAvailable ? h(React.Fragment, null,
|
|
@@ -6315,7 +6612,7 @@ function isTopmostDialog(z) {
|
|
|
6315
6612
|
h("button", {
|
|
6316
6613
|
type: "button",
|
|
6317
6614
|
className: "sm-nativeDialogButton sm-nativeDialogConfirm",
|
|
6318
|
-
onClick: () => updateStore.startUpdate()
|
|
6615
|
+
onClick: () => updateStore.startUpdate({ openDialog: true })
|
|
6319
6616
|
}, t("update.btn.update", { version: updateState.latestVersion }))
|
|
6320
6617
|
) : null,
|
|
6321
6618
|
isUpdating ? h("button", {
|
|
@@ -6339,7 +6636,7 @@ function isTopmostDialog(z) {
|
|
|
6339
6636
|
className: "sm-nativeDialogButton sm-nativeDialogConfirm",
|
|
6340
6637
|
onClick: () => {
|
|
6341
6638
|
if (updateState.latestVersion && compareSemver(updateState.latestVersion, updateState.currentVersion) > 0) {
|
|
6342
|
-
updateStore.startUpdate();
|
|
6639
|
+
updateStore.startUpdate({ openDialog: true });
|
|
6343
6640
|
} else {
|
|
6344
6641
|
updateStore.checkForUpdate({ manual: true, openDialog: true });
|
|
6345
6642
|
}
|
|
@@ -6352,11 +6649,15 @@ function isTopmostDialog(z) {
|
|
|
6352
6649
|
className: "sm-nativeDialogButton sm-nativeDialogCancel",
|
|
6353
6650
|
onClick: handleClose
|
|
6354
6651
|
}, t("update.btn.close")),
|
|
6355
|
-
|
|
6652
|
+
h("button", {
|
|
6356
6653
|
type: "button",
|
|
6357
|
-
className: "sm-nativeDialogButton",
|
|
6358
|
-
|
|
6359
|
-
|
|
6654
|
+
className: "sm-nativeDialogButton sm-nativeDialogConfirm",
|
|
6655
|
+
disabled: isChecking,
|
|
6656
|
+
style: { minWidth: "96px", whiteSpace: "nowrap" },
|
|
6657
|
+
onClick: () => {
|
|
6658
|
+
if (!isChecking) updateStore.checkForUpdate({ manual: true, openDialog: true });
|
|
6659
|
+
}
|
|
6660
|
+
}, isChecking ? t("update.checking") : t("update.btn.check"))
|
|
6360
6661
|
) : null
|
|
6361
6662
|
)
|
|
6362
6663
|
)
|
|
@@ -6393,12 +6694,20 @@ function isTopmostDialog(z) {
|
|
|
6393
6694
|
updateStore.setDialogOpacity(e.target.value);
|
|
6394
6695
|
};
|
|
6395
6696
|
|
|
6697
|
+
useEffect(() => {
|
|
6698
|
+
try { updateStore.checkRecentStatus().catch(() => {}); } catch (_) {}
|
|
6699
|
+
}, []);
|
|
6700
|
+
|
|
6701
|
+
const runningV = updateState.currentVersion || updateState.runningVersion || CURRENT_VERSION;
|
|
6702
|
+
const hasInstalledDiff = !!(updateState.installedVersion && compareSemver(updateState.installedVersion, runningV) > 0);
|
|
6703
|
+
const targetV = hasInstalledDiff ? updateState.installedVersion : (updateState.latestVersion || runningV);
|
|
6704
|
+
|
|
6396
6705
|
return h("div", { className: "sm-settingsCard" },
|
|
6397
6706
|
h("div", { className: "sm-settingsHeader" },
|
|
6398
6707
|
h("h3", { className: "sm-settingsTitle" },
|
|
6399
6708
|
h(NpmIcon, { size: 18 }),
|
|
6400
6709
|
h("span", null, t("settings.title")),
|
|
6401
|
-
h("span", { className: "sm-settingsTag" }, "v" +
|
|
6710
|
+
h("span", { className: "sm-settingsTag" }, "v" + runningV)
|
|
6402
6711
|
)
|
|
6403
6712
|
),
|
|
6404
6713
|
h("div", { className: "sm-settingsSection" },
|
|
@@ -6415,31 +6724,48 @@ function isTopmostDialog(z) {
|
|
|
6415
6724
|
type: "button",
|
|
6416
6725
|
className: "sm-nativeDialogButton sm-nativeDialogConfirm sm-settingsCheckBtn",
|
|
6417
6726
|
disabled: isUpdating,
|
|
6418
|
-
onClick: () => updateStore.startUpdate({ openDialog:
|
|
6727
|
+
onClick: () => updateStore.startUpdate({ openDialog: true })
|
|
6419
6728
|
}, isUpdating ? t("update.btn.updating") : t("update.btn.update", { version: updateState.latestVersion })) : null
|
|
6420
6729
|
)
|
|
6421
6730
|
),
|
|
6422
6731
|
h("div", { className: "sm-settingsRow" },
|
|
6423
|
-
h("span", null, t("update.currentVersion")),
|
|
6424
|
-
h("span", { style: { fontFamily: "monospace" } }, "v" +
|
|
6732
|
+
h("span", null, hasInstalledDiff ? t("update.runningVersion") : t("update.currentVersion")),
|
|
6733
|
+
h("span", { style: { fontFamily: "monospace" } }, "v" + runningV)
|
|
6425
6734
|
),
|
|
6735
|
+
hasInstalledDiff ? h("div", { className: "sm-settingsRow" },
|
|
6736
|
+
h("span", null, t("update.installedVersion")),
|
|
6737
|
+
h("span", { style: { fontFamily: "monospace" } }, "v" + updateState.installedVersion)
|
|
6738
|
+
) : null,
|
|
6426
6739
|
h("div", { className: "sm-settingsRow" },
|
|
6427
6740
|
h("span", null, t("update.latestVersion")),
|
|
6428
6741
|
h("span", { style: { fontFamily: "monospace" } },
|
|
6429
6742
|
updateState.latestVersion ? "v" + updateState.latestVersion : (isChecking ? t("update.checking") : "-")
|
|
6430
6743
|
)
|
|
6431
6744
|
),
|
|
6745
|
+
updateState.notes ? h("div", { className: "sm-updateStatusBox sm-warn" },
|
|
6746
|
+
t(updateState.notes)
|
|
6747
|
+
) : null,
|
|
6432
6748
|
updateState.status === "available" ? h("div", { className: "sm-updateStatusBox sm-warn" },
|
|
6433
6749
|
t("update.newVersion") + " (v" + updateState.latestVersion + ")"
|
|
6434
6750
|
) : null,
|
|
6435
6751
|
updateState.status === "updating" ? h("div", { className: "sm-updateStatusBox sm-warn" },
|
|
6436
6752
|
t("update.installing")
|
|
6437
6753
|
) : null,
|
|
6438
|
-
updateState.status === "done" ? h("div", { className: "sm-updateStatusBox sm-success" },
|
|
6439
|
-
updateState.application === "applied"
|
|
6754
|
+
updateState.status === "done" ? h("div", { className: "sm-updateStatusBox sm-success", style: { whiteSpace: "pre-wrap" } },
|
|
6755
|
+
updateState.application === "applied" && runningV === targetV
|
|
6756
|
+
? t("update.done.applied", { to: targetV, version: targetV })
|
|
6757
|
+
: (updateState.application === "refresh-required"
|
|
6758
|
+
? t("update.done.refresh", { from: runningV, to: targetV })
|
|
6759
|
+
: t("update.done.restart", { from: runningV, to: targetV })
|
|
6760
|
+
)
|
|
6440
6761
|
) : null,
|
|
6441
|
-
updateState.status === "error" ? h("div", {
|
|
6442
|
-
updateState.
|
|
6762
|
+
updateState.status === "error" ? h("div", {
|
|
6763
|
+
className: "sm-updateStatusBox " + (updateState.rollbackInfo ? "sm-warn" : "sm-error"),
|
|
6764
|
+
style: { whiteSpace: "pre-wrap" }
|
|
6765
|
+
},
|
|
6766
|
+
updateState.rollbackInfo
|
|
6767
|
+
? (t("update.rolledBack", { version: updateState.rollbackInfo.currentVersion }) + "\n" + t("update.rolledBack.reason", { reason: updateState.rollbackInfo.reason }))
|
|
6768
|
+
: (updateState.error || t("update.error"))
|
|
6443
6769
|
) : null
|
|
6444
6770
|
),
|
|
6445
6771
|
h("div", { className: "sm-settingsSection" },
|
|
@@ -6465,7 +6791,8 @@ function isTopmostDialog(z) {
|
|
|
6465
6791
|
"aria-label": t("settings.registry")
|
|
6466
6792
|
},
|
|
6467
6793
|
h("option", { value: "registry.npmjs.org" }, t("settings.registry.npm")),
|
|
6468
|
-
h("option", { value: "registry.npmmirror.com" }, t("settings.registry.china"))
|
|
6794
|
+
h("option", { value: "registry.npmmirror.com" }, t("settings.registry.china")),
|
|
6795
|
+
h("option", { value: "127.0.0.1:4873" }, t("settings.registry.local"))
|
|
6469
6796
|
)
|
|
6470
6797
|
),
|
|
6471
6798
|
h("div", { className: "sm-settingsRow" },
|
|
@@ -6767,6 +7094,12 @@ function isTopmostDialog(z) {
|
|
|
6767
7094
|
inject: () => actions()
|
|
6768
7095
|
}, SessionManagerSettingsCard));
|
|
6769
7096
|
|
|
7097
|
+
ctx.effect(() => {
|
|
7098
|
+
try {
|
|
7099
|
+
updateStore.checkRecentStatus().catch(() => {});
|
|
7100
|
+
} catch (_) {}
|
|
7101
|
+
}, "session-manager: check update status on boot");
|
|
7102
|
+
|
|
6770
7103
|
ctx.effect(() => {
|
|
6771
7104
|
if (!updateStore.getAutoCheck()) return;
|
|
6772
7105
|
const timer = setTimeout(() => {
|
|
@@ -6856,6 +7189,7 @@ function isTopmostDialog(z) {
|
|
|
6856
7189
|
exports.openCustomSelect = openCustomSelect;
|
|
6857
7190
|
exports.closeCustomSelect = closeCustomSelect;
|
|
6858
7191
|
exports.installCustomDropdownInterceptor = installCustomDropdownInterceptor;
|
|
7192
|
+
exports.getTargetSmSelect = getTargetSmSelect;
|
|
6859
7193
|
exports.SM_SELECT_SELECTOR = SM_SELECT_SELECTOR;
|
|
6860
7194
|
return module.exports;
|
|
6861
7195
|
}
|