diff --git a/components/nav/NavLogo.vue b/components/nav/NavLogo.vue index f541f257..6fc5549d 100644 --- a/components/nav/NavLogo.vue +++ b/components/nav/NavLogo.vue @@ -1,3 +1,6 @@ +<script setup lang="ts"> +</script> + <template> <span shrink-0 aspect="1/1" sm:h-8 xl:h-10 class="rtl-flip"><svg xmlns="http://www.w3.org/2000/svg" w-full diff --git a/components/settings/SettingsThemeColors.vue b/components/settings/SettingsThemeColors.vue index 6caceb10..1fc3c946 100644 --- a/components/settings/SettingsThemeColors.vue +++ b/components/settings/SettingsThemeColors.vue @@ -1,10 +1,42 @@ <script setup lang="ts"> import type { ThemeColors } from '~/composables/settings' +import { THEME_COLORS } from '~/constants' + +const themes = await import('~/constants/themes.json').then((r) => { + const map = new Map<'dark' | 'light', [string, ThemeColors][]>([['dark', []], ['light', []]]) + const themes = r.default as [string, ThemeColors][] + for (const [key, theme] of themes) { + map.get('dark')!.push([key, theme]) + map.get('light')!.push([key, { + ...theme, + '--c-primary': `color-mix(in srgb, ${theme['--c-primary']}, black 25%)`, + }]) + } + return map +}) -const themes = await import('~/constants/themes.json').then(r => r.default) as [string, ThemeColors][] const settings = useUserSettings() -const currentTheme = computed(() => settings.value.themeColors?.['--theme-color-name'] || themes[0][1]['--theme-color-name']) +const media = useMediaQuery('(prefers-color-scheme: dark)') + +const colorMode = useColorMode() + +const useThemes = shallowRef<[string, ThemeColors][]>([]) + +watch(() => colorMode.preference, (cm) => { + const dark = cm === 'dark' || (cm === 'system' && media.value) + const newThemes = dark ? themes.get('dark')! : themes.get('light')! + const key = settings.value.themeColors?.['--theme-color-name'] || THEME_COLORS.defaultTheme + for (const [k, theme] of newThemes) { + if (k === key) { + settings.value.themeColors = theme + break + } + } + useThemes.value = newThemes +}, { immediate: true, flush: 'post' }) + +const currentTheme = computed(() => settings.value.themeColors?.['--theme-color-name'] || THEME_COLORS.defaultTheme) function updateTheme(theme: ThemeColors) { settings.value.themeColors = theme @@ -18,10 +50,11 @@ function updateTheme(theme: ThemeColors) { </h2> <div flex="~ gap4 wrap" p2 role="group" aria-labelledby="interface-tc"> <button - v-for="[key, theme] in themes" :key="key" + v-for="[key, theme] in useThemes" :key="key" :style="{ - 'background': key, - '--local-ring-color': key, + '--rgb-primary': theme['--rgb-primary'], + 'background': theme['--c-primary'], + '--local-ring-color': theme['--c-primary'], }" type="button" :class="currentTheme === theme['--theme-color-name'] ? 'ring-2' : 'scale-90'" diff --git a/constants/index.ts b/constants/index.ts index aff99d1f..2ded6500 100644 --- a/constants/index.ts +++ b/constants/index.ts @@ -31,6 +31,7 @@ export const HANDLED_MASTO_URLS = /^(https?:\/\/)?([\w\-]+\.)+\w+\/(@[@\w\-.]+)( export const NOTIFICATION_FILTER_TYPES: mastodon.v1.NotificationType[] = ['status', 'reblog', 'follow', 'follow_request', 'favourite', 'poll', 'update', 'admin.sign_up', 'admin.report'] export const THEME_COLORS = { + defaultTheme: '#cc7d24', themeDark: '#111111', themeLight: '#fafafa', backgroundDark: '#fafafa',