From d5266fa0030e886d28ea00e1f3bd617ed820aff5 Mon Sep 17 00:00:00 2001 From: coolcoala Date: Wed, 9 Jul 2025 04:49:05 +0300 Subject: [PATCH] fixed theme viewer --- package.json | 1 + pnpm-lock.yaml | 14 ++++ src/components/setting/mods/theme-viewer.tsx | 83 ++++++++++---------- 3 files changed, 58 insertions(+), 40 deletions(-) diff --git a/package.json b/package.json index 0bd19749..3e28b48c 100644 --- a/package.json +++ b/package.json @@ -86,6 +86,7 @@ "peggy": "^5.0.3", "react": "19.1.0", "react-chartjs-2": "^5.3.0", + "react-colorful": "^5.6.1", "react-dom": "19.1.0", "react-error-boundary": "6.0.0", "react-hook-form": "^7.57.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3f2ae253..01c45c64 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -191,6 +191,9 @@ importers: react-chartjs-2: specifier: ^5.3.0 version: 5.3.0(chart.js@4.5.0)(react@19.1.0) + react-colorful: + specifier: ^5.6.1 + version: 5.6.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0) react-dom: specifier: 19.1.0 version: 19.1.0(react@19.1.0) @@ -3329,6 +3332,12 @@ packages: chart.js: ^4.1.1 react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-colorful@5.6.1: + resolution: {integrity: sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + react-dom@19.1.0: resolution: {integrity: sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==} peerDependencies: @@ -7031,6 +7040,11 @@ snapshots: chart.js: 4.5.0 react: 19.1.0 + react-colorful@5.6.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + react-dom@19.1.0(react@19.1.0): dependencies: react: 19.1.0 diff --git a/src/components/setting/mods/theme-viewer.tsx b/src/components/setting/mods/theme-viewer.tsx index addfe4b3..00c2b5c3 100644 --- a/src/components/setting/mods/theme-viewer.tsx +++ b/src/components/setting/mods/theme-viewer.tsx @@ -1,9 +1,7 @@ -import { forwardRef, useImperativeHandle, useState, useMemo } from "react"; +import { forwardRef, useImperativeHandle, useState, useEffect, useCallback } from "react"; import { useLockFn } from "ahooks"; import { useTranslation } from "react-i18next"; -import { useTheme } from "@mui/material/styles"; // Оставляем для получения дефолтных цветов темы -// Новые импорты import { useVerge } from "@/hooks/use-verge"; import { defaultTheme, defaultDarkTheme } from "@/pages/_theme"; import { DialogRef } from "@/components/base"; @@ -14,54 +12,63 @@ import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DialogC import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Edit } from "lucide-react"; +import { useThemeMode } from "@/services/states"; // Наш хук для получения текущего режима +import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"; +import {HexColorPicker} from "react-colorful"; + interface Props {} -// Дочерний компонент для одной строки настройки цвета const ColorSettingRow = ({ label, value, placeholder, onChange }: { label: string; value: string; placeholder: string; - onChange: (e: React.ChangeEvent) => void; -}) => ( -
- -
- {/* --- НАЧАЛО ИЗМЕНЕНИЙ --- */} - {/* Этот контейнер теперь позиционирован, чтобы спрятать input внутри */} -
- {/* Видимый образец цвета */} -
- {/* Невидимый input, который и открывает палитру */} + onChange: (e: { target: { value: string } }) => void; // Адаптируем тип для совместимости +}) => { + const color = value || placeholder; + + return ( +
+ +
+ + +
- {/* --- КОНЕЦ ИЗМЕНЕНИЙ --- */} -
-
-); + ); +}; + export const ThemeViewer = forwardRef((props, ref) => { const { t } = useTranslation(); const [open, setOpen] = useState(false); const [editorOpen, setEditorOpen] = useState(false); - const { verge, patchVerge } = useVerge(); + const { verge, patchVerge, mutateVerge } = useVerge(); const { theme_setting } = verge ?? {}; const [theme, setTheme] = useState(theme_setting || {}); + const mode = useThemeMode(); + const resolvedMode = mode === 'system' + ? (window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light") + : mode; + useImperativeHandle(ref, () => ({ open: () => { setOpen(true); @@ -70,32 +77,30 @@ export const ThemeViewer = forwardRef((props, ref) => { close: () => setOpen(false), })); - const handleChange = (field: keyof typeof theme) => (e: any) => { + const handleChange = (field: keyof typeof theme) => (e: { target: { value: string } }) => { setTheme((t) => ({ ...t, [field]: e.target.value })); }; const onSave = useLockFn(async () => { try { await patchVerge({ theme_setting: theme }); + await mutateVerge(); setOpen(false); - showNotice("success", t("Saved Successfully, please restart the app to take effect")); + showNotice("success", t("Theme updated successfully")); } catch (err: any) { showNotice("error", err.toString()); } }); - const muiTheme = useTheme(); - const dt = muiTheme.palette.mode === "light" ? defaultTheme : defaultDarkTheme; + + const dt = resolvedMode === "light" ? defaultTheme : defaultDarkTheme; type ThemeKey = keyof typeof theme & keyof typeof defaultTheme; const renderItem = (label: string, key: ThemeKey) => { return ( @@ -124,9 +129,7 @@ export const ThemeViewer = forwardRef((props, ref) => {