diff --git a/apps/stage-capacitor/package.json b/apps/stage-capacitor/package.json index 7e8957a95..9fc49037a 100644 --- a/apps/stage-capacitor/package.json +++ b/apps/stage-capacitor/package.json @@ -32,6 +32,7 @@ "@proj-airi/font-xiaolai": "workspace:^", "@proj-airi/i18n": "workspace:^", "@proj-airi/server-sdk": "workspace:^", + "@proj-airi/stage-layouts": "workspace:^", "@proj-airi/stage-ui": "workspace:^", "@proj-airi/stage-ui-three": "workspace:^", "@proj-airi/stage-ui-three-performance-runtime": "workspace:^", diff --git a/apps/stage-capacitor/src/layouts/settings.vue b/apps/stage-capacitor/src/layouts/settings.vue deleted file mode 100644 index 3645f1286..000000000 --- a/apps/stage-capacitor/src/layouts/settings.vue +++ /dev/null @@ -1,157 +0,0 @@ - - - diff --git a/apps/stage-capacitor/src/pages/devtools/background-gradient-blending.vue b/apps/stage-capacitor/src/pages/devtools/background-gradient-blending.vue index d004edf0a..dbe37f6e8 100644 --- a/apps/stage-capacitor/src/pages/devtools/background-gradient-blending.vue +++ b/apps/stage-capacitor/src/pages/devtools/background-gradient-blending.vue @@ -1,11 +1,10 @@ - - diff --git a/apps/stage-tamagotchi/tsconfig.web.json b/apps/stage-tamagotchi/tsconfig.web.json index 5856b3757..dfc56acad 100644 --- a/apps/stage-tamagotchi/tsconfig.web.json +++ b/apps/stage-tamagotchi/tsconfig.web.json @@ -15,6 +15,9 @@ "paths": { "@proj-airi/stage-ui/*": [ "../../packages/stage-ui/src/*" + ], + "@proj-airi/stage-layouts/*": [ + "../../packages/stage-layouts/src/*" ] }, "resolveJsonModule": true, diff --git a/apps/stage-web/package.json b/apps/stage-web/package.json index cdeea2f5a..cc1c58697 100644 --- a/apps/stage-web/package.json +++ b/apps/stage-web/package.json @@ -30,6 +30,7 @@ "@proj-airi/i18n": "workspace:^", "@proj-airi/model-driver-mediapipe": "workspace:^", "@proj-airi/server-sdk": "workspace:^", + "@proj-airi/stage-layouts": "workspace:^", "@proj-airi/stage-ui": "workspace:^", "@proj-airi/stage-ui-three": "workspace:^", "@proj-airi/stage-ui-three-performance-runtime": "workspace:^", diff --git a/apps/stage-web/src/components/Backgrounds/DialogPicker.vue b/apps/stage-web/src/components/Backgrounds/DialogPicker.vue deleted file mode 100644 index c00bd30d0..000000000 --- a/apps/stage-web/src/components/Backgrounds/DialogPicker.vue +++ /dev/null @@ -1,21 +0,0 @@ - - - diff --git a/apps/stage-web/src/components/Backgrounds/Line1.vue b/apps/stage-web/src/components/Backgrounds/Line1.vue deleted file mode 100644 index 2beb911ff..000000000 --- a/apps/stage-web/src/components/Backgrounds/Line1.vue +++ /dev/null @@ -1,16 +0,0 @@ - - - diff --git a/apps/stage-web/src/components/Backgrounds/Provider.vue b/apps/stage-web/src/components/Backgrounds/Provider.vue deleted file mode 100644 index c7615bbae..000000000 --- a/apps/stage-web/src/components/Backgrounds/Provider.vue +++ /dev/null @@ -1,56 +0,0 @@ - - - - - diff --git a/apps/stage-web/src/components/Backgrounds/SakuraPetal.vue b/apps/stage-web/src/components/Backgrounds/SakuraPetal.vue deleted file mode 100644 index 1e1b01237..000000000 --- a/apps/stage-web/src/components/Backgrounds/SakuraPetal.vue +++ /dev/null @@ -1,166 +0,0 @@ - - - - - diff --git a/apps/stage-web/src/components/Backgrounds/TicTacToe.vue b/apps/stage-web/src/components/Backgrounds/TicTacToe.vue deleted file mode 100644 index c05d5e4c4..000000000 --- a/apps/stage-web/src/components/Backgrounds/TicTacToe.vue +++ /dev/null @@ -1,34 +0,0 @@ - - - diff --git a/apps/stage-web/src/components/Backgrounds/default/index.ts b/apps/stage-web/src/components/Backgrounds/default/index.ts deleted file mode 100644 index d393f9ed0..000000000 --- a/apps/stage-web/src/components/Backgrounds/default/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export { default as DefaultBackground } from './index.vue' -export { default as PartAnimatedWave } from './part-animated-wave.vue' -export { default as PatternCross } from './pattern-cross.vue' -export { default as DefaultBackgroundPreview } from './preview.vue' diff --git a/apps/stage-web/src/components/Backgrounds/default/index.vue b/apps/stage-web/src/components/Backgrounds/default/index.vue deleted file mode 100644 index 0adf4b682..000000000 --- a/apps/stage-web/src/components/Backgrounds/default/index.vue +++ /dev/null @@ -1,20 +0,0 @@ - - - diff --git a/apps/stage-web/src/components/Backgrounds/default/part-animated-wave.vue b/apps/stage-web/src/components/Backgrounds/default/part-animated-wave.vue deleted file mode 100644 index b3b7f5647..000000000 --- a/apps/stage-web/src/components/Backgrounds/default/part-animated-wave.vue +++ /dev/null @@ -1,138 +0,0 @@ - - - - - diff --git a/apps/stage-web/src/components/Backgrounds/default/pattern-cross.vue b/apps/stage-web/src/components/Backgrounds/default/pattern-cross.vue deleted file mode 100644 index 4e5850598..000000000 --- a/apps/stage-web/src/components/Backgrounds/default/pattern-cross.vue +++ /dev/null @@ -1,41 +0,0 @@ - - - diff --git a/apps/stage-web/src/components/Backgrounds/default/preview.vue b/apps/stage-web/src/components/Backgrounds/default/preview.vue deleted file mode 100644 index a0f5cca14..000000000 --- a/apps/stage-web/src/components/Backgrounds/default/preview.vue +++ /dev/null @@ -1,20 +0,0 @@ - - - diff --git a/apps/stage-web/src/components/Backgrounds/index.ts b/apps/stage-web/src/components/Backgrounds/index.ts deleted file mode 100644 index 82ec7dcef..000000000 --- a/apps/stage-web/src/components/Backgrounds/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default as BackgroundDialogPicker } from './DialogPicker.vue' -export { default as BackgroundProvider } from './Provider.vue' diff --git a/apps/stage-web/src/components/Layouts/Header.vue b/apps/stage-web/src/components/Layouts/Header.vue deleted file mode 100644 index 479ac351c..000000000 --- a/apps/stage-web/src/components/Layouts/Header.vue +++ /dev/null @@ -1,24 +0,0 @@ - - - diff --git a/apps/stage-web/src/components/Layouts/HeaderLink.vue b/apps/stage-web/src/components/Layouts/HeaderLink.vue deleted file mode 100644 index 430695cd1..000000000 --- a/apps/stage-web/src/components/Layouts/HeaderLink.vue +++ /dev/null @@ -1,32 +0,0 @@ - - - - - diff --git a/apps/stage-web/src/components/Layouts/InteractiveArea.vue b/apps/stage-web/src/components/Layouts/InteractiveArea.vue deleted file mode 100644 index d3d585200..000000000 --- a/apps/stage-web/src/components/Layouts/InteractiveArea.vue +++ /dev/null @@ -1,64 +0,0 @@ - - - - - diff --git a/apps/stage-web/src/components/Layouts/InteractiveArea/Actions/About.vue b/apps/stage-web/src/components/Layouts/InteractiveArea/Actions/About.vue deleted file mode 100644 index 969828253..000000000 --- a/apps/stage-web/src/components/Layouts/InteractiveArea/Actions/About.vue +++ /dev/null @@ -1,23 +0,0 @@ - - - diff --git a/apps/stage-web/src/components/Layouts/InteractiveArea/Actions/ViewControls.vue b/apps/stage-web/src/components/Layouts/InteractiveArea/Actions/ViewControls.vue deleted file mode 100644 index e3ee30932..000000000 --- a/apps/stage-web/src/components/Layouts/InteractiveArea/Actions/ViewControls.vue +++ /dev/null @@ -1,73 +0,0 @@ - - - - - diff --git a/apps/stage-web/src/components/Layouts/MobileHeader.vue b/apps/stage-web/src/components/Layouts/MobileHeader.vue deleted file mode 100644 index 46b106466..000000000 --- a/apps/stage-web/src/components/Layouts/MobileHeader.vue +++ /dev/null @@ -1,11 +0,0 @@ - - - diff --git a/apps/stage-web/src/components/Layouts/MobileHeaderLink.vue b/apps/stage-web/src/components/Layouts/MobileHeaderLink.vue deleted file mode 100644 index b2776f66c..000000000 --- a/apps/stage-web/src/components/Layouts/MobileHeaderLink.vue +++ /dev/null @@ -1,35 +0,0 @@ - - - - - diff --git a/apps/stage-web/src/components/Layouts/MobileInteractiveArea.vue b/apps/stage-web/src/components/Layouts/MobileInteractiveArea.vue deleted file mode 100644 index 39ac71ac0..000000000 --- a/apps/stage-web/src/components/Layouts/MobileInteractiveArea.vue +++ /dev/null @@ -1,280 +0,0 @@ - - - - - diff --git a/apps/stage-web/src/components/Layouts/ViewControls/Inputs.vue b/apps/stage-web/src/components/Layouts/ViewControls/Inputs.vue deleted file mode 100644 index bb7a5e7ff..000000000 --- a/apps/stage-web/src/components/Layouts/ViewControls/Inputs.vue +++ /dev/null @@ -1,205 +0,0 @@ - - - - - diff --git a/apps/stage-web/src/components/Widgets/ChatActionButtons.vue b/apps/stage-web/src/components/Widgets/ChatActionButtons.vue deleted file mode 100644 index b35962681..000000000 --- a/apps/stage-web/src/components/Widgets/ChatActionButtons.vue +++ /dev/null @@ -1,54 +0,0 @@ - - - diff --git a/apps/stage-web/src/components/Widgets/ChatArea.vue b/apps/stage-web/src/components/Widgets/ChatArea.vue deleted file mode 100644 index d0970f674..000000000 --- a/apps/stage-web/src/components/Widgets/ChatArea.vue +++ /dev/null @@ -1,210 +0,0 @@ - - - diff --git a/apps/stage-web/src/components/Widgets/ChatContainer.vue b/apps/stage-web/src/components/Widgets/ChatContainer.vue deleted file mode 100644 index a89207d67..000000000 --- a/apps/stage-web/src/components/Widgets/ChatContainer.vue +++ /dev/null @@ -1,10 +0,0 @@ - diff --git a/apps/stage-web/src/components/Widgets/IndicatorMicVolume.vue b/apps/stage-web/src/components/Widgets/IndicatorMicVolume.vue deleted file mode 100644 index 7fff11675..000000000 --- a/apps/stage-web/src/components/Widgets/IndicatorMicVolume.vue +++ /dev/null @@ -1,77 +0,0 @@ - - - diff --git a/apps/stage-web/src/composables/theme-color.ts b/apps/stage-web/src/composables/theme-color.ts deleted file mode 100644 index 18db8f6bf..000000000 --- a/apps/stage-web/src/composables/theme-color.ts +++ /dev/null @@ -1,193 +0,0 @@ -import type { Ref } from 'vue' - -import type { BackgroundProvider } from '../components/Backgrounds' -import type { BackgroundItem } from '../stores/background' - -import Color from 'colorjs.io' - -import { withRetry } from '@moeru/std' -import { colorFromElement, patchThemeSamplingHtml2CanvasClone } from '@proj-airi/stage-ui/libs' -import { useSettings } from '@proj-airi/stage-ui/stores/settings' -import { useTheme } from '@proj-airi/ui' -import { useDocumentVisibility, useIntervalFn } from '@vueuse/core' -import { storeToRefs } from 'pinia' -import { nextTick, watch } from 'vue' - -import { BackgroundKind } from '../stores/background' - -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 { isDark: dark } = useTheme() - 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, - } -} - -export function useBackgroundThemeColor({ - backgroundSurface, - selectedOption, - sampledColor, -}: { - backgroundSurface: Ref | undefined | null> - selectedOption: Ref - sampledColor: Ref -}) { - const visibility = useDocumentVisibility() - const { themeColorsHueDynamic } = storeToRefs(useSettings()) - - let samplingToken = 0 - - const { isDark } = useTheme() - const waveThemeColor = themeColorFromPropertyOf('.widgets.top-widgets .colored-area', 'background-color') - - const { updateThemeColor } = useThemeColor(() => { - if (selectedOption.value?.kind === BackgroundKind.Wave) { - return waveThemeColor() - } - - return sampledColor.value - }) - - // Keep theme-color reasonably fresh for animated wave backgrounds without doing per-frame work. - const { pause, resume } = useIntervalFn(() => { - if (visibility.value !== 'visible') - return - if (selectedOption.value?.kind === BackgroundKind.Wave && themeColorsHueDynamic) - void updateThemeColor() - }, 250, { immediate: false }) - - watch([() => selectedOption.value?.kind, () => themeColorsHueDynamic], ([kind, dynamic]) => { - if (kind === BackgroundKind.Wave && dynamic) { - void updateThemeColor() - resume() - } - else { - pause() - } - }, { immediate: true }) - - async function waitForBackgroundReady() { - await nextTick() - const image = backgroundSurface.value?.surfaceEl?.querySelector('img') - if (image && !image.complete) { - await new Promise((resolve, reject) => { - image.addEventListener('load', () => resolve(), { once: true }) - image.addEventListener('error', () => reject(new Error('Background image failed to load')), { once: true }) - }) - } - } - - // Exposed for optional manual triggers; also used within syncBackgroundTheme. - async function sampleBackgroundColor() { - const token = ++samplingToken - const optionId = selectedOption.value?.id - if (selectedOption.value?.kind === BackgroundKind.Wave) { - await updateThemeColor() - return - } - - const el = backgroundSurface.value?.surfaceEl - if (!el) - return - - await waitForBackgroundReady() - - const result = await colorFromElement(el, { - mode: 'html2canvas', - html2canvas: { - region: { - x: 0, - y: 0, - width: el.offsetWidth, - height: Math.min(140, el.offsetHeight), - }, - sampleHeight: 20, - sampleStride: 10, - scale: 0.5, - backgroundColor: null, - allowTaint: true, - useCORS: true, - onclone: patchThemeSamplingHtml2CanvasClone, - }, - }) - - const color = result.html2canvas?.average - if (token !== samplingToken) - return - if (optionId && selectedOption.value?.id !== optionId) - return - - if (color) { - sampledColor.value = color - } - } - - async function syncBackgroundTheme() { - if (selectedOption.value?.kind === BackgroundKind.Wave) { - await updateThemeColor() - } - else if (sampledColor.value) { - await updateThemeColor() - } - else { - await sampleBackgroundColor() - } - } - - watch([selectedOption], () => { - syncBackgroundTheme() - }, { immediate: true }) - - watch(sampledColor, () => { - syncBackgroundTheme() - }) - - watch(() => backgroundSurface.value?.surfaceEl, (el) => { - if (el) - syncBackgroundTheme() - }) - - watch(isDark, () => { - syncBackgroundTheme() - }) - - return { - sampledColor, - sampleBackgroundColor, - syncBackgroundTheme, - } -} diff --git a/apps/stage-web/src/layouts/default.vue b/apps/stage-web/src/layouts/default.vue deleted file mode 100644 index e917d47bc..000000000 --- a/apps/stage-web/src/layouts/default.vue +++ /dev/null @@ -1,30 +0,0 @@ - - - diff --git a/apps/stage-web/src/layouts/home.vue b/apps/stage-web/src/layouts/home.vue deleted file mode 100644 index 2b34eac02..000000000 --- a/apps/stage-web/src/layouts/home.vue +++ /dev/null @@ -1,20 +0,0 @@ - - - diff --git a/apps/stage-web/src/layouts/plain.vue b/apps/stage-web/src/layouts/plain.vue deleted file mode 100644 index 7c2aa3f3e..000000000 --- a/apps/stage-web/src/layouts/plain.vue +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/apps/stage-web/src/layouts/stage.vue b/apps/stage-web/src/layouts/stage.vue deleted file mode 100644 index cd46f3ce6..000000000 --- a/apps/stage-web/src/layouts/stage.vue +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/stage-web/src/pages/devtools/background-gradient-blending.vue b/apps/stage-web/src/pages/devtools/background-gradient-blending.vue index d004edf0a..dbe37f6e8 100644 --- a/apps/stage-web/src/pages/devtools/background-gradient-blending.vue +++ b/apps/stage-web/src/pages/devtools/background-gradient-blending.vue @@ -1,11 +1,10 @@