diff --git a/apps/stage-web/src/composables/theme-color.ts b/apps/stage-web/src/composables/theme-color.ts new file mode 100644 index 000000000..145ecc84e --- /dev/null +++ b/apps/stage-web/src/composables/theme-color.ts @@ -0,0 +1,46 @@ +import Color from 'colorjs.io' + +import { withRetry } from '@moeru/std' +import { useDark } from '@vueuse/core' + +export function themeColorFromPropertyOf(colorFromClass: string, property: string): () => Promise { + return async () => { + const fetchUntilWidgetMounted = withRetry(() => { + const widgets = document.querySelector(colorFromClass) as HTMLDivElement | undefined + if (!widgets) + throw new Error('Widgets element not found') + + return widgets + }, { retry: 10, retryDelay: 1000 }) + + const widgets = await fetchUntilWidgetMounted() + return window.getComputedStyle(widgets).getPropertyValue(property) + } +} + +export function themeColorFromValue(value: string | { light: string, dark: string }): () => Promise { + return async () => { + if (typeof value === 'string') { + return value + } + else { + const dark = useDark() + return dark.value ? value.dark : value.light + } + } +} + +export function useThemeColor(colorFrom: () => string | Promise) { + async function updateThemeColor() { + if (!('document' in globalThis && globalThis.document != null)) + return + if (!('window' in globalThis && globalThis.window != null)) + return + + document.querySelector('meta[name="theme-color"]')?.setAttribute('content', new Color(await colorFrom()).to('srgb').toString({ format: 'hex' })) + } + + return { + updateThemeColor, + } +} diff --git a/apps/stage-web/src/layouts/settings.vue b/apps/stage-web/src/layouts/settings.vue index 836d010c4..ced0136a7 100644 --- a/apps/stage-web/src/layouts/settings.vue +++ b/apps/stage-web/src/layouts/settings.vue @@ -1,14 +1,18 @@