From 15a76a53135fcc258306c0e5524dc97e00b89492 Mon Sep 17 00:00:00 2001 From: sqj Date: Fri, 3 Oct 2025 15:42:22 +0800 Subject: [PATCH] =?UTF-8?q?1.=20=E6=94=AF=E6=8C=81=E6=9A=97=E9=BB=91?= =?UTF-8?q?=E4=B8=BB=E9=A2=98=202.=20=E8=B0=83=E6=95=B4=E6=8F=92=E4=BB=B6?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2ui?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 119 +--- docs/guide/sponsorship.md | 6 + docs/guide/update.md | 2 +- docs/guide/updateLog.md | 22 + electron-builder.yml | 2 +- src/renderer/components.d.ts | 10 + src/renderer/src/App.vue | 55 +- src/renderer/src/assets/base.css | 8 +- src/renderer/src/assets/main.css | 597 ++++++++++++++++-- src/renderer/src/assets/theme/blue.css | 5 +- src/renderer/src/assets/theme/cyan.css | 5 +- src/renderer/src/assets/theme/orange.css | 5 +- src/renderer/src/assets/theme/pink.css | 5 +- .../src/components/Music/SongVirtualList.vue | 82 +-- .../src/components/Settings/plugins.vue | 345 ++++++---- src/renderer/src/components/ThemeSelector.vue | 359 +++++------ .../src/components/TitleBarControls.vue | 26 +- src/renderer/src/components/Versions.vue | 50 ++ .../src/components/layout/HomeLayout.vue | 73 ++- src/renderer/src/views/ThemeDemo.vue | 368 +++++++++++ src/renderer/src/views/music/find.vue | 50 +- src/renderer/src/views/music/list.vue | 25 +- src/renderer/src/views/music/local.vue | 125 ++-- src/renderer/src/views/music/recent.vue | 46 +- src/renderer/src/views/music/search.vue | 21 +- src/renderer/src/views/settings/index.vue | 174 ++--- src/renderer/src/views/welcome/index.vue | 45 +- website/script.js | 32 +- 28 files changed, 1854 insertions(+), 808 deletions(-) create mode 100644 src/renderer/src/views/ThemeDemo.vue diff --git a/README.md b/README.md index 3975434..1e8c7f3 100644 --- a/README.md +++ b/README.md @@ -27,16 +27,7 @@ Ceru Music 是基于 Electron 和 Vue 开发的跨平台桌面音乐播放器工 ```ast CeruMuisc/ ├── .github/ - │ └── workflows/ - │ ├── auto-sync-release.yml - │ ├── deploydocs.yml - │ ├── main.yml - │ ├── sync-releases-to-webdav.yml - │ └── uploadpan.yml ├── scripts/ - │ ├── auth-test.js - │ ├── genAst.js - │ └── test-alist.js ├── src/ │ ├── common/ │ │ ├── types/ @@ -56,6 +47,7 @@ CeruMuisc/ │ │ │ ├── autoUpdate.ts │ │ │ ├── directorySettings.ts │ │ │ ├── musicCache.ts + │ │ │ ├── pluginNotice.ts │ │ │ └── songList.ts │ │ ├── services/ │ │ │ ├── music/ @@ -77,91 +69,10 @@ CeruMuisc/ │ │ │ ├── songList/ │ │ │ │ ├── ManageSongList.ts │ │ │ │ └── PlayListSongs.ts - │ │ │ └── ai-service.ts + │ │ │ ├── ai-service.ts + │ │ │ └── ConfigManager.ts │ │ ├── utils/ │ │ │ ├── musicSdk/ - │ │ │ │ ├── kg/ - │ │ │ │ │ ├── temp/ - │ │ │ │ │ │ ├── musicSearch-new.js - │ │ │ │ │ │ └── songList-new.js - │ │ │ │ │ ├── vendors/ - │ │ │ │ │ │ └── infSign.min.js - │ │ │ │ │ ├── album.js - │ │ │ │ │ ├── api-test.js - │ │ │ │ │ ├── comment.js - │ │ │ │ │ ├── hotSearch.js - │ │ │ │ │ ├── index.js - │ │ │ │ │ ├── leaderboard.js - │ │ │ │ │ ├── lyric.js - │ │ │ │ │ ├── musicInfo.js - │ │ │ │ │ ├── musicSearch.js - │ │ │ │ │ ├── pic.js - │ │ │ │ │ ├── singer.js - │ │ │ │ │ ├── songList.js - │ │ │ │ │ ├── tipSearch.js - │ │ │ │ │ └── util.js - │ │ │ │ ├── kw/ - │ │ │ │ │ ├── album.js - │ │ │ │ │ ├── api-temp.js - │ │ │ │ │ ├── api-test.js - │ │ │ │ │ ├── comment.js - │ │ │ │ │ ├── hotSearch.js - │ │ │ │ │ ├── index.js - │ │ │ │ │ ├── kwdecode.ts - │ │ │ │ │ ├── leaderboard.js - │ │ │ │ │ ├── lyric.js - │ │ │ │ │ ├── musicSearch.js - │ │ │ │ │ ├── pic.js - │ │ │ │ │ ├── songList.js - │ │ │ │ │ ├── tipSearch.js - │ │ │ │ │ └── util.js - │ │ │ │ ├── mg/ - │ │ │ │ │ ├── temp/ - │ │ │ │ │ │ └── leaderboard-old.js - │ │ │ │ │ ├── utils/ - │ │ │ │ │ │ ├── index.js - │ │ │ │ │ │ └── mrc.js - │ │ │ │ │ ├── album.js - │ │ │ │ │ ├── api-test.js - │ │ │ │ │ ├── comment.js - │ │ │ │ │ ├── hotSearch.js - │ │ │ │ │ ├── index.js - │ │ │ │ │ ├── leaderboard.js - │ │ │ │ │ ├── lyric.js - │ │ │ │ │ ├── musicInfo.js - │ │ │ │ │ ├── musicSearch.js - │ │ │ │ │ ├── pic.js - │ │ │ │ │ ├── songId.js - │ │ │ │ │ ├── songList.js - │ │ │ │ │ └── tipSearch.js - │ │ │ │ ├── tx/ - │ │ │ │ │ ├── api-test.js - │ │ │ │ │ ├── comment.js - │ │ │ │ │ ├── hotSearch.js - │ │ │ │ │ ├── index.js - │ │ │ │ │ ├── leaderboard.js - │ │ │ │ │ ├── lyric.js - │ │ │ │ │ ├── musicInfo.js - │ │ │ │ │ ├── musicSearch.js - │ │ │ │ │ ├── singer.js - │ │ │ │ │ ├── songList.js - │ │ │ │ │ └── tipSearch.js - │ │ │ │ ├── wy/ - │ │ │ │ │ ├── utils/ - │ │ │ │ │ │ ├── crypto.js - │ │ │ │ │ │ └── index.js - │ │ │ │ │ ├── api-test.js - │ │ │ │ │ ├── comment.js - │ │ │ │ │ ├── hotSearch.js - │ │ │ │ │ ├── index.js - │ │ │ │ │ ├── leaderboard.js - │ │ │ │ │ ├── lyric.js - │ │ │ │ │ ├── musicDetail.js - │ │ │ │ │ ├── musicInfo.js - │ │ │ │ │ ├── musicSearch.js - │ │ │ │ │ ├── singer.js - │ │ │ │ │ ├── songList.js - │ │ │ │ │ └── tipSearch.js │ │ │ │ ├── api-source-info.ts │ │ │ │ ├── index.js │ │ │ │ ├── options.js @@ -190,6 +101,16 @@ CeruMuisc/ │ │ │ ├── components/ │ │ │ │ ├── AI/ │ │ │ │ │ └── FloatBall.vue + │ │ │ │ ├── ContextMenu/ + │ │ │ │ │ ├── composables.ts + │ │ │ │ │ ├── ContextMenu.vue + │ │ │ │ │ ├── demo.vue + │ │ │ │ │ ├── index.ts + │ │ │ │ │ ├── README.md + │ │ │ │ │ ├── types.ts + │ │ │ │ │ └── utils.ts + │ │ │ │ ├── layout/ + │ │ │ │ │ └── HomeLayout.vue │ │ │ │ ├── Music/ │ │ │ │ │ └── SongVirtualList.vue │ │ │ │ ├── Play/ @@ -200,14 +121,14 @@ CeruMuisc/ │ │ │ │ │ ├── PlaylistDrawer.vue │ │ │ │ │ ├── PlayMusic.vue │ │ │ │ │ └── ShaderBackground.vue - │ │ │ │ ├── Search/ - │ │ │ │ │ └── SearchComponent.vue │ │ │ │ ├── Settings/ │ │ │ │ │ ├── AIFloatBallSettings.vue │ │ │ │ │ ├── DirectorySettings.vue │ │ │ │ │ ├── MusicCache.vue │ │ │ │ │ ├── PlaylistSettings.vue + │ │ │ │ │ ├── plugins.vue │ │ │ │ │ └── UpdateSettings.vue + │ │ │ │ ├── PluginNoticeDialog.vue │ │ │ │ ├── ThemeSelector.vue │ │ │ │ ├── TitleBarControls.vue │ │ │ │ ├── UpdateExample.vue @@ -215,8 +136,6 @@ CeruMuisc/ │ │ │ │ └── Versions.vue │ │ │ ├── composables/ │ │ │ │ └── useAutoUpdate.ts - │ │ │ ├── layout/ - │ │ │ │ └── index.vue │ │ │ ├── router/ │ │ │ │ └── index.ts │ │ │ ├── services/ @@ -255,10 +174,10 @@ CeruMuisc/ │ │ │ │ │ ├── recent.vue │ │ │ │ │ └── search.vue │ │ │ │ ├── settings/ - │ │ │ │ │ ├── index.vue - │ │ │ │ │ └── plugins.vue - │ │ │ │ └── welcome/ - │ │ │ │ └── index.vue + │ │ │ │ │ └── index.vue + │ │ │ │ ├── welcome/ + │ │ │ │ │ └── index.vue + │ │ │ │ └── ThemeDemo.vue │ │ │ ├── App.vue │ │ │ ├── env.d.ts │ │ │ └── main.ts diff --git a/docs/guide/sponsorship.md b/docs/guide/sponsorship.md index d3e2dff..31635c1 100644 --- a/docs/guide/sponsorship.md +++ b/docs/guide/sponsorship.md @@ -8,3 +8,9 @@ | **群友**:🍀 | 5 | | **群友**:涟漪 | 50 | | **作者朋友** | 188 | +| **群友**:我叫阿狸 | 3 | +| RiseSun | 9.9 | +| **b站小友**:光牙阿普斯木兰 | 5 | +| 青禾 | 8.8 | + +据不完全统计 如有疏漏可联系sqj@shiqianjiang.cn \ No newline at end of file diff --git a/docs/guide/update.md b/docs/guide/update.md index 5f2bce0..1b43bf9 100644 --- a/docs/guide/update.md +++ b/docs/guide/update.md @@ -12,5 +12,5 @@ - [x] 软件能不能记住上次打开的窗口大小,每次都要手动拉 - [x] 歌单右键菜单 - [x] 播放列表滚动条适配 -- [ ] 暗色主题 +- [x] 暗色主题 - [x] 歌单页支持修改封面 diff --git a/docs/guide/updateLog.md b/docs/guide/updateLog.md index f69d70e..d734664 100644 --- a/docs/guide/updateLog.md +++ b/docs/guide/updateLog.md @@ -2,7 +2,29 @@ ## 日志 +- ###### 2025-10-3 (v1.3.12) + + 1. 支持暗黑主题 + 2. 调整插件页面ui + +- ###### 2025-9-29 (v1.3.11) + + 1. 新增插件在线导入 + +- ###### 2025-9-28 (v1.3.10) + + 1. 优化播放列表 + 2. 单击播放 + 3. 右键菜单 + 4. 调整播放进度调粗细 + +- ###### 2025-09-27 (v1.3.9) + + 1. debug:flac格式使用ffmpeg + 2. 修复高音质下载失效 + - ###### 2025-9-26 (v1.3.8) + 1. 写入歌曲tag信息 2. 歌曲下载 选择音质 3. 歌单 头部自动压缩 diff --git a/electron-builder.yml b/electron-builder.yml index 263beeb..6ea8fd9 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -81,4 +81,4 @@ publish: provider: generic url: https://update.ceru.shiqianjiang.cn electronDownload: - mirror: https://npmmirror.com/mirrors/electron/ \ No newline at end of file + mirror: https://npmmirror.com/mirrors/electron/ diff --git a/src/renderer/components.d.ts b/src/renderer/components.d.ts index a69e450..3bcc6e1 100644 --- a/src/renderer/components.d.ts +++ b/src/renderer/components.d.ts @@ -37,6 +37,11 @@ declare module 'vue' { TContent: typeof import('tdesign-vue-next')['Content'] TDialog: typeof import('tdesign-vue-next')['Dialog'] TDivider: typeof import('tdesign-vue-next')['Divider'] + TDrawer: typeof import('tdesign-vue-next')['Drawer'] + TDropdown: typeof import('tdesign-vue-next')['Dropdown'] + TEmpty: typeof import('tdesign-vue-next')['Empty'] + TForm: typeof import('tdesign-vue-next')['Form'] + TFormItem: typeof import('tdesign-vue-next')['FormItem'] ThemeSelector: typeof import('./src/components/ThemeSelector.vue')['default'] TIcon: typeof import('tdesign-vue-next')['Icon'] TImage: typeof import('tdesign-vue-next')['Image'] @@ -44,11 +49,16 @@ declare module 'vue' { TitleBarControls: typeof import('./src/components/TitleBarControls.vue')['default'] TLayout: typeof import('tdesign-vue-next')['Layout'] TLoading: typeof import('tdesign-vue-next')['Loading'] + TOption: typeof import('tdesign-vue-next')['Option'] TRadioButton: typeof import('tdesign-vue-next')['RadioButton'] TRadioGroup: typeof import('tdesign-vue-next')['RadioGroup'] + TSelect: typeof import('tdesign-vue-next')['Select'] TSlider: typeof import('tdesign-vue-next')['Slider'] TSwitch: typeof import('tdesign-vue-next')['Switch'] + TTabPanel: typeof import('tdesign-vue-next')['TabPanel'] + TTabs: typeof import('tdesign-vue-next')['Tabs'] TTag: typeof import('tdesign-vue-next')['Tag'] + TTextarea: typeof import('tdesign-vue-next')['Textarea'] TTooltip: typeof import('tdesign-vue-next')['Tooltip'] UpdateExample: typeof import('./src/components/UpdateExample.vue')['default'] UpdateProgress: typeof import('./src/components/UpdateProgress.vue')['default'] diff --git a/src/renderer/src/App.vue b/src/renderer/src/App.vue index 2ebb13f..4a22fa4 100644 --- a/src/renderer/src/App.vue +++ b/src/renderer/src/App.vue @@ -25,6 +25,7 @@ import './assets/theme/cyan.css' onMounted(() => { userInfo.init() + setupSystemThemeListener() loadSavedTheme() // 应用启动后延迟3秒检查更新,避免影响启动速度 @@ -44,24 +45,70 @@ const themes = [ const loadSavedTheme = () => { const savedTheme = localStorage.getItem('selected-theme') + const savedDarkMode = localStorage.getItem('dark-mode') + + let themeName = 'default' + let isDarkMode = false + if (savedTheme && themes.some((t) => t.name === savedTheme)) { - applyTheme(savedTheme) + themeName = savedTheme } + + if (savedDarkMode !== null) { + isDarkMode = savedDarkMode === 'true' + } else { + // 如果没有保存的设置,检测系统偏好 + isDarkMode = detectSystemTheme() + } + + applyTheme(themeName, isDarkMode) } -const applyTheme = (themeName) => { +const applyTheme = (themeName, darkMode = false) => { const documentElement = document.documentElement - // 移除之前的主题 + // 移除之前的主题属性 documentElement.removeAttribute('theme-mode') + documentElement.removeAttribute('data-theme') - // 应用新主题(如果不是默认主题) + // 应用主题色彩 if (themeName !== 'default') { documentElement.setAttribute('theme-mode', themeName) } + // 应用明暗模式 + if (darkMode) { + documentElement.setAttribute('data-theme', 'dark') + } else { + documentElement.setAttribute('data-theme', 'light') + } + // 保存到本地存储 localStorage.setItem('selected-theme', themeName) + localStorage.setItem('dark-mode', darkMode.toString()) +} + +// 检测系统主题偏好 +const detectSystemTheme = () => { + if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { + return true + } + return false +} + +// 监听系统主题变化 +const setupSystemThemeListener = () => { + if (window.matchMedia) { + const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)') + mediaQuery.addEventListener('change', (e) => { + const savedDarkMode = localStorage.getItem('dark-mode') + // 如果用户没有手动设置暗色模式,则跟随系统主题 + if (savedDarkMode === null) { + const savedTheme = localStorage.getItem('selected-theme') || 'default' + applyTheme(savedTheme, e.matches) + } + }) + } } diff --git a/src/renderer/src/assets/base.css b/src/renderer/src/assets/base.css index 48456fc..3e38343 100644 --- a/src/renderer/src/assets/base.css +++ b/src/renderer/src/assets/base.css @@ -60,22 +60,22 @@ body { } &::-webkit-scrollbar-track { - background: #f1f5f9; + background: var(--td-scroll-track-color); border-radius: 0.1875rem; } &::-webkit-scrollbar-thumb { - background: #cbd5e1; + background: var(--td-scrollbar-color); border-radius: 0.1875rem; transition: background-color 0.2s ease; &:hover { - background: #94a3b8; + background: var(--td-scrollbar-hover-color); } } /* Firefox 滚动条样式 */ scrollbar-width: thin; - scrollbar-color: #cbd5e1 #f1f5f9; + scrollbar-color: var(--td-scrollbar-color) var(--td-scroll-track-color); } .t-dialog__mask { backdrop-filter: blur(5px); diff --git a/src/renderer/src/assets/main.css b/src/renderer/src/assets/main.css index 48307f6..cdc30e6 100644 --- a/src/renderer/src/assets/main.css +++ b/src/renderer/src/assets/main.css @@ -1,15 +1,19 @@ -:root, -:root[theme-mode='light'] { - --td-brand-color-1: #e2fae2; - --td-brand-color-2: #c5f4cb; - --td-brand-color-3: #91dca1; - --td-brand-color-4: #55c277; - --td-brand-color-5: #2ba55b; - --td-brand-color-6: #008942; - --td-brand-color-7: #006d33; - --td-brand-color-8: #005426; - --td-brand-color-9: #003c19; - --td-brand-color-10: #00260d; +:root[data-theme='light'], +:root:not([data-theme]) { + --hover-nav-color: #f3f4f6; + --hover-nav-text: #6b7280; + --hover-nav-text-hover: #111827; + + --td-brand-color-1: #ddfbdd; + --td-brand-color-2: #bdf6c3; + --td-brand-color-3: #80df94; + --td-brand-color-4: #03de6d; + --td-brand-color-5: #00a74d; + --td-brand-color-6: #00893e; + --td-brand-color-7: #006d2f; + --td-brand-color-8: #005423; + --td-brand-color-9: #003c16; + --td-brand-color-10: #00260b; --td-brand-color-light: var(--td-brand-color-1); --td-brand-color-focus: var(--td-brand-color-2); --td-brand-color-disabled: var(--td-brand-color-3); @@ -64,16 +68,16 @@ --td-success-color-active: var(--td-success-color-6); --td-success-color-disabled: var(--td-success-color-3); --td-success-color-light: var(--td-success-color-1); - --td-gray-color-1: #f0f4f1; - --td-gray-color-2: #e9efeb; - --td-gray-color-3: #e1eae4; - --td-gray-color-4: #d4dfd8; - --td-gray-color-5: #bdc8c1; - --td-gray-color-6: #9ca8a1; - --td-gray-color-7: #808d86; - --td-gray-color-8: #6d7873; - --td-gray-color-9: #565f5b; - --td-gray-color-10: #454c48; + --td-gray-color-1: #f3f3f3; + --td-gray-color-2: #eee; + --td-gray-color-3: #e7e7e7; + --td-gray-color-4: #dcdcdc; + --td-gray-color-5: #c5c5c5; + --td-gray-color-6: #a6a6a6; + --td-gray-color-7: #8b8b8b; + --td-gray-color-8: #777; + --td-gray-color-9: #5e5e5e; + --td-gray-color-10: #4b4b4b; --td-gray-color-11: #383838; --td-gray-color-12: #2c2c2c; --td-gray-color-13: #242424; @@ -133,21 +137,273 @@ --td-shadow-inset-right: inset 0.5px 0 0 #dcdcdc; --td-shadow-inset-bottom: inset 0 -0.5px 0 #dcdcdc; --td-shadow-inset-left: inset -0.5px 0 0 #dcdcdc; - --td-mask-active: rgba(255, 255, 255, 0.6); + --td-mask-active: rgba(0, 0, 0, 0.6); --td-mask-disabled: rgba(255, 255, 255, 0.6); + + /* 通用颜色变量 - 亮色主题 */ + --theme-bg-primary: #ffffff; + --theme-bg-secondary: #f8f9fa; + --theme-bg-tertiary: #fafafa; + --theme-text-primary: #111827; + --theme-text-secondary: #6b7280; + --theme-text-tertiary: #9ca3af; + --theme-text-muted: #9ca3af; + --theme-text-disabled: #666666; + --theme-border-light: #f3f4f6; + --theme-border-medium: #e5e7eb; + --theme-border-strong: #f3f3f3; + --theme-border: #e5e7eb; + --theme-hover-bg: #f9fafb; + --theme-overlay: rgba(0, 0, 0, 0.7); + --theme-shadow-light: 0 2px 8px rgba(0, 0, 0, 0.06); + --theme-shadow-medium: 0 2px 8px rgba(0, 0, 0, 0.1); + --theme-shadow-hover: 0 8px 25px rgba(0, 0, 0, 0.12), 0 4px 10px rgba(0, 0, 0, 0.08); + --theme-card-bg: #ffffff; + --theme-card-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + --theme-card-shadow-hover: 0 8px 25px rgba(0, 0, 0, 0.15); + --theme-header-bg: #f9fafb; + --theme-badge-bg: #f3f4f6; + --theme-tips-bg: linear-gradient(135deg, #f8fafc, #f1f5f9); + --theme-warning-bg: #fef3c7; + --theme-warning-text: #d97706; + --theme-code-bg: rgba(255, 255, 255, 0.6); + --theme-code-hover-bg: rgba(255, 255, 255, 0.9); + --theme-note-bg: rgba(255, 255, 255, 0.5); + + /* Find 页面专用变量 - 亮色主题 */ + --find-bg-primary: var(--theme-bg-primary); + --find-bg-secondary: var(--theme-bg-secondary); + --find-text-primary: var(--theme-text-primary); + --find-text-secondary: var(--theme-text-secondary); + --find-text-muted: var(--theme-text-muted); + --find-card-bg: var(--theme-bg-primary); + --find-song-count-bg: rgba(156, 163, 175, 0.1); + --find-card-info-bg: rgba(255, 255, 255, 0.95); + --find-card-shadow: var(--theme-shadow-light), 0 1px 4px rgba(0, 0, 0, 0.04); + --find-card-shadow-hover: var(--theme-shadow-hover); + --find-song-bg: var(--theme-bg-primary); + --find-song-hover-bg: var(--theme-hover-bg); + --find-border-color: var(--theme-border-light); + --find-meta-border: rgba(229, 231, 235, 0.5); + + /* HomeLayout 页面专用变量 - 亮色主题 */ + --home-nav-btn-color: #3d4043; + --home-nav-btn-hover: var(--theme-text-primary); + --home-source-selector-hover: var(--theme-border-light); + --home-source-list-bg: var(--theme-bg-primary); + --home-source-list-border: var(--theme-border-medium); + --home-source-list-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1); + --home-source-item-hover: var(--theme-border-light); + --home-scrollbar-track: #f1f5f9; + --home-scrollbar-thumb: #cbd5e1; + --home-scrollbar-thumb-hover: #94a3b8; + --home-scrollbar-color: #cbd5e1 #f1f5f9; + + /* List 页面专用变量 - 亮色主题 */ + --list-bg-primary: var(--theme-bg-tertiary); + --list-content-bg: var(--theme-bg-primary); + --list-header-bg: var(--theme-bg-primary); + --list-header-shadow: var(--theme-shadow-medium); + --list-content-shadow: var(--theme-shadow-light); + --list-title-color: var(--theme-text-primary); + --list-author-color: var(--theme-text-secondary); + --list-stats-color: var(--theme-text-muted); + --list-loading-text: var(--theme-text-disabled); + --list-loading-border: var(--theme-border-strong); + --list-loading-spinner: var(--td-brand-color); + --list-cover-overlay: var(--theme-overlay); + + /* SongVirtualList 组件专用变量 - 亮色主题 */ + --song-list-header-bg: #fafafa; + --song-list-header-border: #e9e9e9; + --song-list-header-text: #999999; + --song-list-content-bg: var(--theme-bg-primary); + --song-list-item-border: #f5f5f5; + --song-list-item-hover: #f5f5f5; + --song-list-item-current: #f0f7ff; + --song-list-item-playing: #e6f7ff; + --song-list-track-number: #999999; + --song-list-title-color: #333333; + --song-list-title-hover: var(--td-brand-color); + --song-list-artist-color: #999999; + --song-list-album-color: #999999; + --song-list-album-hover: var(--td-brand-color); + --song-list-duration-color: #999999; + --song-list-btn-color: #cccccc; + --song-list-btn-hover: var(--td-brand-color); + --song-list-btn-bg-hover: var(--td-brand-color-light); + --song-list-quality-bg: #fff7e6; + --song-list-quality-color: #fa8c16; + + /* Search 页面专用变量 - 亮色主题 */ + --search-bg: var(--theme-bg-tertiary); + --search-title-color: #333333; + --search-keyword-color: var(--td-brand-color); + --search-info-color: #999999; + --search-content-bg: var(--theme-bg-primary); + --search-content-shadow: var(--theme-shadow-light); + --search-empty-title: #333333; + --search-empty-text: #999999; + --search-loading-text: #666666; + --search-loading-border: #f3f3f3; + --search-loading-spinner: var(--td-brand-color); + + /* Recent 页面专用变量 - 亮色主题 */ + --recent-bg: var(--theme-bg-tertiary); + --recent-title-color: #111827; + --recent-subtitle-color: #6b7280; + --recent-section-title: #111827; + --recent-card-bg: var(--theme-bg-primary); + --recent-card-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + --recent-card-shadow-hover: 0 4px 12px rgba(0, 0, 0, 0.15); + --recent-playlist-title: #111827; + --recent-playlist-desc: #6b7280; + --recent-playlist-meta: #9ca3af; + --recent-song-item-border: #f3f4f6; + --recent-song-item-hover: #f9fafb; + --recent-song-index: #6b7280; + --recent-song-title: #111827; + --recent-song-artist: #6b7280; + --recent-song-stats: #6b7280; + --recent-song-duration: #6b7280; + --recent-empty-icon: #d1d5db; + --recent-empty-title: #111827; + --recent-empty-text: #6b7280; + + /* Local 页面专用变量 - 亮色主题 */ + --local-bg: var(--theme-bg-tertiary); + --local-text-primary: var(--theme-text-primary); + --local-text-secondary: var(--theme-text-secondary); + --local-text-tertiary: var(--theme-text-tertiary); + --local-card-bg: var(--theme-card-bg); + --local-card-shadow: var(--theme-card-shadow); + --local-card-shadow-hover: var(--theme-card-shadow-hover); + --local-border: var(--theme-border); + --local-hover-bg: var(--theme-hover-bg); + --local-header-bg: var(--theme-header-bg); + --local-badge-bg: var(--theme-badge-bg); + --local-tips-bg: var(--theme-tips-bg); + --local-warning-bg: var(--theme-warning-bg); + --local-warning-text: var(--theme-warning-text); + --local-code-bg: var(--theme-code-bg); + --local-code-hover-bg: var(--theme-code-hover-bg); + --local-note-bg: var(--theme-note-bg); + + /* Welcome 页面专用变量 - 亮色主题 */ + --welcome-bg: #ffffff; + --welcome-subtitle-color: #666666; + --welcome-loading-text: #888888; + --welcome-progress-bg: #f0f0f0; + --welcome-tag-bg: #b8f1ce; + --welcome-tag-border: #e9ecef; + --welcome-tag-color: #333333; + --welcome-version-color: #9e9e9e; + + /* TitleBarControls 组件专用变量 - 亮色主题 */ + --titlebar-icon-color: #111827; + --titlebar-icon-hover: #111827; + --titlebar-btn-hover-bg: #f3f4f6; + --titlebar-close-hover-bg: #fee2e2; + --titlebar-close-hover-color: #dc2626; + + /* Settings 页面专用变量 - 亮色主题 */ + --settings-main-bg: #f8fafc; + --settings-header-bg: #ffffff; + --settings-sidebar-bg: #ffffff; + --settings-sidebar-border: #e2e8f0; + --settings-nav-hover-bg: #f1f5f9; + --settings-nav-active-bg: var(--td-brand-color-1); + --settings-nav-active-border: var(--td-brand-color-5); + --settings-nav-icon-color: #64748b; + --settings-nav-icon-active: var(--td-brand-color-5); + --settings-nav-label-color: #334155; + --settings-nav-label-active: var(--td-brand-color-6); + --settings-nav-desc-color: #64748b; + --settings-content-bg: #f8fafc; + --settings-group-bg: #ffffff; + --settings-group-border: #e2e8f0; + --settings-group-shadow: rgba(0, 0, 0, 0.1); + --settings-text-primary: #1e293b; + --settings-text-secondary: #64748b; + --settings-preview-bg: #f8fafc; + --settings-preview-border: #e2e8f0; + --settings-mock-titlebar-bg: #f6f6f6; + --settings-mock-titlebar-border: #d1d5db; + --settings-feature-bg: #f8fafc; + --settings-feature-border: #e2e8f0; + --settings-api-tips-bg: #f8fafc; + --settings-api-tips-border: #e2e8f0; + --settings-source-card-bg: #ffffff; + --settings-source-card-border: #e2e8f0; + --settings-source-card-hover-border: var(--td-brand-color-3); + --settings-source-card-active-border: var(--td-brand-color-5); + --settings-source-card-active-bg: var(--td-brand-color-1); + --settings-source-icon-bg: #f1f5f9; + --settings-quality-container-bg: #f8fafc; + --settings-quality-container-border: #e2e8f0; + --settings-status-item-bg: #f8fafc; + --settings-status-item-border: #e2e8f0; + --settings-plugin-prompt-bg: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%); + --settings-plugin-prompt-border: #cbd5e1; + --settings-tech-item-bg: #f8fafc; + --settings-tech-item-border: #e2e8f0; + --settings-developer-item-bg: #f8fafc; + --settings-developer-item-border: #e2e8f0; + --settings-tag-option-bg: #f8fafc; + --settings-tag-option-border: #e2e8f0; + --settings-tag-status-bg: #f8fafc; + --settings-tag-status-border: #e2e8f0; + + /* Plugins 组件专用变量 - 亮色主题 */ + --plugins-bg: var(--theme-bg-tertiary); + --plugins-container-bg: var(--theme-bg-primary); + --plugins-header-bg: var(--theme-bg-primary); + --plugins-text-primary: var(--theme-text-primary); + --plugins-text-secondary: var(--theme-text-secondary); + --plugins-text-muted: var(--theme-text-muted); + --plugins-border: var(--theme-border); + --plugins-card-bg: var(--theme-card-bg); + --plugins-card-shadow: var(--theme-card-shadow); + --plugins-card-shadow-hover: var(--theme-card-shadow-hover); + --plugins-card-selected-bg: #e8f5e8; + --plugins-card-selected-border: #28a745; + --plugins-loading-spinner: var(--td-brand-color); + --plugins-error-color: #dc3545; + --plugins-success-color: #28a745; + --plugins-console-bg: #1e1e1e; + --plugins-console-header-bg: #2d2d2d; + --plugins-console-border: #404040; + --plugins-console-text: #ffffff; + --plugins-console-prompt: var(--td-brand-color); + --plugins-console-path: #8a8a8a; + --plugins-console-time: #666666; + --plugins-console-scrollbar-track: #2d2d2d; + --plugins-console-scrollbar-thumb: #555555; + --plugins-console-scrollbar-thumb-hover: #666666; + --plugins-log-error: #ff6b6b; + --plugins-log-warn: #ffd93d; + --plugins-log-info: #74b9ff; + --plugins-log-debug: #a29bfe; + --plugins-mac-close: #ff5f57; + --plugins-mac-minimize: #ffbd2e; + --plugins-mac-maximize: #28ca42; } -:root[theme-mode='dark'] { - --td-brand-color-1: #2ba55b20; - --td-brand-color-2: #003c19; - --td-brand-color-3: #005426; - --td-brand-color-4: #006d33; - --td-brand-color-5: #008942; - --td-brand-color-6: #2ba55b; - --td-brand-color-7: #4cd47c; - --td-brand-color-8: #91dca1; - --td-brand-color-9: #c5f4cb; - --td-brand-color-10: #e2fae2; +:root[data-theme='dark'] { + --hover-nav-color: #ffffff18; + --hover-nav-text: #a5a5a5; + --hover-nav-text-hover: #f3f4f6; + + --td-brand-color-1: #00a74d20; + --td-brand-color-2: #003c16; + --td-brand-color-3: #005423; + --td-brand-color-4: #006d2f; + --td-brand-color-5: #00893e; + --td-brand-color-6: #00a74d; + --td-brand-color-7: #03de6d; + --td-brand-color-8: #80df94; + --td-brand-color-9: #bdf6c3; + --td-brand-color-10: #ddfbdd; --td-brand-color-light: var(--td-brand-color-1); --td-brand-color-focus: var(--td-brand-color-2); --td-brand-color-disabled: var(--td-brand-color-3); @@ -184,16 +440,16 @@ --td-success-color-8: #80d2b6; --td-success-color-9: #b4e1d3; --td-success-color-10: #deede8; - --td-gray-color-1: #f0f4f1; - --td-gray-color-2: #e9efeb; - --td-gray-color-3: #e1eae4; - --td-gray-color-4: #d4dfd8; - --td-gray-color-5: #bdc8c1; - --td-gray-color-6: #9ca8a1; - --td-gray-color-7: #808d86; - --td-gray-color-8: #6d7873; - --td-gray-color-9: #565f5b; - --td-gray-color-10: #454c48; + --td-gray-color-1: #f3f3f3; + --td-gray-color-2: #eee; + --td-gray-color-3: #e7e7e7; + --td-gray-color-4: #dcdcdc; + --td-gray-color-5: #c5c5c5; + --td-gray-color-6: #a6a6a6; + --td-gray-color-7: #8b8b8b; + --td-gray-color-8: #777; + --td-gray-color-9: #5e5e5e; + --td-gray-color-10: #4b4b4b; --td-gray-color-11: #383838; --td-gray-color-12: #2c2c2c; --td-gray-color-13: #242424; @@ -244,8 +500,259 @@ --td-bg-color-specialcomponent: transparent; --td-border-level-1-color: var(--td-gray-color-11); --td-border-level-2-color: var(--td-gray-color-9); - --td-mask-active: rgba(0, 0, 0, 0.1); + --td-mask-active: rgba(0, 0, 0, 0.4); --td-mask-disabled: rgba(0, 0, 0, 0.6); + + /* 通用颜色变量 - 暗色主题 */ + --theme-bg-primary: #2d2d2d; + --theme-bg-secondary: #1a1a1a; + --theme-bg-tertiary: #1a1a1a; + --theme-text-primary: #ffffff; + --theme-text-secondary: #b3b3b3; + --theme-text-tertiary: #8a8a8a; + --theme-text-muted: #8a8a8a; + --theme-text-disabled: #b3b3b3; + --theme-border-light: #404040; + --theme-border-medium: #404040; + --theme-border-strong: #404040; + --theme-border: #404040; + --theme-hover-bg: #3a3a3a; + --theme-overlay: rgba(0, 0, 0, 0.8); + --theme-shadow-light: 0 2px 8px rgba(0, 0, 0, 0.2); + --theme-shadow-medium: 0 2px 8px rgba(0, 0, 0, 0.3); + --theme-shadow-hover: 0 8px 25px rgba(0, 0, 0, 0.4), 0 4px 10px rgba(0, 0, 0, 0.3); + --theme-card-bg: #2d2d2d; + --theme-card-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); + --theme-card-shadow-hover: 0 8px 25px rgba(0, 0, 0, 0.4); + --theme-header-bg: #2a2a2a; + --theme-badge-bg: #404040; + --theme-tips-bg: linear-gradient(135deg, #2a2a2a, #333333); + --theme-warning-bg: #4a3a2a; + --theme-warning-text: #ffa726; + --theme-code-bg: rgba(255, 255, 255, 0.1); + --theme-code-hover-bg: rgba(255, 255, 255, 0.15); + --theme-note-bg: rgba(255, 255, 255, 0.08); + + /* Find 页面专用变量 - 暗色主题 */ + --find-bg-primary: var(--theme-bg-secondary); + --find-bg-secondary: var(--theme-bg-primary); + --find-text-primary: var(--theme-text-primary); + --find-text-secondary: var(--theme-text-secondary); + --find-text-muted: var(--theme-text-muted); + --find-card-bg: var(--theme-bg-primary); + --find-song-count-bg: rgba(255, 255, 255, 0.1); + --find-card-info-bg: rgba(45, 45, 45, 0.95); + --find-card-shadow: var(--theme-shadow-medium), 0 1px 4px rgba(0, 0, 0, 0.2); + --find-card-shadow-hover: var(--theme-shadow-hover); + --find-song-bg: var(--theme-bg-primary); + --find-song-hover-bg: var(--theme-hover-bg); + --find-border-color: var(--theme-border-light); + --find-meta-border: rgba(64, 64, 64, 0.5); + + /* HomeLayout 页面专用变量 - 暗色主题 */ + --home-nav-btn-color: var(--theme-text-secondary); + --home-nav-btn-hover: var(--theme-text-primary); + --home-source-selector-hover: var(--theme-hover-bg); + --home-source-list-bg: var(--theme-bg-primary); + --home-source-list-border: var(--theme-border-light); + --home-source-list-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.3); + --home-source-item-hover: var(--theme-hover-bg); + --home-scrollbar-track: var(--theme-bg-primary); + --home-scrollbar-thumb: #4a4a4a; + --home-scrollbar-thumb-hover: #5a5a5a; + --home-scrollbar-color: #4a4a4a var(--theme-bg-primary); + + /* List 页面专用变量 - 暗色主题 */ + --list-bg-primary: var(--theme-bg-tertiary); + --list-content-bg: var(--theme-bg-primary); + --list-header-bg: var(--theme-bg-primary); + --list-header-shadow: var(--theme-shadow-medium); + --list-content-shadow: var(--theme-shadow-light); + --list-title-color: var(--theme-text-primary); + --list-author-color: var(--theme-text-secondary); + --list-stats-color: var(--theme-text-muted); + --list-loading-text: var(--theme-text-disabled); + --list-loading-border: var(--theme-border-strong); + --list-loading-spinner: var(--td-brand-color); + --list-cover-overlay: var(--theme-overlay); + + /* SongVirtualList 组件专用变量 - 暗色主题 */ + --song-list-header-bg: #2a2a2a; + --song-list-header-border: #404040; + --song-list-header-text: #8a8a8a; + --song-list-content-bg: var(--theme-bg-primary); + --song-list-item-border: #3a3a3a; + --song-list-item-hover: var(--theme-hover-bg); + --song-list-item-current: #1a3a5a; + --song-list-item-playing: #1a4a6a; + --song-list-track-number: #8a8a8a; + --song-list-title-color: var(--theme-text-primary); + --song-list-title-hover: var(--td-brand-color); + --song-list-artist-color: var(--theme-text-muted); + --song-list-album-color: var(--theme-text-muted); + --song-list-album-hover: var(--td-brand-color); + --song-list-duration-color: var(--theme-text-muted); + --song-list-btn-color: #666666; + --song-list-btn-hover: var(--td-brand-color); + --song-list-btn-bg-hover: var(--td-brand-color-light); + --song-list-quality-bg: #3a2a1a; + --song-list-quality-color: #fa8c16; + + /* Search 页面专用变量 - 暗色主题 */ + --search-bg: var(--theme-bg-tertiary); + --search-title-color: var(--theme-text-primary); + --search-keyword-color: var(--td-brand-color); + --search-info-color: var(--theme-text-muted); + --search-content-bg: var(--theme-bg-primary); + --search-content-shadow: var(--theme-shadow-light); + --search-empty-title: var(--theme-text-primary); + --search-empty-text: var(--theme-text-muted); + --search-loading-text: var(--theme-text-secondary); + --search-loading-border: var(--theme-border-light); + --search-loading-spinner: var(--td-brand-color); + + /* Recent 页面专用变量 - 暗色主题 */ + --recent-bg: var(--theme-bg-tertiary); + --recent-title-color: var(--theme-text-primary); + --recent-subtitle-color: var(--theme-text-secondary); + --recent-section-title: var(--theme-text-primary); + --recent-card-bg: var(--theme-bg-primary); + --recent-card-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); + --recent-card-shadow-hover: 0 4px 12px rgba(0, 0, 0, 0.4); + --recent-playlist-title: var(--theme-text-primary); + --recent-playlist-desc: var(--theme-text-secondary); + --recent-playlist-meta: var(--theme-text-muted); + --recent-song-item-border: var(--theme-border-light); + --recent-song-item-hover: var(--theme-hover-bg); + --recent-song-index: var(--theme-text-secondary); + --recent-song-title: var(--theme-text-primary); + --recent-song-artist: var(--theme-text-secondary); + --recent-song-stats: var(--theme-text-secondary); + --recent-song-duration: var(--theme-text-secondary); + --recent-empty-icon: #666666; + --recent-empty-title: var(--theme-text-primary); + --recent-empty-text: var(--theme-text-secondary); + + /* Local 页面专用变量 - 暗色主题 */ + --local-bg: var(--theme-bg-tertiary); + --local-text-primary: var(--theme-text-primary); + --local-text-secondary: var(--theme-text-secondary); + --local-text-tertiary: var(--theme-text-tertiary); + --local-card-bg: var(--theme-card-bg); + --local-card-shadow: var(--theme-card-shadow); + --local-card-shadow-hover: var(--theme-card-shadow-hover); + --local-border: var(--theme-border); + --local-hover-bg: var(--theme-hover-bg); + --local-header-bg: var(--theme-header-bg); + --local-badge-bg: var(--theme-badge-bg); + --local-tips-bg: var(--theme-tips-bg); + --local-warning-bg: var(--theme-warning-bg); + --local-warning-text: var(--theme-warning-text); + --local-code-bg: var(--theme-code-bg); + --local-code-hover-bg: var(--theme-code-hover-bg); + --local-note-bg: var(--theme-note-bg); + + /* Welcome 页面专用变量 - 暗色主题 */ + --welcome-bg: #1a1a1a; + --welcome-subtitle-color: #999999; + --welcome-loading-text: #aaaaaa; + --welcome-progress-bg: #333333; + --welcome-tag-bg: #2d2d2d; + --welcome-tag-border: #404040; + --welcome-tag-color: #cccccc; + --welcome-version-color: #666666; + + /* TitleBarControls 组件专用变量 - 暗色主题 */ + --titlebar-icon-color: #ffffff; + --titlebar-icon-hover: #ffffff; + --titlebar-btn-hover-bg: #3a3a3a; + --titlebar-close-hover-bg: #4a2a2a; + --titlebar-close-hover-color: #ff6b6b; + + /* Settings 页面专用变量 - 暗色主题 */ + --settings-main-bg: #1a1a1a; + --settings-header-bg: #2d2d2d; + --settings-sidebar-bg: #2d2d2d; + --settings-sidebar-border: #404040; + --settings-nav-hover-bg: #3a3a3a; + --settings-nav-active-bg: var(--td-brand-color-1); + --settings-nav-active-border: var(--td-brand-color-5); + --settings-nav-icon-color: #8a8a8a; + --settings-nav-icon-active: var(--td-brand-color-5); + --settings-nav-label-color: #ffffff; + --settings-nav-label-active: var(--td-brand-color-6); + --settings-nav-desc-color: #8a8a8a; + --settings-content-bg: #1a1a1a; + --settings-group-bg: #2d2d2d; + --settings-group-border: #404040; + --settings-group-shadow: rgba(0, 0, 0, 0.3); + --settings-text-primary: #ffffff; + --settings-text-secondary: #b3b3b3; + --settings-text-tertiary: #8a8a8a; + --settings-footer-bg: #2d2d2d; + --settings-version-bg: #404040; + --settings-preview-bg: #2a2a2a; + --settings-preview-border: #404040; + --settings-mock-titlebar-bg: #333333; + --settings-mock-titlebar-border: #555555; + --settings-feature-bg: #2a2a2a; + --settings-feature-border: #404040; + --settings-api-tips-bg: #2a2a2a; + --settings-api-tips-border: #404040; + --settings-source-card-bg: #2d2d2d; + --settings-source-card-border: #404040; + --settings-source-card-hover-border: var(--td-brand-color-3); + --settings-source-card-active-border: var(--td-brand-color-5); + --settings-source-card-active-bg: var(--td-brand-color-1); + --settings-source-icon-bg: #3a3a3a; + --settings-quality-container-bg: #2a2a2a; + --settings-quality-container-border: #404040; + --settings-status-item-bg: #2a2a2a; + --settings-status-item-border: #404040; + --settings-plugin-prompt-bg: linear-gradient(135deg, #2a2a2a 0%, #333333 100%); + --settings-plugin-prompt-border: #555555; + --settings-tech-item-bg: #2a2a2a; + --settings-tech-item-border: #404040; + --settings-developer-item-bg: #2a2a2a; + --settings-developer-item-border: #404040; + --settings-tag-option-bg: #2a2a2a; + --settings-tag-option-border: #404040; + --settings-tag-status-bg: #2a2a2a; + --settings-tag-status-border: #404040; + + /* Plugins 组件专用变量 - 暗色主题 */ + --plugins-bg: var(--theme-bg-tertiary); + --plugins-container-bg: var(--theme-bg-primary); + --plugins-header-bg: var(--theme-bg-primary); + --plugins-text-primary: var(--theme-text-primary); + --plugins-text-secondary: var(--theme-text-secondary); + --plugins-text-muted: var(--theme-text-muted); + --plugins-border: var(--theme-border); + --plugins-card-bg: var(--theme-card-bg); + --plugins-card-shadow: var(--theme-card-shadow); + --plugins-card-shadow-hover: var(--theme-card-shadow-hover); + --plugins-card-selected-bg: #1a3a1a; + --plugins-card-selected-border: #28a745; + --plugins-loading-spinner: var(--td-brand-color); + --plugins-error-color: #ff6b6b; + --plugins-success-color: #4ade80; + --plugins-console-bg: #0d1117; + --plugins-console-header-bg: #161b22; + --plugins-console-border: #30363d; + --plugins-console-text: #f0f6fc; + --plugins-console-prompt: var(--td-brand-color); + --plugins-console-path: #7d8590; + --plugins-console-time: #6e7681; + --plugins-console-scrollbar-track: #161b22; + --plugins-console-scrollbar-thumb: #30363d; + --plugins-console-scrollbar-thumb-hover: #484f58; + --plugins-log-error: #ff7b72; + --plugins-log-warn: #f0d852; + --plugins-log-info: #79c0ff; + --plugins-log-debug: #d2a8ff; + --plugins-mac-close: #ff5f57; + --plugins-mac-minimize: #ffbd2e; + --plugins-mac-maximize: #28ca42; } :root { diff --git a/src/renderer/src/assets/theme/blue.css b/src/renderer/src/assets/theme/blue.css index 42e4a76..ec9a587 100644 --- a/src/renderer/src/assets/theme/blue.css +++ b/src/renderer/src/assets/theme/blue.css @@ -1,4 +1,5 @@ -:root[theme-mode='blue'] { +:root[theme-mode='blue'], +:root[theme-mode='blue'][data-theme='light'] { --td-brand-color-1: #ecf4ff; --td-brand-color-2: #cde5ff; --td-brand-color-3: #9aceff; @@ -136,7 +137,7 @@ --td-mask-disabled: rgba(255, 255, 255, 0.6); } -:root[theme-mode='dark'] { +:root[theme-mode='blue'][data-theme='dark'] { --td-brand-color-1: #3198e220; --td-brand-color-2: #003355; --td-brand-color-3: #004a77; diff --git a/src/renderer/src/assets/theme/cyan.css b/src/renderer/src/assets/theme/cyan.css index a51927e..1567d1b 100644 --- a/src/renderer/src/assets/theme/cyan.css +++ b/src/renderer/src/assets/theme/cyan.css @@ -1,4 +1,5 @@ -:root[theme-mode='cyan'] { +:root[theme-mode='cyan'][data-theme='light'], +:root[theme-mode='cyan']:not([data-theme]) { --td-brand-color-1: #e3fcf8; --td-brand-color-2: #beefe9; --td-brand-color-3: #86dad1; @@ -136,7 +137,7 @@ --td-mask-disabled: rgba(255, 255, 255, 0.6); } -:root[theme-mode='dark'] { +:root[theme-mode='cyan'][data-theme='dark'] { --td-brand-color-1: #00a59b20; --td-brand-color-2: #003b36; --td-brand-color-3: #00524c; diff --git a/src/renderer/src/assets/theme/orange.css b/src/renderer/src/assets/theme/orange.css index a510ed7..82dbebb 100644 --- a/src/renderer/src/assets/theme/orange.css +++ b/src/renderer/src/assets/theme/orange.css @@ -1,4 +1,5 @@ -:root[theme-mode='orange'] { +:root[theme-mode='orange'][data-theme='light'], +:root[theme-mode='orange']:not([data-theme]) { --td-brand-color-1: #fff1ea; --td-brand-color-2: #ffd9c5; --td-brand-color-3: #ffb991; @@ -136,7 +137,7 @@ --td-mask-disabled: rgba(255, 255, 255, 0.6); } -:root[theme-mode='dark'] { +:root[theme-mode='orange'][data-theme='dark'] { --td-brand-color-1: #e4722820; --td-brand-color-2: #552100; --td-brand-color-3: #753000; diff --git a/src/renderer/src/assets/theme/pink.css b/src/renderer/src/assets/theme/pink.css index 91190b1..c2db67f 100644 --- a/src/renderer/src/assets/theme/pink.css +++ b/src/renderer/src/assets/theme/pink.css @@ -1,4 +1,5 @@ -:root[theme-mode='pink'] { +:root[theme-mode='pink'][data-theme='light'], +:root[theme-mode='pink']:not([data-theme]) { --td-brand-color-1: #fff0f1; --td-brand-color-2: #ffd8dd; --td-brand-color-3: #ffb7c1; @@ -136,7 +137,7 @@ --td-mask-disabled: rgba(255, 255, 255, 0.6); } -:root[theme-mode='dark'] { +:root[theme-mode='pink'][data-theme='dark'] { --td-brand-color-1: #ff547920; --td-brand-color-2: #690021; --td-brand-color-3: #8d1135; diff --git a/src/renderer/src/components/Music/SongVirtualList.vue b/src/renderer/src/components/Music/SongVirtualList.vue index d5569eb..0ef6ae4 100644 --- a/src/renderer/src/components/Music/SongVirtualList.vue +++ b/src/renderer/src/components/Music/SongVirtualList.vue @@ -104,7 +104,7 @@ @@ -456,10 +464,10 @@ onMounted(() => { display: grid; grid-template-columns: 60px 1fr 200px 60px 80px; padding: 8px 20px; - background: #fafafa; - border-bottom: 1px solid #e9e9e9; + background: var(--song-list-header-bg); + border-bottom: 1px solid var(--song-list-header-border); font-size: 12px; - color: #999; + color: var(--song-list-header-text); flex-shrink: 0; height: 40px; box-sizing: border-box; @@ -501,7 +509,7 @@ onMounted(() => { } .virtual-scroll-container { - background: #fff; + background: var(--song-list-content-bg); overflow-y: auto; position: relative; flex: 1; @@ -522,24 +530,32 @@ onMounted(() => { display: grid; grid-template-columns: 60px 1fr 200px 60px 80px; padding: 8px 20px; - border-bottom: 1px solid #f5f5f5; + border-bottom: 1px solid var(--song-list-item-border); cursor: pointer; transition: background-color 0.2s ease; height: 64px; &:hover, &.is-hovered { - background: #f5f5f5; + background: var(--song-list-item-hover); + + .col-title .song-info .song-title { + color: var(--song-list-title-hover); + } + + .col-album .album-name { + color: var(--song-list-album-hover); + } } &.is-current { - background: #f0f7ff; - color: #507daf; + background: var(--song-list-item-current); + color: var(--song-list-btn-hover); } &.is-playing { - background: #e6f7ff; - color: #507daf; + background: var(--song-list-item-playing); + color: var(--song-list-btn-hover); } .col-index { @@ -550,7 +566,7 @@ onMounted(() => { .track-number { font-size: 14px; - color: #999; + color: var(--song-list-track-number); font-variant-numeric: tabular-nums; width: 100%; text-align: center; @@ -560,7 +576,7 @@ onMounted(() => { background: none; border: none; cursor: pointer; - color: #507daf; + color: var(--song-list-btn-hover); font-size: 16px; padding: 8px; border-radius: 50%; @@ -573,8 +589,8 @@ onMounted(() => { font-style: none; &:hover { - background: rgba(80, 125, 175, 0.1); - color: #3a5d8f; + background: var(--song-list-btn-bg-hover); + color: var(--song-list-btn-hover); } i { @@ -616,21 +632,18 @@ onMounted(() => { .song-title { font-size: 14px; - color: #333; + color: var(--song-list-title-color); margin-bottom: 4px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; line-height: 1.2; - - &:hover { - color: #507daf; - } + transition: color 0.2s ease; } .song-artist { font-size: 12px; - color: #999; + color: var(--song-list-artist-color); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; @@ -640,8 +653,8 @@ onMounted(() => { gap: 4px; .quality-tag { - background: #fff7e6; - color: #fa8c16; + background: var(--song-list-quality-bg); + color: var(--song-list-quality-color); padding: 1px 4px; border-radius: 2px; font-size: 10px; @@ -659,16 +672,13 @@ onMounted(() => { .album-name { font-size: 12px; - color: #999; + color: var(--song-list-album-color); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; width: 100%; - - &:hover { - color: #507daf; - cursor: pointer; - } + transition: color 0.2s ease; + cursor: pointer; } } @@ -682,7 +692,7 @@ onMounted(() => { background: none; border: none; cursor: pointer; - color: #ccc; + color: var(--song-list-btn-color); padding: 8px; border-radius: 50%; transition: all 0.2s; @@ -693,8 +703,8 @@ onMounted(() => { justify-content: center; &:hover { - color: #507daf; - background: rgba(80, 125, 175, 0.1); + color: var(--song-list-btn-hover); + background: var(--song-list-btn-bg-hover); } i { @@ -719,7 +729,7 @@ onMounted(() => { .duration { font-size: 12px; - color: #999; + color: var(--song-list-duration-color); font-variant-numeric: tabular-nums; min-width: 35px; text-align: center; @@ -735,7 +745,7 @@ onMounted(() => { background: none; border: none; cursor: pointer; - color: #ccc; + color: var(--song-list-btn-color); padding: 6px; border-radius: 50%; transition: all 0.2s; @@ -746,8 +756,8 @@ onMounted(() => { justify-content: center; &:hover { - color: #507daf; - background: rgba(80, 125, 175, 0.1); + color: var(--song-list-btn-hover); + background: var(--song-list-btn-bg-hover); } i { diff --git a/src/renderer/src/components/Settings/plugins.vue b/src/renderer/src/components/Settings/plugins.vue index 857b508..4f29a3a 100644 --- a/src/renderer/src/components/Settings/plugins.vue +++ b/src/renderer/src/components/Settings/plugins.vue @@ -5,7 +5,7 @@

插件管理

-
+
添加插件 @@ -597,38 +597,62 @@ onMounted(async () => { .page { display: flex; flex-direction: column; - height: 100vh; + // height: 100%; + // max-height: 100vh; + background: var(--plugins-bg); + color: var(--plugins-text-primary); + overflow: hidden; + h2 { font-weight: 600; + color: var(--plugins-text-primary); + margin: 0 0 16px 0; } } + .header { -webkit-app-region: drag; display: flex; align-items: center; - background-color: #fff; + background-color: var(--plugins-header-bg); padding: 1.5rem; position: sticky; z-index: 1000; top: 0; left: 0; right: 0; + border-bottom: 1px solid var(--plugins-border); + flex-shrink: 0; } .plugins-container { flex: 1; - padding: 20px; + padding: 24px; box-sizing: border-box; display: flex; flex-direction: column; - overflow-y: auto; + overflow: hidden; min-height: 0; + background: var(--plugins-bg); +} + +.plugin-actions-hearder { + margin-bottom: 24px; + flex-shrink: 0; + + h2 { + margin-bottom: 16px; + font-size: 24px; + font-weight: 600; + color: var(--plugins-text-primary); + } } .plugin-actions { display: flex; - margin-top: 10px; - margin-bottom: 20px; + + gap: 12px; + margin-top: 16px; } .loading { @@ -636,17 +660,25 @@ onMounted(async () => { flex-direction: column; align-items: center; justify-content: center; - padding: 40px 0; + padding: 60px 0; + background: var(--plugins-container-bg); + border-radius: 12px; + margin: 20px 0; } .spinner { - width: 30px; - height: 30px; - border: 3px solid rgba(0, 0, 0, 0.1); + width: 32px; + height: 32px; + border: 3px solid var(--plugins-border); border-radius: 50%; - border-top-color: var(--color-primary, #007bff); + border-top-color: var(--plugins-loading-spinner); animation: spin 1s ease-in-out infinite; - margin-bottom: 10px; + margin-bottom: 16px; +} + +.loading span { + color: var(--plugins-text-secondary); + font-size: 14px; } .error-state { @@ -654,15 +686,26 @@ onMounted(async () => { flex-direction: column; align-items: center; justify-content: center; - padding: 40px 0; - color: #666; + padding: 60px 0; + color: var(--plugins-text-secondary); + background: var(--plugins-container-bg); + border-radius: 12px; + margin: 20px 0; +} + +.error-state p { + color: var(--plugins-text-primary); + font-size: 16px; + margin: 8px 0; } .error-message { - color: #dc3545; - margin-bottom: 15px; + color: var(--plugins-error-color); + margin-bottom: 20px; text-align: center; max-width: 80%; + font-size: 14px; + line-height: 1.5; } @keyframes spin { @@ -676,103 +719,167 @@ onMounted(async () => { flex-direction: column; align-items: center; justify-content: center; - padding: 40px 0; - color: #666; + padding: 60px 0; + color: var(--plugins-text-secondary); + background: var(--plugins-container-bg); + border-radius: 12px; + margin: 20px 0; +} + +.empty-state p { + color: var(--plugins-text-primary); + font-size: 16px; + margin: 8px 0; } .hint { - font-size: 0.9em; - color: #999; + font-size: 14px; + color: var(--plugins-text-muted); + line-height: 1.5; } .plugin-list { display: flex; flex-direction: column; - gap: 15px; + gap: 16px; flex: 1; - overflow-y: auto; + // overflow-y: auto; + // overflow-x: hidden; min-height: 0; + max-height: 100%; + + /* 自定义滚动条 */ + &::-webkit-scrollbar { + width: 6px; + } + + &::-webkit-scrollbar-track { + background: var(--plugins-bg); + border-radius: 3px; + } + + &::-webkit-scrollbar-thumb { + background: var(--plugins-border); + border-radius: 3px; + + &:hover { + background: var(--plugins-text-muted); + } + } } .plugin-item { display: flex; justify-content: space-between; - align-items: center; - padding: 15px; - border-radius: 8px; - background-color: #fefefe; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); + align-items: flex-start; + padding: 20px; + border-radius: 12px; + background-color: var(--plugins-card-bg); + box-shadow: var(--plugins-card-shadow); transition: all 0.3s ease; border: 2px solid transparent; + position: relative; + + // &:hover { + // box-shadow: var(--plugins-card-shadow-hover); + // transform: translateY(-2px); + // } } .plugin-item.selected { - background-color: #e8f5e8; - border: 2px solid #28a745; + background-color: var(--plugins-card-selected-bg); + border: 2px solid var(--plugins-card-selected-border); + + // &::before { + // content: ''; + // position: absolute; + // top: 0; + // left: 0; + // right: 0; + // height: 3px; + // background: linear-gradient(90deg, var(--plugins-card-selected-border), var(--td-brand-color)); + // border-radius: 12px 12px 0 0; + // } } .plugin-info { flex: 1; + margin-right: 20px; } .plugin-info h3 { - margin: 0 0 5px 0; - font-size: 1.1em; + margin: 0 0 8px 0; + font-size: 18px; + font-weight: 600; display: flex; align-items: center; - gap: 8px; + gap: 12px; + color: var(--plugins-text-primary); + line-height: 1.4; } .version { - font-size: 0.8em; - color: #666; - font-weight: normal; + font-size: 12px; + color: var(--plugins-text-muted); + font-weight: 500; + background: var(--plugins-border); + padding: 2px 8px; + border-radius: 6px; } .current-tag { - background-color: var(--td-brand-color-5); + background: linear-gradient(135deg, var(--td-brand-color-5), var(--td-brand-color-6)); color: white; - padding: 2px 8px; - border-radius: 12px; - font-size: 0.75em; - font-weight: normal; + padding: 4px 12px; + border-radius: 16px; + font-size: 12px; + font-weight: 500; + box-shadow: 0 2px 4px rgba(0, 167, 77, 0.2); } .author { - margin: 0 0 5px 0; - font-size: 0.9em; - color: #666; + margin: 0 0 8px 0; + font-size: 14px; + color: var(--plugins-text-secondary); } .description { - margin: 0 0 8px 0; - font-size: 0.9em; + margin: 0 0 12px 0; + font-size: 14px; + color: var(--plugins-text-secondary); + line-height: 1.5; + max-width: 500px; } .plugin-sources { display: flex; flex-wrap: wrap; - gap: 5px; + gap: 8px; align-items: center; - margin-top: 5px; + margin-top: 8px; } .source-label { - font-size: 0.85em; - color: #666; + font-size: 13px; + color: var(--plugins-text-muted); + font-weight: 500; } .source-tag { - background-color: var(--color-primary, #007bff); + background: linear-gradient(135deg, var(--td-brand-color-4), var(--td-brand-color-5)); color: white; - padding: 2px 8px; + padding: 4px 10px; border-radius: 12px; - font-size: 0.8em; + font-size: 12px; + font-weight: 500; + box-shadow: 0 1px 3px rgba(0, 167, 77, 0.2); } .plugin-actions { display: flex; + flex-direction: column; gap: 8px; + min-width: 120px; } /* 日志弹窗样式 */ @@ -780,15 +887,16 @@ onMounted(async () => { height: 80vh; .t-dialog { - background: #1e1e1e; + background: var(--plugins-console-bg); border-radius: 12px; - box-shadow: 0 20px 60px rgba(0, 0, 0, 0.4); + box-shadow: var(--plugins-dialog-shadow, 0 20px 60px rgba(0, 0, 0, 0.4)); overflow: hidden; + border: 1px solid var(--plugins-console-border); } .t-dialog__header { - background: #2d2d2d; - border-bottom: 1px solid #404040; + background: var(--plugins-console-header-bg); + border-bottom: 1px solid var(--plugins-console-border); padding: 0; border-radius: 12px 12px 0 0; overflow: hidden; @@ -796,12 +904,11 @@ onMounted(async () => { .t-dialog__body { padding: 0; - background: #1e1e1e; - border-left: 2px solid #272727; - border-right: 2px solid #272727; - border-bottom: 2px solid #272727; + background: var(--plugins-console-bg); + border-left: 2px solid var(--plugins-console-border); + border-right: 2px solid var(--plugins-console-border); + border-bottom: 2px solid var(--plugins-console-border); border-radius: 0 0 12px 12px; - // max-height: 600px; overflow: hidden; } } @@ -810,7 +917,10 @@ onMounted(async () => { display: flex; align-items: center; padding: 12px 20px; - background: linear-gradient(135deg, #2d2d2d 0%, #1e1e1e 100%); + background: var( + --plugins-dialog-header-bg, + linear-gradient(135deg, var(--plugins-console-header-bg) 0%, var(--plugins-console-bg) 100%) + ); min-height: 48px; width: 100%; @@ -818,14 +928,14 @@ onMounted(async () => { display: flex; align-items: center; gap: 8px; - color: #ffffff; + color: var(--plugins-console-text); font-weight: 600; font-size: 14px; flex: 1; .iconfont { font-size: 16px; - color: #00d4aa; + color: var(--plugins-console-prompt); } } @@ -836,15 +946,15 @@ onMounted(async () => { :deep(.t-button) { background: rgba(255, 255, 255, 0.1); - border: 1px solid rgba(255, 255, 255, 0.2); - color: #ffffff; + border: 1px solid var(--plugins-console-border); + color: var(--plugins-console-text); font-size: 12px; padding: 4px 12px; height: auto; &:hover { background: rgba(255, 255, 255, 0.2) !important; - border-color: rgba(255, 255, 255, 0.3); + border-color: var(--plugins-console-prompt); } .t-icon { @@ -866,7 +976,7 @@ onMounted(async () => { transition: all 0.2s ease; &.close { - background: #ff5f57; + background: var(--plugins-mac-close); &:hover { background: #ff3b30; @@ -874,7 +984,7 @@ onMounted(async () => { } &.minimize { - background: #ffbd2e; + background: var(--plugins-mac-minimize); &:hover { background: #ff9500; @@ -882,7 +992,7 @@ onMounted(async () => { } &.maximize { - background: #28ca42; + background: var(--plugins-mac-maximize); &:hover { background: #30d158; @@ -893,21 +1003,20 @@ onMounted(async () => { } .console-container { - background: #1e1e1e; - color: #ffffff; + background: var(--plugins-console-bg); + color: var(--plugins-console-text); font-family: 'SF Mono', 'Monaco', 'Inconsolata', 'Fira Code', 'Consolas', monospace; font-size: 13px; line-height: 1.4; height: calc(80vh - 64px - 48px); - // max-height: 500px; min-height: 300px; display: flex; flex-direction: column; } .console-header { - background: #2d2d2d; - border-bottom: 1px solid #404040; + background: var(--plugins-console-header-bg); + border-bottom: 1px solid var(--plugins-console-border); padding: 8px 16px; flex-shrink: 0; @@ -916,17 +1025,18 @@ onMounted(async () => { align-items: center; gap: 12px; font-size: 12px; + .console-prompt { - color: var(--td-brand-color-5); + color: var(--plugins-console-prompt); font-weight: bold; } .console-path { - color: #8a8a8a; + color: var(--plugins-console-path); } .console-time { - color: #666666; + color: var(--plugins-console-time); margin-left: auto; } } @@ -935,9 +1045,9 @@ onMounted(async () => { .console-content { flex: 1; overflow-y: auto; - scrollbar-color: #555555 #2d2d2d; + scrollbar-color: var(--plugins-console-scrollbar-thumb) var(--plugins-console-scrollbar-track); padding: 16px; - background: #1e1e1e; + background: var(--plugins-console-bg); position: relative; &.loading { @@ -952,15 +1062,15 @@ onMounted(async () => { } &::-webkit-scrollbar-track { - background: #2d2d2d; + background: var(--plugins-console-scrollbar-track); } &::-webkit-scrollbar-thumb { - background: #555555; + background: var(--plugins-console-scrollbar-thumb); border-radius: 4px; &:hover { - background: #666666; + background: var(--plugins-console-scrollbar-thumb-hover); } } } @@ -970,13 +1080,13 @@ onMounted(async () => { flex-direction: column; align-items: center; gap: 12px; - color: #8a8a8a; + color: var(--plugins-console-path); .loading-spinner { width: 20px; height: 20px; - border: 2px solid #404040; - border-top: 2px solid #00d4aa; + border: 2px solid var(--plugins-console-border); + border-top: 2px solid var(--plugins-console-prompt); border-radius: 50%; animation: spin 1s linear infinite; } @@ -986,11 +1096,11 @@ onMounted(async () => { display: flex; align-items: center; gap: 8px; - color: #ff6b6b; + color: var(--plugins-log-error); padding: 12px; background: rgba(255, 107, 107, 0.1); border-radius: 6px; - border-left: 4px solid #ff6b6b; + border-left: 4px solid var(--plugins-log-error); .error-icon { font-size: 16px; @@ -1003,7 +1113,7 @@ onMounted(async () => { align-items: center; justify-content: center; gap: 8px; - color: #8a8a8a; + color: var(--plugins-console-path); height: 200px; .empty-icon { @@ -1025,7 +1135,7 @@ onMounted(async () => { } .log-timestamp { - color: #666666; + color: var(--plugins-console-time); font-size: 11px; width: 80px; text-align: center; @@ -1044,47 +1154,47 @@ onMounted(async () => { /* 不同日志级别的颜色 */ &.log-error { .log-content { - color: #ff6b6b; + color: var(--plugins-log-error); } .log-timestamp { - color: #ff6b6b; + color: var(--plugins-log-error); } } &.log-warn { .log-content { - color: #ffd93d; + color: var(--plugins-log-warn); } .log-timestamp { - color: #ffd93d; + color: var(--plugins-log-warn); } } &.log-info { .log-content { - color: #74b9ff; + color: var(--plugins-log-info); } .log-timestamp { - color: #74b9ff; + color: var(--plugins-log-info); } } &.log-debug { .log-content { - color: #a29bfe; + color: var(--plugins-log-debug); } .log-timestamp { - color: #a29bfe; + color: var(--plugins-log-debug); } } &.log-default { .log-content { - color: #ffffff; + color: var(--plugins-console-text); } } } @@ -1102,26 +1212,49 @@ onMounted(async () => { /* 导入方式选择样式 */ .import-method-container { - padding: 10px 0; + padding: 16px 0; } .online-input-container { - margin-top: 15px; + margin-top: 16px; } .hint-text { - font-size: 12px; - color: #666; + font-size: 13px; + color: var(--plugins-text-muted); margin-top: 8px; - line-height: 1.4; + line-height: 1.5; } .local-hint-container { - margin-top: 15px; + margin-top: 16px; + padding: 12px; + background: var(--plugins-border); + border-radius: 8px; } /* 响应式设计 */ @media (max-width: 768px) { + .plugins-container { + padding: 16px; + } + + .plugin-item { + flex-direction: column; + align-items: stretch; + gap: 16px; + + .plugin-info { + margin-right: 0; + } + + .plugin-actions { + flex-direction: row; + justify-content: flex-end; + min-width: auto; + } + } + :deep(.log-dialog) { .t-dialog { width: 95% !important; diff --git a/src/renderer/src/components/ThemeSelector.vue b/src/renderer/src/components/ThemeSelector.vue index bd7f01c..4ab3709 100644 --- a/src/renderer/src/components/ThemeSelector.vue +++ b/src/renderer/src/components/ThemeSelector.vue @@ -1,54 +1,35 @@ + - diff --git a/src/renderer/src/components/TitleBarControls.vue b/src/renderer/src/components/TitleBarControls.vue index 75cb03b..94217fb 100644 --- a/src/renderer/src/components/TitleBarControls.vue +++ b/src/renderer/src/components/TitleBarControls.vue @@ -9,7 +9,7 @@ const props = withDefaults(defineProps(), { showSettings: true, showBack: false, title: '', - color: 'black' + color: 'var(--titlebar-btn-text-color)' }) const Store = LocalUserDetailStore() const { userInfo } = storeToRefs(Store) @@ -202,7 +202,7 @@ const handleBack = (): void => { } &:hover .iconfont { - color: #111827; + color: v-bind(color) !important; } } @@ -222,12 +222,20 @@ const handleBack = (): void => { -webkit-app-region: no-drag; margin-right: 0.5rem; &:hover { - background-color: #f3f4f6; + background-color: var(--titlebar-btn-hover-bg); } } } .title-box { flex: 1; + + p { + margin: 0; + font-size: 0.875rem; + font-weight: 500; + color: var(--settings-text-primary, v-bind(color)); + line-height: 1.2; + } } } @@ -235,7 +243,7 @@ const handleBack = (): void => { margin-right: 0.5rem; &:hover { - background-color: #f3f4f6; + background-color: var(--titlebar-btn-hover-bg); } } @@ -251,23 +259,23 @@ const handleBack = (): void => { } &:hover { - background-color: #f3f4f6; + background-color: var(--titlebar-btn-hover-bg); } } .minimize-btn:hover { - background-color: #f3f4f6; + background-color: var(--titlebar-btn-hover-bg); } .maximize-btn:hover { - background-color: #f3f4f6; + background-color: var(--titlebar-btn-hover-bg); } .close-btn:hover { - background-color: #fee2e2; + background-color: var(--titlebar-close-hover-bg); .iconfont { - color: #dc2626; + color: v-bind(color) !important; } } } diff --git a/src/renderer/src/components/Versions.vue b/src/renderer/src/components/Versions.vue index c72967a..3415eb2 100644 --- a/src/renderer/src/components/Versions.vue +++ b/src/renderer/src/components/Versions.vue @@ -11,3 +11,53 @@ const versions = reactive({ ...window.electron.process.versions })
  • Node v{{ versions.node }}
  • + + diff --git a/src/renderer/src/components/layout/HomeLayout.vue b/src/renderer/src/components/layout/HomeLayout.vue index 5df8baf..a59b3b5 100644 --- a/src/renderer/src/components/layout/HomeLayout.vue +++ b/src/renderer/src/components/layout/HomeLayout.vue @@ -164,7 +164,7 @@ const handleKeyDown = () => {

    - Ceru Music + Ceru Music

    @@ -240,13 +240,13 @@ const handleKeyDown = () => { style="display: flex; align-items: center; justify-content: center" @click="handleSearch" > - +
    - + @@ -305,8 +305,12 @@ const handleKeyDown = () => { .sidebar { width: 15rem; - background-image: linear-gradient(to bottom, var(--td-brand-color-4) -140vh, #ffffff 30vh); - border-right: 0.0625rem solid #e5e7eb; + background-image: linear-gradient( + to bottom, + var(--td-brand-color-4) -140vh, + var(--td-bg-color-container) 30vh + ); + border-right: 0.0625rem solid var(--td-border-level-1-color); flex-shrink: 0; .sidebar-content { @@ -330,18 +334,17 @@ const handleKeyDown = () => { .iconfont { font-size: 1.25rem; - color: white; + color: #fff; } } .app-title { font-weight: 500; font-size: 1.125rem; - color: #111827; + color: var(--td-text-color-primary); span { font-weight: 500; - color: #b8f0cc; } } } @@ -363,22 +366,30 @@ const handleKeyDown = () => { margin-right: 0.75rem; font-size: 1rem; } - + div { + display: none !important; + visibility: hidden; + } &.active { background-color: var(--td-brand-color-4); - color: rgb(255, 255, 255); + color: var(--td-text-color-anti); + &:active { + background-color: var(--td-brand-color-5) !important; + } &:hover { - background-color: var(--td-brand-color-5); + background-color: var(--td-brand-color-5) !important; } } &:not(.active) { - color: #6b7280; + color: var(--hover-nav-text); + + // color: var(--td-text-color-secondary); &:hover { - color: #111827; - background-color: #f3f4f6; + color: var(--hover-nav-text-hover); + background-color: var(--hover-nav-color); } } } @@ -393,7 +404,11 @@ const handleKeyDown = () => { .content { padding: 0; - background-image: linear-gradient(to bottom, var(--td-brand-color-4) -110vh, #ffffff 15vh); + background-image: linear-gradient( + to bottom, + var(--td-brand-color-4) -110vh, + var(--td-bg-color-container) 15vh + ); display: flex; flex: 1; @@ -415,11 +430,11 @@ const handleKeyDown = () => { .iconfont { font-size: 1rem; - color: #3d4043; + color: var(--home-nav-btn-color); } &:hover .iconfont { - color: #111827; + color: var(--home-nav-btn-hover); } } @@ -438,7 +453,7 @@ const handleKeyDown = () => { width: min(18.75rem, 400px); margin-right: 0.5rem; border-radius: 1.25rem !important; - background-color: #fff; + background-color: var(--td-bg-color-container); overflow: visible; position: relative; @@ -458,7 +473,7 @@ const handleKeyDown = () => { transition: background-color 0.2s; &:hover { - background-color: #f3f4f6; + background-color: var(--home-source-selector-hover); } .source-arrow { @@ -489,10 +504,10 @@ const handleKeyDown = () => { top: 100%; left: 0; z-index: 10000000; - background: white; - border: 1px solid #e5e7eb; + background: var(--home-source-list-bg); + border: 1px solid var(--home-source-list-border); border-radius: 0.5rem; - box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1); + box-shadow: var(--home-source-list-shadow); min-width: 10rem; overflow-y: hidden; margin-top: 0.25rem; @@ -534,7 +549,7 @@ const handleKeyDown = () => { } &:hover { - background-color: #f3f4f6; + background-color: var(--home-source-item-hover); } &.active { @@ -568,11 +583,11 @@ const handleKeyDown = () => { .settings-btn { .iconfont { font-size: 1rem; - color: #6b7280; + color: var(--td-text-color-secondary); } &:hover .iconfont { - color: #111827; + color: var(--td-text-color-primary); } } } @@ -591,23 +606,23 @@ const handleKeyDown = () => { } &::-webkit-scrollbar-track { - background: #f1f5f9; + background: var(--home-scrollbar-track); border-radius: 0.1875rem; } &::-webkit-scrollbar-thumb { - background: #cbd5e1; + background: var(--home-scrollbar-thumb); border-radius: 0.1875rem; transition: background-color 0.2s ease; &:hover { - background: #94a3b8; + background: var(--home-scrollbar-thumb-hover); } } /* Firefox 滚动条样式 */ scrollbar-width: thin; - scrollbar-color: #cbd5e1 #f1f5f9; + scrollbar-color: var(--home-scrollbar-color); } } diff --git a/src/renderer/src/views/ThemeDemo.vue b/src/renderer/src/views/ThemeDemo.vue new file mode 100644 index 0000000..7e9a7d2 --- /dev/null +++ b/src/renderer/src/views/ThemeDemo.vue @@ -0,0 +1,368 @@ + + + + + + diff --git a/src/renderer/src/views/music/find.vue b/src/renderer/src/views/music/find.vue index c1737e0..2c97baf 100644 --- a/src/renderer/src/views/music/find.vue +++ b/src/renderer/src/views/music/find.vue @@ -228,14 +228,14 @@ onUnmounted(() => { margin-bottom: 2rem; h2 { - color: #111827; + color: var(--td-text-color-primary); margin-bottom: 0.5rem; font-size: 1.875rem; font-weight: 600; } p { - color: #6b7280; + color: var(--find-text-secondary); font-size: 1rem; } } @@ -244,7 +244,7 @@ onUnmounted(() => { margin-bottom: 3rem; .section-title { - color: #111827; + color: var(--td-text-color-primary); font-size: 1.25rem; font-weight: 600; margin-bottom: 1.5rem; @@ -293,12 +293,10 @@ onUnmounted(() => { .playlist-card { // 卡片样式 - background: #fff; + background: var(--find-card-bg); border-radius: 1rem; overflow: hidden; - box-shadow: - 0 2px 8px rgba(0, 0, 0, 0.06), - 0 1px 4px rgba(0, 0, 0, 0.04); + box-shadow: var(--find-card-shadow); transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); cursor: pointer; position: relative; @@ -306,9 +304,7 @@ onUnmounted(() => { // 现代化悬浮效果 &:hover { transform: translateY(-4px) scale(1.02); - box-shadow: - 0 8px 25px rgba(0, 0, 0, 0.12), - 0 4px 10px rgba(0, 0, 0, 0.08); + box-shadow: var(--find-card-shadow-hover); .playlist-cover::after { opacity: 1; @@ -317,7 +313,7 @@ onUnmounted(() => { .playlist-info { backdrop-filter: blur(8px); background-color: var(--hover-bg-color); - color: #111827; + color: var(--find-text-primary); .playlist-title { color: var(--hover-text-color); } @@ -377,7 +373,7 @@ onUnmounted(() => { .playlist-info { padding: 1.25rem 1rem; position: relative; - background: rgba(255, 255, 255, 0.95); + background: var(--find-card-info-bg); backdrop-filter: blur(4px); transition: all 0.3s ease; @@ -385,7 +381,7 @@ onUnmounted(() => { .playlist-title { font-size: 1rem; font-weight: 600; - color: #1f2937; + color: var(--find-text-primary); margin-bottom: 0.5rem; line-height: 1.4; display: -webkit-box; @@ -398,7 +394,7 @@ onUnmounted(() => { .playlist-desc { font-size: 0.875rem; - color: #6b7280; + color: var(--find-text-secondary); margin-bottom: 0.75rem; line-height: 1.5; display: -webkit-box; @@ -416,13 +412,13 @@ onUnmounted(() => { gap: 0.5rem; margin-top: auto; // 推到底部 padding-top: 0.5rem; - border-top: 1px solid rgba(229, 231, 235, 0.5); + border-top: 1px solid var(--find-meta-border); transition: color 0.3s ease; } .play-count { font-size: 0.75rem; - color: #9ca3af; + color: var(--find-text-muted); display: flex; align-items: center; gap: 0.25rem; @@ -437,9 +433,9 @@ onUnmounted(() => { .song-count { font-size: 0.75rem; - color: #9ca3af; + color: var(--find-text-muted); font-weight: 500; - background: rgba(156, 163, 175, 0.1); + background: var(--find-song-count-bg); padding: 0.125rem 0.5rem; border-radius: 0.375rem; transition: color 0.3s ease; @@ -447,7 +443,7 @@ onUnmounted(() => { .playlist-author { font-size: 0.75rem; - color: #6b7280; + color: var(--find-text-secondary); font-style: italic; margin-top: 0.25rem; opacity: 0.8; @@ -457,17 +453,17 @@ onUnmounted(() => { } .song-list { - background: #fff; + background: var(--find-song-bg); border-radius: 0.75rem; overflow: hidden; - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + box-shadow: var(--td-shadow-1); } .song-item { display: flex; align-items: center; padding: 1rem 1.5rem; - border-bottom: 1px solid #f3f4f6; + border-bottom: 1px solid var(--find-border-color); cursor: pointer; transition: background-color 0.2s ease; @@ -476,14 +472,14 @@ onUnmounted(() => { } &:hover { - background-color: #f9fafb; + background-color: var(--find-song-hover-bg); } .song-index { width: 2rem; text-align: center; font-size: 0.875rem; - color: #6b7280; + color: var(--find-text-secondary); font-weight: 500; } @@ -494,19 +490,19 @@ onUnmounted(() => { .song-title { font-size: 0.875rem; font-weight: 500; - color: #111827; + color: var(--find-text-primary); margin-bottom: 0.25rem; } .song-artist { font-size: 0.75rem; - color: #6b7280; + color: var(--find-text-secondary); } } .song-duration { font-size: 0.75rem; - color: #6b7280; + color: var(--find-text-secondary); margin-right: 1rem; } diff --git a/src/renderer/src/views/music/list.vue b/src/renderer/src/views/music/list.vue index e3e1c1f..eb7fcab 100644 --- a/src/renderer/src/views/music/list.vue +++ b/src/renderer/src/views/music/list.vue @@ -543,8 +543,7 @@ onUnmounted(() => { diff --git a/src/renderer/src/views/music/search.vue b/src/renderer/src/views/music/search.vue index bb02fff..14e186f 100644 --- a/src/renderer/src/views/music/search.vue +++ b/src/renderer/src/views/music/search.vue @@ -218,6 +218,7 @@ const handleScroll = (event: Event) => { diff --git a/website/script.js b/website/script.js index ddcd9f6..d57880f 100644 --- a/website/script.js +++ b/website/script.js @@ -43,7 +43,7 @@ async function getAllReleases() { // Filter and sort releases by version const releases = data - .filter(release => !release.draft && !release.prerelease) + .filter((release) => !release.draft && !release.prerelease) .sort((a, b) => compareVersions(b.tag_name, a.tag_name)) // Cache the data @@ -99,15 +99,15 @@ async function downloadApp(platform) { ) // Use proxy for download if it's a GitHub URL - const finalDownloadUrl = downloadUrl.includes('github.com') ? - `${GITHUB_PROXY}${downloadUrl}` : downloadUrl - + const finalDownloadUrl = downloadUrl.includes('github.com') + ? `${GITHUB_PROXY}${downloadUrl}` + : downloadUrl + // Start download window.open(finalDownloadUrl, '_blank') // Track download trackDownload(platform, release.tag_name, asset ? asset.name : '') - } catch (error) { console.error('Download error:', error) showNotification(`下载失败: ${error.message}`, 'error') @@ -126,8 +126,6 @@ async function downloadApp(platform) { } } - - // Get latest release from GitHub API async function getLatestRelease() { // Check cache first @@ -156,8 +154,6 @@ async function getLatestRelease() { } } - - // Find appropriate download asset based on platform function findDownloadAsset(assets, platform) { if (!assets || !Array.isArray(assets)) { @@ -632,12 +628,10 @@ async function updateVersionInfo() { } } - - // Find asset for platform (helper function) function findAssetForPlatform(assets, platform) { const userArch = detectArchitecture() - + // Filter out unwanted files const filteredAssets = assets.filter((asset) => { const name = asset.name.toLowerCase() @@ -919,22 +913,22 @@ function compareVersions(a, b) { // Remove 'v' prefix if present const versionA = a.replace(/^v/, '') const versionB = b.replace(/^v/, '') - + // Split version numbers into parts - const partsA = versionA.split('.').map(num => parseInt(num, 10)) - const partsB = versionB.split('.').map(num => parseInt(num, 10)) - + const partsA = versionA.split('.').map((num) => parseInt(num, 10)) + const partsB = versionB.split('.').map((num) => parseInt(num, 10)) + // Compare each part const maxLength = Math.max(partsA.length, partsB.length) - + for (let i = 0; i < maxLength; i++) { const partA = partsA[i] || 0 const partB = partsB[i] || 0 - + if (partA > partB) return 1 if (partA < partB) return -1 } - + return 0 }