refs #4794 Add proxy settings

This commit is contained in:
AkiraFukushima 2024-09-10 01:43:49 +09:00
parent 833430b4db
commit 284a22b004
No known key found for this signature in database
GPG Key ID: B7EA3A3C9AEC9F0E
5 changed files with 172 additions and 4 deletions

View File

@ -178,7 +178,18 @@
"mode": "Color mode",
"dark_mode": "Dark mode",
"light_mode": "Light mode",
"theme": "Color theme"
"theme": "Color theme",
"proxy": {
"title": "Proxy",
"no": "No proxy",
"os": "Use system proxy settings",
"manual": "Manual proxy configuration",
"protocol": "Protocol",
"http": "http",
"socks": "socks",
"host": "Host",
"port": "Port"
}
},
"thirdparty": {
"title": "Third-party licenses"

View File

@ -1,5 +1,5 @@
import path from 'path'
import { app, ipcMain, shell, IpcMainInvokeEvent } from 'electron'
import { app, ipcMain, shell, IpcMainInvokeEvent, BrowserWindow } from 'electron'
import serve from 'electron-serve'
import { createWindow } from './helpers'
@ -11,6 +11,8 @@ if (isProd) {
app.setPath('userData', `${app.getPath('userData')} (development)`)
}
let main: BrowserWindow = null
;(async () => {
await app.whenReady()
@ -24,6 +26,7 @@ if (isProd) {
preload: path.join(__dirname, 'preload.js')
}
})
main = mainWindow
if (isProd) {
await mainWindow.loadURL('app://./')
@ -45,3 +48,24 @@ ipcMain.on('message', async (event, arg) => {
ipcMain.handle('open-browser', (_event: IpcMainInvokeEvent, url: string) => {
shell.openExternal(url)
})
ipcMain.handle('set-proxy', (_event: IpcMainInvokeEvent, data: any) => {
if (main === null) return
const { mode, protocol, host, port } = data
switch (mode) {
case 'os':
console.log('Using system proxy')
main.webContents.session.setProxy({ mode: 'system' })
break
case 'manual':
console.log(`Using proxy: ${protocol}=${host}:${port}`)
main.webContents.session.setProxy({
proxyRules: `${protocol}=${host}:${port}`
})
break
default:
console.log('No proxy configuration')
main.webContents.session.setProxy({ mode: 'direct' })
break
}
})

View File

@ -1,7 +1,7 @@
import { localeType } from '@/provider/i18n'
import { Dialog, DialogBody, DialogHeader, Input, Option, Radio, Select, Typography } from '@material-tailwind/react'
import { ChangeEvent, useEffect, useState } from 'react'
import { FormattedMessage } from 'react-intl'
import { FormattedMessage, useIntl } from 'react-intl'
type Props = {
opened: boolean
@ -59,11 +59,18 @@ const themes = [
}
]
type ProxyValue = 'no' | 'os' | 'manual'
export default function Settings(props: Props) {
const [language, setLanguage] = useState<localeType>('en')
const [fontSize, setFontSize] = useState<number>(16)
const [theme, setTheme] = useState<string>('theme-blue')
const [isDark, setIsDark] = useState(false)
const [proxy, setProxy] = useState<ProxyValue>('no')
const [proxyProtocol, setProxyProtocol] = useState<string | null>(null)
const [proxyHost, setProxyHost] = useState<string | null>(null)
const [proxyPort, setProxyPort] = useState<string | null>(null)
const { formatMessage } = useIntl()
useEffect(() => {
if (typeof localStorage !== 'undefined') {
@ -79,6 +86,22 @@ export default function Settings(props: Props) {
} else {
setIsDark(false)
}
const proxyMode = localStorage.getItem('proxyMode')
if (proxyMode) {
setProxy(proxyMode as ProxyValue)
}
const proxyProtocol = localStorage.getItem('proxyProtocol')
if (proxyProtocol) {
setProxyProtocol(proxyProtocol)
}
const proxyHost = localStorage.getItem('proxyHost')
if (proxyHost) {
setProxyHost(proxyHost)
}
const proxyPort = localStorage.getItem('proxyPort')
if (proxyPort) {
setProxyPort(proxyPort)
}
}
}, [])
@ -118,6 +141,38 @@ export default function Settings(props: Props) {
props.reloadSettings()
}
const proxyModeChanged = (mode: ProxyValue) => {
setProxy(mode)
if (typeof localStorage !== 'undefined') {
localStorage.setItem('proxyMode', mode)
}
props.reloadSettings()
}
const proxyProtocolChanged = (protocol: string) => {
setProxyProtocol(protocol)
if (typeof localStorage !== 'undefined') {
localStorage.setItem('proxyProtocol', proxyProtocol)
}
props.reloadSettings()
}
const proxyHostChanged = (host: string) => {
setProxyHost(host)
if (typeof localStorage !== 'undefined') {
localStorage.setItem('proxyHost', proxyHost)
}
props.reloadSettings()
}
const proxyPortChanged = (port: string) => {
setProxyPort(port)
if (typeof localStorage !== 'undefined') {
localStorage.setItem('proxyPort', proxyPort)
}
props.reloadSettings()
}
return (
<Dialog open={props.opened} handler={props.close} size="sm">
<DialogHeader>
@ -190,6 +245,76 @@ export default function Settings(props: Props) {
</Select>
</div>
</div>
<div>
<div className="mb-2">
<Typography>
<FormattedMessage id="settings.proxy.title" />
</Typography>
</div>
<div className="flex flex-col gap-2">
<Radio
name="proxy"
color="blue"
label={<FormattedMessage id="settings.proxy.no" />}
defaultChecked={proxy === 'no'}
onClick={() => proxyModeChanged('no')}
/>
<Radio
name="proxy"
color="blue"
label={<FormattedMessage id="settings.proxy.os" />}
defaultChecked={proxy === 'os'}
onClick={() => proxyModeChanged('os')}
/>
<Radio
name="proxy"
color="blue"
label={
<div>
<FormattedMessage id="settings.proxy.manual" />
<div className="flex gap-2">
<div className="w-1/5">
<Select
label={formatMessage({ id: 'settings.proxy.protocol' })}
containerProps={{
className: '!min-w-2'
}}
value={proxyProtocol}
onChange={val => proxyProtocolChanged(val)}
>
<Option value="http">
<FormattedMessage id="settings.proxy.http" />
</Option>
<Option value="socks">
<FormattedMessage id="settings.proxy.socks" />
</Option>
</Select>
</div>
<div className="w-3/5">
<Input
defaultValue={proxyHost}
label={formatMessage({ id: 'settings.proxy.host' })}
onChange={e => proxyHostChanged(e.target.value)}
/>
</div>
<div className="w-1/5">
<Input
defaultValue={proxyPort}
label={formatMessage({ id: 'settings.proxy.port' })}
containerProps={{
className: '!min-w-2'
}}
onChange={e => proxyPortChanged(e.target.value)}
/>
</div>
</div>
</div>
}
defaultChecked={proxy === 'manual'}
onClick={() => proxyModeChanged('manual')}
/>
</div>
</div>
</div>
</DialogBody>
</Dialog>

View File

@ -21,6 +21,7 @@ import {
import Thirdparty from '../Thirdparty'
import { useUnreads } from '@/provider/unreads'
import { useAccounts } from '@/provider/accounts'
import { invoke } from '@/utils/invoke'
type LayoutProps = {
children: React.ReactNode
@ -128,12 +129,16 @@ export default function Layout({ children }: LayoutProps) {
setTheme(t)
}
const dark = localStorage.getItem('color-mode')
console.log(dark)
if (dark && dark === 'dark') {
setIsDark(true)
} else {
setIsDark(false)
}
const proxyMode = localStorage.getItem('proxyMode')
const proxyProtocol = localStorage.getItem('proxyProtocol')
const proxyHost = localStorage.getItem('proxyHost')
const proxyPort = localStorage.getItem('proxyPort')
invoke('set-proxy', { mode: proxyMode, protocol: proxyProtocol, host: proxyHost, port: proxyPort })
}
}

View File

@ -7,6 +7,9 @@ export function invoke(event: string, data: any) {
case 'open-browser':
window.open(data, '_blank').focus()
return
case 'set-proxy':
console.warn('Can not use proxy in this environment')
return
default:
console.error(`Unknown event: ${event}`)
return