diff --git a/packages/client/src/pages/settings/theme.vue b/packages/client/src/pages/settings/theme.vue index 92a6fee7a..d134a092b 100644 --- a/packages/client/src/pages/settings/theme.vue +++ b/packages/client/src/pages/settings/theme.vue @@ -101,7 +101,7 @@ import { ColdDeviceStorage } from '@/store'; import { i18n } from '@/i18n'; import { defaultStore } from '@/store'; import { instance } from '@/instance'; -import { concat } from '@/scripts/array'; +import { concat, uniqueBy } from '@/scripts/array'; import { fetchThemes, getThemes } from '@/theme-store'; import * as symbols from '@/symbols'; @@ -128,7 +128,7 @@ export default defineComponent({ const instanceThemes = []; if (instance.defaultLightTheme != null) instanceThemes.push(JSON5.parse(instance.defaultLightTheme)); if (instance.defaultDarkTheme != null) instanceThemes.push(JSON5.parse(instance.defaultDarkTheme)); - const themes = computed(() => instanceThemes.concat(builtinThemes.concat(installedThemes.value))); + const themes = computed(() => uniqueBy(instanceThemes.concat(builtinThemes.concat(installedThemes.value)), theme => theme.id)); const darkThemes = computed(() => themes.value.filter(t => t.base === 'dark' || t.kind === 'dark')); const lightThemes = computed(() => themes.value.filter(t => t.base === 'light' || t.kind === 'light')); const darkTheme = ColdDeviceStorage.ref('darkTheme'); diff --git a/packages/client/src/scripts/array.ts b/packages/client/src/scripts/array.ts index d63f0475d..29d027de1 100644 --- a/packages/client/src/scripts/array.ts +++ b/packages/client/src/scripts/array.ts @@ -52,6 +52,17 @@ export function unique(xs: T[]): T[] { return [...new Set(xs)]; } +export function uniqueBy(values: TValue[], keySelector: (value: TValue) => TKey): TValue[] { + const map = new Map(); + + for (const value of values) { + const key = keySelector(value); + if (!map.has(key)) map.set(key, value); + } + + return [...map.values()]; +} + export function sum(xs: number[]): number { return xs.reduce((a, b) => a + b, 0); }