From a6a11a70267b92e2fd05a0bbd3ef168408c8a8c2 Mon Sep 17 00:00:00 2001 From: bietiaop <1527109126@qq.com> Date: Sat, 8 Feb 2025 23:38:30 +0800 Subject: [PATCH] fix --- napcat.webui/index.html | 1 + napcat.webui/src/components/ColorPicker.tsx | 24 ++-- .../src/pages/dashboard/config/index.tsx | 19 ++- .../src/pages/dashboard/config/login.tsx | 11 +- .../src/pages/dashboard/config/theme.tsx | 130 ++++++++++++++++-- napcat.webui/vite.config.ts | 3 +- src/webui/index.ts | 18 +++ 7 files changed, 171 insertions(+), 35 deletions(-) diff --git a/napcat.webui/index.html b/napcat.webui/index.html index 995dfcb2..12511914 100644 --- a/napcat.webui/index.html +++ b/napcat.webui/index.html @@ -13,6 +13,7 @@ content="viewport-fit=cover, width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport" /> + diff --git a/napcat.webui/src/components/ColorPicker.tsx b/napcat.webui/src/components/ColorPicker.tsx index 856ecc11..eb9f423a 100644 --- a/napcat.webui/src/components/ColorPicker.tsx +++ b/napcat.webui/src/components/ColorPicker.tsx @@ -6,32 +6,28 @@ import { ColorResult, SketchPicker } from 'react-color' interface ColorPickerProps { color: string - onChange: (color: string) => void + onChange: (color: ColorResult) => void } const ColorPicker: React.FC = ({ color, onChange }) => { const handleChange = (colorResult: ColorResult) => { - const hsl = colorResult.hsl - const color = `${hsl.h} ${hsl.s}% ${hsl.l}%` - onChange(color) + onChange(colorResult) } return ( - +
- + ) diff --git a/napcat.webui/src/pages/dashboard/config/index.tsx b/napcat.webui/src/pages/dashboard/config/index.tsx index f61748ff..067f6c4d 100644 --- a/napcat.webui/src/pages/dashboard/config/index.tsx +++ b/napcat.webui/src/pages/dashboard/config/index.tsx @@ -1,5 +1,6 @@ import { Card, CardBody } from '@heroui/card' import { Tab, Tabs } from '@heroui/tabs' +import clsx from 'clsx' import { useMediaQuery } from 'react-responsive' import { useNavigate, useSearchParams } from 'react-router-dom' @@ -11,13 +12,25 @@ import WebUIConfigCard from './webui' export interface ConfigPageProps { children?: React.ReactNode + size?: 'sm' | 'md' | 'lg' } -const ConfingPageItem: React.FC = ({ children }) => { +const ConfingPageItem: React.FC = ({ + children, + size = 'md' +}) => { return ( -
{children}
+
+ {children} +
) @@ -71,7 +84,7 @@ export default function ConfigPage() { - + diff --git a/napcat.webui/src/pages/dashboard/config/login.tsx b/napcat.webui/src/pages/dashboard/config/login.tsx index 155170f5..8138408c 100644 --- a/napcat.webui/src/pages/dashboard/config/login.tsx +++ b/napcat.webui/src/pages/dashboard/config/login.tsx @@ -1,6 +1,6 @@ import { Input } from '@heroui/input' import { useRequest } from 'ahooks' -import { useEffect, useState } from 'react' +import { useEffect } from 'react' import { Controller, useForm } from 'react-hook-form' import toast from 'react-hot-toast' @@ -16,7 +16,6 @@ const LoginConfigCard = () => { error: quickLoginError, refreshAsync: refreshQuickLogin } = useRequest(QQManager.getQuickLoginQQ) - const [loading, setLoading] = useState(false) const { control, handleSubmit: handleOnebotSubmit, @@ -36,27 +35,21 @@ const LoginConfigCard = () => { const onSubmit = handleOnebotSubmit((data) => { try { - setLoading(true) QQManager.setQuickLoginQQ(data.quickLoginQQ) toast.success('保存成功') } catch (error) { const msg = (error as Error).message toast.error(`保存失败: ${msg}`) - } finally { - setLoading(false) } }) const onRefresh = async () => { try { - setLoading(true) await refreshQuickLogin() toast.success('刷新成功') } catch (error) { const msg = (error as Error).message toast.error(`刷新失败: ${msg}`) - } finally { - setLoading(false) } } @@ -64,7 +57,7 @@ const LoginConfigCard = () => { reset() }, [quickLoginData]) - if (loading) return + if (quickLoginLoading) return return ( <> diff --git a/napcat.webui/src/pages/dashboard/config/theme.tsx b/napcat.webui/src/pages/dashboard/config/theme.tsx index e62582f2..3116fa78 100644 --- a/napcat.webui/src/pages/dashboard/config/theme.tsx +++ b/napcat.webui/src/pages/dashboard/config/theme.tsx @@ -53,6 +53,10 @@ const ThemeConfigCard = () => { } } + useEffect(() => { + reset() + }, [data]) + if (loading) return if (error) @@ -60,10 +64,115 @@ const ThemeConfigCard = () => {
{error.message}
) + // 将颜色 key 补全为 ThemeConfigItem 中定义的所有颜色相关属性 const colorKeys = [ '--heroui-background', + + '--heroui-foreground-50', + '--heroui-foreground-100', + '--heroui-foreground-200', + '--heroui-foreground-300', + '--heroui-foreground-400', + '--heroui-foreground-500', + '--heroui-foreground-600', + '--heroui-foreground-700', + '--heroui-foreground-800', + '--heroui-foreground-900', + '--heroui-foreground', + + '--heroui-content1', + '--heroui-content1-foreground', + '--heroui-content2', + '--heroui-content2-foreground', + '--heroui-content3', + '--heroui-content3-foreground', + '--heroui-content4', + '--heroui-content4-foreground', + + '--heroui-default-50', + '--heroui-default-100', + '--heroui-default-200', + '--heroui-default-300', + '--heroui-default-400', + '--heroui-default-500', + '--heroui-default-600', + '--heroui-default-700', + '--heroui-default-800', + '--heroui-default-900', + '--heroui-default-foreground', + '--heroui-default', + + '--heroui-danger-50', + '--heroui-danger-100', + '--heroui-danger-200', + '--heroui-danger-300', + '--heroui-danger-400', + '--heroui-danger-500', + '--heroui-danger-600', + '--heroui-danger-700', + '--heroui-danger-800', + '--heroui-danger-900', + '--heroui-danger-foreground', + '--heroui-danger', + + '--heroui-primary-50', + '--heroui-primary-100', + '--heroui-primary-200', + '--heroui-primary-300', + '--heroui-primary-400', + '--heroui-primary-500', + '--heroui-primary-600', + '--heroui-primary-700', + '--heroui-primary-800', + '--heroui-primary-900', + '--heroui-primary-foreground', '--heroui-primary', - '--heroui-danger' + + '--heroui-secondary-50', + '--heroui-secondary-100', + '--heroui-secondary-200', + '--heroui-secondary-300', + '--heroui-secondary-400', + '--heroui-secondary-500', + '--heroui-secondary-600', + '--heroui-secondary-700', + '--heroui-secondary-800', + '--heroui-secondary-900', + '--heroui-secondary-foreground', + '--heroui-secondary', + + '--heroui-success-50', + '--heroui-success-100', + '--heroui-success-200', + '--heroui-success-300', + '--heroui-success-400', + '--heroui-success-500', + '--heroui-success-600', + '--heroui-success-700', + '--heroui-success-800', + '--heroui-success-900', + '--heroui-success-foreground', + '--heroui-success', + + '--heroui-warning-50', + '--heroui-warning-100', + '--heroui-warning-200', + '--heroui-warning-300', + '--heroui-warning-400', + '--heroui-warning-500', + '--heroui-warning-600', + '--heroui-warning-700', + '--heroui-warning-800', + '--heroui-warning-900', + '--heroui-warning-foreground', + '--heroui-warning', + + '--heroui-focus', + '--heroui-overlay', + '--heroui-divider', + '--heroui-code-background', + '--heroui-strong', + '--heroui-code-mdx' ] as const return ( @@ -74,19 +183,24 @@ const ThemeConfigCard = () => {

{mode === 'dark' ? '暗色主题' : '亮色主题'}

{colorKeys.map((key) => ( -
- +
+ { - console.log(value) const hslArray = value?.split(' ') ?? [0, 0, 0] const color = `hsl(${hslArray[0]}, ${hslArray[1]}, ${hslArray[2]})` - return + return ( + { + onChange( + `${result.hsl.h} ${result.hsl.s * 100}% ${result.hsl.l * 100}%` + ) + }} + /> + ) }} />
diff --git a/napcat.webui/vite.config.ts b/napcat.webui/vite.config.ts index 043e0bfa..d9cf306c 100644 --- a/napcat.webui/vite.config.ts +++ b/napcat.webui/vite.config.ts @@ -34,7 +34,8 @@ export default defineConfig(({ mode }) => { ws: true, changeOrigin: true }, - '/api': backendDebugUrl + '/api': backendDebugUrl, + '/files': backendDebugUrl } }, build: { diff --git a/src/webui/index.ts b/src/webui/index.ts index bb4d8949..2e35497f 100644 --- a/src/webui/index.ts +++ b/src/webui/index.ts @@ -81,6 +81,24 @@ export async function InitWebUi(logger: LogWrapper, pathWrapper: NapCatPathWrapp } }); + // 如果是自定义色彩,构建一个css文件 + app.use('/files/theme.css', async (_req, res) => { + const colors = await WebUiConfig.GetTheme(); + // 生成css(分为亮色和暗色,靠class和[data-theme="light"]) + let css = '.dark, [data-theme="dark"] {'; + for (const key in colors.dark) { + css += `--${key}: ${colors.dark[key]};`; + } + css += '}'; + css += '.light, [data-theme="light"] {'; + for (const key in colors.light) { + css += `--${key}: ${colors.light[key]};`; + } + css += '}'; + + res.send(css); + }); + // ------------中间件结束------------ // ------------挂载路由------------