mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-05 04:19:02 +08:00
feat: added proxy settings and handling functionality
This commit is contained in:
parent
17943cdf44
commit
1bd190e986
@ -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))
|
||||||
|
|
||||||
|
|||||||
@ -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>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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')
|
||||||
|
|||||||
@ -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": {
|
||||||
|
|||||||
@ -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": {
|
||||||
|
|||||||
@ -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": {
|
||||||
|
|||||||
@ -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": {
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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
|
||||||
},
|
},
|
||||||
|
|||||||
@ -689,6 +689,10 @@ const migrateConfig = {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
return state
|
return state
|
||||||
|
},
|
||||||
|
'42': (state: RootState) => {
|
||||||
|
state.settings.proxyMode = state.settings.proxyUrl ? 'custom' : 'none'
|
||||||
|
return state
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user