mirror of
https://gh.catmak.name/https://github.com/mihomo-party-org/mihomo-party
synced 2025-12-27 13:10:30 +08:00
add gray theme
This commit is contained in:
parent
ab30a2e3bf
commit
2959cee2df
@ -1,6 +1,7 @@
|
|||||||
export const defaultConfig: IAppConfig = {
|
export const defaultConfig: IAppConfig = {
|
||||||
core: 'mihomo',
|
core: 'mihomo',
|
||||||
silentStart: false,
|
silentStart: false,
|
||||||
|
appTheme: 'system',
|
||||||
proxyDisplayMode: 'simple',
|
proxyDisplayMode: 'simple',
|
||||||
proxyDisplayOrder: 'default',
|
proxyDisplayOrder: 'default',
|
||||||
autoCheckUpdate: true,
|
autoCheckUpdate: true,
|
||||||
|
|||||||
@ -18,30 +18,18 @@ import LogCard from '@renderer/components/sider/log-card'
|
|||||||
import MihomoCoreCard from '@renderer/components/sider/mihomo-core-card'
|
import MihomoCoreCard from '@renderer/components/sider/mihomo-core-card'
|
||||||
import ResourceCard from '@renderer/components/sider/resource-card'
|
import ResourceCard from '@renderer/components/sider/resource-card'
|
||||||
import UpdaterButton from '@renderer/components/updater/updater-button'
|
import UpdaterButton from '@renderer/components/updater/updater-button'
|
||||||
|
import { useAppConfig } from './hooks/use-app-config'
|
||||||
|
|
||||||
const App: React.FC = () => {
|
const App: React.FC = () => {
|
||||||
|
const { appConfig } = useAppConfig()
|
||||||
|
const { appTheme = 'system' } = appConfig || {}
|
||||||
const { setTheme } = useTheme()
|
const { setTheme } = useTheme()
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const location = useLocation()
|
const location = useLocation()
|
||||||
const page = useRoutes(routes)
|
const page = useRoutes(routes)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
try {
|
setTheme(appTheme)
|
||||||
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
|
||||||
setTheme('dark')
|
|
||||||
} else {
|
|
||||||
setTheme('light')
|
|
||||||
}
|
|
||||||
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
|
|
||||||
if (e.matches) {
|
|
||||||
setTheme('dark')
|
|
||||||
} else {
|
|
||||||
setTheme('light')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} catch {
|
|
||||||
throw new Error('Failed to set theme')
|
|
||||||
}
|
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -40,7 +40,7 @@ const EditFileModal: React.FC<Props> = (props) => {
|
|||||||
height="100%"
|
height="100%"
|
||||||
language="yaml"
|
language="yaml"
|
||||||
value={currData}
|
value={currData}
|
||||||
theme={theme === 'dark' ? 'vs-dark' : 'vs'}
|
theme={theme === 'light' ? 'vs' : 'vs-dark'}
|
||||||
options={{
|
options={{
|
||||||
minimap: {
|
minimap: {
|
||||||
enabled: false
|
enabled: false
|
||||||
|
|||||||
@ -58,7 +58,7 @@ const ProxyItem: React.FC<Props> = (props) => {
|
|||||||
onPress={() => onSelect(group.name, proxy.name)}
|
onPress={() => onSelect(group.name, proxy.name)}
|
||||||
isPressable
|
isPressable
|
||||||
fullWidth
|
fullWidth
|
||||||
className={`${selected ? 'bg-primary/30' : ''}`}
|
className={`${selected ? 'bg-primary/30' : 'bg-content2'}`}
|
||||||
radius="sm"
|
radius="sm"
|
||||||
>
|
>
|
||||||
<CardBody className="p-2">
|
<CardBody className="p-2">
|
||||||
|
|||||||
@ -39,7 +39,7 @@ const ConfigViewer: React.FC<Props> = (props) => {
|
|||||||
height="100%"
|
height="100%"
|
||||||
language="yaml"
|
language="yaml"
|
||||||
value={currData}
|
value={currData}
|
||||||
theme={theme === 'dark' ? 'vs-dark' : 'vs'}
|
theme={theme === 'light' ? 'vs' : 'vs-dark'}
|
||||||
options={{
|
options={{
|
||||||
readOnly: true,
|
readOnly: true,
|
||||||
minimap: {
|
minimap: {
|
||||||
|
|||||||
@ -32,7 +32,7 @@ const PacEditorViewer: React.FC<Props> = (props) => {
|
|||||||
height="100%"
|
height="100%"
|
||||||
language="javascript"
|
language="javascript"
|
||||||
value={currData}
|
value={currData}
|
||||||
theme={theme === 'dark' ? 'vs-dark' : 'vs'}
|
theme={theme === 'light' ? 'vs' : 'vs-dark'}
|
||||||
options={{
|
options={{
|
||||||
minimap: {
|
minimap: {
|
||||||
enabled: false
|
enabled: false
|
||||||
|
|||||||
@ -11,7 +11,12 @@ init().then(() => {
|
|||||||
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
|
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
<NextUIProvider>
|
<NextUIProvider>
|
||||||
<NextThemesProvider attribute="class" defaultTheme="dark">
|
<NextThemesProvider
|
||||||
|
attribute="class"
|
||||||
|
themes={['light', 'dark', 'gray']}
|
||||||
|
enableSystem
|
||||||
|
defaultTheme="dark"
|
||||||
|
>
|
||||||
<HashRouter>
|
<HashRouter>
|
||||||
<App />
|
<App />
|
||||||
</HashRouter>
|
</HashRouter>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { Button, Input, Switch } from '@nextui-org/react'
|
import { Button, Input, Switch, Tab, Tabs } from '@nextui-org/react'
|
||||||
import BasePage from '@renderer/components/base/base-page'
|
import BasePage from '@renderer/components/base/base-page'
|
||||||
import SettingCard from '@renderer/components/base/base-setting-card'
|
import SettingCard from '@renderer/components/base/base-setting-card'
|
||||||
import SettingItem from '@renderer/components/base/base-setting-item'
|
import SettingItem from '@renderer/components/base/base-setting-item'
|
||||||
@ -15,20 +15,22 @@ import { version } from '@renderer/utils/init'
|
|||||||
import useSWR from 'swr'
|
import useSWR from 'swr'
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import debounce from '@renderer/utils/debounce'
|
import debounce from '@renderer/utils/debounce'
|
||||||
|
import { useTheme } from 'next-themes'
|
||||||
|
|
||||||
const Settings: React.FC = () => {
|
const Settings: React.FC = () => {
|
||||||
|
const { setTheme } = useTheme()
|
||||||
const { data: enable, mutate } = useSWR('checkAutoRun', checkAutoRun, {
|
const { data: enable, mutate } = useSWR('checkAutoRun', checkAutoRun, {
|
||||||
errorRetryCount: 5,
|
errorRetryCount: 5,
|
||||||
errorRetryInterval: 200
|
errorRetryInterval: 200
|
||||||
})
|
})
|
||||||
|
|
||||||
const { appConfig, patchAppConfig } = useAppConfig()
|
const { appConfig, patchAppConfig } = useAppConfig()
|
||||||
const {
|
const {
|
||||||
silentStart = false,
|
silentStart = false,
|
||||||
delayTestUrl,
|
delayTestUrl,
|
||||||
delayTestTimeout,
|
delayTestTimeout,
|
||||||
autoCheckUpdate,
|
autoCheckUpdate,
|
||||||
userAgent
|
userAgent,
|
||||||
|
appTheme = 'system'
|
||||||
} = appConfig || {}
|
} = appConfig || {}
|
||||||
const [url, setUrl] = useState(delayTestUrl)
|
const [url, setUrl] = useState(delayTestUrl)
|
||||||
const [ua, setUa] = useState(userAgent)
|
const [ua, setUa] = useState(userAgent)
|
||||||
@ -72,7 +74,7 @@ const Settings: React.FC = () => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</SettingItem>
|
</SettingItem>
|
||||||
<SettingItem title="静默启动">
|
<SettingItem title="静默启动" divider>
|
||||||
<Switch
|
<Switch
|
||||||
size="sm"
|
size="sm"
|
||||||
isSelected={silentStart}
|
isSelected={silentStart}
|
||||||
@ -81,6 +83,24 @@ const Settings: React.FC = () => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</SettingItem>
|
</SettingItem>
|
||||||
|
<SettingItem title="应用主题">
|
||||||
|
<Tabs
|
||||||
|
size="sm"
|
||||||
|
color="primary"
|
||||||
|
selectedKey={appTheme}
|
||||||
|
onSelectionChange={(key) => {
|
||||||
|
console.log(key)
|
||||||
|
setTheme(key as AppTheme)
|
||||||
|
|
||||||
|
patchAppConfig({ appTheme: key as AppTheme })
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Tab key="system" title="自动" />
|
||||||
|
<Tab key="dark" title="深色" />
|
||||||
|
<Tab key="gray" title="灰色" />
|
||||||
|
<Tab key="light" title="浅色" />
|
||||||
|
</Tabs>
|
||||||
|
</SettingItem>
|
||||||
</SettingCard>
|
</SettingCard>
|
||||||
<SettingCard>
|
<SettingCard>
|
||||||
<SettingItem title="订阅拉取 UA" divider>
|
<SettingItem title="订阅拉取 UA" divider>
|
||||||
|
|||||||
2
src/shared/types.d.ts
vendored
2
src/shared/types.d.ts
vendored
@ -1,6 +1,7 @@
|
|||||||
type OutboundMode = 'rule' | 'global' | 'direct'
|
type OutboundMode = 'rule' | 'global' | 'direct'
|
||||||
type LogLevel = 'info' | 'debug' | 'warning' | 'error' | 'silent'
|
type LogLevel = 'info' | 'debug' | 'warning' | 'error' | 'silent'
|
||||||
type SysProxyMode = 'auto' | 'manual'
|
type SysProxyMode = 'auto' | 'manual'
|
||||||
|
type AppTheme = 'system' | 'light' | 'dark' | 'gray'
|
||||||
type MihomoGroupType = 'Selector' | 'URLTest' | 'LoadBalance' | 'Relay'
|
type MihomoGroupType = 'Selector' | 'URLTest' | 'LoadBalance' | 'Relay'
|
||||||
type MihomoProxyType =
|
type MihomoProxyType =
|
||||||
| 'Direct'
|
| 'Direct'
|
||||||
@ -191,6 +192,7 @@ interface IAppConfig {
|
|||||||
core: 'mihomo' | 'mihomo-alpha'
|
core: 'mihomo' | 'mihomo-alpha'
|
||||||
proxyDisplayMode: 'simple' | 'full'
|
proxyDisplayMode: 'simple' | 'full'
|
||||||
proxyDisplayOrder: 'default' | 'delay' | 'name'
|
proxyDisplayOrder: 'default' | 'delay' | 'name'
|
||||||
|
appTheme: AppTheme
|
||||||
autoCheckUpdate: boolean
|
autoCheckUpdate: boolean
|
||||||
silentStart: boolean
|
silentStart: boolean
|
||||||
sysProxy: ISysProxyConfig
|
sysProxy: ISysProxyConfig
|
||||||
|
|||||||
@ -10,5 +10,27 @@ module.exports = {
|
|||||||
extend: {}
|
extend: {}
|
||||||
},
|
},
|
||||||
darkMode: 'class',
|
darkMode: 'class',
|
||||||
plugins: [nextui()]
|
plugins: [
|
||||||
|
nextui({
|
||||||
|
themes: {
|
||||||
|
gray: {
|
||||||
|
extend: 'dark',
|
||||||
|
colors: {
|
||||||
|
background: '#18181b',
|
||||||
|
content1: '#27272a',
|
||||||
|
content2: '#3f3f46',
|
||||||
|
content3: '#52525b',
|
||||||
|
default: {
|
||||||
|
DEFAULT: '#52525b',
|
||||||
|
50: '#27272a',
|
||||||
|
100: '#3f3f46',
|
||||||
|
200: '#52525b',
|
||||||
|
300: '#71717a',
|
||||||
|
400: '#a1a1aa'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user