diff --git a/packages/shared/IpcChannel.ts b/packages/shared/IpcChannel.ts index 8782d02f24..daea5dad6e 100644 --- a/packages/shared/IpcChannel.ts +++ b/packages/shared/IpcChannel.ts @@ -15,8 +15,8 @@ export enum IpcChannel { App_SetTrayOnClose = 'app:set-tray-on-close', App_SetTheme = 'app:set-theme', App_SetAutoUpdate = 'app:set-auto-update', - App_SetEnableEarlyAccess = 'app:set-enable-early-access', - App_SetUpgradeChannel = 'app:set-upgrade-channel', + App_SetTestPlan = 'app:set-test-plan', + App_SetTestChannel = 'app:set-test-channel', App_HandleZoomFactor = 'app:handle-zoom-factor', App_Select = 'app:select', App_HasWritePermission = 'app:has-write-permission', diff --git a/packages/shared/config/constant.ts b/packages/shared/config/constant.ts index 975767fefa..e4545d44cb 100644 --- a/packages/shared/config/constant.ts +++ b/packages/shared/config/constant.ts @@ -406,7 +406,8 @@ export const defaultLanguage = 'en-US' export enum FeedUrl { PRODUCTION = 'https://releases.cherry-ai.com', - GITHUB_LATEST = 'https://github.com/CherryHQ/cherry-studio/releases/latest/download' + GITHUB_LATEST = 'https://github.com/CherryHQ/cherry-studio/releases/latest/download', + PRERELEASE_LOWEST = 'https://github.com/CherryHQ/cherry-studio/releases/download/v1.4.0' } export enum UpgradeChannel { diff --git a/src/main/ipc.ts b/src/main/ipc.ts index 32baecac35..8c6810bcdc 100644 --- a/src/main/ipc.ts +++ b/src/main/ipc.ts @@ -142,14 +142,20 @@ export function registerIpc(mainWindow: BrowserWindow, app: Electron.App) { configManager.setAutoUpdate(isActive) }) - ipcMain.handle(IpcChannel.App_SetEnableEarlyAccess, async (_, isActive: boolean) => { - appUpdater.cancelDownload() - configManager.setEnableEarlyAccess(isActive) + ipcMain.handle(IpcChannel.App_SetTestPlan, async (_, isActive: boolean) => { + log.info('set test plan', isActive) + if (isActive !== configManager.getTestPlan()) { + appUpdater.cancelDownload() + configManager.setTestPlan(isActive) + } }) - ipcMain.handle(IpcChannel.App_SetUpgradeChannel, async (_, channel: UpgradeChannel) => { - appUpdater.cancelDownload() - configManager.setUpgradeChannel(channel) + ipcMain.handle(IpcChannel.App_SetTestChannel, async (_, channel: UpgradeChannel) => { + log.info('set test channel', channel) + if (channel !== configManager.getTestChannel()) { + appUpdater.cancelDownload() + configManager.setTestChannel(channel) + } }) ipcMain.handle(IpcChannel.Config_Set, (_, key: string, value: any, isNotify: boolean = false) => { diff --git a/src/main/services/AppUpdater.ts b/src/main/services/AppUpdater.ts index e26a779d59..82165fd715 100644 --- a/src/main/services/AppUpdater.ts +++ b/src/main/services/AppUpdater.ts @@ -5,7 +5,7 @@ import { IpcChannel } from '@shared/IpcChannel' import { CancellationToken, UpdateInfo } from 'builder-util-runtime' import { app, BrowserWindow, dialog } from 'electron' import logger from 'electron-log' -import { AppUpdater as _AppUpdater, autoUpdater, NsisUpdater } from 'electron-updater' +import { AppUpdater as _AppUpdater, autoUpdater, NsisUpdater, UpdateCheckResult } from 'electron-updater' import path from 'path' import icon from '../../../build/icon.png?asset' @@ -15,6 +15,7 @@ export default class AppUpdater { autoUpdater: _AppUpdater = autoUpdater private releaseInfo: UpdateInfo | undefined private cancellationToken: CancellationToken = new CancellationToken() + private updateCheckResult: UpdateCheckResult | null = null constructor(mainWindow: BrowserWindow) { logger.transports.file.level = 'info' @@ -65,6 +66,7 @@ export default class AppUpdater { private async _getPreReleaseVersionFromGithub(channel: UpgradeChannel) { try { + logger.info('get pre release version from github', channel) const responses = await fetch('https://api.github.com/repos/CherryHQ/cherry-studio/releases?per_page=8', { headers: { Accept: 'application/vnd.github+json', @@ -73,11 +75,12 @@ export default class AppUpdater { } }) const data = (await responses.json()) as GithubReleaseInfo[] - logger.debug('github release data', data) const release: GithubReleaseInfo | undefined = data.find((item: GithubReleaseInfo) => { return item.prerelease && item.tag_name.includes(`-${channel}.`) }) + logger.info('release info', release) + if (!release) { return null } @@ -119,31 +122,57 @@ export default class AppUpdater { autoUpdater.autoInstallOnAppQuit = isActive } - private async _setFeedUrl() { - // disable downgrade and differential download - // github and gitcode don't support multiple range download - this.autoUpdater.allowDowngrade = false - this.autoUpdater.disableDifferentialDownload = true + private _getChannelByVersion(version: string) { + if (version.includes(`-${UpgradeChannel.BETA}.`)) { + return UpgradeChannel.BETA + } + if (version.includes(`-${UpgradeChannel.RC}.`)) { + return UpgradeChannel.RC + } + return UpgradeChannel.LATEST + } + + private _getTestChannel() { + const currentChannel = this._getChannelByVersion(app.getVersion()) + const savedChannel = configManager.getTestChannel() + + if (currentChannel === UpgradeChannel.LATEST) { + return savedChannel || UpgradeChannel.RC + } + + if (savedChannel === currentChannel) { + return savedChannel + } + + // if the upgrade channel is not equal to the current channel, use the latest channel + return UpgradeChannel.LATEST + } + + private async _setFeedUrl() { + const testPlan = configManager.getTestPlan() + if (testPlan) { + const channel = this._getTestChannel() - if (configManager.getEnableEarlyAccess()) { - const channel = configManager.getUpgradeChannel() if (channel === UpgradeChannel.LATEST) { - this.autoUpdater.setFeedURL(FeedUrl.GITHUB_LATEST) this.autoUpdater.channel = UpgradeChannel.LATEST - return true + this.autoUpdater.setFeedURL(FeedUrl.GITHUB_LATEST) + return } const preReleaseUrl = await this._getPreReleaseVersionFromGithub(channel) if (preReleaseUrl) { this.autoUpdater.setFeedURL(preReleaseUrl) this.autoUpdater.channel = channel - return true + return } - return false + + // if no prerelease url, use lowest prerelease version to avoid error + this.autoUpdater.setFeedURL(FeedUrl.PRERELEASE_LOWEST) + this.autoUpdater.channel = UpgradeChannel.LATEST + return } - // no early access, use latest version - this.autoUpdater.channel = 'latest' + this.autoUpdater.channel = UpgradeChannel.LATEST this.autoUpdater.setFeedURL(FeedUrl.PRODUCTION) const ipCountry = await this._getIpCountry() @@ -151,12 +180,14 @@ export default class AppUpdater { if (ipCountry.toLowerCase() !== 'cn') { this.autoUpdater.setFeedURL(FeedUrl.GITHUB_LATEST) } - return true } public cancelDownload() { this.cancellationToken.cancel() this.cancellationToken = new CancellationToken() + if (this.autoUpdater.autoDownload) { + this.updateCheckResult?.cancellationToken?.cancel() + } } public async checkForUpdates() { @@ -167,17 +198,17 @@ export default class AppUpdater { } } - const isSetFeedUrl = await this._setFeedUrl() - if (!isSetFeedUrl) { - return { - currentVersion: app.getVersion(), - updateInfo: null - } - } + await this._setFeedUrl() + + // disable downgrade after change the channel + this.autoUpdater.allowDowngrade = false + + // github and gitcode don't support multiple range download + this.autoUpdater.disableDifferentialDownload = true try { - const update = await this.autoUpdater.checkForUpdates() - if (update?.isUpdateAvailable && !this.autoUpdater.autoDownload) { + this.updateCheckResult = await this.autoUpdater.checkForUpdates() + if (this.updateCheckResult?.isUpdateAvailable && !this.autoUpdater.autoDownload) { // 如果 autoDownload 为 false,则需要再调用下面的函数触发下 // do not use await, because it will block the return of this function logger.info('downloadUpdate manual by check for updates', this.cancellationToken) @@ -186,7 +217,7 @@ export default class AppUpdater { return { currentVersion: this.autoUpdater.currentVersion, - updateInfo: update?.updateInfo + updateInfo: this.updateCheckResult?.updateInfo } } catch (error) { logger.error('Failed to check for update:', error) diff --git a/src/main/services/ConfigManager.ts b/src/main/services/ConfigManager.ts index 6d33b6e3dd..8e4b5d2bf1 100644 --- a/src/main/services/ConfigManager.ts +++ b/src/main/services/ConfigManager.ts @@ -16,8 +16,8 @@ export enum ConfigKeys { ClickTrayToShowQuickAssistant = 'clickTrayToShowQuickAssistant', EnableQuickAssistant = 'enableQuickAssistant', AutoUpdate = 'autoUpdate', - EnableEarlyAccess = 'enableEarlyAccess', - UpgradeChannel = 'upgradeChannel', + TestPlan = 'testPlan', + TestChannel = 'testChannel', EnableDataCollection = 'enableDataCollection', SelectionAssistantEnabled = 'selectionAssistantEnabled', SelectionAssistantTriggerMode = 'selectionAssistantTriggerMode', @@ -143,20 +143,20 @@ export class ConfigManager { this.set(ConfigKeys.AutoUpdate, value) } - getEnableEarlyAccess(): boolean { - return this.get(ConfigKeys.EnableEarlyAccess, false) + getTestPlan(): boolean { + return this.get(ConfigKeys.TestPlan, false) } - setEnableEarlyAccess(value: boolean) { - this.set(ConfigKeys.EnableEarlyAccess, value) + setTestPlan(value: boolean) { + this.set(ConfigKeys.TestPlan, value) } - getUpgradeChannel(): UpgradeChannel { - return this.get(ConfigKeys.UpgradeChannel, UpgradeChannel.LATEST) + getTestChannel(): UpgradeChannel { + return this.get(ConfigKeys.TestChannel) } - setUpgradeChannel(value: UpgradeChannel) { - this.set(ConfigKeys.UpgradeChannel, value) + setTestChannel(value: UpgradeChannel) { + this.set(ConfigKeys.TestChannel, value) } getEnableDataCollection(): boolean { diff --git a/src/preload/index.ts b/src/preload/index.ts index 7867c66917..8412e00bc3 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -23,8 +23,8 @@ const api = { setLaunchToTray: (isActive: boolean) => ipcRenderer.invoke(IpcChannel.App_SetLaunchToTray, isActive), setTray: (isActive: boolean) => ipcRenderer.invoke(IpcChannel.App_SetTray, isActive), setTrayOnClose: (isActive: boolean) => ipcRenderer.invoke(IpcChannel.App_SetTrayOnClose, isActive), - setEnableEarlyAccess: (isActive: boolean) => ipcRenderer.invoke(IpcChannel.App_SetEnableEarlyAccess, isActive), - setUpgradeChannel: (channel: UpgradeChannel) => ipcRenderer.invoke(IpcChannel.App_SetUpgradeChannel, channel), + setTestPlan: (isActive: boolean) => ipcRenderer.invoke(IpcChannel.App_SetTestPlan, isActive), + setTestChannel: (channel: UpgradeChannel) => ipcRenderer.invoke(IpcChannel.App_SetTestChannel, channel), setTheme: (theme: ThemeMode) => ipcRenderer.invoke(IpcChannel.App_SetTheme, theme), handleZoomFactor: (delta: number, reset: boolean = false) => ipcRenderer.invoke(IpcChannel.App_HandleZoomFactor, delta, reset), diff --git a/src/renderer/src/hooks/useSettings.ts b/src/renderer/src/hooks/useSettings.ts index 72560706e6..dfb75cc791 100644 --- a/src/renderer/src/hooks/useSettings.ts +++ b/src/renderer/src/hooks/useSettings.ts @@ -4,7 +4,6 @@ import { SendMessageShortcut, setAssistantIconType, setAutoCheckUpdate as _setAutoCheckUpdate, - setEarlyAccess as _setEarlyAccess, setLaunchOnBoot, setLaunchToTray, setPinTopicsToTop, @@ -12,12 +11,13 @@ import { setShowTokens, setSidebarIcons, setTargetLanguage, + setTestChannel as _setTestChannel, + setTestPlan as _setTestPlan, setTheme, SettingsState, setTopicPosition, setTray as _setTray, setTrayOnClose, - setUpgradeChannel as _setUpgradeChannel, setWindowStyle } from '@renderer/store/settings' import { SidebarIcon, ThemeMode, TranslateLanguageVarious } from '@renderer/types' @@ -61,14 +61,14 @@ export function useSettings() { window.api.setAutoUpdate(isAutoUpdate) }, - setEarlyAccess(isEarlyAccess: boolean) { - dispatch(_setEarlyAccess(isEarlyAccess)) - window.api.setEnableEarlyAccess(isEarlyAccess) + setTestPlan(isTestPlan: boolean) { + dispatch(_setTestPlan(isTestPlan)) + window.api.setTestPlan(isTestPlan) }, - setUpgradeChannel(channel: UpgradeChannel) { - dispatch(_setUpgradeChannel(channel)) - window.api.setUpgradeChannel(channel) + setTestChannel(channel: UpgradeChannel) { + dispatch(_setTestChannel(channel)) + window.api.setTestChannel(channel) }, setTheme(theme: ThemeMode) { diff --git a/src/renderer/src/i18n/locales/en-us.json b/src/renderer/src/i18n/locales/en-us.json index ecb7182753..9a5e61122e 100644 --- a/src/renderer/src/i18n/locales/en-us.json +++ b/src/renderer/src/i18n/locales/en-us.json @@ -1392,15 +1392,14 @@ "general.emoji_picker": "Emoji Picker", "general.image_upload": "Image Upload", "general.auto_check_update.title": "Auto Update", - "general.early_access.title": "Early Access", - "general.early_access.tooltip": "Updating to test versions cannot be downgraded, there is a risk of data loss, please backup your data in advance", - "general.early_access.beta_version": "Beta Version", - "general.early_access.rc_version": "RC Version", - "general.early_access.latest_version": "Latest Version", - "general.early_access.latest_version_tooltip": "github latest version, latest stable version", - "general.early_access.version_options": "Version Options", - "general.early_access.rc_version_tooltip": "More stable, please backup your data", - "general.early_access.beta_version_tooltip": "Latest features but unstable, use with caution", + "general.test_plan.title": "Test Plan", + "general.test_plan.tooltip": "Participate in the test plan to experience the latest features faster, but also brings more risks, please backup your data in advance", + "general.test_plan.beta_version": "Beta Version (Beta)", + "general.test_plan.beta_version_tooltip": "Features may change at any time, bugs are more, upgrade quickly", + "general.test_plan.rc_version": "Preview Version (RC)", + "general.test_plan.rc_version_tooltip": "Close to stable version, features are basically stable, bugs are few", + "general.test_plan.version_options": "Version Options", + "general.test_plan.version_channel_not_match": "Preview and test version switching will take effect after the next stable version is released", "general.reset.button": "Reset", "general.reset.title": "Data Reset", "general.restore.button": "Restore", diff --git a/src/renderer/src/i18n/locales/ja-jp.json b/src/renderer/src/i18n/locales/ja-jp.json index 4b0d34eeb2..b1b03c4f3b 100644 --- a/src/renderer/src/i18n/locales/ja-jp.json +++ b/src/renderer/src/i18n/locales/ja-jp.json @@ -1863,15 +1863,14 @@ } }, "general.auto_check_update.title": "自動更新", - "general.early_access.title": "早期アクセス", - "general.early_access.tooltip": "更新すると、データが失われる可能性があります。データを事前にバックアップしてください。", - "general.early_access.beta_version": "ベータ版", - "general.early_access.rc_version": "RC版", - "general.early_access.latest_version": "最新版", - "general.early_access.latest_version_tooltip": "github latest バージョン, 最新安定版", - "general.early_access.version_options": "バージョンオプション", - "general.early_access.rc_version_tooltip": "より安定しています。データを事前にバックアップしてください。", - "general.early_access.beta_version_tooltip": "最新の機能ですが、不安定な場合があります。使用には注意してください。", + "general.test_plan.title": "テストプラン", + "general.test_plan.tooltip": "テストプランに参加すると、最新の機能をより早く体験できますが、同時により多くのリスクが伴います。データを事前にバックアップしてください。", + "general.test_plan.beta_version": "ベータ版(Beta)", + "general.test_plan.beta_version_tooltip": "機能が変更される可能性があります。バグが多く、迅速にアップグレードされます。", + "general.test_plan.rc_version": "プレビュー版(RC)", + "general.test_plan.rc_version_tooltip": "安定版に近い機能ですが、バグが少なく、迅速にアップグレードされます。", + "general.test_plan.version_options": "バージョンオプション", + "general.test_plan.version_channel_not_match": "プレビュー版とテスト版の切り替えは、次の正式版リリース時に有効になります。", "quickPhrase": { "title": "クイックフレーズ", "add": "フレーズを追加", diff --git a/src/renderer/src/i18n/locales/ru-ru.json b/src/renderer/src/i18n/locales/ru-ru.json index d7f20e297b..46faee8677 100644 --- a/src/renderer/src/i18n/locales/ru-ru.json +++ b/src/renderer/src/i18n/locales/ru-ru.json @@ -1863,15 +1863,14 @@ } }, "general.auto_check_update.title": "Автоматическое обновление", - "general.early_access.title": "Ранний доступ", - "general.early_access.tooltip": "Обновление до тестовых версий не может быть откачено, существует риск потери данных, пожалуйста, сделайте резервную копию данных заранее", - "general.early_access.beta_version": "Бета версия", - "general.early_access.rc_version": "RC версия", - "general.early_access.latest_version": "Стабильная версия", - "general.early_access.latest_version_tooltip": "github latest версия, стабильная версия", - "general.early_access.version_options": "Варианты версии", - "general.early_access.rc_version_tooltip": "Более стабильно, пожалуйста, сделайте резервную копию данных заранее", - "general.early_access.beta_version_tooltip": "Самые последние функции, но нестабильно, используйте с осторожностью", + "general.test_plan.title": "Тестовый план", + "general.test_plan.tooltip": "Участвовать в тестовом плане, чтобы быстрее получать новые функции, но при этом возникает больше рисков, пожалуйста, сделайте резервную копию данных заранее", + "general.test_plan.beta_version": "Тестовая версия (Beta)", + "general.test_plan.beta_version_tooltip": "Функции могут меняться в любое время, ошибки больше, обновление происходит быстрее", + "general.test_plan.rc_version": "Предварительная версия (RC)", + "general.test_plan.rc_version_tooltip": "Похожа на стабильную версию, функции стабильны, ошибки меньше, обновление происходит быстрее", + "general.test_plan.version_options": "Варианты версии", + "general.test_plan.version_channel_not_match": "Предварительная и тестовая версия будут доступны после выхода следующей стабильной версии", "quickPhrase": { "title": "Быстрые фразы", "add": "Добавить фразу", diff --git a/src/renderer/src/i18n/locales/zh-cn.json b/src/renderer/src/i18n/locales/zh-cn.json index 6b662d38ee..828d46d3c7 100644 --- a/src/renderer/src/i18n/locales/zh-cn.json +++ b/src/renderer/src/i18n/locales/zh-cn.json @@ -1392,15 +1392,14 @@ "general.emoji_picker": "表情选择器", "general.image_upload": "图片上传", "general.auto_check_update.title": "自动更新", - "general.early_access.title": "抢先体验", - "general.early_access.tooltip": "更新到测试版本不能降级,有数据丢失风险,请务必提前备份数据", - "general.early_access.beta_version": "预览版本", - "general.early_access.rc_version": "公测版本", - "general.early_access.latest_version": "稳定版本", - "general.early_access.version_options": "版本选择", - "general.early_access.rc_version_tooltip": "相对稳定,请备份数据", - "general.early_access.beta_version_tooltip": "功能最新但不稳定,谨慎使用", - "general.early_access.latest_version_tooltip": "github latest 版本, 最新稳定版本", + "general.test_plan.title": "测试计划", + "general.test_plan.tooltip": "参与测试计划,可以更快体验到最新功能,但同时也会带来更多风险,务必提前做好备份", + "general.test_plan.beta_version": "测试版(Beta)", + "general.test_plan.beta_version_tooltip": "功能可能随时变化,bug较多,升级较快", + "general.test_plan.rc_version": "预览版(RC)", + "general.test_plan.rc_version_tooltip": "接近正式版,功能基本稳定,bug较少", + "general.test_plan.version_options": "版本选择", + "general.test_plan.version_channel_not_match": "预览版和测试版的切换将在下一个正式版发布时生效", "general.reset.button": "重置", "general.reset.title": "重置数据", "general.restore.button": "恢复", diff --git a/src/renderer/src/i18n/locales/zh-tw.json b/src/renderer/src/i18n/locales/zh-tw.json index 44d99d4da9..0b833c5b5e 100644 --- a/src/renderer/src/i18n/locales/zh-tw.json +++ b/src/renderer/src/i18n/locales/zh-tw.json @@ -1866,15 +1866,14 @@ } }, "general.auto_check_update.title": "自動更新", - "general.early_access.title": "搶先體驗", - "general.early_access.tooltip": "更新到測試版本不能降級,有數據丟失風險,請務必提前備份數據", - "general.early_access.beta_version": "預覽版本", - "general.early_access.rc_version": "公測版本", - "general.early_access.latest_version": "穩定版本", - "general.early_access.latest_version_tooltip": "github latest 版本, 最新穩定版本", - "general.early_access.version_options": "版本選項", - "general.early_access.rc_version_tooltip": "相對穩定,請務必提前備份數據", - "general.early_access.beta_version_tooltip": "功能最新但不穩定,謹慎使用", + "general.test_plan.title": "測試計畫", + "general.test_plan.tooltip": "參與測試計畫,體驗最新功能,但同時也帶來更多風險,請務必提前備份數據", + "general.test_plan.beta_version": "測試版本(Beta)", + "general.test_plan.beta_version_tooltip": "功能可能會隨時變化,錯誤較多,升級較快", + "general.test_plan.rc_version": "預覽版本(RC)", + "general.test_plan.rc_version_tooltip": "相對穩定,請務必提前備份數據", + "general.test_plan.version_options": "版本選項", + "general.test_plan.version_channel_not_match": "預覽版和測試版的切換將在下一個正式版發布時生效", "quickPhrase": { "title": "快捷短語", "add": "新增短語", diff --git a/src/renderer/src/pages/settings/AboutSettings.tsx b/src/renderer/src/pages/settings/AboutSettings.tsx index 9bf65e4489..50832da2e6 100644 --- a/src/renderer/src/pages/settings/AboutSettings.tsx +++ b/src/renderer/src/pages/settings/AboutSettings.tsx @@ -26,8 +26,7 @@ const AboutSettings: FC = () => { const [version, setVersion] = useState('') const [isPortable, setIsPortable] = useState(false) const { t } = useTranslation() - const { autoCheckUpdate, setAutoCheckUpdate, earlyAccess, setEarlyAccess, upgradeChannel, setUpgradeChannel } = - useSettings() + const { autoCheckUpdate, setAutoCheckUpdate, testPlan, setTestPlan, testChannel, setTestChannel } = useSettings() const { theme } = useTheme() const dispatch = useAppDispatch() const { update } = useRuntime() @@ -97,8 +96,20 @@ const AboutSettings: FC = () => { const hasNewVersion = update?.info?.version && version ? compareVersions(update.info.version, version) > 0 : false - const handleUpgradeChannelChange = async (value: UpgradeChannel) => { - setUpgradeChannel(value) + const currentChannelByVersion = + [ + { pattern: `-${UpgradeChannel.BETA}.`, channel: UpgradeChannel.BETA }, + { pattern: `-${UpgradeChannel.RC}.`, channel: UpgradeChannel.RC } + ].find(({ pattern }) => version.includes(pattern))?.channel || UpgradeChannel.LATEST + + useEffect(() => { + if (testPlan && currentChannelByVersion !== UpgradeChannel.LATEST && testChannel !== currentChannelByVersion) { + window.message.warning(t('settings.general.test_plan.version_channel_not_match')) + } + }, [testPlan, testChannel, currentChannelByVersion, t]) + + const handleTestChannelChange = async (value: UpgradeChannel) => { + setTestChannel(value) // Clear update info when switching upgrade channel dispatch( setUpdateState({ @@ -116,25 +127,20 @@ const AboutSettings: FC = () => { const getAvailableTestChannels = () => { return [ { - tooltip: t('settings.general.early_access.latest_version_tooltip'), - label: t('settings.general.early_access.latest_version'), - value: UpgradeChannel.LATEST - }, - { - tooltip: t('settings.general.early_access.rc_version_tooltip'), - label: t('settings.general.early_access.rc_version'), + tooltip: t('settings.general.test_plan.rc_version_tooltip'), + label: t('settings.general.test_plan.rc_version'), value: UpgradeChannel.RC }, { - tooltip: t('settings.general.early_access.beta_version_tooltip'), - label: t('settings.general.early_access.beta_version'), + tooltip: t('settings.general.test_plan.beta_version_tooltip'), + label: t('settings.general.test_plan.beta_version'), value: UpgradeChannel.BETA } ] } - const handlerSetEarlyAccess = (value: boolean) => { - setEarlyAccess(value) + const handleSetTestPlan = (value: boolean) => { + setTestPlan(value) dispatch( setUpdateState({ available: false, @@ -145,7 +151,17 @@ const AboutSettings: FC = () => { downloadProgress: 0 }) ) - if (value === false) setUpgradeChannel(UpgradeChannel.LATEST) + + if (value === true) { + setTestChannel(getTestChannel()) + } + } + + const getTestChannel = () => { + if (testChannel === UpgradeChannel.LATEST) { + return UpgradeChannel.RC + } + return testChannel } useEffect(() => { @@ -155,7 +171,7 @@ const AboutSettings: FC = () => { setIsPortable(appInfo.isPortable) }) setAutoCheckUpdate(autoCheckUpdate) - }, [autoCheckUpdate, setAutoCheckUpdate, setEarlyAccess]) + }, [autoCheckUpdate, setAutoCheckUpdate]) return ( @@ -217,22 +233,21 @@ const AboutSettings: FC = () => { - {t('settings.general.early_access.title')} - - handlerSetEarlyAccess(v)} /> + {t('settings.general.test_plan.title')} + + handleSetTestPlan(v)} /> - {earlyAccess && getAvailableTestChannels().length > 0 && ( + {testPlan && ( <> - {t('settings.general.early_access.version_options')} + {t('settings.general.test_plan.version_options')} handleUpgradeChannelChange(e.target.value)}> + value={getTestChannel()} + onChange={(e) => handleTestChannelChange(e.target.value)}> {getAvailableTestChannels().map((option) => ( {option.label} diff --git a/src/renderer/src/store/migrate.ts b/src/renderer/src/store/migrate.ts index c8a132180f..501c5e483a 100644 --- a/src/renderer/src/store/migrate.ts +++ b/src/renderer/src/store/migrate.ts @@ -1543,7 +1543,7 @@ const migrateConfig = { state.paintings.tokenFluxPaintings = [] } state.settings.showTokens = true - state.settings.earlyAccess = false + state.settings.testPlan = false return state } catch (error) { return state @@ -1629,7 +1629,7 @@ const migrateConfig = { } }) if (state.settings) { - state.settings.upgradeChannel = UpgradeChannel.LATEST + state.settings.testChannel = UpgradeChannel.LATEST } return state } catch (error) { diff --git a/src/renderer/src/store/settings.ts b/src/renderer/src/store/settings.ts index ee991556f7..7d8e14ed11 100644 --- a/src/renderer/src/store/settings.ts +++ b/src/renderer/src/store/settings.ts @@ -68,8 +68,8 @@ export interface SettingsState { pasteLongTextThreshold: number clickAssistantToShowTopic: boolean autoCheckUpdate: boolean - earlyAccess: boolean - upgradeChannel: UpgradeChannel + testPlan: boolean + testChannel: UpgradeChannel renderInputMessageAsMarkdown: boolean // 代码执行 codeExecution: { @@ -222,8 +222,8 @@ export const initialState: SettingsState = { pasteLongTextThreshold: 1500, clickAssistantToShowTopic: true, autoCheckUpdate: true, - earlyAccess: false, - upgradeChannel: UpgradeChannel.LATEST, + testPlan: false, + testChannel: UpgradeChannel.LATEST, renderInputMessageAsMarkdown: false, codeExecution: { enabled: false, @@ -429,11 +429,11 @@ const settingsSlice = createSlice({ setAutoCheckUpdate: (state, action: PayloadAction) => { state.autoCheckUpdate = action.payload }, - setEarlyAccess: (state, action: PayloadAction) => { - state.earlyAccess = action.payload + setTestPlan: (state, action: PayloadAction) => { + state.testPlan = action.payload }, - setUpgradeChannel: (state, action: PayloadAction) => { - state.upgradeChannel = action.payload + setTestChannel: (state, action: PayloadAction) => { + state.testChannel = action.payload }, setRenderInputMessageAsMarkdown: (state, action: PayloadAction) => { state.renderInputMessageAsMarkdown = action.payload @@ -730,8 +730,8 @@ export const { setAssistantIconType, setPasteLongTextAsFile, setAutoCheckUpdate, - setEarlyAccess, - setUpgradeChannel, + setTestPlan, + setTestChannel, setRenderInputMessageAsMarkdown, setClickAssistantToShowTopic, setSkipBackupFile,