Skip to content

Commit e79f766

Browse files
authored
feat(#159): 主题跟随系统
1 parent 34b0857 commit e79f766

5 files changed

Lines changed: 89 additions & 11 deletions

File tree

messages/en.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
"edit": "Edit",
1111
"create": "Create",
1212
"theme": "Theme",
13+
"light": "Light",
14+
"dark": "Dark",
15+
"system": "System",
1316
"pin": "Pin",
1417
"unpin": "Unpin",
1518
"settings": "Settings",
@@ -136,6 +139,7 @@
136139
},
137140
"theme": {
138141
"title": "Appearance",
142+
"appTheme": "Application theme",
139143
"previewTheme": "Preview content theme",
140144
"codeTheme": "Code block highlight theme",
141145
"selectTheme": "Select Theme"

messages/ja.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@
1111
"edit": "編集",
1212
"create": "作成",
1313
"theme": "テーマ",
14+
"light": "ライトモード",
15+
"dark": "ダークモード",
16+
"system": "システム設定に従う",
1417
"pin": "ピン留め",
15-
"unpin": "キャンセルピン留め",
18+
"unpin": "ピン留めを解除",
1619
"settings": "設定",
1720
"sync": "同期",
1821
"language": "言語",
@@ -134,6 +137,7 @@
134137
},
135138
"theme": {
136139
"title": "外観",
140+
"appTheme": "アプリテーマ",
137141
"previewTheme": "プレビュー用テーマ",
138142
"codeTheme": "コードブロックのハイライトテーマ",
139143
"selectTheme": "テーマを選択"

messages/zh.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
"edit": "编辑",
1212
"create": "创建",
1313
"theme": "主题",
14+
"light": "亮色",
15+
"dark": "暗色",
16+
"system": "跟随系统",
1417
"pin": "置顶",
1518
"unpin": "取消置顶",
1619
"settings": "设置",
@@ -134,6 +137,7 @@
134137
},
135138
"theme": {
136139
"title": "外观",
140+
"appTheme": "应用配色",
137141
"previewTheme": "预览内容主题",
138142
"codeTheme": "代码块高亮主题",
139143
"selectTheme": "选择主题"

src/app/core/setting/theme/setting-theme.tsx

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import useSettingStore from "@/stores/setting";
44
import { Store } from "@tauri-apps/plugin-store";
55
import { useTranslations } from 'next-intl';
66
import { useEffect } from "react";
7+
import { useTheme } from "next-themes";
78

89
export function PreviewThemeSelect() {
910
const t = useTranslations();
@@ -46,10 +47,37 @@ export function PreviewThemeSelect() {
4647
)
4748
}
4849

50+
export function AppThemeSelect() {
51+
const t = useTranslations();
52+
const { theme, setTheme } = useTheme()
53+
54+
const themes = [
55+
{ value: 'light', label: '亮色' },
56+
{ value: 'dark', label: '暗色' },
57+
{ value: 'system', label: '跟随系统' }
58+
]
59+
60+
return (
61+
<Select onValueChange={setTheme} value={theme}>
62+
<SelectTrigger className="w-[180px]">
63+
<SelectValue placeholder={t('settings.theme.selectTheme')} />
64+
</SelectTrigger>
65+
<SelectContent>
66+
{
67+
themes.map((theme) => (
68+
<SelectItem key={theme.value} value={theme.value}>{theme.label}</SelectItem>
69+
))
70+
}
71+
</SelectContent>
72+
</Select>
73+
)
74+
}
75+
4976
export function CodeThemeSelect() {
5077
const t = useTranslations();
5178
const { codeTheme, setCodeTheme } = useSettingStore()
52-
const themes = ['github', 'atom', 'a11y', 'gradient', 'kimbie', 'paraiso', 'qtcreator', 'stackoverflow']
79+
80+
const themes = ['github', 'github-dark', 'material-darker', 'material-palenight', 'one-dark']
5381

5482
async function changeHandler(e: string) {
5583
setCodeTheme(e)
@@ -91,6 +119,10 @@ export function SettingTheme({id, icon}: {id: string, icon?: React.ReactNode}) {
91119

92120
return (
93121
<SettingType id={id} icon={icon} title={t('settings.theme.title')}>
122+
<SettingRow border>
123+
<span>{t('settings.theme.appTheme') || '应用配色'}</span>
124+
<AppThemeSelect />
125+
</SettingRow>
94126
<SettingRow border>
95127
<span>{t('settings.theme.previewTheme')}</span>
96128
<PreviewThemeSelect />

src/components/mode-toggle.tsx

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,59 @@
11
"use client"
22

33
import * as React from "react"
4-
import { Moon, Sun } from "lucide-react"
4+
import { Laptop, Moon, Sun } from "lucide-react"
55
import { useTheme } from "next-themes"
66
import { useTranslations } from 'next-intl'
77

88
import { Button } from "@/components/ui/button"
9+
import {
10+
DropdownMenu,
11+
DropdownMenuContent,
12+
DropdownMenuItem,
13+
DropdownMenuTrigger,
14+
} from "@/components/ui/dropdown-menu"
915
import { SidebarMenuButton } from "./ui/sidebar"
1016

1117
function Toggle() {
18+
const t = useTranslations();
1219
const { theme, setTheme } = useTheme()
20+
const [open, setOpen] = React.useState(false)
21+
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+
}
1328

1429
return (
15-
<Button
16-
variant="ghost"
17-
size="sm"
18-
onClick={() => setTheme(theme === "light" ? "dark" : "light")}
19-
>
20-
<Sun className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
21-
<Moon className="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
22-
</Button>
30+
<DropdownMenu open={open} onOpenChange={setOpen}>
31+
<DropdownMenuTrigger asChild>
32+
<Button
33+
variant="ghost"
34+
size="sm"
35+
onClick={cycleTheme}
36+
>
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>
41+
</DropdownMenuTrigger>
42+
<DropdownMenuContent align="end">
43+
<DropdownMenuItem onClick={() => setTheme("light")}>
44+
<Sun className="mr-2 h-4 w-4" />
45+
<span>{t('common.light')}</span>
46+
</DropdownMenuItem>
47+
<DropdownMenuItem onClick={() => setTheme("dark")}>
48+
<Moon className="mr-2 h-4 w-4" />
49+
<span>{t('common.dark')}</span>
50+
</DropdownMenuItem>
51+
<DropdownMenuItem onClick={() => setTheme("system")}>
52+
<Laptop className="mr-2 h-4 w-4" />
53+
<span>{t('common.system')}</span>
54+
</DropdownMenuItem>
55+
</DropdownMenuContent>
56+
</DropdownMenu>
2357
)
2458
}
2559

0 commit comments

Comments
 (0)