Skip to content

Commit 8ee9998

Browse files
committed
fix: 解决跟随系统主题编辑器未监听的问题
1 parent e79f766 commit 8ee9998

File tree

3 files changed

+80
-51
lines changed

3 files changed

+80
-51
lines changed

src/app/core/article/md-editor.tsx

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import { open } from '@tauri-apps/plugin-shell'
2525
export function MdEditor() {
2626
const [editor, setEditor] = useState<Vditor>();
2727
const { currentArticle, saveCurrentArticle, loading, activeFilePath, matchPosition, setMatchPosition } = useArticleStore()
28-
const { theme, setTheme } = useTheme()
28+
const { theme } = useTheme()
2929
const t = useTranslations('article.editor')
3030
const { currentLocale } = useI18n()
3131
const [localMode, setLocalMode] = useLocalStorage<'ir' | 'sv' | 'wysiwyg'>('useLocalMode', 'ir')
@@ -330,6 +330,15 @@ export function MdEditor() {
330330
}
331331
}
332332

333+
function setTheme(theme: string) {
334+
if (editor) {
335+
const editorTheme = theme === 'dark' ? 'dark' : 'light'
336+
const contentTheme = theme === 'dark' ? 'dark' : 'light'
337+
const codeTheme = theme === 'dark' ? 'github-dark' : 'github-light'
338+
editor.setTheme(editorTheme === 'dark' ? 'dark' : 'classic', contentTheme, codeTheme)
339+
}
340+
}
341+
333342
useEffect(() => {
334343
if (!activeFilePath) {
335344
editor?.destroy()
@@ -359,20 +368,31 @@ export function MdEditor() {
359368
}, [loading])
360369

361370
useEffect(() => {
371+
let editorTheme: string | undefined
362372
if (theme === 'system') {
363373
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
364-
setTheme('dark')
365-
} else {
366-
setTheme('light')
374+
editorTheme = 'dark'
367375
}
368376
} else {
369-
if (editor) {
370-
const editorTheme = theme === 'dark' ? 'dark' : 'light'
371-
const contentTheme = theme === 'dark' ? 'dark' : 'light'
372-
const codeTheme = theme === 'dark' ? 'github-dark' : 'github-light'
373-
editor.setTheme(editorTheme === 'dark' ? 'dark' : 'classic', contentTheme, codeTheme)
377+
editorTheme = theme
378+
}
379+
if (editor) {
380+
setTheme(editorTheme || 'light')
381+
}
382+
}, [theme, editor])
383+
384+
useEffect(() => {
385+
const matchMedia = window.matchMedia('(prefers-color-scheme: dark)')
386+
const handler = () => {
387+
if (editor && theme === 'system') {
388+
const editorTheme = matchMedia.matches ? 'dark' : 'light'
389+
setTheme(editorTheme)
374390
}
375391
}
392+
matchMedia.addEventListener('change', handler)
393+
return () => {
394+
matchMedia.removeEventListener('change', handler)
395+
}
376396
}, [theme, editor])
377397

378398
useEffect(() => {

src/app/core/record/chat/chat-preview.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,20 @@ export default function ChatPreview({text}: {text: string}) {
4444
setMdTheme(theme as Themes)
4545
}
4646
}, [theme])
47+
48+
useEffect(() => {
49+
const matchMedia = window.matchMedia('(prefers-color-scheme: dark)')
50+
const handler = () => {
51+
if (theme === 'system') {
52+
const mdTheme = matchMedia.matches ? 'dark' : 'light'
53+
setMdTheme(mdTheme)
54+
}
55+
}
56+
matchMedia.addEventListener('change', handler)
57+
return () => {
58+
matchMedia.removeEventListener('change', handler)
59+
}
60+
}, [theme])
4761

4862
return <div>
4963
<MdPreview

src/components/mode-toggle.tsx

Lines changed: 37 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,76 +1,71 @@
11
"use client"
22

33
import * as React from "react"
4-
import { Laptop, Moon, Sun } from "lucide-react"
4+
import { Moon, Sun, SunMoon } from "lucide-react"
55
import { useTheme } from "next-themes"
66
import { useTranslations } from 'next-intl'
7-
8-
import { Button } from "@/components/ui/button"
97
import {
108
DropdownMenu,
119
DropdownMenuContent,
1210
DropdownMenuItem,
1311
DropdownMenuTrigger,
1412
} from "@/components/ui/dropdown-menu"
15-
import { SidebarMenuButton } from "./ui/sidebar"
13+
import { SidebarMenuButton } from "@/components/ui/sidebar";
14+
import { Button } from "@/components/ui/button";
1615

17-
function Toggle() {
16+
export function ModeToggle() {
1817
const t = useTranslations();
1918
const { theme, setTheme } = useTheme()
2019
const [open, setOpen] = React.useState(false)
2120

22-
// 循环切换主题:light -> dark -> system -> light
23-
const cycleTheme = () => {
24-
if (theme === "light") setTheme("dark")
25-
else if (theme === "dark") setTheme("system")
26-
else setTheme("light")
27-
}
28-
2921
return (
3022
<DropdownMenu open={open} onOpenChange={setOpen}>
3123
<DropdownMenuTrigger asChild>
32-
<Button
33-
variant="ghost"
34-
size="sm"
35-
onClick={cycleTheme}
24+
<SidebarMenuButton asChild className="md:h-8 md:p-0"
25+
tooltip={{
26+
children: t('common.theme'),
27+
hidden: false,
28+
}}
3629
>
37-
<Sun className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
38-
<Moon className="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
39-
<span className="sr-only">{t('common.theme')}</span>
40-
</Button>
30+
<a href="#">
31+
<div className="flex size-8 items-center justify-center rounded-lg">
32+
<Button
33+
variant="ghost"
34+
size="sm"
35+
>
36+
<ThemeIcon theme={theme} />
37+
</Button>
38+
</div>
39+
</a>
40+
</SidebarMenuButton>
4141
</DropdownMenuTrigger>
42-
<DropdownMenuContent align="end">
42+
<DropdownMenuContent align="end" side="right">
4343
<DropdownMenuItem onClick={() => setTheme("light")}>
4444
<Sun className="mr-2 h-4 w-4" />
45-
<span>{t('common.light')}</span>
45+
<span>{t('common.light')} {theme === "light" && "✓"}</span>
4646
</DropdownMenuItem>
4747
<DropdownMenuItem onClick={() => setTheme("dark")}>
4848
<Moon className="mr-2 h-4 w-4" />
49-
<span>{t('common.dark')}</span>
49+
<span>{t('common.dark')} {theme === "dark" && "✓"}</span>
5050
</DropdownMenuItem>
5151
<DropdownMenuItem onClick={() => setTheme("system")}>
52-
<Laptop className="mr-2 h-4 w-4" />
53-
<span>{t('common.system')}</span>
52+
<SunMoon className="mr-2 h-4 w-4" />
53+
<span>{t('common.system')} {theme === "system" && "✓"}</span>
5454
</DropdownMenuItem>
5555
</DropdownMenuContent>
5656
</DropdownMenu>
5757
)
5858
}
5959

60-
export function ModeToggle() {
61-
const t = useTranslations();
62-
return (
63-
<SidebarMenuButton asChild className="md:h-8 md:p-0"
64-
tooltip={{
65-
children: t('common.theme'),
66-
hidden: false,
67-
}}
68-
>
69-
<a href="#">
70-
<div className="flex size-8 items-center justify-center rounded-lg">
71-
<Toggle />
72-
</div>
73-
</a>
74-
</SidebarMenuButton>
75-
)
76-
}
60+
function ThemeIcon({ theme }: { theme?: string }) {
61+
switch (theme) {
62+
case "light":
63+
return <Sun />
64+
case "dark":
65+
return <Moon />
66+
case "system":
67+
return <SunMoon />
68+
default:
69+
return <SunMoon />
70+
}
71+
}

0 commit comments

Comments
 (0)