From 43cb59922ca0e78df22dace498a7d1df4fc36120 Mon Sep 17 00:00:00 2001 From: Zyy Date: Tue, 30 Jun 2026 15:28:34 +0800 Subject: [PATCH] refactor(web): simplify frontend utilities --- web/index.html | 23 ------------- .../{useJsonDownload.ts => useDownload.ts} | 2 +- web/src/directives/loading.ts | 2 +- web/src/main.ts | 4 +-- web/src/stores/modules/ui.ts | 34 ++++++++++++------- .../composables/useAccountMutations.ts | 4 +-- .../dashboard/composables/useDashboard.ts | 6 +++- 7 files changed, 33 insertions(+), 42 deletions(-) rename web/src/composables/{useJsonDownload.ts => useDownload.ts} (94%) diff --git a/web/index.html b/web/index.html index 2076e3544..4b99e07db 100644 --- a/web/index.html +++ b/web/index.html @@ -5,29 +5,6 @@ Codex Proxy RS -
diff --git a/web/src/composables/useJsonDownload.ts b/web/src/composables/useDownload.ts similarity index 94% rename from web/src/composables/useJsonDownload.ts rename to web/src/composables/useDownload.ts index 8685d6abd..3b16e5f24 100644 --- a/web/src/composables/useJsonDownload.ts +++ b/web/src/composables/useDownload.ts @@ -2,7 +2,7 @@ import { useObjectUrl } from '@vueuse/core' import { nextTick, shallowRef } from 'vue' -export function useJsonDownload() { +export function useDownload() { const object = shallowRef(null) const objectUrl = useObjectUrl(object) diff --git a/web/src/directives/loading.ts b/web/src/directives/loading.ts index 0b50e2091..316d47b9f 100644 --- a/web/src/directives/loading.ts +++ b/web/src/directives/loading.ts @@ -137,7 +137,7 @@ function syncLoading(element: LoadingElement, binding: DirectiveBinding = { +export const loading: Directive = { mounted: syncLoading, updated: syncLoading, beforeUnmount: hideLoading, diff --git a/web/src/main.ts b/web/src/main.ts index dd50eb67d..e08835ed0 100644 --- a/web/src/main.ts +++ b/web/src/main.ts @@ -5,8 +5,8 @@ import '@fontsource-variable/jetbrains-mono' import App from './App.vue' import { router } from './router' import { pinia } from './stores' -import { loadingDirective } from './directives/loading' +import { loading } from './directives/loading' import './styles/index.css' -createApp(App).directive('loading', loadingDirective).use(pinia).use(router).mount('#app') +createApp(App).directive('loading', loading).use(pinia).use(router).mount('#app') diff --git a/web/src/stores/modules/ui.ts b/web/src/stores/modules/ui.ts index 9de5bbe8f..340ee258b 100644 --- a/web/src/stores/modules/ui.ts +++ b/web/src/stores/modules/ui.ts @@ -1,9 +1,10 @@ -import { usePreferredDark, usePreferredReducedMotion, useTimeoutFn } from '@vueuse/core' +import { useDark, usePreferredReducedMotion, useTimeoutFn } from '@vueuse/core' import { defineStore } from 'pinia' -import { computed, shallowRef, watch } from 'vue' +import { computed, shallowRef } from 'vue' type ThemeMode = 'system' | 'light' | 'dark' type ThemeName = 'light' | 'dark' +type ColorModeStorageValue = 'auto' | ThemeName type ThemeTransitionOrigin = { x: number; y: number } type ViewTransition = { ready: Promise @@ -20,14 +21,7 @@ export const useUiStore = defineStore( const sidebarCollapsed = shallowRef(false) const themeMode = shallowRef('system') const themeRevision = shallowRef(0) - const prefersDark = usePreferredDark() const preferredMotion = usePreferredReducedMotion() - const systemTheme = computed(() => (prefersDark.value ? 'dark' : 'light')) - - const effectiveTheme = computed(() => - themeMode.value === 'system' ? systemTheme.value : themeMode.value, - ) - let themeApplied = false let themeTransitionOrigin: ThemeTransitionOrigin | undefined let themeTransitionRequested = false @@ -39,6 +33,22 @@ export const useUiStore = defineStore( { immediate: false }, ) + const colorModeStorage = computed({ + get: () => (themeMode.value === 'system' ? 'auto' : themeMode.value), + set: (mode) => { + themeMode.value = mode === 'auto' ? 'system' : mode + }, + }) + + const isDark = useDark({ + storageRef: colorModeStorage, + onChanged: (dark) => { + applyTheme(dark ? 'dark' : 'light') + }, + }) + + const effectiveTheme = computed(() => (isDark.value ? 'dark' : 'light')) + function toggleSidebar() { sidebarCollapsed.value = !sidebarCollapsed.value } @@ -124,7 +134,9 @@ export const useUiStore = defineStore( } function initializeTheme() { - applyTheme(effectiveTheme.value) + if (!themeApplied) { + applyTheme(effectiveTheme.value) + } } function setThemeMode(mode: ThemeMode) { @@ -142,8 +154,6 @@ export const useUiStore = defineStore( themeMode.value = effectiveTheme.value === 'dark' ? 'light' : 'dark' } - watch(effectiveTheme, applyTheme, { immediate: true }) - return { sidebarCollapsed, themeMode, diff --git a/web/src/views/accounts/composables/useAccountMutations.ts b/web/src/views/accounts/composables/useAccountMutations.ts index d96b1fc86..b48560b48 100644 --- a/web/src/views/accounts/composables/useAccountMutations.ts +++ b/web/src/views/accounts/composables/useAccountMutations.ts @@ -14,7 +14,7 @@ import { updateAccount, } from '@/api' import { toast } from '@/components/base/BaseToast' -import { useJsonDownload } from '@/composables/useJsonDownload' +import { useDownload } from '@/composables/useDownload' import { withMinimumDuration } from '@/utils/async' export function useAccountMutations(options: { @@ -24,7 +24,7 @@ export function useAccountMutations(options: { selectedIds: Ref> totalAccounts: Ref }) { - const { downloadJson } = useJsonDownload() + const { downloadJson } = useDownload() const loading = ref(true) const accounts = ref([]) const accountSummary = ref({ diff --git a/web/src/views/dashboard/composables/useDashboard.ts b/web/src/views/dashboard/composables/useDashboard.ts index a4b257b3c..af3e78e9d 100644 --- a/web/src/views/dashboard/composables/useDashboard.ts +++ b/web/src/views/dashboard/composables/useDashboard.ts @@ -239,7 +239,11 @@ export function useDashboard(): any { points.map((point) => point.cachedTokensValue), 'warning', ), - trend: trendState(cache.todayHitRateValue ?? 0, cache.yesterdayHitRateValue ?? 0, 'warning'), + trend: trendState( + cache.todayHitRateValue ?? 0, + cache.yesterdayHitRateValue ?? 0, + 'warning', + ), details: [ { label: '总缓存命中', value: cache.totalHitRate, tone: 'warning' }, {