feat: added proxy settings and handling functionality

This commit is contained in:
kangfenmao 2024-11-18 14:05:17 +08:00
parent 17943cdf44
commit 1bd190e986
11 changed files with 118 additions and 17 deletions

View File

@ -26,7 +26,21 @@ export function registerIpc(mainWindow: BrowserWindow, app: Electron.App) {
filesPath: path.join(app.getPath('userData'), 'Data', 'Files') 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('app:reload', () => mainWindow.reload())
ipcMain.handle('open:website', (_, url: string) => shell.openExternal(url)) ipcMain.handle('open:website', (_, url: string) => shell.openExternal(url))

View File

@ -114,7 +114,15 @@ const PopupContainer: React.FC<Props> = ({ app, resolve }) => {
<BeatLoader color="var(--color-text-2)" size="10" style={{ marginTop: 15 }} /> <BeatLoader color="var(--color-text-2)" size="10" style={{ marginTop: 15 }} />
</EmptyView> </EmptyView>
)} )}
{opened && <webview src={app.url} ref={webviewRef} style={WebviewStyle} allowpopups={'true' as any} />} {opened && (
<webview
src={app.url}
ref={webviewRef}
style={WebviewStyle}
allowpopups={'true' as any}
partition="persist:webview"
/>
)}
</Drawer> </Drawer>
) )
} }

View File

@ -14,7 +14,7 @@ import { useSettings } from './useSettings'
export function useAppInit() { export function useAppInit() {
const dispatch = useAppDispatch() const dispatch = useAppDispatch()
const { proxyUrl, language, windowStyle, manualUpdateCheck } = useSettings() const { proxyUrl, language, windowStyle, manualUpdateCheck, proxyMode } = useSettings()
const { minappShow } = useRuntime() const { minappShow } = useRuntime()
const { setDefaultModel, setTopicNamingModel, setTranslateModel } = useDefaultModel() const { setDefaultModel, setTopicNamingModel, setTranslateModel } = useDefaultModel()
const avatar = useLiveQuery(() => db.settings.get('image://avatar')) const avatar = useLiveQuery(() => db.settings.get('image://avatar'))
@ -35,8 +35,14 @@ export function useAppInit() {
}, []) }, [])
useEffect(() => { useEffect(() => {
proxyUrl && window.api.setProxy(proxyUrl) if (proxyMode === 'system') {
}, [proxyUrl]) window.api.setProxy('system')
} else if (proxyMode === 'custom') {
proxyUrl && window.api.setProxy(proxyUrl)
} else {
window.api.setProxy('')
}
}, [proxyUrl, proxyMode])
useEffect(() => { useEffect(() => {
i18n.changeLanguage(language || navigator.language || 'en-US') i18n.changeLanguage(language || navigator.language || 'en-US')

View File

@ -382,6 +382,15 @@
"add.name.placeholder": "Example: OpenAI", "add.name.placeholder": "Example: OpenAI",
"add.type": "Provider Type", "add.type": "Provider Type",
"no_models": "Please add models first before checking the API connection" "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": { "translate": {

View File

@ -382,6 +382,15 @@
"add.name.placeholder": "Пример: OpenAI", "add.name.placeholder": "Пример: OpenAI",
"add.type": "Тип провайдера", "add.type": "Тип провайдера",
"no_models": "Пожалуйста, добавьте модели перед проверкой соединения с API" "no_models": "Пожалуйста, добавьте модели перед проверкой соединения с API"
},
"proxy": {
"title": "Настройки прокси",
"mode": {
"title": "Режим прокси",
"system": "Системный прокси",
"custom": "Пользовательский прокси",
"none": "Не использовать прокси"
}
} }
}, },
"translate": { "translate": {

View File

@ -370,6 +370,15 @@
"add.name.placeholder": "例如 OpenAI", "add.name.placeholder": "例如 OpenAI",
"add.type": "提供商类型", "add.type": "提供商类型",
"no_models": "请先添加模型再检查 API 连接" "no_models": "请先添加模型再检查 API 连接"
},
"proxy": {
"title": "代理设置",
"mode": {
"title": "代理模式",
"system": "系统代理",
"custom": "自定义代理",
"none": "不使用代理"
}
} }
}, },
"translate": { "translate": {

View File

@ -370,6 +370,15 @@
"add.name.placeholder": "例如OpenAI", "add.name.placeholder": "例如OpenAI",
"add.type": "提供商類型", "add.type": "提供商類型",
"no_models": "請先添加模型再檢查 API 連接" "no_models": "請先添加模型再檢查 API 連接"
},
"proxy": {
"title": "代理設定",
"mode": {
"title": "代理模式",
"system": "系統代理",
"custom": "自定義代理",
"none": "不使用代理"
}
} }
}, },
"translate": { "translate": {

View File

@ -3,7 +3,7 @@ import { useSettings } from '@renderer/hooks/useSettings'
import i18n from '@renderer/i18n' import i18n from '@renderer/i18n'
import { useAppDispatch } from '@renderer/store' import { useAppDispatch } from '@renderer/store'
import { setLanguage } from '@renderer/store/settings' 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 { LanguageVarious, ThemeMode } from '@renderer/types'
import { isValidProxyUrl } from '@renderer/utils' import { isValidProxyUrl } from '@renderer/utils'
import { Input, Select, Space, Switch } from 'antd' import { Input, Select, Space, Switch } from 'antd'
@ -21,7 +21,8 @@ const GeneralSettings: FC = () => {
setTray, setTray,
tray, tray,
windowStyle, windowStyle,
setWindowStyle setWindowStyle,
proxyMode: storeProxyMode
} = useSettings() } = useSettings()
const [proxyUrl, setProxyUrl] = useState<string | undefined>(storeProxyUrl) const [proxyUrl, setProxyUrl] = useState<string | undefined>(storeProxyUrl)
@ -50,6 +51,23 @@ const GeneralSettings: FC = () => {
window.api.setProxy(proxyUrl) 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 }[] = [ const languagesOptions: { value: LanguageVarious; label: string; flag: string }[] = [
{ value: 'zh-CN', label: '中文', flag: '🇨🇳' }, { value: 'zh-CN', label: '中文', flag: '🇨🇳' },
{ value: 'zh-TW', label: '中文(繁体)', flag: '🇹🇼' }, { value: 'zh-TW', label: '中文(繁体)', flag: '🇹🇼' },
@ -109,16 +127,25 @@ const GeneralSettings: FC = () => {
)} )}
<SettingDivider /> <SettingDivider />
<SettingRow> <SettingRow>
<SettingRowTitle>{t('settings.proxy.title')}</SettingRowTitle> <SettingRowTitle>{t('settings.proxy.mode.title')}</SettingRowTitle>
<Input <Select value={storeProxyMode} style={{ width: 180 }} onChange={onProxyModeChange} options={proxyModeOptions} />
placeholder="socks5://127.0.0.1:6153"
value={proxyUrl}
onChange={(e) => setProxyUrl(e.target.value)}
style={{ width: 180 }}
onBlur={() => onSetProxyUrl()}
type="url"
/>
</SettingRow> </SettingRow>
{storeProxyMode === 'custom' && (
<>
<SettingDivider />
<SettingRow>
<SettingRowTitle>{t('settings.proxy.title')}</SettingRowTitle>
<Input
placeholder="socks5://127.0.0.1:6153"
value={proxyUrl}
onChange={(e) => setProxyUrl(e.target.value)}
style={{ width: 180 }}
onBlur={() => onSetProxyUrl()}
type="url"
/>
</SettingRow>
</>
)}
<SettingDivider /> <SettingDivider />
<SettingRow> <SettingRow>
<SettingRowTitle>{t('settings.tray.title')}</SettingRowTitle> <SettingRowTitle>{t('settings.tray.title')}</SettingRowTitle>

