From 1bd190e986f055e49ca15cf4bf0918cc7ded841e Mon Sep 17 00:00:00 2001 From: kangfenmao Date: Mon, 18 Nov 2024 14:05:17 +0800 Subject: [PATCH] feat: added proxy settings and handling functionality --- src/main/ipc.ts | 16 +++++- src/renderer/src/components/MinApp/index.tsx | 10 +++- src/renderer/src/hooks/useAppInit.ts | 12 +++-- src/renderer/src/i18n/locales/en-us.json | 9 ++++ src/renderer/src/i18n/locales/ru-ru.json | 9 ++++ src/renderer/src/i18n/locales/zh-cn.json | 9 ++++ src/renderer/src/i18n/locales/zh-tw.json | 9 ++++ .../src/pages/settings/GeneralSettings.tsx | 49 ++++++++++++++----- src/renderer/src/store/index.ts | 2 +- src/renderer/src/store/migrate.ts | 4 ++ src/renderer/src/store/settings.ts | 6 +++ 11 files changed, 118 insertions(+), 17 deletions(-) diff --git a/src/main/ipc.ts b/src/main/ipc.ts index 70b5eec285..3d7efd1ba9 100644 --- a/src/main/ipc.ts +++ b/src/main/ipc.ts @@ -26,7 +26,21 @@ export function registerIpc(mainWindow: BrowserWindow, app: Electron.App) { filesPath: path.join(app.getPath('userData'), 'Data', 'Files') })) - ipcMain.handle('app:proxy', (_, proxy: string) => session.defaultSession.setProxy(proxy ? { proxyRules: proxy } : {})) + ipcMain.handle('app:proxy', async (_, proxy: string) => { + if (proxy === 'system') { + await session.defaultSession.setProxy({ mode: 'system' }) + const webviewSession = session.fromPartition('persist:webview') + await webviewSession.setProxy({ mode: 'system' }) + } else if (proxy) { + await session.defaultSession.setProxy({ proxyRules: proxy }) + const webviewSession = session.fromPartition('persist:webview') + await webviewSession.setProxy({ proxyRules: proxy }) + } else { + await session.defaultSession.setProxy({}) + const webviewSession = session.fromPartition('persist:webview') + await webviewSession.setProxy({}) + } + }) ipcMain.handle('app:reload', () => mainWindow.reload()) ipcMain.handle('open:website', (_, url: string) => shell.openExternal(url)) diff --git a/src/renderer/src/components/MinApp/index.tsx b/src/renderer/src/components/MinApp/index.tsx index 127dda7c0a..285e0c1e4b 100644 --- a/src/renderer/src/components/MinApp/index.tsx +++ b/src/renderer/src/components/MinApp/index.tsx @@ -114,7 +114,15 @@ const PopupContainer: React.FC = ({ app, resolve }) => { )} - {opened && } + {opened && ( + + )} ) } diff --git a/src/renderer/src/hooks/useAppInit.ts b/src/renderer/src/hooks/useAppInit.ts index fdd70f6147..3e111599c4 100644 --- a/src/renderer/src/hooks/useAppInit.ts +++ b/src/renderer/src/hooks/useAppInit.ts @@ -14,7 +14,7 @@ import { useSettings } from './useSettings' export function useAppInit() { const dispatch = useAppDispatch() - const { proxyUrl, language, windowStyle, manualUpdateCheck } = useSettings() + const { proxyUrl, language, windowStyle, manualUpdateCheck, proxyMode } = useSettings() const { minappShow } = useRuntime() const { setDefaultModel, setTopicNamingModel, setTranslateModel } = useDefaultModel() const avatar = useLiveQuery(() => db.settings.get('image://avatar')) @@ -35,8 +35,14 @@ export function useAppInit() { }, []) useEffect(() => { - proxyUrl && window.api.setProxy(proxyUrl) - }, [proxyUrl]) + if (proxyMode === 'system') { + window.api.setProxy('system') + } else if (proxyMode === 'custom') { + proxyUrl && window.api.setProxy(proxyUrl) + } else { + window.api.setProxy('') + } + }, [proxyUrl, proxyMode]) useEffect(() => { i18n.changeLanguage(language || navigator.language || 'en-US') diff --git a/src/renderer/src/i18n/locales/en-us.json b/src/renderer/src/i18n/locales/en-us.json index 962b03cda7..bde091b096 100644 --- a/src/renderer/src/i18n/locales/en-us.json +++ b/src/renderer/src/i18n/locales/en-us.json @@ -382,6 +382,15 @@ "add.name.placeholder": "Example: OpenAI", "add.type": "Provider Type", "no_models": "Please add models first before checking the API connection" + }, + "proxy": { + "title": "Proxy Settings", + "mode": { + "title": "Proxy Mode", + "system": "System Proxy", + "custom": "Custom Proxy", + "none": "No Proxy" + } } }, "translate": { diff --git a/src/renderer/src/i18n/locales/ru-ru.json b/src/renderer/src/i18n/locales/ru-ru.json index 364b3349b5..114daee707 100644 --- a/src/renderer/src/i18n/locales/ru-ru.json +++ b/src/renderer/src/i18n/locales/ru-ru.json @@ -382,6 +382,15 @@ "add.name.placeholder": "Пример: OpenAI", "add.type": "Тип провайдера", "no_models": "Пожалуйста, добавьте модели перед проверкой соединения с API" + }, + "proxy": { + "title": "Настройки прокси", + "mode": { + "title": "Режим прокси", + "system": "Системный прокси", + "custom": "Пользовательский прокси", + "none": "Не использовать прокси" + } } }, "translate": { diff --git a/src/renderer/src/i18n/locales/zh-cn.json b/src/renderer/src/i18n/locales/zh-cn.json index 527f112e7b..86093ce2c8 100644 --- a/src/renderer/src/i18n/locales/zh-cn.json +++ b/src/renderer/src/i18n/locales/zh-cn.json @@ -370,6 +370,15 @@ "add.name.placeholder": "例如 OpenAI", "add.type": "提供商类型", "no_models": "请先添加模型再检查 API 连接" + }, + "proxy": { + "title": "代理设置", + "mode": { + "title": "代理模式", + "system": "系统代理", + "custom": "自定义代理", + "none": "不使用代理" + } } }, "translate": { diff --git a/src/renderer/src/i18n/locales/zh-tw.json b/src/renderer/src/i18n/locales/zh-tw.json index cca217b42c..d8c4486a4b 100644 --- a/src/renderer/src/i18n/locales/zh-tw.json +++ b/src/renderer/src/i18n/locales/zh-tw.json @@ -370,6 +370,15 @@ "add.name.placeholder": "例如:OpenAI", "add.type": "提供商類型", "no_models": "請先添加模型再檢查 API 連接" + }, + "proxy": { + "title": "代理設定", + "mode": { + "title": "代理模式", + "system": "系統代理", + "custom": "自定義代理", + "none": "不使用代理" + } } }, "translate": { diff --git a/src/renderer/src/pages/settings/GeneralSettings.tsx b/src/renderer/src/pages/settings/GeneralSettings.tsx index a61142dced..9e73ec2073 100644 --- a/src/renderer/src/pages/settings/GeneralSettings.tsx +++ b/src/renderer/src/pages/settings/GeneralSettings.tsx @@ -3,7 +3,7 @@ import { useSettings } from '@renderer/hooks/useSettings' import i18n from '@renderer/i18n' import { useAppDispatch } from '@renderer/store' import { setLanguage } from '@renderer/store/settings' -import { setProxyUrl as _setProxyUrl } from '@renderer/store/settings' +import { setProxyMode, setProxyUrl as _setProxyUrl } from '@renderer/store/settings' import { LanguageVarious, ThemeMode } from '@renderer/types' import { isValidProxyUrl } from '@renderer/utils' import { Input, Select, Space, Switch } from 'antd' @@ -21,7 +21,8 @@ const GeneralSettings: FC = () => { setTray, tray, windowStyle, - setWindowStyle + setWindowStyle, + proxyMode: storeProxyMode } = useSettings() const [proxyUrl, setProxyUrl] = useState(storeProxyUrl) @@ -50,6 +51,23 @@ const GeneralSettings: FC = () => { window.api.setProxy(proxyUrl) } + const proxyModeOptions = [ + { value: 'system', label: t('settings.proxy.mode.system') }, + { value: 'custom', label: t('settings.proxy.mode.custom') }, + { value: 'none', label: t('settings.proxy.mode.none') } + ] + + const onProxyModeChange = (mode: 'system' | 'custom' | 'none') => { + dispatch(setProxyMode(mode)) + if (mode === 'system') { + window.api.setProxy('system') + dispatch(_setProxyUrl(undefined)) + } else if (mode === 'none') { + window.api.setProxy(undefined) + dispatch(_setProxyUrl(undefined)) + } + } + const languagesOptions: { value: LanguageVarious; label: string; flag: string }[] = [ { value: 'zh-CN', label: '中文', flag: '🇨🇳' }, { value: 'zh-TW', label: '中文(繁体)', flag: '🇹🇼' }, @@ -109,16 +127,25 @@ const GeneralSettings: FC = () => { )} - {t('settings.proxy.title')} - setProxyUrl(e.target.value)} - style={{ width: 180 }} - onBlur={() => onSetProxyUrl()} - type="url" - /> + {t('settings.proxy.mode.title')} + setProxyUrl(e.target.value)} + style={{ width: 180 }} + onBlur={() => onSetProxyUrl()} + type="url" + /> + + + )} {t('settings.tray.title')} diff --git a/src/renderer/src/store/index.ts b/src/renderer/src/store/index.ts index 823773616b..9bcf44f7c4 100644 --- a/src/renderer/src/store/index.ts +++ b/src/renderer/src/store/index.ts @@ -24,7 +24,7 @@ const persistedReducer = persistReducer( { key: 'cherry-studio', storage, - version: 41, + version: 42, blacklist: ['runtime'], migrate }, diff --git a/src/renderer/src/store/migrate.ts b/src/renderer/src/store/migrate.ts index 594daddbba..09f7699285 100644 --- a/src/renderer/src/store/migrate.ts +++ b/src/renderer/src/store/migrate.ts @@ -689,6 +689,10 @@ const migrateConfig = { } }) return state + }, + '42': (state: RootState) => { + state.settings.proxyMode = state.settings.proxyUrl ? 'custom' : 'none' + return state } } diff --git a/src/renderer/src/store/settings.ts b/src/renderer/src/store/settings.ts index b23d4a6e84..9649e77754 100644 --- a/src/renderer/src/store/settings.ts +++ b/src/renderer/src/store/settings.ts @@ -8,6 +8,7 @@ export interface SettingsState { showTopics: boolean sendMessageShortcut: SendMessageShortcut language: LanguageVarious + proxyMode: 'system' | 'custom' | 'none' proxyUrl?: string userName: string showMessageDivider: boolean @@ -39,6 +40,7 @@ const initialState: SettingsState = { showTopics: true, sendMessageShortcut: 'Enter', language: navigator.language as LanguageVarious, + proxyMode: 'none', proxyUrl: undefined, userName: '', showMessageDivider: false, @@ -86,6 +88,9 @@ const settingsSlice = createSlice({ setLanguage: (state, action: PayloadAction) => { state.language = action.payload }, + setProxyMode: (state, action: PayloadAction<'system' | 'custom' | 'none'>) => { + state.proxyMode = action.payload + }, setProxyUrl: (state, action: PayloadAction) => { state.proxyUrl = action.payload }, @@ -166,6 +171,7 @@ export const { toggleShowTopics, setSendMessageShortcut, setLanguage, + setProxyMode, setProxyUrl, setUserName, setShowMessageDivider,