Merge pull request #208 from kahosan/refactor_dark_mode

fix: the dark mode does not work for the `OperationSetting` and `SystemSetting` panels
This commit is contained in:
Calcium-Ion 2024-04-17 15:13:24 +08:00 committed by GitHub
commit 9dfd405ba9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 114 additions and 55 deletions

View File

@ -1,6 +1,7 @@
import React, { useContext, useEffect, useState } from 'react';
import { Link, useNavigate } from 'react-router-dom';
import { UserContext } from '../context/User';
import { useSetTheme, useTheme } from '../context/Theme';
import { API, getLogo, getSystemName, showSuccess } from '../helpers';
import '../index.css';
@ -34,10 +35,8 @@ const HeaderBar = () => {
let navigate = useNavigate();
const [showSidebar, setShowSidebar] = useState(false);
const [dark, setDark] = useState(false);
const systemName = getSystemName();
const logo = getLogo();
var themeMode = localStorage.getItem('theme-mode');
const currentDate = new Date();
// enable fireworks on new year(1.1 and 2.9-2.24)
const isNewYear =
@ -66,26 +65,19 @@ const HeaderBar = () => {
}, 3000);
};
const theme = useTheme();
const setTheme = useSetTheme();
useEffect(() => {
if (themeMode === 'dark') {
switchMode(true);
if (theme === 'dark') {
document.body.setAttribute('theme-mode', 'dark');
}
if (isNewYear) {
console.log('Happy New Year!');
}
}, []);
const switchMode = (model) => {
const body = document.body;
if (!model) {
body.removeAttribute('theme-mode');
localStorage.setItem('theme-mode', 'light');
} else {
body.setAttribute('theme-mode', 'dark');
localStorage.setItem('theme-mode', 'dark');
}
setDark(model);
};
return (
<>
<Layout>
@ -132,9 +124,11 @@ const HeaderBar = () => {
<Switch
checkedText='🌞'
size={'large'}
checked={dark}
checked={theme === 'dark'}
uncheckedText='🌙'
onChange={switchMode}
onChange={(checked) => {
setTheme(checked);
}}
/>
{userState.user ? (
<>

View File

@ -8,6 +8,8 @@ import {
verifyJSON,
} from '../helpers';
import { useTheme } from '../context/Theme';
const OperationSetting = () => {
let now = new Date();
let [inputs, setInputs] = useState({
@ -77,6 +79,9 @@ const OperationSetting = () => {
}
};
const theme = useTheme();
const isDark = theme === 'dark';
useEffect(() => {
getOptions().then();
}, []);
@ -219,8 +224,10 @@ const OperationSetting = () => {
return (
<Grid columns={1}>
<Grid.Column>
<Form loading={loading}>
<Header as='h3'>通用设置</Header>
<Form loading={loading} inverted={isDark}>
<Header as='h3' inverted={isDark}>
通用设置
</Header>
<Form.Group widths={4}>
<Form.Input
label='充值链接'
@ -299,7 +306,9 @@ const OperationSetting = () => {
保存通用设置
</Form.Button>
<Divider />
<Header as='h3'>绘图设置</Header>
<Header as='h3' inverted={isDark}>
绘图设置
</Header>
<Form.Group inline>
<Form.Checkbox
checked={inputs.DrawingEnabled === 'true'}
@ -321,7 +330,9 @@ const OperationSetting = () => {
/>
</Form.Group>
<Divider />
<Header as='h3'>屏蔽词过滤设置</Header>
<Header as='h3' inverted={isDark}>
屏蔽词过滤设置
</Header>
<Form.Group inline>
<Form.Checkbox
checked={inputs.CheckSensitiveEnabled === 'true'}
@ -381,7 +392,9 @@ const OperationSetting = () => {
保存屏蔽词设置
</Form.Button>
<Divider />
<Header as='h3'>日志设置</Header>
<Header as='h3' inverted={isDark}>
日志设置
</Header>
<Form.Group inline>
<Form.Checkbox
checked={inputs.LogConsumeEnabled === 'true'}
@ -409,7 +422,9 @@ const OperationSetting = () => {
清理历史日志
</Form.Button>
<Divider />
<Header as='h3'>数据看板</Header>
<Header as='h3' inverted={isDark}>
数据看板
</Header>
<Form.Checkbox
checked={inputs.DataExportEnabled === 'true'}
label='启用数据看板(实验性)'
@ -439,7 +454,9 @@ const OperationSetting = () => {
/>
</Form.Group>
<Divider />
<Header as='h3'>监控设置</Header>
<Header as='h3' inverted={isDark}>
监控设置
</Header>
<Form.Group widths={3}>
<Form.Input
label='最长响应时间'
@ -484,7 +501,9 @@ const OperationSetting = () => {
保存监控设置
</Form.Button>
<Divider />
<Header as='h3'>额度设置</Header>
<Header as='h3' inverted={isDark}>
额度设置
</Header>
<Form.Group widths={4}>
<Form.Input
label='新用户初始额度'
@ -535,7 +554,9 @@ const OperationSetting = () => {
保存额度设置
</Form.Button>
<Divider />
<Header as='h3'>倍率设置</Header>
<Header as='h3' inverted={isDark}>
倍率设置
</Header>
<Form.Group widths='equal'>
<Form.TextArea
label='模型固定价格(一次调用消耗多少刀,优先级大于模型倍率)'

View File

@ -10,6 +10,8 @@ import {
} from 'semantic-ui-react';
import { API, removeTrailingSlash, showError, verifyJSON } from '../helpers';
import { useTheme } from '../context/Theme';
const SystemSetting = () => {
let [inputs, setInputs] = useState({
PasswordLoginEnabled: '',
@ -57,6 +59,9 @@ const SystemSetting = () => {
const [showPasswordWarningModal, setShowPasswordWarningModal] =
useState(false);
const theme = useTheme();
const isDark = theme === 'dark';
const getOptions = async () => {
const res = await API.get('/api/option/');
const { success, message, data } = res.data;
@ -306,8 +311,8 @@ const SystemSetting = () => {
return (
<Grid columns={1}>
<Grid.Column>
<Form loading={loading}>
<Header as='h3'>通用设置</Header>
<Form loading={loading} inverted={isDark}>
<Header as='h3' inverted={isDark}>通用设置</Header>
<Form.Group widths='equal'>
<Form.Input
label='服务器地址'
@ -321,7 +326,7 @@ const SystemSetting = () => {
更新服务器地址
</Form.Button>
<Divider />
<Header as='h3'>
<Header as='h3' inverted={isDark}>
支付设置当前仅支持易支付接口默认使用上方服务器地址作为回调地址
</Header>
<Form.Group widths='equal'>
@ -385,7 +390,7 @@ const SystemSetting = () => {
</Form.Group>
<Form.Button onClick={submitPayAddress}>更新支付设置</Form.Button>
<Divider />
<Header as='h3'>配置登录注册</Header>
<Header as='h3' inverted={isDark}>配置登录注册</Header>
<Form.Group inline>
<Form.Checkbox
checked={inputs.PasswordLoginEnabled === 'true'}
@ -468,7 +473,7 @@ const SystemSetting = () => {
/>
</Form.Group>
<Divider />
<Header as='h3'>
<Header as='h3' inverted={isDark}>
配置邮箱域名白名单
<Header.Subheader>
用以防止恶意用户利用临时邮箱批量注册
@ -533,7 +538,7 @@ const SystemSetting = () => {
保存邮箱域名白名单设置
</Form.Button>
<Divider />
<Header as='h3'>
<Header as='h3' inverted={isDark}>
配置 SMTP
<Header.Subheader>用以支持系统的邮件发送</Header.Subheader>
</Header>
@ -592,7 +597,7 @@ const SystemSetting = () => {
</Form.Group>
<Form.Button onClick={submitSMTP}>保存 SMTP 设置</Form.Button>
<Divider />
<Header as='h3'>
<Header as='h3' inverted={isDark}>
配置 GitHub OAuth App
<Header.Subheader>
用以支持通过 GitHub 进行登录注册
@ -634,7 +639,7 @@ const SystemSetting = () => {
保存 GitHub OAuth 设置
</Form.Button>
<Divider />
<Header as='h3'>
<Header as='h3' inverted={isDark}>
配置 WeChat Server
<Header.Subheader>
用以支持通过微信进行登录注册
@ -679,7 +684,7 @@ const SystemSetting = () => {
保存 WeChat Server 设置
</Form.Button>
<Divider />
<Header as='h3'>配置 Telegram 登录</Header>
<Header as='h3' inverted={isDark}>配置 Telegram 登录</Header>
<Form.Group inline>
<Form.Input
label='Telegram Bot Token'
@ -700,7 +705,7 @@ const SystemSetting = () => {
保存 Telegram 登录设置
</Form.Button>
<Divider />
<Header as='h3'>
<Header as='h3' inverted={isDark}>
配置 Turnstile
<Header.Subheader>
用以支持用户校验

View File

@ -0,0 +1,36 @@
import { createContext, useCallback, useContext, useState } from 'react';
const ThemeContext = createContext(null);
export const useTheme = () => useContext(ThemeContext);
const SetThemeContext = createContext(null);
export const useSetTheme = () => useContext(SetThemeContext);
export const ThemeProvider = ({ children }) => {
const [theme, _setTheme] = useState(() => {
try {
return localStorage.getItem('theme-mode') || null;
} catch {
return null;
}
});
const setTheme = useCallback((input) => {
_setTheme(input ? 'dark' : 'light');
const body = document.body;
if (!input) {
body.removeAttribute('theme-mode');
localStorage.setItem('theme-mode', 'light');
} else {
body.setAttribute('theme-mode', 'dark');
localStorage.setItem('theme-mode', 'dark');
}
}, []);
return (
<SetThemeContext.Provider value={setTheme}>
<ThemeContext.Provider value={theme}>{children}</ThemeContext.Provider>
</SetThemeContext.Provider>
);
};

View File

@ -12,6 +12,7 @@ import 'react-toastify/dist/ReactToastify.css';
import { StatusProvider } from './context/Status';
import { Layout } from '@douyinfe/semi-ui';
import SiderBar from './components/SiderBar';
import { ThemeProvider } from './context/Theme';
// initialization
@ -22,6 +23,7 @@ root.render(
<StatusProvider>
<UserProvider>
<BrowserRouter>
<ThemeProvider>
<Layout>
<Sider>
<SiderBar />
@ -43,6 +45,7 @@ root.render(
</Layout>
<ToastContainer />
</Layout>
</ThemeProvider>
</BrowserRouter>
</UserProvider>
</StatusProvider>