refactor: improve PageHeader behavior

This commit is contained in:
Neko Ayaka
2025-04-25 14:09:07 +08:00
parent ad1cbccaf9
commit 83926d89bf
68 changed files with 626 additions and 196 deletions
@@ -0,0 +1,128 @@
<script setup lang="ts">
import { PageHeader } from '@proj-airi/stage-ui/components'
import { useProvidersStore } from '@proj-airi/stage-ui/stores'
import { storeToRefs } from 'pinia'
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { RouterView, useRoute } from 'vue-router'
import HeaderLink from '../components/Layouts/HeaderLink.vue'
const route = useRoute()
const { t } = useI18n()
const providersStore = useProvidersStore()
const { allProvidersMetadata } = storeToRefs(providersStore)
const routeHeaderMetadataMap = computed(() => {
const map: Record<string, { subtitle?: string, title: string }> = {
'/settings/airi-card': {
subtitle: t('settings.title'),
title: t('settings.pages.card.title'),
},
'/settings/appearance': {
subtitle: t('settings.title'),
title: t('settings.pages.themes.title'),
},
'/settings/memory': {
subtitle: t('settings.title'),
title: t('settings.pages.memory.title'),
},
'/settings/models': {
subtitle: t('settings.title'),
title: t('settings.pages.models.title'),
},
'/settings/modules': {
subtitle: t('settings.title'),
title: t('settings.pages.modules.title'),
},
'/settings/modules/consciousness': {
subtitle: t('settings.title'),
title: t('settings.pages.modules.consciousness.title'),
},
'/settings/modules/speech': {
subtitle: t('settings.title'),
title: t('settings.pages.modules.speech.title'),
},
'/settings/modules/hearing': {
subtitle: t('settings.title'),
title: t('settings.pages.modules.hearing.title'),
},
'/settings/modules/memory-short-term': {
subtitle: t('settings.title'),
title: t('settings.pages.modules.memory-short-term.title'),
},
'/settings/modules/memory-long-term': {
subtitle: t('settings.title'),
title: t('settings.pages.modules.memory-long-term.title'),
},
'/settings/modules/messaging-discord': {
subtitle: t('settings.title'),
title: t('settings.pages.modules.messaging-discord.title'),
},
'/settings/modules/x': {
subtitle: t('settings.title'),
title: t('settings.pages.modules.x.title'),
},
'/settings/modules/gaming-minecraft': {
subtitle: t('settings.title'),
title: t('settings.pages.modules.gaming-minecraft.title'),
},
'/settings/modules/gaming-factorio': {
subtitle: t('settings.title'),
title: t('settings.pages.modules.gaming-factorio.title'),
},
'/settings/providers': {
subtitle: t('settings.title'),
title: t('settings.pages.providers.title'),
},
'/settings/scene': {
subtitle: t('settings.title'),
title: t('settings.pages.scene.title'),
},
'/settings': {
title: t('settings.title'),
},
}
for (const key in allProvidersMetadata.value) {
map[`/settings/providers/${key}`] = {
subtitle: t('settings.title'),
title: t(allProvidersMetadata.value[key]?.nameKey),
}
}
return map
})
// const activeSettingsTutorial = ref('default')
const routeHeaderMetadata = computed(() => routeHeaderMetadataMap.value[route.path])
</script>
<template>
<div
:style="{
paddingBottom: 'env(safe-area-inset-bottom, 0px)',
paddingTop: 'env(safe-area-inset-top, 0px)',
paddingRight: 'env(safe-area-inset-right, 0px)',
paddingLeft: 'env(safe-area-inset-left, 0px)',
}"
>
<!-- Header -->
<div
class="px-0 py-1 md:px-3 md:py-3"
w-full gap-2
bg="$bg-color"
>
<HeaderLink />
</div>
<!-- Content -->
<div class="px-3 py-2 md:px-5 md:py-5" flex="~ col" mx-auto max-w-screen-xl>
<PageHeader
v-if="routeHeaderMetadata"
:title="routeHeaderMetadata.title"
:subtitle="routeHeaderMetadata.subtitle"
/>
<RouterView />
</div>
</div>
</template>
@@ -1,7 +1,7 @@
<script setup lang="ts">
import type { ccv3 } from '@proj-airi/ccc'
import { InputFile, PageHeader } from '@proj-airi/stage-ui/components'
import { InputFile } from '@proj-airi/stage-ui/components'
import { useAiriCardStore } from '@proj-airi/stage-ui/stores'
import { storeToRefs } from 'pinia'
import { computed, ref, watch } from 'vue'
@@ -146,11 +146,6 @@ function getModuleShortName(id: string, module: 'consciousness' | 'voice') {
</script>
<template>
<PageHeader
:title="$t('settings.pages.card.title')"
:subtitle="$t('settings.title')"
/>
<div rounded-xl p-4 flex="~ col gap-4">
<!-- Toolbar with search and filters -->
<div flex="~ row" flex-wrap items-center justify-between gap-4>
@@ -301,6 +296,7 @@ function getModuleShortName(id: string, module: 'consciousness' | 'voice') {
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { PageHeader, Section } from '@proj-airi/stage-ui/components'
import { Section } from '@proj-airi/stage-ui/components'
import { useSettings } from '@proj-airi/stage-ui/stores'
import { useDark } from '@vueuse/core'
import { ref, watch } from 'vue'
@@ -22,11 +22,6 @@ watch(() => [settings.usePageSpecificTransitions, settings.disableTransitions],
</script>
<template>
<PageHeader
:title="$t('settings.pages.themes.title')"
:subtitle="$t('settings.title')"
/>
<Section
v-motion
:title="t('settings.sections.section.general.title')"
@@ -320,6 +315,7 @@ watch(() => [settings.usePageSpecificTransitions, settings.disableTransitions],
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
pageSpecificAvailable: true
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { IconItem, PageHeader } from '@proj-airi/stage-ui/components'
import { IconItem } from '@proj-airi/stage-ui/components'
import { useSettings } from '@proj-airi/stage-ui/stores'
import { computed, nextTick, ref } from 'vue'
import { useI18n } from 'vue-i18n'
@@ -106,7 +106,6 @@ const settings = computed(() => [
</script>
<template>
<PageHeader :title="$t('settings.title')" />
<div flex="~ col gap-4">
<div />
<div flex="~ col gap-4">
@@ -156,6 +155,7 @@ const settings = computed(() => [
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -3,8 +3,6 @@
// import { storeToRefs } from 'pinia'
// import { onMounted } from 'vue'
import { PageHeader } from '@proj-airi/stage-ui/components'
// const { server } = storeToRefs(useServerStore())
// onMounted(() => {
@@ -13,15 +11,11 @@ import { PageHeader } from '@proj-airi/stage-ui/components'
</script>
<template>
<PageHeader
:title="$t('settings.pages.memory.title')"
:subtitle="$t('settings.title')"
/>
<div
v-motion
text="neutral-200/50 dark:neutral-600/20" pointer-events-none
fixed top="[calc(100dvh-20rem)]" bottom-0 right--15 z--1
:initial="{ scale: 0.9, opacity: 0, y: 40 }"
fixed top="[calc(100dvh-15rem)]" bottom-0 right--5 z--1
:initial="{ scale: 0.9, opacity: 0, y: 15 }"
:enter="{ scale: 1, opacity: 1, y: 0 }"
:duration="500"
size-60
@@ -30,3 +24,10 @@ import { PageHeader } from '@proj-airi/stage-ui/components'
<div text="60" i-solar:leaf-bold-duotone />
</div>
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { Live2DCanvas, Live2DModel, PageHeader } from '@proj-airi/stage-ui/components'
import { Live2DCanvas, Live2DModel } from '@proj-airi/stage-ui/components'
import { useElementBounding } from '@vueuse/core'
import { Vibrant } from 'node-vibrant/browser'
import { ref } from 'vue'
@@ -43,10 +43,6 @@ const {
</script>
<template>
<PageHeader
:title="$t('settings.pages.models.title')"
:subtitle="$t('settings.title')"
/>
<div flex>
<div ref="live2dContainerRef" w="50%" h="80vh">
<Live2DCanvas v-slot="{ app }" ref="live2dCanvasRef" :width="width" :height="height">
@@ -84,6 +80,7 @@ const {
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
pageSpecificAvailable: true
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { PageHeader, RadioCardDetailManySelect, RadioCardSimple } from '@proj-airi/stage-ui/components'
import { RadioCardDetailManySelect, RadioCardSimple } from '@proj-airi/stage-ui/components'
import { useConsciousnessStore, useProvidersStore } from '@proj-airi/stage-ui/stores'
import { storeToRefs } from 'pinia'
import { onMounted } from 'vue'
@@ -32,10 +32,6 @@ function updateCustomModelName(value: string) {
</script>
<template>
<PageHeader
:title="$t('settings.pages.modules.consciousness.title')"
:subtitle="$t('settings.pages.modules.title')"
/>
<div bg="neutral-50 dark:[rgba(0,0,0,0.3)]" rounded-xl p-4 flex="~ col gap-4">
<div>
<div flex="~ col gap-4">
@@ -213,6 +209,7 @@ function updateCustomModelName(value: string) {
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { IconStatusItem, PageHeader } from '@proj-airi/stage-ui/components'
import { IconStatusItem } from '@proj-airi/stage-ui/components'
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
@@ -111,10 +111,6 @@ const {
</script>
<template>
<PageHeader
:title="$t('settings.pages.modules.title')"
:subtitle="$t('settings.title')"
/>
<div grid="~ cols-1 sm:cols-2 gap-4">
<IconStatusItem
v-for="(module, index) of modulesList"
@@ -161,6 +157,7 @@ const {
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
pageSpecificAvailable: true
@@ -1,14 +1,16 @@
<script setup lang="ts">
// import { useServerStore } from '@proj-airi/stage-ui/stores'
import { PageHeader } from '@proj-airi/stage-ui/components'
// const serverStore = useServerStore()
</script>
<template>
<PageHeader
:title="$t('settings.pages.modules.memory-long-term.title')"
:subtitle="$t('settings.title')"
/>
<div />
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -1,14 +1,16 @@
<script setup lang="ts">
// import { useServerStore } from '@proj-airi/stage-ui/stores'
import { PageHeader } from '@proj-airi/stage-ui/components'
// const serverStore = useServerStore()
</script>
<template>
<PageHeader
:title="$t('settings.pages.modules.memory-short-term.title')"
:subtitle="$t('settings.title')"
/>
<div />
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -5,7 +5,6 @@ import {
FieldCheckbox,
FieldInput,
FieldRange,
PageHeader,
RadioCardDetailManySelect,
RadioCardSimple,
Skeleton,
@@ -166,10 +165,6 @@ function updateCustomModelName(value: string) {
</script>
<template>
<PageHeader
:title="t('settings.pages.modules.speech.title')"
:subtitle="t('settings.pages.modules.title')"
/>
<div flex="~ col md:row gap-6">
<div bg="neutral-100 dark:[rgba(0,0,0,0.3)]" rounded-xl p-4 flex="~ col gap-4" class="w-full md:w-[40%]">
<div>
@@ -517,6 +512,7 @@ function updateCustomModelName(value: string) {
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -152,3 +152,10 @@ watch(providers, async () => {
</template>
</SpeechProviderSettings>
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -117,3 +117,10 @@ function handleResetSettings() {
</ProviderSettingsContainer>
</ProviderSettingsLayout>
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -97,3 +97,10 @@ function handleResetSettings() {
</ProviderSettingsContainer>
</ProviderSettingsLayout>
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -98,3 +98,10 @@ function handleResetSettings() {
</ProviderSettingsContainer>
</ProviderSettingsLayout>
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -215,3 +215,10 @@ watch(providers, async () => {
</template>
</SpeechProviderSettings>
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -98,3 +98,10 @@ function handleResetSettings() {
</ProviderSettingsContainer>
</ProviderSettingsLayout>
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -98,3 +98,10 @@ function handleResetSettings() {
</ProviderSettingsContainer>
</ProviderSettingsLayout>
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -102,3 +102,10 @@ function handleResetSettings() {
</ProviderSettingsContainer>
</ProviderSettingsLayout>
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { IconStatusItem, PageHeader } from '@proj-airi/stage-ui/components'
import { IconStatusItem } from '@proj-airi/stage-ui/components'
import { useProvidersStore } from '@proj-airi/stage-ui/stores'
import { storeToRefs } from 'pinia'
@@ -16,10 +16,6 @@ const {
</script>
<template>
<PageHeader
:title="$t('settings.pages.providers.title')"
:subtitle="$t('settings.title')"
/>
<div grid="~ cols-2 gap-4">
<IconStatusItem
v-for="(provider, index) of allProvidersMetadata"
@@ -66,6 +62,7 @@ const {
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
pageSpecificAvailable: true
@@ -171,3 +171,10 @@ async function handleGenerateSpeech(input: string, voiceId: string, useSSML: boo
</template>
</SpeechProviderSettings>
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -98,3 +98,10 @@ function handleResetSettings() {
</ProviderSettingsContainer>
</ProviderSettingsLayout>
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -98,3 +98,10 @@ function handleResetSettings() {
</ProviderSettingsContainer>
</ProviderSettingsLayout>
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -98,3 +98,10 @@ function handleResetSettings() {
</ProviderSettingsContainer>
</ProviderSettingsLayout>
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -119,3 +119,10 @@ watch(headers, (headers) => {
</ProviderSettingsContainer>
</ProviderSettingsLayout>
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -102,3 +102,10 @@ function handleResetSettings() {
</ProviderSettingsContainer>
</ProviderSettingsLayout>
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -97,3 +97,10 @@ function handleResetSettings() {
</ProviderSettingsContainer>
</ProviderSettingsLayout>
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -98,3 +98,10 @@ function handleResetSettings() {
</ProviderSettingsContainer>
</ProviderSettingsLayout>
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -142,3 +142,10 @@ watch([providers, appId], async () => {
</template>
</SpeechProviderSettings>
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -98,3 +98,10 @@ function handleResetSettings() {
</ProviderSettingsContainer>
</ProviderSettingsLayout>
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -1,6 +1,4 @@
<script setup lang="ts">
import { PageHeader } from '@proj-airi/stage-ui/components'
import { useIconAnimation } from '../../../composables/useIconAnimation'
const {
@@ -11,10 +9,6 @@ const {
</script>
<template>
<PageHeader
:title="$t('settings.pages.scene.title')"
:subtitle="$t('settings.title')"
/>
<div>
Scene
</div>
@@ -46,6 +40,7 @@ const {
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
pageSpecificAvailable: true
@@ -1,39 +0,0 @@
<script setup lang="ts">
import { useRouter } from 'vue-router'
defineProps<{
title: string
subtitle?: string
}>()
const router = useRouter()
</script>
<template>
<div
v-motion
:initial="{ opacity: 0, x: 10 }"
:enter="{ opacity: 1, x: 0 }"
:duration="250"
:style="{
top: 'env(safe-area-inset-top, 0px)',
right: 'env(safe-area-inset-right, 0px)',
left: 'env(safe-area-inset-left, 0px)',
}"
sticky inset-x-0 top-0 z-99 mb-4 w-full py-10
flex="~ row items-center gap-2"
bg="$bg-color"
>
<button @click="router.back()">
<div i-solar:alt-arrow-left-line-duotone text-2xl />
</button>
<h1 relative>
<div v-if="subtitle" absolute left-0 top-0 translate-y="[-80%]">
<span text="neutral-300 dark:neutral-500" text-nowrap>{{ subtitle }}</span>
</div>
<div text-nowrap text-3xl font-semibold>
{{ title }}
</div>
</h1>
</div>
</template>
+128
View File
@@ -0,0 +1,128 @@
<script setup lang="ts">
import { PageHeader } from '@proj-airi/stage-ui/components'
import { useProvidersStore } from '@proj-airi/stage-ui/stores'
import { storeToRefs } from 'pinia'
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { RouterView, useRoute } from 'vue-router'
import HeaderLink from '../components/Layouts/HeaderLink.vue'
const route = useRoute()
const { t } = useI18n()
const providersStore = useProvidersStore()
const { allProvidersMetadata } = storeToRefs(providersStore)
const routeHeaderMetadataMap = computed(() => {
const map: Record<string, { subtitle?: string, title: string }> = {
'/settings/airi-card': {
subtitle: t('settings.title'),
title: t('settings.pages.card.title'),
},
'/settings/appearance': {
subtitle: t('settings.title'),
title: t('settings.pages.themes.title'),
},
'/settings/memory': {
subtitle: t('settings.title'),
title: t('settings.pages.memory.title'),
},
'/settings/models': {
subtitle: t('settings.title'),
title: t('settings.pages.models.title'),
},
'/settings/modules': {
subtitle: t('settings.title'),
title: t('settings.pages.modules.title'),
},
'/settings/modules/consciousness': {
subtitle: t('settings.title'),
title: t('settings.pages.modules.consciousness.title'),
},
'/settings/modules/speech': {
subtitle: t('settings.title'),
title: t('settings.pages.modules.speech.title'),
},
'/settings/modules/hearing': {
subtitle: t('settings.title'),
title: t('settings.pages.modules.hearing.title'),
},
'/settings/modules/memory-short-term': {
subtitle: t('settings.title'),
title: t('settings.pages.modules.memory-short-term.title'),
},
'/settings/modules/memory-long-term': {
subtitle: t('settings.title'),
title: t('settings.pages.modules.memory-long-term.title'),
},
'/settings/modules/messaging-discord': {
subtitle: t('settings.title'),
title: t('settings.pages.modules.messaging-discord.title'),
},
'/settings/modules/x': {
subtitle: t('settings.title'),
title: t('settings.pages.modules.x.title'),
},
'/settings/modules/gaming-minecraft': {
subtitle: t('settings.title'),
title: t('settings.pages.modules.gaming-minecraft.title'),
},
'/settings/modules/gaming-factorio': {
subtitle: t('settings.title'),
title: t('settings.pages.modules.gaming-factorio.title'),
},
'/settings/providers': {
subtitle: t('settings.title'),
title: t('settings.pages.providers.title'),
},
'/settings/scene': {
subtitle: t('settings.title'),
title: t('settings.pages.scene.title'),
},
'/settings': {
title: t('settings.title'),
},
}
for (const key in allProvidersMetadata.value) {
map[`/settings/providers/${key}`] = {
subtitle: t('settings.title'),
title: t(allProvidersMetadata.value[key]?.nameKey),
}
}
return map
})
// const activeSettingsTutorial = ref('default')
const routeHeaderMetadata = computed(() => routeHeaderMetadataMap.value[route.path])
</script>
<template>
<div
:style="{
paddingBottom: 'env(safe-area-inset-bottom, 0px)',
paddingTop: 'env(safe-area-inset-top, 0px)',
paddingRight: 'env(safe-area-inset-right, 0px)',
paddingLeft: 'env(safe-area-inset-left, 0px)',
}"
>
<!-- Header -->
<div
class="px-0 py-1 md:px-3 md:py-3"
w-full gap-2
bg="$bg-color"
>
<HeaderLink />
</div>
<!-- Content -->
<div class="px-3 py-2 md:px-5 md:py-5" flex="~ col" mx-auto max-w-screen-xl>
<PageHeader
v-if="routeHeaderMetadata"
:title="routeHeaderMetadata.title"
:subtitle="routeHeaderMetadata.subtitle"
/>
<RouterView />
</div>
</div>
</template>
@@ -1,7 +1,7 @@
<script setup lang="ts">
import type { ccv3 } from '@proj-airi/ccc'
import { InputFile, PageHeader } from '@proj-airi/stage-ui/components'
import { InputFile } from '@proj-airi/stage-ui/components'
import { useAiriCardStore } from '@proj-airi/stage-ui/stores'
import { storeToRefs } from 'pinia'
import { computed, ref, watch } from 'vue'
@@ -146,11 +146,6 @@ function getModuleShortName(id: string, module: 'consciousness' | 'voice') {
</script>
<template>
<PageHeader
:title="$t('settings.pages.card.title')"
:subtitle="$t('settings.title')"
/>
<div rounded-xl p-4 flex="~ col gap-4">
<!-- Toolbar with search and filters -->
<div flex="~ row" flex-wrap items-center justify-between gap-4>
@@ -301,6 +296,7 @@ function getModuleShortName(id: string, module: 'consciousness' | 'voice') {
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { PageHeader, Section } from '@proj-airi/stage-ui/components'
import { Section } from '@proj-airi/stage-ui/components'
import { useSettings } from '@proj-airi/stage-ui/stores'
import { useDark } from '@vueuse/core'
import { ref, watch } from 'vue'
@@ -22,11 +22,6 @@ watch(() => [settings.usePageSpecificTransitions, settings.disableTransitions],
</script>
<template>
<PageHeader
:title="$t('settings.pages.themes.title')"
:subtitle="$t('settings.title')"
/>
<Section
v-motion
:title="t('settings.sections.section.general.title')"
@@ -320,6 +315,7 @@ watch(() => [settings.usePageSpecificTransitions, settings.disableTransitions],
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
pageSpecificAvailable: true
+2 -2
View File
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { IconItem, PageHeader } from '@proj-airi/stage-ui/components'
import { IconItem } from '@proj-airi/stage-ui/components'
import { useSettings } from '@proj-airi/stage-ui/stores'
import { computed, nextTick, ref } from 'vue'
import { useI18n } from 'vue-i18n'
@@ -106,7 +106,6 @@ const settings = computed(() => [
</script>
<template>
<PageHeader :title="$t('settings.title')" />
<div flex="~ col gap-4">
<div />
<div flex="~ col gap-4">
@@ -156,6 +155,7 @@ const settings = computed(() => [
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -3,8 +3,6 @@
// import { storeToRefs } from 'pinia'
// import { onMounted } from 'vue'
import { PageHeader } from '@proj-airi/stage-ui/components'
// const { server } = storeToRefs(useServerStore())
// onMounted(() => {
@@ -13,15 +11,11 @@ import { PageHeader } from '@proj-airi/stage-ui/components'
</script>
<template>
<PageHeader
:title="$t('settings.pages.memory.title')"
:subtitle="$t('settings.title')"
/>
<div
v-motion
text="neutral-200/50 dark:neutral-600/20" pointer-events-none
fixed top="[calc(100dvh-20rem)]" bottom-0 right--15 z--1
:initial="{ scale: 0.9, opacity: 0, y: 40 }"
fixed top="[calc(100dvh-15rem)]" bottom-0 right--5 z--1
:initial="{ scale: 0.9, opacity: 0, y: 15 }"
:enter="{ scale: 1, opacity: 1, y: 0 }"
:duration="500"
size-60
@@ -30,3 +24,10 @@ import { PageHeader } from '@proj-airi/stage-ui/components'
<div text="60" i-solar:leaf-bold-duotone />
</div>
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { Live2DCanvas, Live2DModel, PageHeader } from '@proj-airi/stage-ui/components'
import { Live2DCanvas, Live2DModel } from '@proj-airi/stage-ui/components'
import { useElementBounding } from '@vueuse/core'
import { Vibrant } from 'node-vibrant/browser'
import { ref } from 'vue'
@@ -43,10 +43,6 @@ const {
</script>
<template>
<PageHeader
:title="$t('settings.pages.models.title')"
:subtitle="$t('settings.title')"
/>
<div flex>
<div ref="live2dContainerRef" w="50%" h="80vh">
<Live2DCanvas v-slot="{ app }" ref="live2dCanvasRef" :width="width" :height="height">
@@ -84,6 +80,7 @@ const {
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
pageSpecificAvailable: true
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { PageHeader, RadioCardDetailManySelect, RadioCardSimple } from '@proj-airi/stage-ui/components'
import { RadioCardDetailManySelect, RadioCardSimple } from '@proj-airi/stage-ui/components'
import { useConsciousnessStore, useProvidersStore } from '@proj-airi/stage-ui/stores'
import { storeToRefs } from 'pinia'
import { onMounted } from 'vue'
@@ -32,10 +32,6 @@ function updateCustomModelName(value: string) {
</script>
<template>
<PageHeader
:title="$t('settings.pages.modules.consciousness.title')"
:subtitle="$t('settings.pages.modules.title')"
/>
<div bg="neutral-50 dark:[rgba(0,0,0,0.3)]" rounded-xl p-4 flex="~ col gap-4">
<div>
<div flex="~ col gap-4">
@@ -213,6 +209,7 @@ function updateCustomModelName(value: string) {
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { IconStatusItem, PageHeader } from '@proj-airi/stage-ui/components'
import { IconStatusItem } from '@proj-airi/stage-ui/components'
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
@@ -111,10 +111,6 @@ const {
</script>
<template>
<PageHeader
:title="$t('settings.pages.modules.title')"
:subtitle="$t('settings.title')"
/>
<div grid="~ cols-1 sm:cols-2 gap-4">
<IconStatusItem
v-for="(module, index) of modulesList"
@@ -161,6 +157,7 @@ const {
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
pageSpecificAvailable: true
@@ -1,14 +1,16 @@
<script setup lang="ts">
// import { useServerStore } from '@proj-airi/stage-ui/stores'
import { PageHeader } from '@proj-airi/stage-ui/components'
// const serverStore = useServerStore()
</script>
<template>
<PageHeader
:title="$t('settings.pages.modules.memory-long-term.title')"
:subtitle="$t('settings.title')"
/>
<div />
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -1,14 +1,16 @@
<script setup lang="ts">
// import { useServerStore } from '@proj-airi/stage-ui/stores'
import { PageHeader } from '@proj-airi/stage-ui/components'
// const serverStore = useServerStore()
</script>
<template>
<PageHeader
:title="$t('settings.pages.modules.memory-short-term.title')"
:subtitle="$t('settings.title')"
/>
<div />
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -5,7 +5,6 @@ import {
FieldCheckbox,
FieldInput,
FieldRange,
PageHeader,
RadioCardDetailManySelect,
RadioCardSimple,
Skeleton,
@@ -166,10 +165,6 @@ function updateCustomModelName(value: string) {
</script>
<template>
<PageHeader
:title="t('settings.pages.modules.speech.title')"
:subtitle="t('settings.pages.modules.title')"
/>
<div flex="~ col md:row gap-6">
<div bg="neutral-100 dark:[rgba(0,0,0,0.3)]" rounded-xl p-4 flex="~ col gap-4" class="w-full md:w-[40%]">
<div>
@@ -517,6 +512,7 @@ function updateCustomModelName(value: string) {
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -152,3 +152,10 @@ watch(providers, async () => {
</template>
</SpeechProviderSettings>
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -117,3 +117,10 @@ function handleResetSettings() {
</ProviderSettingsContainer>
</ProviderSettingsLayout>
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -97,3 +97,10 @@ function handleResetSettings() {
</ProviderSettingsContainer>
</ProviderSettingsLayout>
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -98,3 +98,10 @@ function handleResetSettings() {
</ProviderSettingsContainer>
</ProviderSettingsLayout>
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -215,3 +215,10 @@ watch(providers, async () => {
</template>
</SpeechProviderSettings>
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -98,3 +98,10 @@ function handleResetSettings() {
</ProviderSettingsContainer>
</ProviderSettingsLayout>
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -98,3 +98,10 @@ function handleResetSettings() {
</ProviderSettingsContainer>
</ProviderSettingsLayout>
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -102,3 +102,10 @@ function handleResetSettings() {
</ProviderSettingsContainer>
</ProviderSettingsLayout>
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { IconStatusItem, PageHeader } from '@proj-airi/stage-ui/components'
import { IconStatusItem } from '@proj-airi/stage-ui/components'
import { useProvidersStore } from '@proj-airi/stage-ui/stores'
import { storeToRefs } from 'pinia'
@@ -16,10 +16,6 @@ const {
</script>
<template>
<PageHeader
:title="$t('settings.pages.providers.title')"
:subtitle="$t('settings.title')"
/>
<div grid="~ cols-2 gap-4">
<IconStatusItem
v-for="(provider, index) of allProvidersMetadata"
@@ -66,6 +62,7 @@ const {
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
pageSpecificAvailable: true
@@ -171,3 +171,10 @@ async function handleGenerateSpeech(input: string, voiceId: string, useSSML: boo
</template>
</SpeechProviderSettings>
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -98,3 +98,10 @@ function handleResetSettings() {
</ProviderSettingsContainer>
</ProviderSettingsLayout>
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -98,3 +98,10 @@ function handleResetSettings() {
</ProviderSettingsContainer>
</ProviderSettingsLayout>
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -98,3 +98,10 @@ function handleResetSettings() {
</ProviderSettingsContainer>
</ProviderSettingsLayout>
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -119,3 +119,10 @@ watch(headers, (headers) => {
</ProviderSettingsContainer>
</ProviderSettingsLayout>
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -102,3 +102,10 @@ function handleResetSettings() {
</ProviderSettingsContainer>
</ProviderSettingsLayout>
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -97,3 +97,10 @@ function handleResetSettings() {
</ProviderSettingsContainer>
</ProviderSettingsLayout>
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -98,3 +98,10 @@ function handleResetSettings() {
</ProviderSettingsContainer>
</ProviderSettingsLayout>
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -142,3 +142,10 @@ watch([providers, appId], async () => {
</template>
</SpeechProviderSettings>
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -98,3 +98,10 @@ function handleResetSettings() {
</ProviderSettingsContainer>
</ProviderSettingsLayout>
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -1,6 +1,4 @@
<script setup lang="ts">
import { PageHeader } from '@proj-airi/stage-ui/components'
import { useIconAnimation } from '../../../composables/useIconAnimation'
const {
@@ -11,10 +9,6 @@ const {
</script>
<template>
<PageHeader
:title="$t('settings.pages.scene.title')"
:subtitle="$t('settings.title')"
/>
<div>
Scene
</div>
@@ -46,6 +40,7 @@ const {
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
pageSpecificAvailable: true
@@ -1,20 +1,49 @@
<script setup lang="ts">
import { useRouter } from 'vue-router'
import { useMotion } from '@vueuse/motion'
import { onMounted, onUnmounted, ref, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
defineProps<{
const props = defineProps<{
title: string
subtitle?: string
}>()
const router = useRouter()
const route = useRoute()
const pageHeaderRef = ref<HTMLElement>()
const title = ref(props.title)
const subtitle = ref(props.subtitle)
const { apply } = useMotion(pageHeaderRef, {
initial: { opacity: 0, x: 10, transition: { duration: 250 } },
enter: { opacity: 1, x: 0, transition: { duration: 250 } },
leave: { opacity: 0, x: -5, transition: { duration: 100 } },
})
onMounted(async () => {
await apply('initial')
await apply('enter')
})
onUnmounted(async () => {
await apply('leave')
})
watch([() => props.title, () => props.subtitle, route], async () => {
await apply('leave')
title.value = props.title
subtitle.value = props.subtitle
await apply('initial')
await apply('enter')
})
</script>
<template>
<div
v-motion
:initial="{ opacity: 0, x: 10 }"
:enter="{ opacity: 1, x: 0 }"
:duration="250"
ref="pageHeaderRef"
:style="{
top: 'env(safe-area-inset-top, 0px)',
right: 'env(safe-area-inset-right, 0px)',
@@ -1,23 +1,13 @@
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import PageHeader from '../../components/Layouts/PageHeader.vue'
defineProps<{
providerName: string
providerIcon?: string
providerIconColor?: string
onBack?: () => void
}>()
const { t } = useI18n()
</script>
<template>
<PageHeader
:title="providerName"
:subtitle="t('settings.pages.providers.title')"
/>
<slot />
<div
v-motion
@@ -1,23 +1,13 @@
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import PageHeader from '../../components/Layouts/PageHeader.vue'
defineProps<{
providerName: string
providerIcon?: string
providerIconColor?: string
onBack?: () => void
}>()
const { t } = useI18n()
</script>
<template>
<PageHeader
:title="providerName"
:subtitle="t('settings.pages.providers.title')"
/>
<slot />
<div
v-motion
@@ -8,6 +8,7 @@ import Live2DCanvas from '../Live2D/Canvas.vue'
import Live2DModel from '../Live2D/Model.vue'
import Screen from '../Screen.vue'
import TransitionVertical from '../TransitionVertical.vue'
import '../../utils/live2d-zip-loader'
withDefaults(defineProps<{
paused: boolean
@@ -26,7 +26,6 @@ import { useProvidersStore } from '../../stores/providers'
import { useSettings } from '../../stores/settings'
import Live2DScene from '../Scenes/Live2D.vue'
import VRMScene from '../Scenes/VRM.vue'
import '../../utils/live2d-zip-loader'
withDefaults(defineProps<{ paused?: boolean }>(), { paused: false })