1
0
mirror of https://github.com/h3poteto/whalebird-desktop synced 2024-12-27 01:05:21 +01:00
Whalebird-desktop-client-ma.../renderer/components/Settings.tsx

350 lines
10 KiB
TypeScript
Raw Normal View History

import { localeType } from '@/provider/i18n'
2024-09-23 12:19:16 +02:00
import { invoke } from '@/utils/invoke'
2024-09-10 16:26:00 +02:00
import { Button, Dialog, DialogBody, DialogFooter, DialogHeader, Input, Option, Radio, Select, Typography } from '@material-tailwind/react'
2023-12-04 17:17:52 +01:00
import { ChangeEvent, useEffect, useState } from 'react'
2024-09-09 18:43:49 +02:00
import { FormattedMessage, useIntl } from 'react-intl'
2023-12-04 17:08:12 +01:00
type Props = {
opened: boolean
close: () => void
2023-12-04 17:17:52 +01:00
reloadSettings: () => void
2023-12-04 17:08:12 +01:00
}
const languages = [
{
label: 'English',
value: 'en'
},
{
label: '日本語',
value: 'ja'
2024-02-05 13:52:13 +01:00
},
{
label: 'Português',
value: 'pt-PT'
},
{
label: '繁体字',
value: 'zh-TW'
2024-06-12 16:32:34 +02:00
},
{
label: 'español',
value: 'es-ES'
2023-12-04 17:08:12 +01:00
}
]
2024-03-09 11:09:36 +01:00
const themes = [
{
label: 'Blue',
value: 'theme-blue'
},
{
label: 'Orange',
value: 'theme-orange'
2024-03-09 14:13:44 +01:00
},
{
label: 'Purple',
value: 'theme-purple'
},
{
label: 'Green',
value: 'theme-green'
},
{
label: 'Brown',
value: 'theme-brown'
},
{
label: 'Gray',
value: 'theme-gray'
2024-03-09 11:09:36 +01:00
}
]
2024-09-09 18:43:49 +02:00
type ProxyValue = 'no' | 'os' | 'manual'
2023-12-04 17:08:12 +01:00
export default function Settings(props: Props) {
const [language, setLanguage] = useState<localeType>('en')
2023-12-06 16:10:16 +01:00
const [fontSize, setFontSize] = useState<number>(16)
2024-03-09 11:09:36 +01:00
const [theme, setTheme] = useState<string>('theme-blue')
2024-03-12 15:02:18 +01:00
const [isDark, setIsDark] = useState(false)
2024-09-09 18:43:49 +02:00
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)
2024-09-23 12:19:16 +02:00
const [fontFamilies, setFontFamilies] = useState<Array<string>>([])
const [fontFamily, setFontFamily] = useState<string | null>(null)
2024-09-09 18:43:49 +02:00
const { formatMessage } = useIntl()
2023-12-04 17:08:12 +01:00
useEffect(() => {
2024-09-23 12:19:16 +02:00
const f = async () => {
const lists = await invoke('list-fonts', null)
if (lists) {
setFontFamilies(lists)
}
}
f()
2023-12-04 17:08:12 +01:00
if (typeof localStorage !== 'undefined') {
const lang = localStorage.getItem('language')
2024-02-05 13:52:13 +01:00
if (lang) {
setLanguage(lang as localeType)
} else {
setLanguage('en')
}
2024-09-23 12:19:16 +02:00
const fontSize = localStorage.getItem('fontSize')
if (fontSize) {
setFontSize(parseInt(fontSize))
}
const fontFamily = localStorage.getItem('fontFamily')
if (fontFamily) {
setFontFamily(fontFamily)
}
2024-03-12 15:02:18 +01:00
const dark = localStorage.getItem('color-mode')
if (dark === 'dark') {
setIsDark(true)
} else {
setIsDark(false)
}
2024-09-09 18:43:49 +02:00
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)
}
2023-12-04 17:08:12 +01:00
}
}, [])
const languageChanged = (e: string) => {
2024-02-05 13:52:13 +01:00
setLanguage(e as localeType)
2023-12-04 17:08:12 +01:00
if (typeof localStorage !== 'undefined') {
localStorage.setItem('language', e)
2023-12-04 17:08:12 +01:00
}
2023-12-04 17:17:52 +01:00
props.reloadSettings()
2023-12-04 17:08:12 +01:00
}
2023-12-06 16:10:16 +01:00
const fontSizeChanged = (e: ChangeEvent<HTMLInputElement>) => {
setFontSize(parseInt(e.target.value))
if (typeof localStorage !== 'undefined') {
localStorage.setItem('fontSize', e.target.value)
}
props.reloadSettings()
}
2024-09-23 12:19:16 +02:00
const fontFamilyChanged = (e: string) => {
setFontFamily(e)
if (typeof localStorage !== 'undefined') {
localStorage.setItem('fontFamily', e)
}
props.reloadSettings()
}
2024-03-09 11:09:36 +01:00
const themeChanged = (e: string) => {
setTheme(e)
if (typeof localStorage !== 'undefined') {
localStorage.setItem('theme', e)
}
props.reloadSettings()
}
2024-03-12 15:02:18 +01:00
const modeChanged = (isDark: boolean) => {
setIsDark(isDark)
if (typeof localStorage !== 'undefined') {
if (isDark) {
localStorage.setItem('color-mode', 'dark')
} else {
localStorage.setItem('color-mode', 'light')
}
}
props.reloadSettings()
}
2024-09-10 16:26:00 +02:00
const save = () => {
2024-09-09 18:43:49 +02:00
if (typeof localStorage !== 'undefined') {
2024-09-10 16:26:00 +02:00
localStorage.setItem('proxyMode', proxy)
2024-09-09 18:43:49 +02:00
localStorage.setItem('proxyProtocol', proxyProtocol)
localStorage.setItem('proxyHost', proxyHost)
localStorage.setItem('proxyPort', proxyPort)
}
props.reloadSettings()
2024-09-10 16:26:00 +02:00
props.close()
2024-09-09 18:43:49 +02:00
}
2023-12-04 17:08:12 +01:00
return (
<Dialog open={props.opened} handler={props.close} size="sm">
<DialogHeader>
2023-12-04 17:08:12 +01:00
<FormattedMessage id="settings.title" />
</DialogHeader>
<DialogBody>
2023-12-06 16:10:16 +01:00
<div className="flex flex-col gap-4">
<div>
<div className="mb-2">
<Typography>
2023-12-06 16:10:16 +01:00
<FormattedMessage id="settings.font_size" />
</Typography>
2023-12-06 16:10:16 +01:00
</div>
<div>
2024-03-14 17:12:19 +01:00
<Input type="number" color="blue-gray" value={fontSize} onChange={fontSizeChanged} />
2023-12-06 16:10:16 +01:00
</div>
2024-09-23 12:19:16 +02:00
<div className="mb-2">
<Typography>
<FormattedMessage id="settings.font_family" />
</Typography>
</div>
<div>
<Select onChange={fontFamilyChanged} value={fontFamily}>
{fontFamilies.map((font, index) => (
<Option key={index} value={font}>
{font}
</Option>
))}
</Select>
</div>
2023-12-06 16:10:16 +01:00
</div>
<div>
<div className="mb-2">
<Typography>
2023-12-06 16:10:16 +01:00
<FormattedMessage id="settings.language" />
</Typography>
2023-12-06 16:10:16 +01:00
</div>
<div>
2024-03-14 17:12:19 +01:00
<Select id="language" color="blue-gray" onChange={languageChanged} value={language}>
2023-12-06 16:10:16 +01:00
{languages.map(lang => (
<Option key={lang.value} value={lang.value}>
2023-12-06 16:10:16 +01:00
{lang.label}
</Option>
2023-12-06 16:10:16 +01:00
))}
</Select>
</div>
</div>
2024-03-12 15:02:18 +01:00
<div>
<div className="mb-2">
<Typography>
<FormattedMessage id="settings.mode" />
</Typography>
</div>
<div>
<Radio
name="mode"
2024-03-14 17:12:19 +01:00
color="blue"
2024-03-12 15:02:18 +01:00
label={<FormattedMessage id="settings.dark_mode" />}
onClick={() => modeChanged(true)}
defaultChecked={isDark}
/>
<Radio
name="mode"
2024-03-14 17:12:19 +01:00
color="blue"
2024-03-12 15:02:18 +01:00
label={<FormattedMessage id="settings.light_mode" />}
onClick={() => modeChanged(false)}
defaultChecked={!isDark}
/>
</div>
</div>
2024-03-09 11:09:36 +01:00
<div>
<div className="mb-2">
<Typography>
<FormattedMessage id="settings.theme" />
</Typography>
</div>
<div>
2024-03-14 17:12:19 +01:00
<Select id="theme" color="blue-gray" onChange={themeChanged} value={theme}>
2024-03-09 11:09:36 +01:00
{themes.map(t => (
<Option key={t.value} value={t.value}>
{t.label}
</Option>
))}
</Select>
</div>
</div>
2024-09-09 18:43:49 +02:00
<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'}
2024-09-10 16:26:00 +02:00
onClick={() => setProxy('no')}
2024-09-09 18:43:49 +02:00
/>
<Radio
name="proxy"
color="blue"
label={<FormattedMessage id="settings.proxy.os" />}
defaultChecked={proxy === 'os'}
2024-09-10 16:26:00 +02:00
onClick={() => setProxy('os')}
2024-09-09 18:43:49 +02:00
/>
<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}
2024-09-10 16:26:00 +02:00
onChange={val => setProxyProtocol(val)}
2024-09-09 18:43:49 +02:00
>
<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' })}
2024-09-10 16:26:00 +02:00
onChange={e => setProxyHost(e.target.value)}
2024-09-09 18:43:49 +02:00
/>
</div>
<div className="w-1/5">
<Input
defaultValue={proxyPort}
label={formatMessage({ id: 'settings.proxy.port' })}
containerProps={{
className: '!min-w-2'
}}
2024-09-10 16:26:00 +02:00
onChange={e => setProxyPort(e.target.value)}
2024-09-09 18:43:49 +02:00
/>
</div>
</div>
</div>
}
defaultChecked={proxy === 'manual'}
2024-09-10 16:26:00 +02:00
onClick={() => setProxy('manual')}
2024-09-09 18:43:49 +02:00
/>
</div>
</div>
2023-12-04 17:08:12 +01:00
</div>
</DialogBody>
2024-09-10 16:26:00 +02:00
<DialogFooter>
<Button variant="text" color="red" onClick={props.close}>
<FormattedMessage id="settings.cancel" />
</Button>
<Button variant="gradient" color="blue" onClick={save}>
<FormattedMessage id="settings.save" />
</Button>
</DialogFooter>
</Dialog>
2023-12-04 17:08:12 +01:00
)
}