Skip to content

Commit 83d311b

Browse files
committed
✨ feat: 添加深色主题
1 parent 34bcd51 commit 83d311b

File tree

5 files changed

+104
-40
lines changed

5 files changed

+104
-40
lines changed

src/App.vue

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,41 @@
11
<script setup>
2-
import { onMounted, ref, h, watch } from 'vue';
3-
import { ConfigProvider, Layout, Menu } from 'ant-design-vue';
2+
import { onMounted, ref, h, watch, computed } from 'vue';
3+
import { ConfigProvider, Layout, Menu, theme as antTheme } from 'ant-design-vue';
44
import { FileTextOutlined, SettingOutlined } from '@ant-design/icons-vue';
55
import HomeView from './components/HomeView.vue';
66
import ConfigView from './components/ConfigView.vue';
77
import { useCommitTypesStore } from './stores/commitTypes';
8+
import { useSettingsStore } from './stores/settings';
89
910
const { Sider, Content } = Layout;
1011
1112
const currentView = ref(['home']);
1213
const enterAction = ref({});
1314
const commitTypesStore = useCommitTypesStore();
15+
const settingsStore = useSettingsStore();
16+
17+
// 主题相关
18+
const systemDarkMode = ref(window.matchMedia('(prefers-color-scheme: dark)').matches);
19+
20+
// 计算实际使用的主题
21+
const actualTheme = computed(() => {
22+
if (settingsStore.theme === 'system') {
23+
return systemDarkMode.value ? 'dark' : 'light';
24+
}
25+
return settingsStore.theme;
26+
});
27+
28+
// Ant Design 主题配置
29+
const themeConfig = computed(() => {
30+
return {
31+
algorithm: actualTheme.value === 'dark' ? antTheme.darkAlgorithm : antTheme.defaultAlgorithm
32+
};
33+
});
34+
35+
// 应用主题到document
36+
const applyTheme = () => {
37+
document.documentElement.setAttribute('data-theme', actualTheme.value);
38+
};
1439
1540
const menuItems = [
1641
{
@@ -68,6 +93,16 @@ const registerCommands = () => {
6893
};
6994
7095
onMounted(() => {
96+
// 应用初始主题
97+
applyTheme();
98+
99+
// 监听系统主题变化
100+
const darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
101+
const handleThemeChange = (e) => {
102+
systemDarkMode.value = e.matches;
103+
};
104+
darkModeMediaQuery.addEventListener('change', handleThemeChange);
105+
71106
// 清理可能存在的旧动态功能
72107
try {
73108
const existingFeatures = window.utools.getFeatures();
@@ -108,18 +143,25 @@ watch(
108143
}
109144
);
110145
146+
// 监听主题变化
147+
watch(actualTheme, () => {
148+
applyTheme();
149+
});
150+
111151
const handleMenuClick = ({ key }) => {
112152
currentView.value = [key];
113153
};
114154
</script>
115155

116156
<template>
117-
<ConfigProvider>
157+
<ConfigProvider :theme="themeConfig">
118158
<Layout style="min-height: 100vh;">
119-
<Sider theme="light" :width="150" style="border-right: 1px solid #f0f0f0;">
120-
<Menu v-model:selectedKeys="currentView" mode="inline" :items="menuItems" @click="handleMenuClick" />
159+
<Sider :theme="actualTheme === 'dark' ? 'dark' : 'light'" :width="150"
160+
:style="{ borderRight: actualTheme === 'dark' ? '1px solid #303030' : '1px solid #f0f0f0' }">
161+
<Menu style="height: 100%;" v-model:selectedKeys="currentView" mode="inline" :items="menuItems"
162+
@click="handleMenuClick" />
121163
</Sider>
122-
<Content style="background: #fff;">
164+
<Content :style="{ background: actualTheme === 'dark' ? '#141414' : '#fff' }">
123165
<HomeView v-if="currentView[0] === 'home'" :enterAction="enterAction" />
124166
<ConfigView v-else-if="currentView[0] === 'config'" />
125167
</Content>

src/components/ConfigView.vue

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -80,22 +80,26 @@ const autoClassify = computed({
8080
set: (val) => settingsStore.setAutoClassify(val)
8181
});
8282
83+
const theme = computed({
84+
get: () => settingsStore.theme,
85+
set: (val) => settingsStore.setTheme(val)
86+
});
87+
88+
// 主题选项
89+
const themeOptions = [
90+
{ label: '跟随系统', value: 'system' },
91+
{ label: '浅色主题', value: 'light' },
92+
{ label: '深色主题', value: 'dark' }
93+
];
94+
8395
// 重置为默认配置
8496
const resetConfig = () => {
8597
settingsStore.resetToDefault();
86-
message.success("如你所愿");
87-
}
88-
89-
const logs = () => {
90-
console.log('isKill', isKill.value);
91-
console.log('useIcon', useIcon.value);
92-
console.log('autoClassify', autoClassify.value);
9398
}
9499
95100
// 保存配置文件(Pinia 自动持久化,这里只显示提示)
96101
const saveData = () => {
97102
message.success("保存好了");
98-
logs();
99103
}
100104
101105
// 打开分类规则管理
@@ -296,6 +300,14 @@ const resetTypesToDefault = () => {
296300
<span style="margin-left:8px;color:#888;cursor:help">?</span>
297301
</a-tooltip>
298302
</div>
303+
<div class="config-row">
304+
<a-typography-text style="margin-right: 10px;">主题:</a-typography-text>
305+
<a-radio-group v-model:value="theme" button-style="solid">
306+
<a-radio-button v-for="option in themeOptions" :key="option.value" :value="option.value">
307+
{{ option.label }}
308+
</a-radio-button>
309+
</a-radio-group>
310+
</div>
299311
<div class="config-row">
300312
<a-button type="default" @click="openRulesManager">
301313
🔧 管理自动分类规则

src/components/HomeView.vue

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,6 @@ textarea.ant-input {
232232
.commit-msg {
233233
font-size: 20px;
234234
width: fit-content;
235-
background: white;
236235
color: #c678dd;
237236
padding: 10px;
238237
border-radius: 10px;

src/main.css

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,23 @@
33
--light: #fff;
44
}
55

6+
/* 浅色主题 */
7+
:root,
8+
:root[data-theme="light"] {
9+
--bg-color: #f4f4f4;
10+
--text-color: #000;
11+
--scrollbar-track: #f4f4f4;
12+
--scrollbar-thumb: #666;
13+
}
14+
15+
/* 深色主题 */
16+
:root[data-theme="dark"] {
17+
--bg-color: #282c34;
18+
--text-color: #e6e6e6;
19+
--scrollbar-track: #303133;
20+
--scrollbar-thumb: #666;
21+
}
22+
623

724
html,
825
body {
@@ -37,32 +54,17 @@ textarea {
3754
margin: 0;
3855
}
3956

40-
@media (prefers-color-scheme: light) {
41-
body {
42-
background-color: #f4f4f4;
43-
}
44-
45-
::-webkit-scrollbar-track-piece {
46-
background-color: #f4f4f4;
47-
}
48-
49-
::-webkit-scrollbar-thumb {
50-
border-color: #f4f4f4;
51-
}
57+
body {
58+
background-color: var(--bg-color);
59+
color: var(--text-color);
60+
transition: background-color 0.3s ease, color 0.3s ease;
5261
}
5362

54-
@media (prefers-color-scheme: dark) {
55-
&::-webkit-scrollbar-track-piece {
56-
background-color: #303133;
57-
}
58-
59-
&::-webkit-scrollbar-thumb {
60-
background-color: #666;
61-
border-color: #303133;
62-
}
63+
::-webkit-scrollbar-track-piece {
64+
background-color: var(--scrollbar-track);
65+
}
6366

64-
body {
65-
background-color: #303133;
66-
color: #fff;
67-
}
67+
::-webkit-scrollbar-thumb {
68+
background-color: var(--scrollbar-thumb);
69+
border-color: var(--scrollbar-track);
6870
}

src/stores/settings.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ export const useSettingsStore = defineStore('settings', {
5151
// 行为设置
5252
isKill: true, // 复制后是否退出
5353

54+
// 主题设置:'light' | 'dark' | 'system'
55+
theme: 'system',
56+
5457
// 远程数据源(保留但不推荐使用)
5558
isCustomType: false,
5659
customFileUrl: '',
@@ -84,6 +87,11 @@ export const useSettingsStore = defineStore('settings', {
8487
this.isKill = value
8588
},
8689

90+
// 设置主题
91+
setTheme(theme) {
92+
this.theme = theme
93+
},
94+
8795
// 设置远程数据源
8896
setCustomType(isCustom, url) {
8997
this.isCustomType = isCustom
@@ -101,6 +109,7 @@ export const useSettingsStore = defineStore('settings', {
101109
this.autoClassify = true
102110
this.classifyRules = { ...defaultClassifyRules }
103111
this.isKill = true
112+
this.theme = 'system'
104113
this.isCustomType = false
105114
this.customFileUrl = ''
106115
this.isCustomIcon = false

0 commit comments

Comments
 (0)