From 9fd8f0005a88e2af4da67066f0740a45643160d3 Mon Sep 17 00:00:00 2001 From: AdingApkgg Date: Fri, 26 Dec 2025 22:32:35 +0800 Subject: [PATCH] Refactor theme management and enhance UI components for improved user experience - Removed the `animejs` dependency and replaced it with a lightweight animation system using the Web Animations API for better performance. - Introduced theme settings in `SettingsModal.vue`, allowing users to select between light, dark, and system themes. - Updated `useUIStore` to manage theme state and apply changes dynamically, enhancing the overall UI consistency. - Improved styling in `VndbPanel.vue` and other components to align with the new theme management system, ensuring a cohesive look and feel across the application. --- package.json | 3 +- pnpm-lock.yaml | 46 +--- src/components/SettingsModal.vue | 78 +++++- src/components/VndbPanel.vue | 6 +- src/composables/useAnime.ts | 411 +++++++++---------------------- src/composables/useProgress.ts | 35 +-- src/stores/ui.ts | 85 +++++-- 7 files changed, 278 insertions(+), 386 deletions(-) diff --git a/package.json b/package.json index e1eb5b6..2989892 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,6 @@ }, "dependencies": { "@fontsource/noto-sans-sc": "^5.2.8", - "animejs": "^4.2.2", "artalk": "^2.9.1", "lucide-vue-next": "^0.562.0", "pinia": "^3.0.4", @@ -35,7 +34,7 @@ "snd-lib": "^1.2.4", "vue": "^3.5.26", "vue-prism-editor": "2.0.0-alpha.2", - "vue-virtual-scroller": "^1.1.2" + "vue-virtual-scroll-list": "^2.3.5" }, "packageManager": "pnpm@10.26.2" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1996c32..acc18e5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,9 +11,6 @@ importers: '@fontsource/noto-sans-sc': specifier: ^5.2.8 version: 5.2.8 - animejs: - specifier: ^4.2.2 - version: 4.2.2 artalk: specifier: ^2.9.1 version: 2.9.1(marked@14.1.4) @@ -35,9 +32,9 @@ importers: vue-prism-editor: specifier: 2.0.0-alpha.2 version: 2.0.0-alpha.2(vue@3.5.26(typescript@5.9.3)) - vue-virtual-scroller: - specifier: ^1.1.2 - version: 1.1.2(vue@3.5.26(typescript@5.9.3)) + vue-virtual-scroll-list: + specifier: ^2.3.5 + version: 2.3.5 devDependencies: '@eslint/js': specifier: ^9.39.2 @@ -674,9 +671,6 @@ packages: alien-signals@3.1.0: resolution: {integrity: sha512-yufC6VpSy8tK3I0lO67pjumo5JvDQVQyr38+3OHqe6CHl1t2VZekKZ7EKKZSqk0cRmE7U7tfZbpXiKNzuc+ckg==} - animejs@4.2.2: - resolution: {integrity: sha512-Ys3RuvLdAeI14fsdKCQy7ytu4057QX6Bb7m4jwmfd6iKmUmLquTwk1ut0e4NtRQgCeq/s2Lv5+oMBjz6c7ZuIg==} - ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} @@ -1146,9 +1140,6 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true - scrollparent@2.1.0: - resolution: {integrity: sha512-bnnvJL28/Rtz/kz2+4wpBjHzWoEzXhVg/TE8BeVGJHUqE8THNIRnDxDWMktwM+qahvlRdvlLdsQfYe+cuqfZeA==} - semver@7.7.3: resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} engines: {node: '>=10'} @@ -1288,30 +1279,20 @@ packages: peerDependencies: eslint: ^8.57.0 || ^9.0.0 - vue-observe-visibility@0.4.6: - resolution: {integrity: sha512-xo0CEVdkjSjhJoDdLSvoZoQrw/H2BlzB5jrCBKGZNXN2zdZgMuZ9BKrxXDjNP2AxlcCoKc8OahI3F3r3JGLv2Q==} - vue-prism-editor@2.0.0-alpha.2: resolution: {integrity: sha512-Gu42ba9nosrE+gJpnAEuEkDMqG9zSUysIR8SdXUw8MQKDjBnnNR9lHC18uOr/ICz7yrA/5c7jHJr9lpElODC7w==} engines: {node: '>=10'} peerDependencies: vue: ^3.0.0 - vue-resize@0.4.5: - resolution: {integrity: sha512-bhP7MlgJQ8TIkZJXAfDf78uJO+mEI3CaLABLjv0WNzr4CcGRGPIAItyWYnP6LsPA4Oq0WE+suidNs6dgpO4RHg==} - peerDependencies: - vue: ^2.3.0 - vue-tsc@3.2.1: resolution: {integrity: sha512-I23Rk8dkQfmcSbxDO0dmg9ioMLjKA1pjlU3Lz6Jfk2pMGu3Uryu9810XkcZH24IzPbhzPCnkKo2rEMRX0skSrw==} hasBin: true peerDependencies: typescript: '>=5.0.0' - vue-virtual-scroller@1.1.2: - resolution: {integrity: sha512-SkUyc7QHCJFB5h1Fya7LxVizlVzOZZuFVipBGHYoTK8dwLs08bIz/tclvRApYhksaJIm/nn51inzO2UjpGJPMQ==} - peerDependencies: - vue: ^2.6.11 + vue-virtual-scroll-list@2.3.5: + resolution: {integrity: sha512-YFK6u5yltqtAOfTBcij/KGAS2SoZvzbNIAf9qTULauPObEp53xj22tDuohrrM2vNkgoD5kejXICIUBt2Q4ZDqQ==} vue@3.5.26: resolution: {integrity: sha512-SJ/NTccVyAoNUJmkM9KUqPcYlY+u8OVL1X5EW9RIs3ch5H2uERxyyIUI4MRxVCSOiEcupX9xNGde1tL9ZKpimA==} @@ -1865,8 +1846,6 @@ snapshots: alien-signals@3.1.0: {} - animejs@4.2.2: {} - ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 @@ -2317,8 +2296,6 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.53.2 fsevents: 2.3.3 - scrollparent@2.1.0: {} - semver@7.7.3: {} shebang-command@2.0.0: @@ -2429,28 +2406,17 @@ snapshots: transitivePeerDependencies: - supports-color - vue-observe-visibility@0.4.6: {} - vue-prism-editor@2.0.0-alpha.2(vue@3.5.26(typescript@5.9.3)): dependencies: vue: 3.5.26(typescript@5.9.3) - vue-resize@0.4.5(vue@3.5.26(typescript@5.9.3)): - dependencies: - vue: 3.5.26(typescript@5.9.3) - vue-tsc@3.2.1(typescript@5.9.3): dependencies: '@volar/typescript': 2.4.27 '@vue/language-core': 3.2.1 typescript: 5.9.3 - vue-virtual-scroller@1.1.2(vue@3.5.26(typescript@5.9.3)): - dependencies: - scrollparent: 2.1.0 - vue: 3.5.26(typescript@5.9.3) - vue-observe-visibility: 0.4.6 - vue-resize: 0.4.5(vue@3.5.26(typescript@5.9.3)) + vue-virtual-scroll-list@2.3.5: {} vue@3.5.26(typescript@5.9.3): dependencies: diff --git a/src/components/SettingsModal.vue b/src/components/SettingsModal.vue index a77247c..3c5d42d 100644 --- a/src/components/SettingsModal.vue +++ b/src/components/SettingsModal.vue @@ -56,6 +56,61 @@
+ +
+
+
+ +
+
+

