From cdfbdd5dd5ed140d200af0273882a7ebbc31e69d Mon Sep 17 00:00:00 2001 From: Syngnat Date: Thu, 9 Jul 2026 13:38:07 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat(update):=20=E4=B8=8B=E8=BD=BD?= =?UTF-8?q?=E8=BF=9B=E5=BA=A6=E5=88=B0=20100%=20=E5=90=8E=E7=94=B1?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E7=82=B9=E5=87=BB=E3=80=8C=E9=87=8D=E5=90=AF?= =?UTF-8?q?=E5=BA=94=E7=94=A8=E6=9B=B4=E6=96=B0=E3=80=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 取消 macOS 下载完成后自动安装/退出,Win/Mac 统一交互 - 进度弹窗在 100% 显示就绪提示,主按钮改为「重启应用更新」 - 关于页安装入口同步文案;点击后才执行安装脚本并重启 - 补充多语言与前端回归测试 --- frontend/src/App.tsx | 22 +++- .../src/hooks/useAppUpdateManager.test.tsx | 35 +++++- frontend/src/hooks/useAppUpdateManager.ts | 111 +++++++++++------- shared/i18n/de-DE.json | 15 ++- shared/i18n/en-US.json | 15 ++- shared/i18n/ja-JP.json | 15 ++- shared/i18n/ru-RU.json | 15 ++- shared/i18n/zh-CN.json | 15 ++- shared/i18n/zh-TW.json | 15 ++- 9 files changed, 192 insertions(+), 66 deletions(-) diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 67c83db1..1f2861fb 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -4201,8 +4201,8 @@ function App() { ) : null, isLatestUpdateDownloaded ? ( - ) : null, ].filter(Boolean); @@ -7961,8 +7961,8 @@ function App() { , - ] : (updateDownloadProgress.status === 'error' ? [ @@ -7974,10 +7974,20 @@ function App() { status={updateDownloadProgress.status === 'error' ? 'exception' : (updateDownloadProgress.status === 'done' ? 'success' : 'active')} />
- {`${formatBytes(updateDownloadProgress.downloaded)} / ${formatBytes(updateDownloadProgress.total)}`} + {updateDownloadProgress.status === 'done' + ? t('app.about.download_progress.complete_hint') + : `${formatBytes(updateDownloadProgress.downloaded)} / ${formatBytes(updateDownloadProgress.total)}`}
{updateDownloadProgress.message ? ( -
{updateDownloadProgress.message}
+
+ {updateDownloadProgress.message} +
) : null} diff --git a/frontend/src/hooks/useAppUpdateManager.test.tsx b/frontend/src/hooks/useAppUpdateManager.test.tsx index a3346227..b77fd290 100644 --- a/frontend/src/hooks/useAppUpdateManager.test.tsx +++ b/frontend/src/hooks/useAppUpdateManager.test.tsx @@ -161,7 +161,7 @@ describe('useAppUpdateManager', () => { expect(hook?.lastUpdateInfo?.downloaded).toBe(true); }); - it('auto-installs a macOS update immediately after download when the backend reports auto relaunch support', async () => { + it('keeps download at 100% ready-to-restart without auto-installing after download completes', async () => { backendApp.CheckForUpdates.mockResolvedValue({ success: true, data: { @@ -193,8 +193,39 @@ describe('useAppUpdateManager', () => { }); expect(backendApp.DownloadUpdate).toHaveBeenCalledTimes(1); - expect(backendApp.InstallUpdateAndRestart).toHaveBeenCalledTimes(1); + // 下载完成后不自动安装;用户需点击「重启应用更新」 + expect(backendApp.InstallUpdateAndRestart).not.toHaveBeenCalled(); expect(backendApp.OpenDownloadedUpdateDirectory).not.toHaveBeenCalled(); + expect(hook?.updateDownloadProgress.status).toBe('done'); + expect(hook?.updateDownloadProgress.percent).toBe(100); + expect(hook?.updateDownloadProgress.open).toBe(true); + expect(hook?.lastUpdateInfo?.downloaded).toBe(true); + }); + + it('installs and restarts only after the user confirms restart-to-update', async () => { + backendApp.CheckForUpdates.mockResolvedValue({ + success: true, + data: { + hasUpdate: true, + currentVersion: '0.8.1', + latestVersion: '0.8.2', + downloaded: true, + assetSize: 2048, + }, + }); + backendApp.InstallUpdateAndRestart.mockResolvedValue({ success: true }); + + renderHook(); + + await act(async () => { + await hook?.checkForUpdates(false); + }); + + await act(async () => { + await hook?.handleInstallFromProgress(); + }); + + expect(backendApp.InstallUpdateAndRestart).toHaveBeenCalledTimes(1); }); it('switches update channel and re-checks against the selected channel', async () => { diff --git a/frontend/src/hooks/useAppUpdateManager.ts b/frontend/src/hooks/useAppUpdateManager.ts index 206898dd..65195856 100644 --- a/frontend/src/hooks/useAppUpdateManager.ts +++ b/frontend/src/hooks/useAppUpdateManager.ts @@ -129,11 +129,6 @@ const normalizeAboutInfo = (value: unknown): AboutInfo => { }; }; -const shouldAutoInstallDownloadedUpdate = (resultData: UpdateDownloadResultData | null | undefined): boolean => { - const platform = String(resultData?.platform || '').trim().toLowerCase(); - return platform === 'darwin' && resultData?.autoRelaunch !== false; -}; - export const useAppUpdateManager = ({ runtimeBuildType, t, @@ -191,7 +186,7 @@ export const useAppUpdateManager = ({ const localDownloaded = updateDownloadedVersionRef.current === buildUpdateKey(info); const hasDownloaded = Boolean(info.downloaded) || localDownloaded; return hasDownloaded - ? t('app.about.update_status.new_version_downloaded', { version: info.latestVersion }) + ? t('app.about.update_status.new_version_ready_restart', { version: info.latestVersion }) : t('app.about.update_status.new_version_not_downloaded', { version: info.latestVersion }); } return t('app.about.update_status.latest', { version: info.currentVersion || t('common.unknown') }); @@ -273,27 +268,22 @@ export const useAppUpdateManager = ({ downloadPath: resultData?.downloadPath || prev.downloadPath || info.downloadPath, }; }); - if (resultData?.downloadPath) { - void message.success({ content: t('app.about.message.download_completed_with_path', { path: resultData.downloadPath }), duration: 5 }); - } else { - void message.success({ content: t('app.about.message.download_completed'), duration: 2 }); - } + // 与 Terminus/Codex 一致:下载到 100% 后停留在就绪态,由用户点击「重启应用更新」 + setUpdateDownloadProgress((prev) => ({ + ...prev, + open: true, + status: 'done', + percent: 100, + downloaded: prev.total > 0 ? prev.total : (info.assetSize || prev.downloaded), + message: t('app.about.download_progress.ready_to_restart'), + })); + void message.success({ + content: resultData?.downloadPath + ? t('app.about.message.download_ready_restart_with_path', { path: resultData.downloadPath }) + : t('app.about.message.download_ready_restart'), + duration: 4, + }); setAboutUpdateStatus(formatAboutUpdateStatus({ ...info, channel: normalizeUpdateChannel(info.channel), downloaded: true })); - - if (shouldAutoInstallDownloadedUpdate(resultData)) { - let installRes: any = null; - try { - installRes = await (window as any).go?.app?.App?.InstallUpdateAndRestart?.(); - } catch (error: any) { - installRes = { success: false, message: error?.message || t('common.unknown') }; - } - if (!installRes?.success) { - void message.error(t('app.about.message.install_failed_with_error', { error: installRes?.message || t('common.unknown') })); - return; - } - updateInstallTriggeredVersionRef.current = targetKey || null; - setUpdateDownloadProgress((prev) => ({ ...prev, open: false })); - } } else { setUpdateDownloadProgress((prev) => ({ ...prev, @@ -335,14 +325,40 @@ export const useAppUpdateManager = ({ if (!canInstall) { return; } - const res = await (window as any).go.app.App.InstallUpdateAndRestart(); + // 点击后进入「正在应用并重启」态,再拉起安装脚本并退出 + setUpdateDownloadProgress((prev) => ({ + ...prev, + open: true, + status: 'downloading', + percent: 100, + message: t('app.about.download_progress.applying_restart'), + })); + let res: any = null; + try { + res = await (window as any).go?.app?.App?.InstallUpdateAndRestart?.(); + } catch (error: any) { + res = { success: false, message: error?.message || t('common.unknown') }; + } if (!res?.success) { + setUpdateDownloadProgress((prev) => ({ + ...prev, + open: true, + status: 'error', + message: res?.message || t('common.unknown'), + })); void message.error(t('app.about.message.install_failed_with_error', { error: res?.message || t('common.unknown') })); return; } updateInstallTriggeredVersionRef.current = lastUpdateKey || null; - hideUpdateDownloadProgress(); - }, [hideUpdateDownloadProgress, lastUpdateInfo, lastUpdateKey, t, updateDownloadProgress.status]); + // 后端会 Quit;此处保持弹窗文案,避免用户误以为失败 + setUpdateDownloadProgress((prev) => ({ + ...prev, + open: true, + status: 'done', + percent: 100, + message: t('app.about.download_progress.restarting'), + })); + }, [lastUpdateInfo, lastUpdateKey, t, updateDownloadProgress.status]); const openDownloadedUpdateDirectory = useCallback(async () => { const backendApp = (window as any).go?.app?.App; @@ -620,16 +636,31 @@ export const useAppUpdateManager = ({ ? event.percent : (total > 0 ? (downloaded / total) * 100 : 0); const percent = Math.max(0, Math.min(100, percentRaw)); - setUpdateDownloadProgress((prev) => ({ - open: prev.open, - version: prev.version, - key: prev.key, - status: nextStatus, - percent, - downloaded, - total, - message: String(event.message || ''), - })); + setUpdateDownloadProgress((prev) => { + // 用户已点「重启应用更新」时,不让 downloading 事件把 100% 就绪态打回中间态文案 + if (updateInstallTriggeredVersionRef.current && prev.key && updateInstallTriggeredVersionRef.current === prev.key) { + return prev; + } + const eventMessage = String(event.message || ''); + let message = eventMessage; + if (!message) { + if (nextStatus === 'done') { + message = t('app.about.download_progress.ready_to_restart'); + } else if (nextStatus === 'start' || nextStatus === 'downloading') { + message = t('app.about.download_progress.downloading'); + } + } + return { + open: prev.open || nextStatus === 'start' || nextStatus === 'downloading' || nextStatus === 'done' || nextStatus === 'error', + version: prev.version, + key: prev.key, + status: nextStatus, + percent: nextStatus === 'done' ? 100 : percent, + downloaded: nextStatus === 'done' && total > 0 ? total : downloaded, + total: total > 0 ? total : prev.total, + message, + }; + }); }); } catch (e) { console.warn('Wails API: EventsOn unavailable', e); @@ -637,7 +668,7 @@ export const useAppUpdateManager = ({ return () => { if (offDownloadProgress) offDownloadProgress(); }; - }, []); + }, [t]); return { aboutDisplayVersion, diff --git a/shared/i18n/de-DE.json b/shared/i18n/de-DE.json index 1e1109f5..88c5fe93 100644 --- a/shared/i18n/de-DE.json +++ b/shared/i18n/de-DE.json @@ -2417,7 +2417,7 @@ "app.about.action.download_progress": "Downloadfortschritt", "app.about.action.download_update": "Update herunterladen", "app.about.action.hide_to_background": "Im Hintergrund ausblenden", - "app.about.action.install_update": "Update installieren", + "app.about.action.install_update": "Zum Aktualisieren neu starten", "app.about.action.mute_this_version": "Diesmal nicht erinnern", "app.about.action.open_install_directory": "Installationsordner öffnen", "app.about.community.ai_book": "AI全书", @@ -2459,7 +2459,7 @@ "app.about.update_status.check_failed": "Updateprüfung fehlgeschlagen: {{error}}", "app.about.update_status.checking": "Suche nach Updates...", "app.about.update_status.latest": "Sie verwenden die neueste Version ({{version}})", - "app.about.update_status.new_version_downloaded": "Neue Version {{version}} gefunden (heruntergeladen; öffnen Sie den Downloadfortschritt zur Installation)", + "app.about.update_status.new_version_downloaded": "Neue Version {{version}} heruntergeladen. Neu starten zum Aktualisieren.", "app.about.update_status.new_version_not_downloaded": "Neue Version {{version}} gefunden (nicht heruntergeladen)", "app.about.update_status.not_checked": "Nicht geprüft", "app.about.version.current": "Aktuelle Version", @@ -8032,5 +8032,14 @@ "ai_settings.open_mode.detached.desc": "Öffnet als ziehbar/skalierbar schwebendes Fenster.", "ai_settings.open_mode.message.dock": "Standard auf Seitenleiste gesetzt", "ai_settings.open_mode.message.detached": "Standard auf schwebendes Fenster gesetzt", - "ai_settings.context.section_title": "Kontextstufe" + "ai_settings.context.section_title": "Kontextstufe", + "app.about.action.restart_to_update": "Zum Aktualisieren neu starten", + "app.about.download_progress.ready_to_restart": "Download abgeschlossen (100%). Klicken Sie auf „Zum Aktualisieren neu starten“.", + "app.about.download_progress.downloading": "Update wird heruntergeladen…", + "app.about.download_progress.applying_restart": "Update wird angewendet und neu gestartet…", + "app.about.download_progress.restarting": "Neustart…", + "app.about.download_progress.complete_hint": "Update-Paket bereit (100%)", + "app.about.message.download_ready_restart": "Update heruntergeladen. Klicken Sie auf „Zum Aktualisieren neu starten“.", + "app.about.message.download_ready_restart_with_path": "Update heruntergeladen. Klicken Sie auf „Zum Aktualisieren neu starten“. Pfad: {{path}}", + "app.about.update_status.new_version_ready_restart": "Neue Version {{version}} bereit. Auf „Zum Aktualisieren neu starten“ klicken." } diff --git a/shared/i18n/en-US.json b/shared/i18n/en-US.json index a957c1e5..3171b672 100644 --- a/shared/i18n/en-US.json +++ b/shared/i18n/en-US.json @@ -2417,7 +2417,7 @@ "app.about.action.download_progress": "Download Progress", "app.about.action.download_update": "Download Update", "app.about.action.hide_to_background": "Hide to Background", - "app.about.action.install_update": "Install Update", + "app.about.action.install_update": "Restart to update", "app.about.action.mute_this_version": "Do Not Remind This Time", "app.about.action.open_install_directory": "Open Install Directory", "app.about.community.ai_book": "AI全书", @@ -2459,7 +2459,7 @@ "app.about.update_status.check_failed": "Update check failed: {{error}}", "app.about.update_status.checking": "Checking for updates...", "app.about.update_status.latest": "You are on the latest version ({{version}})", - "app.about.update_status.new_version_downloaded": "New version {{version}} found (downloaded; open Download Progress to install)", + "app.about.update_status.new_version_downloaded": "New version {{version}} is downloaded. Restart to update.", "app.about.update_status.new_version_not_downloaded": "New version {{version}} found (not downloaded)", "app.about.update_status.not_checked": "Not checked", "app.about.version.current": "Current Version", @@ -8032,5 +8032,14 @@ "ai_settings.open_mode.detached.desc": "Opens as a draggable/resizable floating window for multi-monitor or larger chat space.", "ai_settings.open_mode.message.dock": "Default open style set to sidebar", "ai_settings.open_mode.message.detached": "Default open style set to floating window", - "ai_settings.context.section_title": "Context level" + "ai_settings.context.section_title": "Context level", + "app.about.action.restart_to_update": "Restart to update", + "app.about.download_progress.ready_to_restart": "Download complete (100%). Click “Restart to update” to finish installing.", + "app.about.download_progress.downloading": "Downloading update…", + "app.about.download_progress.applying_restart": "Applying update and restarting…", + "app.about.download_progress.restarting": "Restarting…", + "app.about.download_progress.complete_hint": "Update package ready (100%)", + "app.about.message.download_ready_restart": "Update downloaded. Click “Restart to update” when ready.", + "app.about.message.download_ready_restart_with_path": "Update downloaded. Click “Restart to update” when ready. Path: {{path}}", + "app.about.update_status.new_version_ready_restart": "New version {{version}} is ready. Click “Restart to update”." } diff --git a/shared/i18n/ja-JP.json b/shared/i18n/ja-JP.json index 6279d8ae..f2d756bf 100644 --- a/shared/i18n/ja-JP.json +++ b/shared/i18n/ja-JP.json @@ -2417,7 +2417,7 @@ "app.about.action.download_progress": "ダウンロード状況", "app.about.action.download_update": "更新をダウンロード", "app.about.action.hide_to_background": "バックグラウンドに隠す", - "app.about.action.install_update": "更新をインストール", + "app.about.action.install_update": "再起動して更新", "app.about.action.mute_this_version": "今回は通知しない", "app.about.action.open_install_directory": "インストールディレクトリを開く", "app.about.community.ai_book": "AI全书", @@ -2459,7 +2459,7 @@ "app.about.update_status.check_failed": "更新確認に失敗しました: {{error}}", "app.about.update_status.checking": "更新を確認しています...", "app.about.update_status.latest": "現在は最新バージョンです({{version}})", - "app.about.update_status.new_version_downloaded": "新しいバージョン {{version}} が見つかりました(ダウンロード済み。「ダウンロード状況」からインストールしてください)", + "app.about.update_status.new_version_downloaded": "新しいバージョン {{version}} をダウンロード済みです。再起動して更新できます。", "app.about.update_status.new_version_not_downloaded": "新しいバージョン {{version}} が見つかりました(未ダウンロード)", "app.about.update_status.not_checked": "未確認", "app.about.version.current": "現在のバージョン", @@ -8032,5 +8032,14 @@ "ai_settings.open_mode.detached.desc": "ドラッグ/リサイズ可能な独立ウィンドウで開きます。", "ai_settings.open_mode.message.dock": "デフォルトをサイドバーに設定しました", "ai_settings.open_mode.message.detached": "デフォルトを独立ウィンドウに設定しました", - "ai_settings.context.section_title": "コンテキストレベル" + "ai_settings.context.section_title": "コンテキストレベル", + "app.about.action.restart_to_update": "再起動して更新", + "app.about.download_progress.ready_to_restart": "ダウンロード完了(100%)。「再起動して更新」をクリックしてください。", + "app.about.download_progress.downloading": "更新をダウンロード中…", + "app.about.download_progress.applying_restart": "更新を適用して再起動しています…", + "app.about.download_progress.restarting": "再起動中…", + "app.about.download_progress.complete_hint": "更新パッケージの準備完了(100%)", + "app.about.message.download_ready_restart": "更新のダウンロードが完了しました。「再起動して更新」をクリックしてください。", + "app.about.message.download_ready_restart_with_path": "更新のダウンロードが完了しました。「再起動して更新」をクリックしてください。パス: {{path}}", + "app.about.update_status.new_version_ready_restart": "新しいバージョン {{version}} の準備ができました。「再起動して更新」をクリックしてください。" } diff --git a/shared/i18n/ru-RU.json b/shared/i18n/ru-RU.json index aabcbc44..285d38f2 100644 --- a/shared/i18n/ru-RU.json +++ b/shared/i18n/ru-RU.json @@ -2417,7 +2417,7 @@ "app.about.action.download_progress": "Ход загрузки", "app.about.action.download_update": "Скачать обновление", "app.about.action.hide_to_background": "Скрыть в фон", - "app.about.action.install_update": "Установить обновление", + "app.about.action.install_update": "Перезапустить для обновления", "app.about.action.mute_this_version": "Не напоминать в этот раз", "app.about.action.open_install_directory": "Открыть каталог установки", "app.about.community.ai_book": "AI全书", @@ -2459,7 +2459,7 @@ "app.about.update_status.check_failed": "Проверка обновлений не удалась: {{error}}", "app.about.update_status.checking": "Проверка обновлений...", "app.about.update_status.latest": "У вас установлена последняя версия ({{version}})", - "app.about.update_status.new_version_downloaded": "Найдена новая версия {{version}} (загружена; откройте ход загрузки для установки)", + "app.about.update_status.new_version_downloaded": "Новая версия {{version}} загружена. Перезапустите для обновления.", "app.about.update_status.new_version_not_downloaded": "Найдена новая версия {{version}} (не загружена)", "app.about.update_status.not_checked": "Не проверялось", "app.about.version.current": "Текущая версия", @@ -8032,5 +8032,14 @@ "ai_settings.open_mode.detached.desc": "Открывается как перетаскиваемое/изменяемое отдельное окно.", "ai_settings.open_mode.message.dock": "По умолчанию: боковая панель", "ai_settings.open_mode.message.detached": "По умолчанию: отдельное окно", - "ai_settings.context.section_title": "Уровень контекста" + "ai_settings.context.section_title": "Уровень контекста", + "app.about.action.restart_to_update": "Перезапустить для обновления", + "app.about.download_progress.ready_to_restart": "Загрузка завершена (100%). Нажмите «Перезапустить для обновления».", + "app.about.download_progress.downloading": "Загрузка обновления…", + "app.about.download_progress.applying_restart": "Применение обновления и перезапуск…", + "app.about.download_progress.restarting": "Перезапуск…", + "app.about.download_progress.complete_hint": "Пакет обновления готов (100%)", + "app.about.message.download_ready_restart": "Обновление загружено. Нажмите «Перезапустить для обновления».", + "app.about.message.download_ready_restart_with_path": "Обновление загружено. Нажмите «Перезапустить для обновления». Путь: {{path}}", + "app.about.update_status.new_version_ready_restart": "Новая версия {{version}} готова. Нажмите «Перезапустить для обновления»." } diff --git a/shared/i18n/zh-CN.json b/shared/i18n/zh-CN.json index 1c994cde..6567b05f 100644 --- a/shared/i18n/zh-CN.json +++ b/shared/i18n/zh-CN.json @@ -2417,7 +2417,7 @@ "app.about.action.download_progress": "下载进度", "app.about.action.download_update": "下载更新", "app.about.action.hide_to_background": "隐藏到后台", - "app.about.action.install_update": "安装更新", + "app.about.action.install_update": "重启应用更新", "app.about.action.mute_this_version": "本次不再提示", "app.about.action.open_install_directory": "打开安装目录", "app.about.community.ai_book": "AI全书", @@ -2459,7 +2459,7 @@ "app.about.update_status.check_failed": "检查更新失败: {{error}}", "app.about.update_status.checking": "正在检查更新...", "app.about.update_status.latest": "当前已是最新版本({{version}})", - "app.about.update_status.new_version_downloaded": "发现新版本 {{version}}(已下载,请点击“下载进度”后安装)", + "app.about.update_status.new_version_downloaded": "发现新版本 {{version}}(已下载,可重启应用更新)", "app.about.update_status.new_version_not_downloaded": "发现新版本 {{version}}(未下载)", "app.about.update_status.not_checked": "未检查", "app.about.version.current": "当前版本", @@ -8032,5 +8032,14 @@ "ai_settings.open_mode.detached.desc": "以可拖拽缩放的浮动窗打开,适合多显示器或更大聊天区域。", "ai_settings.open_mode.message.dock": "已设为默认侧栏打开", "ai_settings.open_mode.message.detached": "已设为默认独立窗口打开", - "ai_settings.context.section_title": "上下文级别" + "ai_settings.context.section_title": "上下文级别", + "app.about.action.restart_to_update": "重启应用更新", + "app.about.download_progress.ready_to_restart": "下载完成(100%)。点击「重启应用更新」即可完成安装。", + "app.about.download_progress.downloading": "正在下载更新…", + "app.about.download_progress.applying_restart": "正在应用更新并重启…", + "app.about.download_progress.restarting": "正在重启应用…", + "app.about.download_progress.complete_hint": "更新包已就绪(100%)", + "app.about.message.download_ready_restart": "更新下载完成,可点击「重启应用更新」", + "app.about.message.download_ready_restart_with_path": "更新下载完成,可点击「重启应用更新」。路径:{{path}}", + "app.about.update_status.new_version_ready_restart": "发现新版本 {{version}}(已下载,点击「重启应用更新」)" } diff --git a/shared/i18n/zh-TW.json b/shared/i18n/zh-TW.json index e7d11b12..51be6a1f 100644 --- a/shared/i18n/zh-TW.json +++ b/shared/i18n/zh-TW.json @@ -2417,7 +2417,7 @@ "app.about.action.download_progress": "下載进度", "app.about.action.download_update": "下載更新", "app.about.action.hide_to_background": "隱藏到背景", - "app.about.action.install_update": "安裝更新", + "app.about.action.install_update": "重新啟動應用更新", "app.about.action.mute_this_version": "本次不再提示", "app.about.action.open_install_directory": "開啟安裝目錄", "app.about.community.ai_book": "AI全书", @@ -2459,7 +2459,7 @@ "app.about.update_status.check_failed": "檢查更新失敗: {{error}}", "app.about.update_status.checking": "正在檢查更新...", "app.about.update_status.latest": "目前已是最新版本({{version}})", - "app.about.update_status.new_version_downloaded": "發現新版本 {{version}}(已下載,請點擊「下載進度」後安裝)", + "app.about.update_status.new_version_downloaded": "發現新版本 {{version}}(已下載,可重新啟動應用更新)", "app.about.update_status.new_version_not_downloaded": "發現新版本 {{version}}(未下載)", "app.about.update_status.not_checked": "尚未檢查", "app.about.version.current": "目前版本", @@ -8032,5 +8032,14 @@ "ai_settings.open_mode.detached.desc": "以可拖曳縮放的浮動窗開啟,適合多顯示器或更大聊天區域。", "ai_settings.open_mode.message.dock": "已設為預設側欄開啟", "ai_settings.open_mode.message.detached": "已設為預設獨立視窗開啟", - "ai_settings.context.section_title": "上下文層級" + "ai_settings.context.section_title": "上下文層級", + "app.about.action.restart_to_update": "重新啟動應用更新", + "app.about.download_progress.ready_to_restart": "下載完成(100%)。點選「重新啟動應用更新」即可完成安裝。", + "app.about.download_progress.downloading": "正在下載更新…", + "app.about.download_progress.applying_restart": "正在套用更新並重新啟動…", + "app.about.download_progress.restarting": "正在重新啟動應用…", + "app.about.download_progress.complete_hint": "更新包已就緒(100%)", + "app.about.message.download_ready_restart": "更新下載完成,可點選「重新啟動應用更新」", + "app.about.message.download_ready_restart_with_path": "更新下載完成,可點選「重新啟動應用更新」。路徑:{{path}}", + "app.about.update_status.new_version_ready_restart": "發現新版本 {{version}}(已下載,點選「重新啟動應用更新」)" }