feat: auto switch theme

This commit is contained in:
Zephyruso 2023-09-02 19:06:02 +08:00
parent 28c0b1dc42
commit 0bbc661e93
5 changed files with 106 additions and 4 deletions

View File

@ -3,6 +3,7 @@ import { Show, lazy, onMount } from 'solid-js'
import { Header } from '~/components/Header' import { Header } from '~/components/Header'
import { curTheme, selectedEndpoint } from '~/signals' import { curTheme, selectedEndpoint } from '~/signals'
import { ROUTE } from './config/enum' import { ROUTE } from './config/enum'
import { useAutoSwitchTheme } from './signals/config'
const Setup = lazy(() => import('~/pages/Setup')) const Setup = lazy(() => import('~/pages/Setup'))
const Overview = lazy(() => import('~/pages/Overview')) const Overview = lazy(() => import('~/pages/Overview'))
@ -16,6 +17,8 @@ const Config = lazy(() => import('~/pages/Config'))
export const App = () => { export const App = () => {
const navigate = useNavigate() const navigate = useNavigate()
useAutoSwitchTheme()
onMount(async () => { onMount(async () => {
if (!selectedEndpoint()) { if (!selectedEndpoint()) {
navigate('/setup') navigate('/setup')

View File

@ -40,4 +40,7 @@ export default {
proxiesPreviewType: 'Proxies preview type', proxiesPreviewType: 'Proxies preview type',
urlForDelayTest: 'Url for delay test', urlForDelayTest: 'Url for delay test',
autoCloseConns: 'Automatically close all connections', autoCloseConns: 'Automatically close all connections',
autoSwitchTheme: 'Automatically switch theme',
favDayTheme: 'Favorite light theme',
favNightTheme: 'Favorite dark theme',
} }

View File

@ -40,4 +40,7 @@ export default {
proxiesPreviewType: '节点组预览样式', proxiesPreviewType: '节点组预览样式',
urlForDelayTest: '测速链接', urlForDelayTest: '测速链接',
autoCloseConns: '切换代理时自动断开全部连接', autoCloseConns: '切换代理时自动断开全部连接',
autoSwitchTheme: '自动切换主题',
favDayTheme: '浅色主题偏好',
favNightTheme: '深色主题偏好',
} }

View File

@ -4,11 +4,19 @@ import { useI18n } from '@solid-primitives/i18n'
import { For, Show, createSignal, onMount } from 'solid-js' import { For, Show, createSignal, onMount } from 'solid-js'
import { z } from 'zod' import { z } from 'zod'
import { PROXIES_PREVIEW_TYPE } from '~/config/enum' import { PROXIES_PREVIEW_TYPE } from '~/config/enum'
import { themes } from '~/constants'
import { useRequest } from '~/signals' import { useRequest } from '~/signals'
import { import {
applyThemeByMode,
autoCloseConns, autoCloseConns,
autoSwitchTheme,
favDayTheme,
favNightTheme,
proxiesPreviewType, proxiesPreviewType,
setAutoCloseConns, setAutoCloseConns,
setAutoSwitchTheme,
setFavDayTheme,
setFavNightTheme,
setProxiesPreviewType, setProxiesPreviewType,
setUrlForDelayTest, setUrlForDelayTest,
urlForDelayTest, urlForDelayTest,
@ -142,10 +150,59 @@ const ConfigForXd = () => {
const [t] = useI18n() const [t] = useI18n()
return ( return (
<div class="flex flex-col gap-4"> <div class="grid gap-4">
<div class="flex flex-col">
<div class="pb-4">{t('autoSwitchTheme')}</div>
<input
type="checkbox"
class="toggle"
checked={autoSwitchTheme()}
onChange={(e) => {
setAutoSwitchTheme(e.target.checked)
applyThemeByMode()
}}
/>
</div>
<Show when={autoSwitchTheme()}>
<div class="flex flex-col">
<div class="pb-4">{t('favDayTheme')}</div>
<select
class="select select-bordered w-full max-w-xs"
onChange={(e) => {
setFavDayTheme(e.target.value)
applyThemeByMode()
}}
>
<For each={themes}>
{(theme) => (
<option selected={favDayTheme() === theme} value={theme}>
{theme}
</option>
)}
</For>
</select>
</div>
<div class="flex flex-col">
<div class="pb-4">{t('favNightTheme')}</div>
<select
class="select select-bordered w-full max-w-xs"
onChange={(e) => {
setFavNightTheme(e.target.value)
applyThemeByMode()
}}
>
<For each={themes}>
{(theme) => (
<option selected={favNightTheme() === theme} value={theme}>
{theme}
</option>
)}
</For>
</select>
</div>
</Show>
<div> <div>
<div class="pb-4">{t('proxiesPreviewType')}</div> <div class="pb-4">{t('proxiesPreviewType')}</div>
<div class="flex items-center gap-4"> <div class="flex items-center gap-4">
<For each={Object.values(PROXIES_PREVIEW_TYPE)}> <For each={Object.values(PROXIES_PREVIEW_TYPE)}>
{(value) => ( {(value) => (
@ -176,11 +233,11 @@ const ConfigForXd = () => {
/> />
</div> </div>
<div> <div class="flex flex-col">
<div class="pb-4">{t('urlForDelayTest')}</div> <div class="pb-4">{t('urlForDelayTest')}</div>
<input <input
class="input input-bordered w-96" class="w-100 input input-bordered max-w-md"
value={urlForDelayTest()} value={urlForDelayTest()}
onChange={(e) => setUrlForDelayTest(e.target?.value!)} onChange={(e) => setUrlForDelayTest(e.target?.value!)}
/> />

View File

@ -1,6 +1,7 @@
import { makePersisted } from '@solid-primitives/storage' import { makePersisted } from '@solid-primitives/storage'
import { createSignal } from 'solid-js' import { createSignal } from 'solid-js'
import { PROXIES_PREVIEW_TYPE } from '~/config/enum' import { PROXIES_PREVIEW_TYPE } from '~/config/enum'
import { setCurTheme } from '~/signals'
export const [proxiesPreviewType, setProxiesPreviewType] = makePersisted( export const [proxiesPreviewType, setProxiesPreviewType] = makePersisted(
createSignal(PROXIES_PREVIEW_TYPE.BAR), createSignal(PROXIES_PREVIEW_TYPE.BAR),
@ -14,3 +15,38 @@ export const [autoCloseConns, setAutoCloseConns] = makePersisted(
createSignal(false), createSignal(false),
{ name: 'autoCloseConns', storage: localStorage }, { name: 'autoCloseConns', storage: localStorage },
) )
export const [autoSwitchTheme, setAutoSwitchTheme] = makePersisted(
createSignal(false),
{ name: 'autoSwitchTheme', storage: localStorage },
)
export const [favDayTheme, setFavDayTheme] = makePersisted(
createSignal('light'),
{ name: 'favDayTheme', storage: localStorage },
)
export const [favNightTheme, setFavNightTheme] = makePersisted(
createSignal('night'),
{ name: 'favNightTheme', storage: localStorage },
)
const setTheme = (isDark: boolean) => {
if (autoSwitchTheme()) {
if (isDark) {
setCurTheme(favNightTheme())
} else {
setCurTheme(favDayTheme())
}
}
}
export function applyThemeByMode() {
setTheme(window.matchMedia('(prefers-color-scheme: dark)').matches)
}
export function useAutoSwitchTheme() {
applyThemeByMode()
window
.matchMedia('(prefers-color-scheme: dark)')
.addEventListener('change', (event) => {
setTheme(event.matches)
})
}