外观主题

+

选择亮色、暗色或跟随系统

+
+
+ + +
+ +
+
+
- + {{ getApiUrl(option.value) }} @@ -272,7 +327,26 @@ import { Check, Github, X, + Palette, + Sun, + Moon, + Monitor, } from 'lucide-vue-next' +import { useUIStore, type ThemeMode } from '@/stores/ui' + +const uiStore = useUIStore() + +// 主题选项 +const themeOptions = [ + { value: 'light' as ThemeMode, label: '亮色', icon: Sun }, + { value: 'system' as ThemeMode, label: '系统', icon: Monitor }, + { value: 'dark' as ThemeMode, label: '暗色', icon: Moon }, +] + +function handleThemeChange(mode: ThemeMode) { + playToggle() + uiStore.setThemeMode(mode) +} const props = defineProps<{ isOpen: boolean diff --git a/src/components/VndbPanel.vue b/src/components/VndbPanel.vue index 6a6f457..47b5246 100644 --- a/src/components/VndbPanel.vue +++ b/src/components/VndbPanel.vue @@ -38,7 +38,7 @@ class="flex items-center gap-1 px-3 py-1.5 rounded-full text-sm font-medium transition-all" :class="isTranslatingAll ? 'bg-gray-200 dark:bg-slate-700 text-gray-500 dark:text-slate-400 cursor-wait' - : 'text-white bg-gradient-to-r from-violet-500 to-purple-600 shadow-lg shadow-violet-500/25 hover:shadow-xl'" + : 'text-white bg-violet-500 hover:bg-violet-600'" :disabled="isTranslatingAll" @click="handleTranslateAll" > @@ -61,7 +61,7 @@ :href="vndbUrl" target="_blank" rel="noopener noreferrer" - class="flex items-center gap-1 px-3 py-1.5 rounded-full text-sm font-medium text-white bg-gradient-to-r from-[#ff1493] to-[#d946ef] shadow-lg shadow-pink-500/25 hover:shadow-xl transition-shadow" + class="flex items-center gap-1 px-3 py-1.5 rounded-full text-sm font-medium text-white bg-[#ff1493] hover:bg-[#e6007f]" > @@ -488,7 +488,7 @@