View File

@ -24,7 +24,7 @@ const persistedReducer = persistReducer(
{ {
key: 'cherry-studio', key: 'cherry-studio',
storage, storage,
version: 41, version: 42,
blacklist: ['runtime'], blacklist: ['runtime'],
migrate migrate
}, },

View File

@ -689,6 +689,10 @@ const migrateConfig = {
} }
}) })
return state return state
},
'42': (state: RootState) => {
state.settings.proxyMode = state.settings.proxyUrl ? 'custom' : 'none'
return state
} }
} }

View File

@ -8,6 +8,7 @@ export interface SettingsState {
showTopics: boolean showTopics: boolean
sendMessageShortcut: SendMessageShortcut sendMessageShortcut: SendMessageShortcut
language: LanguageVarious language: LanguageVarious
proxyMode: 'system' | 'custom' | 'none'
proxyUrl?: string proxyUrl?: string
userName: string userName: string
showMessageDivider: boolean showMessageDivider: boolean
@ -39,6 +40,7 @@ const initialState: SettingsState = {
showTopics: true, showTopics: true,
sendMessageShortcut: 'Enter', sendMessageShortcut: 'Enter',
language: navigator.language as LanguageVarious, language: navigator.language as LanguageVarious,
proxyMode: 'none',
proxyUrl: undefined, proxyUrl: undefined,
userName: '', userName: '',
showMessageDivider: false, showMessageDivider: false,
@ -86,6 +88,9 @@ const settingsSlice = createSlice({
setLanguage: (state, action: PayloadAction<LanguageVarious>) => { setLanguage: (state, action: PayloadAction<LanguageVarious>) => {
state.language = action.payload state.language = action.payload
}, },
setProxyMode: (state, action: PayloadAction<'system' | 'custom' | 'none'>) => {
state.proxyMode = action.payload
},
setProxyUrl: (state, action: PayloadAction<string | undefined>) => { setProxyUrl: (state, action: PayloadAction<string | undefined>) => {
state.proxyUrl = action.payload state.proxyUrl = action.payload
}, },
@ -166,6 +171,7 @@ export const {
toggleShowTopics, toggleShowTopics,
setSendMessageShortcut, setSendMessageShortcut,
setLanguage, setLanguage,
setProxyMode,
setProxyUrl, setProxyUrl,
setUserName, setUserName,
setShowMessageDivider, setShowMessageDivider,