diff --git a/src/renderer/src/settings/AboutTab.tsx b/src/renderer/src/settings/AboutTab.tsx index 2109adc..dfe55ac 100644 --- a/src/renderer/src/settings/AboutTab.tsx +++ b/src/renderer/src/settings/AboutTab.tsx @@ -84,7 +84,13 @@ export function AboutTab(): React.JSX.Element { }, []) const status = state?.status ?? 'idle' - const statusText = t(STATUS_TEXT[status]) + (state?.version ? ` v${state.version}` : '') + // A download the app started on its own reads differently from one the user + // pressed the button for — same state, different expectation about install. + const statusKey = + status === 'downloaded' && state?.auto + ? 'settings.about.statusDownloadedAuto' + : STATUS_TEXT[status] + const statusText = t(statusKey) + (state?.version ? ` v${state.version}` : '') return (
diff --git a/src/renderer/src/settings/SettingsTabs.tsx b/src/renderer/src/settings/SettingsTabs.tsx index c626293..1d1cbae 100644 --- a/src/renderer/src/settings/SettingsTabs.tsx +++ b/src/renderer/src/settings/SettingsTabs.tsx @@ -1,6 +1,7 @@ import type { ReactNode } from 'react' import { useMemo, useState } from 'react' import { Input, InputNumber, Radio, Select, Switch } from 'antd' +import { UPDATE_CHECK_INTERVALS, type UpdateCheckInterval } from '@shared/settings' import type { ThemeColors } from '@shared/theme' import { DEFAULT_LANGUAGE, LANGUAGES, t, type Language } from '@shared/i18n' import { isReservedAccelerator } from '@shared/reservedAccelerators' @@ -345,6 +346,18 @@ export function RenderSettingsTab(): React.JSX.Element { ) } +/** + * Label for each offered interval. Keyed by the whitelist union rather than + * built ad hoc, so a new entry in UPDATE_CHECK_INTERVALS fails to type-check + * here until it has a label (and `0` keeps meaning "never"). + */ +const UPDATE_INTERVAL_LABELS: Record = { + 0: 'settings.system.updateCheckNever', + 4: 'settings.system.updateCheck4h', + 12: 'settings.system.updateCheck12h', + 24: 'settings.system.updateCheck24h' +} + export function SystemSettingsTab(): React.JSX.Element { const settings = useSettingsStore((s) => s.settings) const updateSystem = useSettingsStore((s) => s.updateSystem) @@ -403,6 +416,31 @@ export function SystemSettingsTab(): React.JSX.Element { /> } /> + void updateSystem({ updateCheckIntervalHours: value })} + options={UPDATE_CHECK_INTERVALS.map((hours) => ({ + value: hours, + label: t(UPDATE_INTERVAL_LABELS[hours]) + }))} + /> + } + /> + void updateSystem({ autoDownloadUpdate: checked })} + /> + } + /> = { 'main.updater.feedFailed': 'Gitea feed: {gitea}; GitHub: {github}', 'main.updater.checkTimeout': 'Update check timed out', + 'main.updater.notifyAvailableTitle': 'Update available', + 'main.updater.notifyAvailableContent': 'OpenTerminal v{version} is available', + 'main.updater.notifyDownloadedTitle': 'Update downloaded', + 'main.updater.notifyDownloadedContent': 'v{version} downloaded — it installs when you quit the app', 'main.ssh.connectTimeout': 'Connection timed out ({host}:{port})', 'main.ssh.saveFingerprintFailed': 'Failed to save the host fingerprint: {detail}', diff --git a/src/shared/i18n/dicts/en/settings.ts b/src/shared/i18n/dicts/en/settings.ts index c2839de..48b4161 100644 --- a/src/shared/i18n/dicts/en/settings.ts +++ b/src/shared/i18n/dicts/en/settings.ts @@ -94,6 +94,16 @@ const settings: Record = { 'settings.system.preventSleep': 'Prevent system sleep', 'settings.system.preventSleepDesc': 'While on, OpenTerminal keeps the system from sleeping automatically; when off, the system follows its own power settings', + 'settings.system.updateCheckInterval': 'Periodic update check', + 'settings.system.updateCheckIntervalDesc': + 'Check for new versions periodically in the background (startup and manual checks always work)', + 'settings.system.updateCheckNever': 'Never', + 'settings.system.updateCheck4h': 'Every 4 hours', + 'settings.system.updateCheck12h': 'Every 12 hours', + 'settings.system.updateCheck24h': 'Every 24 hours', + 'settings.system.autoDownload': 'Download updates automatically', + 'settings.system.autoDownloadDesc': + 'Silently download new versions in the background; installing stays your call (it installs when you quit the app)', 'settings.system.restoreSession': 'Restore last session on startup', 'settings.system.restoreSessionDesc': 'Restore the split layout on the next launch and return each terminal to its last directory; when off, OpenTerminal always starts with a single terminal', @@ -308,6 +318,7 @@ const settings: Record = { 'settings.about.statusLatest': 'Already up to date', 'settings.about.statusDownloading': 'Downloading…', 'settings.about.statusDownloaded': 'Download complete — restart to install', + 'settings.about.statusDownloadedAuto': 'Downloaded in the background — installs when you quit', 'settings.about.statusError': 'Check failed', 'settings.about.statusDev': 'Update checks are unavailable in development mode', 'settings.about.autoCheck': 'Check automatically at startup', diff --git a/src/shared/i18n/dicts/ja/main.ts b/src/shared/i18n/dicts/ja/main.ts index a7af9c1..ff4e26b 100644 --- a/src/shared/i18n/dicts/ja/main.ts +++ b/src/shared/i18n/dicts/ja/main.ts @@ -17,6 +17,10 @@ const main: Record = { 'main.updater.feedFailed': 'Gitea フィード: {gitea};GitHub: {github}', 'main.updater.checkTimeout': '更新の確認がタイムアウトしました', + 'main.updater.notifyAvailableTitle': '新しいバージョンがあります', + 'main.updater.notifyAvailableContent': 'OpenTerminal v{version} が利用可能です', + 'main.updater.notifyDownloadedTitle': 'アップデートをダウンロードしました', + 'main.updater.notifyDownloadedContent': 'v{version} をダウンロードしました — 終了時にインストールされます', 'main.ssh.connectTimeout': '接続がタイムアウトしました ({host}:{port})', 'main.ssh.saveFingerprintFailed': 'ホスト鍵のフィンガープリントを保存できませんでした: {detail}', diff --git a/src/shared/i18n/dicts/ja/settings.ts b/src/shared/i18n/dicts/ja/settings.ts index 42c656d..1097699 100644 --- a/src/shared/i18n/dicts/ja/settings.ts +++ b/src/shared/i18n/dicts/ja/settings.ts @@ -91,6 +91,16 @@ const settings: Record = { 'settings.system.preventSleep': 'スリープを防止', 'settings.system.preventSleepDesc': 'オンにすると OpenTerminal がシステムの自動スリープを防ぎます。オフにすると OS の設定どおりにスリープします', + 'settings.system.updateCheckInterval': '定期アップデート確認', + 'settings.system.updateCheckIntervalDesc': + 'バックグラウンドで定期的に新バージョンを確認します(起動時と手動確認は常に有効)', + 'settings.system.updateCheckNever': 'なし', + 'settings.system.updateCheck4h': '4 時間ごと', + 'settings.system.updateCheck12h': '12 時間ごと', + 'settings.system.updateCheck24h': '24 時間ごと', + 'settings.system.autoDownload': 'アップデートを自動ダウンロード', + 'settings.system.autoDownloadDesc': + '新バージョンをバックグラウンドで自動ダウンロードします(インストールは終了時に実行されます)', 'settings.system.restoreSession': '起動時に前回のセッションを復元', 'settings.system.restoreSessionDesc': '次回の起動で分割レイアウトを復元し、各ターミナルを前回のディレクトリに戻します。オフにすると毎回 1 つのターミナルで起動します', @@ -303,6 +313,7 @@ const settings: Record = { 'settings.about.statusLatest': '最新バージョンです', 'settings.about.statusDownloading': 'ダウンロードしています…', 'settings.about.statusDownloaded': 'ダウンロード完了。再起動してインストールできます', + 'settings.about.statusDownloadedAuto': 'バックグラウンドでダウンロード完了 — 終了時にインストールされます', 'settings.about.statusError': '確認に失敗しました', 'settings.about.statusDev': '開発モードでは更新を確認できません', 'settings.about.autoCheck': '起動時に自動で確認', diff --git a/src/shared/i18n/dicts/zh-CN/main.ts b/src/shared/i18n/dicts/zh-CN/main.ts index fcb5185..dc7a2ec 100644 --- a/src/shared/i18n/dicts/zh-CN/main.ts +++ b/src/shared/i18n/dicts/zh-CN/main.ts @@ -17,6 +17,10 @@ const main: Record = { 'main.updater.feedFailed': '国内源: {gitea};GitHub: {github}', 'main.updater.checkTimeout': '检查更新超时', + 'main.updater.notifyAvailableTitle': '发现新版本', + 'main.updater.notifyAvailableContent': 'OpenTerminal v{version} 已可用', + 'main.updater.notifyDownloadedTitle': '更新已下载', + 'main.updater.notifyDownloadedContent': 'v{version} 已下载完成,退出应用时将自动安装', 'main.ssh.connectTimeout': '连接超时 ({host}:{port})', 'main.ssh.saveFingerprintFailed': '保存主机指纹失败: {detail}', diff --git a/src/shared/i18n/dicts/zh-CN/settings.ts b/src/shared/i18n/dicts/zh-CN/settings.ts index 9cfdd42..f57c8e4 100644 --- a/src/shared/i18n/dicts/zh-CN/settings.ts +++ b/src/shared/i18n/dicts/zh-CN/settings.ts @@ -89,6 +89,16 @@ const settings: Record = { 'settings.system.preventSleep': '阻止系统休眠', 'settings.system.preventSleepDesc': '开启后 OpenTerminal 将阻止系统自动休眠;关闭则允许系统按系统设置休眠', + 'settings.system.updateCheckInterval': '定时检查更新', + 'settings.system.updateCheckIntervalDesc': + '后台按周期自动检查新版本(启动时与手动检查始终可用)', + 'settings.system.updateCheckNever': '从不', + 'settings.system.updateCheck4h': '每 4 小时', + 'settings.system.updateCheck12h': '每 12 小时', + 'settings.system.updateCheck24h': '每 24 小时', + 'settings.system.autoDownload': '自动下载更新', + 'settings.system.autoDownloadDesc': + '发现新版本时在后台静默下载;安装时机仍由你决定(退出应用时会自动安装)', 'settings.system.restoreSession': '启动时恢复上次会话', 'settings.system.restoreSessionDesc': '下次启动恢复分屏布局,并让每个终端回到它上次所在的目录;关闭则每次都以单个终端启动', @@ -292,6 +302,7 @@ const settings: Record = { 'settings.about.statusLatest': '已经是最新版本', 'settings.about.statusDownloading': '正在下载…', 'settings.about.statusDownloaded': '下载完成,可重启安装', + 'settings.about.statusDownloadedAuto': '已在后台下载完成,退出时自动安装', 'settings.about.statusError': '检查失败', 'settings.about.statusDev': '开发模式不支持更新检查', 'settings.about.autoCheck': '启动时自动检查', diff --git a/src/shared/i18n/dicts/zh-TW/main.ts b/src/shared/i18n/dicts/zh-TW/main.ts index a8f646a..6022ef4 100644 --- a/src/shared/i18n/dicts/zh-TW/main.ts +++ b/src/shared/i18n/dicts/zh-TW/main.ts @@ -17,6 +17,10 @@ const main: Record = { 'main.updater.feedFailed': '國內來源: {gitea};GitHub: {github}', 'main.updater.checkTimeout': '檢查更新逾時', + 'main.updater.notifyAvailableTitle': '發現新版本', + 'main.updater.notifyAvailableContent': 'OpenTerminal v{version} 已可用', + 'main.updater.notifyDownloadedTitle': '更新已下載', + 'main.updater.notifyDownloadedContent': 'v{version} 已下載完成,結束應用程式時將自動安裝', 'main.ssh.connectTimeout': '連線逾時 ({host}:{port})', 'main.ssh.saveFingerprintFailed': '儲存主機指紋失敗: {detail}', diff --git a/src/shared/i18n/dicts/zh-TW/settings.ts b/src/shared/i18n/dicts/zh-TW/settings.ts index 6e46bd4..4aa9c8d 100644 --- a/src/shared/i18n/dicts/zh-TW/settings.ts +++ b/src/shared/i18n/dicts/zh-TW/settings.ts @@ -89,6 +89,16 @@ const settings: Record = { 'settings.system.preventSleep': '防止系統休眠', 'settings.system.preventSleepDesc': '開啟後 OpenTerminal 會防止系統自動休眠;關閉則允許系統依本身的設定休眠', + 'settings.system.updateCheckInterval': '定時檢查更新', + 'settings.system.updateCheckIntervalDesc': + '背景依週期自動檢查新版本(啟動時與手動檢查始終可用)', + 'settings.system.updateCheckNever': '永不', + 'settings.system.updateCheck4h': '每 4 小時', + 'settings.system.updateCheck12h': '每 12 小時', + 'settings.system.updateCheck24h': '每 24 小時', + 'settings.system.autoDownload': '自動下載更新', + 'settings.system.autoDownloadDesc': + '發現新版本時在背景靜默下載;安裝時機仍由你決定(結束應用程式時會自動安裝)', 'settings.system.restoreSession': '啟動時還原上次工作階段', 'settings.system.restoreSessionDesc': '下次啟動時還原分割版面,並讓每個終端回到上次所在的目錄;關閉則每次都以單一終端啟動', @@ -292,6 +302,7 @@ const settings: Record = { 'settings.about.statusLatest': '目前已是最新版本', 'settings.about.statusDownloading': '正在下載…', 'settings.about.statusDownloaded': '下載完成,可重新啟動安裝', + 'settings.about.statusDownloadedAuto': '已在背景下載完成,結束時自動安裝', 'settings.about.statusError': '檢查失敗', 'settings.about.statusDev': '開發模式不支援檢查更新', 'settings.about.autoCheck': '啟動時自動檢查',