style(stage-ui): adjust how the banner works
This commit is contained in:
@@ -1,18 +1,16 @@
|
||||
<script setup lang="ts">
|
||||
import type { ccv3 } from '@proj-airi/ccc'
|
||||
|
||||
import { InputFile } from '@proj-airi/stage-ui/components'
|
||||
import { InputFile, PageHeader } from '@proj-airi/stage-ui/components'
|
||||
import { useAiriCardStore } from '@proj-airi/stage-ui/stores'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
import CardDetailDialog from './components/CardDetailDialog.vue'
|
||||
import CardListItem from './components/CardListItem.vue'
|
||||
import DeleteCardDialog from './components/DeleteCardDialog.vue'
|
||||
|
||||
const router = useRouter()
|
||||
const { t } = useI18n()
|
||||
const cardStore = useAiriCardStore()
|
||||
const { addCard, removeCard } = cardStore
|
||||
@@ -148,26 +146,10 @@ function getModuleShortName(id: string, module: 'consciousness' | 'voice') {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
v-motion
|
||||
flex="~ row" items-center gap-2
|
||||
:initial="{ opacity: 0, x: 10 }"
|
||||
:enter="{ opacity: 1, x: 0 }"
|
||||
:leave="{ opacity: 0, x: -10 }"
|
||||
:duration="250"
|
||||
>
|
||||
<button @click="router.back()">
|
||||
<div i-solar:alt-arrow-left-line-duotone text-2xl />
|
||||
</button>
|
||||
<h1 relative>
|
||||
<div absolute left-0 top-0 translate-y="[-80%]">
|
||||
<span text="neutral-300 dark:neutral-500" text-nowrap>{{ t('settings.title') }}</span>
|
||||
</div>
|
||||
<div text-nowrap text-3xl font-semibold>
|
||||
{{ t('settings.pages.card.title') }}
|
||||
</div>
|
||||
</h1>
|
||||
</div>
|
||||
<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 -->
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
<script setup lang="ts">
|
||||
import { Section } from '@proj-airi/stage-ui/components'
|
||||
import { PageHeader, 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'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
import CheckBar from '../../../components/Settings/CheckBar.vue'
|
||||
import ColorPalette from '../../../components/Settings/ColorPalette.vue'
|
||||
import COLOR_PRESETS from './color-presets.json'
|
||||
|
||||
const router = useRouter()
|
||||
const settings = useSettings()
|
||||
const dark = useDark()
|
||||
const { t } = useI18n()
|
||||
@@ -24,26 +22,10 @@ watch(() => [settings.usePageSpecificTransitions, settings.disableTransitions],
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
v-motion
|
||||
flex="~ row" items-center gap-2
|
||||
:initial="{ opacity: 0, x: 10 }"
|
||||
:enter="{ opacity: 1, x: 0 }"
|
||||
:leave="{ opacity: 0, x: -10 }"
|
||||
:duration="250"
|
||||
>
|
||||
<button @click="router.back()">
|
||||
<div i-solar:alt-arrow-left-line-duotone text-2xl />
|
||||
</button>
|
||||
<h1 relative>
|
||||
<div absolute left-0 top-0 translate-y="[-80%]">
|
||||
<span text="neutral-300 dark:neutral-500" text-nowrap>{{ $t('settings.title') }}</span>
|
||||
</div>
|
||||
<div text-nowrap text-3xl font-semibold>
|
||||
{{ $t('settings.pages.themes.title') }}
|
||||
</div>
|
||||
</h1>
|
||||
</div>
|
||||
<PageHeader
|
||||
:title="$t('settings.pages.themes.title')"
|
||||
:subtitle="$t('settings.title')"
|
||||
/>
|
||||
|
||||
<Section
|
||||
v-motion
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { IconItem } from '@proj-airi/stage-ui/components'
|
||||
import { IconItem, PageHeader } 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,21 +106,9 @@ const settings = computed(() => [
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
v-motion
|
||||
flex items-center gap-2
|
||||
:initial="{ opacity: 0, x: 10 }"
|
||||
:enter="{ opacity: 1, x: 0 }"
|
||||
:duration="100"
|
||||
>
|
||||
<button @click="router.back()">
|
||||
<div i-solar:alt-arrow-left-line-duotone text-2xl />
|
||||
</button>
|
||||
<h1 text-3xl>
|
||||
{{ $t('settings.title') }}
|
||||
</h1>
|
||||
</div>
|
||||
<PageHeader :title="$t('settings.title')" />
|
||||
<div flex="~ col gap-4">
|
||||
<div />
|
||||
<div flex="~ col gap-4">
|
||||
<IconItem
|
||||
v-for="(setting, index) in settings"
|
||||
|
||||
@@ -2,11 +2,8 @@
|
||||
// import { useServerStore } from '@proj-airi/stage-ui/stores'
|
||||
// import { storeToRefs } from 'pinia'
|
||||
// import { onMounted } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
const router = useRouter()
|
||||
const { t } = useI18n()
|
||||
import { PageHeader } from '@proj-airi/stage-ui/components'
|
||||
|
||||
// const { server } = storeToRefs(useServerStore())
|
||||
|
||||
@@ -16,36 +13,20 @@ const { t } = useI18n()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<PageHeader
|
||||
:title="$t('settings.pages.memory.title')"
|
||||
:subtitle="$t('settings.title')"
|
||||
/>
|
||||
<div
|
||||
v-motion
|
||||
flex="~ row" items-center gap-2
|
||||
:initial="{ opacity: 0, x: 10 }"
|
||||
:enter="{ opacity: 1, x: 0 }"
|
||||
:leave="{ opacity: 0, x: -10 }"
|
||||
:duration="250"
|
||||
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 }"
|
||||
:enter="{ scale: 1, opacity: 1, y: 0 }"
|
||||
:duration="500"
|
||||
size-60
|
||||
flex items-center justify-center
|
||||
>
|
||||
<button @click="router.back()">
|
||||
<div i-solar:alt-arrow-left-line-duotone text-2xl />
|
||||
</button>
|
||||
<h1 relative>
|
||||
<div absolute left-0 top-0 translate-y="[-80%]">
|
||||
<span text="neutral-300 dark:neutral-500" text-nowrap>{{ t('settings.title') }}</span>
|
||||
</div>
|
||||
<div text-nowrap text-3xl font-semibold>
|
||||
{{ t('settings.pages.memory.title') }}
|
||||
</div>
|
||||
</h1>
|
||||
<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 }"
|
||||
:enter="{ scale: 1, opacity: 1, y: 0 }"
|
||||
:duration="500"
|
||||
size-60
|
||||
flex items-center justify-center
|
||||
>
|
||||
<div text="60" i-solar:leaf-bold-duotone />
|
||||
</div>
|
||||
<div text="60" i-solar:leaf-bold-duotone />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,17 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import Live2DCanvas from '@proj-airi/stage-ui/components/Live2D/Canvas.vue'
|
||||
import Live2DModel from '@proj-airi/stage-ui/components/Live2D/Model.vue'
|
||||
import { Live2DCanvas, Live2DModel, PageHeader } from '@proj-airi/stage-ui/components'
|
||||
import { useElementBounding } from '@vueuse/core'
|
||||
import { Vibrant } from 'node-vibrant/browser'
|
||||
import { ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
import Live2DSettings from '../../../components/Widgets/Live2DSettings.vue'
|
||||
import { useIconAnimation } from '../../../composables/useIconAnimation'
|
||||
|
||||
const { t } = useI18n()
|
||||
const router = useRouter()
|
||||
const live2dContainerRef = ref<HTMLDivElement>()
|
||||
const live2dCanvasRef = ref<InstanceType<typeof Live2DCanvas>>()
|
||||
const { width, height } = useElementBounding(live2dContainerRef)
|
||||
@@ -48,24 +43,10 @@ const {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
v-motion
|
||||
flex="~ row" items-center gap-2
|
||||
:initial="{ opacity: 0, x: 10 }"
|
||||
:enter="{ opacity: 1, x: 0 }"
|
||||
:leave="{ opacity: 0, x: -10 }"
|
||||
:duration="250"
|
||||
>
|
||||
<button i-solar:alt-arrow-left-line-duotone text-2xl @click="router.back()" />
|
||||
<h1 relative text-nowrap>
|
||||
<div absolute left-0 top-0 translate-y="[-80%]" text="neutral-300 dark:neutral-500">
|
||||
{{ t('settings.title') }}
|
||||
</div>
|
||||
<div text-3xl font-semibold>
|
||||
{{ t('settings.pages.models.title') }}
|
||||
</div>
|
||||
</h1>
|
||||
</div>
|
||||
<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">
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<script setup lang="ts">
|
||||
import { RadioCardDetailManySelect, RadioCardSimple } from '@proj-airi/stage-ui/components'
|
||||
import { PageHeader, 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'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { RouterLink, useRouter } from 'vue-router'
|
||||
import { RouterLink } from 'vue-router'
|
||||
|
||||
const providersStore = useProvidersStore()
|
||||
const consciousnessStore = useConsciousnessStore()
|
||||
@@ -21,7 +21,6 @@ const {
|
||||
} = storeToRefs(consciousnessStore)
|
||||
|
||||
const { t } = useI18n()
|
||||
const router = useRouter()
|
||||
|
||||
onMounted(async () => {
|
||||
await consciousnessStore.loadModelsForProvider(activeProvider.value)
|
||||
@@ -33,26 +32,10 @@ function updateCustomModelName(value: string) {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
v-motion
|
||||
flex="~ row" items-center gap-2
|
||||
:initial="{ opacity: 0, x: 10 }"
|
||||
:enter="{ opacity: 1, x: 0 }"
|
||||
:leave="{ opacity: 0, x: -10 }"
|
||||
:duration="250"
|
||||
>
|
||||
<button @click="router.back()">
|
||||
<div i-solar:alt-arrow-left-line-duotone text-xl />
|
||||
</button>
|
||||
<h1 relative>
|
||||
<div absolute left-0 top-0 translate-y="[-80%]">
|
||||
<span text="neutral-300 dark:neutral-500" text-nowrap>{{ t('settings.pages.modules.title') }}</span>
|
||||
</div>
|
||||
<div text-nowrap text-3xl font-semibold>
|
||||
{{ t('settings.pages.modules.consciousness.title') }}
|
||||
</div>
|
||||
</h1>
|
||||
</div>
|
||||
<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">
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import { IconStatusItem } from '@proj-airi/stage-ui/components'
|
||||
import { IconStatusItem, PageHeader } from '@proj-airi/stage-ui/components'
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
import IconAnimation from '../../../components/IconAnimation.vue'
|
||||
import { useIconAnimation } from '../../../composables/useIconAnimation'
|
||||
|
||||
const router = useRouter()
|
||||
const { t } = useI18n()
|
||||
|
||||
interface Module {
|
||||
@@ -113,26 +111,10 @@ const {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
v-motion
|
||||
flex="~ row" items-center gap-2
|
||||
:initial="{ opacity: 0, x: 10 }"
|
||||
:enter="{ opacity: 1, x: 0 }"
|
||||
:leave="{ opacity: 0, x: -10 }"
|
||||
:duration="250"
|
||||
>
|
||||
<button @click="router.back()">
|
||||
<div i-solar:alt-arrow-left-line-duotone text-2xl />
|
||||
</button>
|
||||
<h1 relative>
|
||||
<div absolute left-0 top-0 translate-y="[-80%]">
|
||||
<span text="neutral-300 dark:neutral-500" text-nowrap>{{ t('settings.title') }}</span>
|
||||
</div>
|
||||
<div text-nowrap text-3xl font-semibold>
|
||||
{{ t('settings.pages.modules.title') }}
|
||||
</div>
|
||||
</h1>
|
||||
</div>
|
||||
<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"
|
||||
|
||||
@@ -1,33 +1,14 @@
|
||||
<script setup lang="ts">
|
||||
// import { useServerStore } from '@proj-airi/stage-ui/stores'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
const router = useRouter()
|
||||
const { t } = useI18n()
|
||||
import { PageHeader } from '@proj-airi/stage-ui/components'
|
||||
|
||||
// const serverStore = useServerStore()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
v-motion
|
||||
flex="~ row" items-center gap-2
|
||||
:initial="{ opacity: 0, x: 10 }"
|
||||
:enter="{ opacity: 1, x: 0 }"
|
||||
:leave="{ opacity: 0, x: -10 }"
|
||||
:duration="250"
|
||||
>
|
||||
<button @click="router.back()">
|
||||
<div i-solar:alt-arrow-left-line-duotone text-2xl />
|
||||
</button>
|
||||
<h1 relative>
|
||||
<div absolute left-0 top-0 translate-y="[-80%]">
|
||||
<span text="neutral-300 dark:neutral-500" text-nowrap>{{ t('settings.title') }}</span>
|
||||
</div>
|
||||
<div text-nowrap text-3xl font-semibold>
|
||||
{{ t('settings.pages.modules.memory-long-term.title') }}
|
||||
</div>
|
||||
</h1>
|
||||
</div>
|
||||
<PageHeader
|
||||
:title="$t('settings.pages.modules.memory-long-term.title')"
|
||||
:subtitle="$t('settings.title')"
|
||||
/>
|
||||
</template>
|
||||
|
||||
@@ -1,33 +1,14 @@
|
||||
<script setup lang="ts">
|
||||
// import { useServerStore } from '@proj-airi/stage-ui/stores'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
const router = useRouter()
|
||||
const { t } = useI18n()
|
||||
import { PageHeader } from '@proj-airi/stage-ui/components'
|
||||
|
||||
// const serverStore = useServerStore()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
v-motion
|
||||
flex="~ row" items-center gap-2
|
||||
:initial="{ opacity: 0, x: 10 }"
|
||||
:enter="{ opacity: 1, x: 0 }"
|
||||
:leave="{ opacity: 0, x: -10 }"
|
||||
:duration="250"
|
||||
>
|
||||
<button @click="router.back()">
|
||||
<div i-solar:alt-arrow-left-line-duotone text-2xl />
|
||||
</button>
|
||||
<h1 relative>
|
||||
<div absolute left-0 top-0 translate-y="[-80%]">
|
||||
<span text="neutral-300 dark:neutral-500" text-nowrap>{{ t('settings.title') }}</span>
|
||||
</div>
|
||||
<div text-nowrap text-3xl font-semibold>
|
||||
{{ t('settings.pages.modules.memory-short-term.title') }}
|
||||
</div>
|
||||
</h1>
|
||||
</div>
|
||||
<PageHeader
|
||||
:title="$t('settings.pages.modules.memory-short-term.title')"
|
||||
:subtitle="$t('settings.title')"
|
||||
/>
|
||||
</template>
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
FieldCheckbox,
|
||||
FieldInput,
|
||||
FieldRange,
|
||||
PageHeader,
|
||||
RadioCardDetailManySelect,
|
||||
RadioCardSimple,
|
||||
Skeleton,
|
||||
@@ -16,7 +17,7 @@ import { generateSpeech } from '@xsai/generate-speech'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { onMounted, onUnmounted, ref, watch } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { RouterLink, useRouter } from 'vue-router'
|
||||
import { RouterLink } from 'vue-router'
|
||||
|
||||
const { t } = useI18n()
|
||||
const providersStore = useProvidersStore()
|
||||
@@ -42,8 +43,6 @@ const {
|
||||
availableVoices,
|
||||
} = storeToRefs(speechStore)
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
const voiceSearchQuery = ref('')
|
||||
const useSSML = ref(false)
|
||||
const testText = ref('Hello, my name is AI Assistant')
|
||||
@@ -166,23 +165,10 @@ function updateCustomModelName(value: string) {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
v-motion flex="~ row" items-center gap-2 :initial="{ opacity: 0, x: 10 }" :enter="{ opacity: 1, x: 0 }"
|
||||
:leave="{ opacity: 0, x: -10 }" :duration="250"
|
||||
>
|
||||
<button @click="router.back()">
|
||||
<div i-solar:alt-arrow-left-line-duotone text-xl />
|
||||
</button>
|
||||
<h1 relative>
|
||||
<div absolute left-0 top-0 translate-y="[-80%]">
|
||||
<span text="neutral-300 dark:neutral-500" text-nowrap>{{ t('settings.pages.modules.title') }}</span>
|
||||
</div>
|
||||
<div text-nowrap text-3xl font-semibold>
|
||||
{{ t('settings.pages.modules.speech.title') }}
|
||||
</div>
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<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>
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
<script setup lang="ts">
|
||||
import { IconStatusItem } from '@proj-airi/stage-ui/components'
|
||||
import { IconStatusItem, PageHeader } from '@proj-airi/stage-ui/components'
|
||||
import { useProvidersStore } from '@proj-airi/stage-ui/stores'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
import { useIconAnimation } from '../../../composables/useIconAnimation'
|
||||
|
||||
const { t } = useI18n()
|
||||
const router = useRouter()
|
||||
const providersStore = useProvidersStore()
|
||||
const { allProvidersMetadata } = storeToRefs(providersStore)
|
||||
|
||||
@@ -20,26 +16,10 @@ const {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
v-motion
|
||||
flex="~ row" items-center gap-2
|
||||
:initial="{ opacity: 0, x: 10 }"
|
||||
:enter="{ opacity: 1, x: 0 }"
|
||||
:leave="{ opacity: 0, x: -10 }"
|
||||
:duration="250"
|
||||
>
|
||||
<button @click="router.back()">
|
||||
<div i-solar:alt-arrow-left-line-duotone text-2xl />
|
||||
</button>
|
||||
<h1 relative>
|
||||
<div absolute left-0 top-0 translate-y="[-80%]">
|
||||
<span text="neutral-300 dark:neutral-500" text-nowrap>{{ t('settings.title') }}</span>
|
||||
</div>
|
||||
<div text-nowrap text-3xl font-semibold>
|
||||
{{ t('settings.pages.providers.title') }}
|
||||
</div>
|
||||
</h1>
|
||||
</div>
|
||||
<PageHeader
|
||||
:title="$t('settings.pages.providers.title')"
|
||||
:subtitle="$t('settings.title')"
|
||||
/>
|
||||
<div grid="~ cols-2 gap-4">
|
||||
<IconStatusItem
|
||||
v-for="(provider, index) of allProvidersMetadata"
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { PageHeader } from '@proj-airi/stage-ui/components'
|
||||
|
||||
import { useIconAnimation } from '../../../composables/useIconAnimation'
|
||||
|
||||
const { t } = useI18n()
|
||||
const router = useRouter()
|
||||
|
||||
const {
|
||||
iconAnimationStarted,
|
||||
showIconAnimation,
|
||||
@@ -15,26 +11,10 @@ const {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
v-motion
|
||||
flex="~ row" items-center gap-2
|
||||
:initial="{ opacity: 0, x: 10 }"
|
||||
:enter="{ opacity: 1, x: 0 }"
|
||||
:leave="{ opacity: 0, x: -10 }"
|
||||
:duration="250"
|
||||
>
|
||||
<button @click="router.back()">
|
||||
<div i-solar:alt-arrow-left-line-duotone text-2xl />
|
||||
</button>
|
||||
<h1 relative>
|
||||
<div absolute left-0 top-0 translate-y="[-80%]">
|
||||
<span text="neutral-300 dark:neutral-500" text-nowrap>{{ t('settings.title') }}</span>
|
||||
</div>
|
||||
<div text-nowrap text-3xl font-semibold>
|
||||
{{ t('settings.pages.scene.title') }}
|
||||
</div>
|
||||
</h1>
|
||||
</div>
|
||||
<PageHeader
|
||||
:title="$t('settings.pages.scene.title')"
|
||||
:subtitle="$t('settings.title')"
|
||||
/>
|
||||
<div>
|
||||
Scene
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
@import './themes.css';
|
||||
@import './transitions.css';
|
||||
|
||||
:root {
|
||||
--bg-color-light: rgb(255 255 255);
|
||||
--bg-color-dark: rgb(18 18 18);
|
||||
--progress-bar-color: rgb(244 114 182);
|
||||
--bg-color: var(--bg-color-light);
|
||||
}
|
||||
|
||||
html,
|
||||
body,
|
||||
#app {
|
||||
@@ -11,23 +18,21 @@ body,
|
||||
}
|
||||
|
||||
html {
|
||||
background: var(--bg-color);
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
html.dark {
|
||||
--bg-color: var(--bg-color-dark);
|
||||
color-scheme: dark;
|
||||
}
|
||||
|
||||
.dark #app {
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
#nprogress {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#nprogress .bar {
|
||||
background: rgb(13, 148, 136);
|
||||
background: var(--progress-bar-color);
|
||||
opacity: 0.75;
|
||||
position: fixed;
|
||||
z-index: 1031;
|
||||
|
||||
@@ -16,13 +16,13 @@ import HeaderLink from '../components/Layouts/HeaderLink.vue'
|
||||
<!-- Header -->
|
||||
<div
|
||||
class="px-0 py-1 md:px-3 md:py-3"
|
||||
mb-4 w-full gap-2
|
||||
w-full gap-2
|
||||
bg="$bg-color"
|
||||
>
|
||||
<HeaderLink />
|
||||
</div>
|
||||
<!-- Content -->
|
||||
<div class="px-3 py-2 md:px-5 md:py-5" flex="~ col gap-4" mx-auto max-w-screen-xl>
|
||||
<div class="px-3 py-2 md:px-5 md:py-5" flex="~ col" mx-auto max-w-screen-xl>
|
||||
<RouterView />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import type { ccv3 } from '@proj-airi/ccc'
|
||||
|
||||
import { InputFile } from '@proj-airi/stage-ui/components'
|
||||
import { InputFile, PageHeader } from '@proj-airi/stage-ui/components'
|
||||
import { useAiriCardStore } from '@proj-airi/stage-ui/stores'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import PageHeader from '../../../components/PageHeader.vue'
|
||||
import CardDetailDialog from './components/CardDetailDialog.vue'
|
||||
import CardListItem from './components/CardListItem.vue'
|
||||
import DeleteCardDialog from './components/DeleteCardDialog.vue'
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
<script setup lang="ts">
|
||||
import { Section } from '@proj-airi/stage-ui/components'
|
||||
import { PageHeader, 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'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import PageHeader from '../../../components/PageHeader.vue'
|
||||
import CheckBar from '../../../components/Settings/CheckBar.vue'
|
||||
import ColorPalette from '../../../components/Settings/ColorPalette.vue'
|
||||
import COLOR_PRESETS from './color-presets.json'
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import { IconItem } from '@proj-airi/stage-ui/components'
|
||||
import { IconItem, PageHeader } 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'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
import IconAnimation from '../../components/IconAnimation.vue'
|
||||
import PageHeader from '../../components/PageHeader.vue'
|
||||
|
||||
const router = useRouter()
|
||||
const iconAnimationStarted = ref(false)
|
||||
@@ -109,6 +108,7 @@ const settings = computed(() => [
|
||||
<template>
|
||||
<PageHeader :title="$t('settings.title')" />
|
||||
<div flex="~ col gap-4">
|
||||
<div />
|
||||
<div flex="~ col gap-4">
|
||||
<IconItem
|
||||
v-for="(setting, index) in settings"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// import { storeToRefs } from 'pinia'
|
||||
// import { onMounted } from 'vue'
|
||||
|
||||
import PageHeader from '../../../components/PageHeader.vue'
|
||||
import { PageHeader } from '@proj-airi/stage-ui/components'
|
||||
|
||||
// const { server } = storeToRefs(useServerStore())
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import Live2DCanvas from '@proj-airi/stage-ui/components/Live2D/Canvas.vue'
|
||||
import Live2DModel from '@proj-airi/stage-ui/components/Live2D/Model.vue'
|
||||
import { Live2DCanvas, Live2DModel, PageHeader } from '@proj-airi/stage-ui/components'
|
||||
import { useElementBounding } from '@vueuse/core'
|
||||
import { Vibrant } from 'node-vibrant/browser'
|
||||
import { ref } from 'vue'
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import { RadioCardDetailManySelect, RadioCardSimple } from '@proj-airi/stage-ui/components'
|
||||
import { PageHeader, 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'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { RouterLink } from 'vue-router'
|
||||
|
||||
import PageHeader from '../../../components/PageHeader.vue'
|
||||
|
||||
const providersStore = useProvidersStore()
|
||||
const consciousnessStore = useConsciousnessStore()
|
||||
const { availableProviders, availableTextGenerationsProvidersMetadata } = storeToRefs(providersStore)
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import { IconStatusItem } from '@proj-airi/stage-ui/components'
|
||||
import { IconStatusItem, PageHeader } from '@proj-airi/stage-ui/components'
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import IconAnimation from '../../../components/IconAnimation.vue'
|
||||
import PageHeader from '../../../components/PageHeader.vue'
|
||||
import { useIconAnimation } from '../../../composables/useIconAnimation'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
// import { useServerStore } from '@proj-airi/stage-ui/stores'
|
||||
|
||||
import PageHeader from '../../../components/PageHeader.vue'
|
||||
import { PageHeader } from '@proj-airi/stage-ui/components'
|
||||
|
||||
// const serverStore = useServerStore()
|
||||
</script>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
// import { useServerStore } from '@proj-airi/stage-ui/stores'
|
||||
|
||||
import PageHeader from '../../../components/PageHeader.vue'
|
||||
import { PageHeader } from '@proj-airi/stage-ui/components'
|
||||
|
||||
// const serverStore = useServerStore()
|
||||
</script>
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
FieldCheckbox,
|
||||
FieldInput,
|
||||
FieldRange,
|
||||
PageHeader,
|
||||
RadioCardDetailManySelect,
|
||||
RadioCardSimple,
|
||||
Skeleton,
|
||||
@@ -16,7 +17,7 @@ import { generateSpeech } from '@xsai/generate-speech'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { onMounted, onUnmounted, ref, watch } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { RouterLink, useRouter } from 'vue-router'
|
||||
import { RouterLink } from 'vue-router'
|
||||
|
||||
const { t } = useI18n()
|
||||
const providersStore = useProvidersStore()
|
||||
@@ -42,8 +43,6 @@ const {
|
||||
availableVoices,
|
||||
} = storeToRefs(speechStore)
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
const voiceSearchQuery = ref('')
|
||||
const useSSML = ref(false)
|
||||
const testText = ref('Hello, my name is AI Assistant')
|
||||
@@ -166,23 +165,10 @@ function updateCustomModelName(value: string) {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
v-motion flex="~ row" items-center gap-2 :initial="{ opacity: 0, x: 10 }" :enter="{ opacity: 1, x: 0 }"
|
||||
:leave="{ opacity: 0, x: -10 }" :duration="250"
|
||||
>
|
||||
<button @click="router.back()">
|
||||
<div i-solar:alt-arrow-left-line-duotone text-xl />
|
||||
</button>
|
||||
<h1 relative>
|
||||
<div absolute left-0 top-0 translate-y="[-80%]">
|
||||
<span text="neutral-300 dark:neutral-500" text-nowrap>{{ t('settings.pages.modules.title') }}</span>
|
||||
</div>
|
||||
<div text-nowrap text-3xl font-semibold>
|
||||
{{ t('settings.pages.modules.speech.title') }}
|
||||
</div>
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<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>
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import { IconStatusItem } from '@proj-airi/stage-ui/components'
|
||||
import { IconStatusItem, PageHeader } from '@proj-airi/stage-ui/components'
|
||||
import { useProvidersStore } from '@proj-airi/stage-ui/stores'
|
||||
import { storeToRefs } from 'pinia'
|
||||
|
||||
import PageHeader from '../../../components/PageHeader.vue'
|
||||
import { useIconAnimation } from '../../../composables/useIconAnimation'
|
||||
|
||||
const providersStore = useProvidersStore()
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import PageHeader from '../../../components/PageHeader.vue'
|
||||
import { PageHeader } from '@proj-airi/stage-ui/components'
|
||||
|
||||
import { useIconAnimation } from '../../../composables/useIconAnimation'
|
||||
|
||||
const {
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
<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 w-full pb-6 pt-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>
|
||||
@@ -0,0 +1 @@
|
||||
export { default as PageHeader } from './PageHeader.vue'
|
||||
@@ -63,9 +63,9 @@ defineProps<{
|
||||
z-index: -1;
|
||||
width: 25%;
|
||||
height: 100%;
|
||||
transition: all 0.4s ease-in-out;
|
||||
mask-image: linear-gradient(120deg, white 30%, transparent 50%);
|
||||
opacity: 0;
|
||||
transition: all 0.4s ease-in-out;
|
||||
}
|
||||
|
||||
.menu-icon-item:hover::before,
|
||||
|
||||
@@ -1,33 +1,22 @@
|
||||
<script setup lang="ts">
|
||||
import { PageHeader } from '@proj-airi/stage-ui/components'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
defineProps<{
|
||||
providerName: string
|
||||
providerIcon?: string
|
||||
providerIconColor?: string
|
||||
onBack?: () => void
|
||||
}>()
|
||||
|
||||
const { t } = useI18n()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
v-motion
|
||||
flex="~ row" items-center gap-2
|
||||
:initial="{ opacity: 0, x: 10 }"
|
||||
:enter="{ opacity: 1, x: 0 }"
|
||||
:leave="{ opacity: 0, x: -10 }"
|
||||
:duration="250"
|
||||
>
|
||||
<button @click="onBack">
|
||||
<div i-solar:alt-arrow-left-line-duotone text-2xl />
|
||||
</button>
|
||||
<h1 relative>
|
||||
<div absolute left-0 top-0 translate-y="[-80%]">
|
||||
<span text="neutral-300 dark:neutral-500" text-nowrap>Provider</span>
|
||||
</div>
|
||||
<div text-nowrap text-3xl font-semibold>
|
||||
{{ providerName }}
|
||||
</div>
|
||||
</h1>
|
||||
</div>
|
||||
<PageHeader
|
||||
:title="providerName"
|
||||
:subtitle="t('settings.pages.providers.title')"
|
||||
/>
|
||||
<slot />
|
||||
<div
|
||||
v-motion
|
||||
|
||||
@@ -1,135 +1,32 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { PageHeader } from '@proj-airi/stage-ui/components'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
const props = defineProps<{
|
||||
/**
|
||||
* Provider name to display in the header
|
||||
*/
|
||||
providerName?: string
|
||||
|
||||
/**
|
||||
* Provider icon CSS class
|
||||
*/
|
||||
defineProps<{
|
||||
providerName: string
|
||||
providerIcon?: string
|
||||
|
||||
/**
|
||||
* Provider icon color CSS class
|
||||
*/
|
||||
providerIconColor?: string
|
||||
|
||||
/**
|
||||
* Optional handler for back button
|
||||
*/
|
||||
onBack?: () => void
|
||||
|
||||
/**
|
||||
* Optional title to display (overrides providerName)
|
||||
*/
|
||||
title?: string
|
||||
|
||||
/**
|
||||
* Optional subtitle to display
|
||||
*/
|
||||
subtitle?: string
|
||||
|
||||
/**
|
||||
* Optional category label to display above the title
|
||||
*/
|
||||
categoryLabel?: string
|
||||
}>()
|
||||
|
||||
// Expose event handlers
|
||||
const emit = defineEmits<{
|
||||
back: []
|
||||
}>()
|
||||
|
||||
// Define slots
|
||||
defineSlots<{
|
||||
default: () => any
|
||||
title: () => any
|
||||
subtitle: () => any
|
||||
backButton: () => any
|
||||
headerExtra: () => any
|
||||
header: () => any
|
||||
}>()
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
// Compute effective title
|
||||
const effectiveTitle = computed(() => props.title || props.providerName || '')
|
||||
|
||||
// Compute effective category label
|
||||
const effectiveCategoryLabel = computed(() => props.categoryLabel || t('settings.pages.providers.title'))
|
||||
|
||||
// Handle back button click
|
||||
function handleBackClick() {
|
||||
if (props.onBack) {
|
||||
props.onBack()
|
||||
}
|
||||
emit('back')
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<!-- Header section -->
|
||||
<slot name="header">
|
||||
<div
|
||||
v-motion
|
||||
flex="~ row"
|
||||
:initial="{ opacity: 0, x: 10 }"
|
||||
:enter="{ opacity: 1, x: 0 }"
|
||||
:leave="{ opacity: 0, x: -10 }"
|
||||
:duration="250"
|
||||
mb-6 items-center gap-3
|
||||
>
|
||||
<!-- Back button -->
|
||||
<slot name="backButton">
|
||||
<button @click="handleBackClick">
|
||||
<div i-solar:alt-arrow-left-line-duotone text-2xl />
|
||||
</button>
|
||||
</slot>
|
||||
|
||||
<!-- Title area -->
|
||||
<div>
|
||||
<slot name="title">
|
||||
<h1 relative>
|
||||
<div v-if="effectiveCategoryLabel" absolute left-0 top-0 translate-y="[-80%]">
|
||||
<span text="neutral-300 dark:neutral-500" text-nowrap>{{ effectiveCategoryLabel }}</span>
|
||||
</div>
|
||||
<div text-nowrap text-3xl font-semibold>
|
||||
{{ effectiveTitle }}
|
||||
</div>
|
||||
</h1>
|
||||
</slot>
|
||||
|
||||
<slot name="subtitle">
|
||||
<div v-if="subtitle" text-sm text="neutral-500 dark:neutral-400">
|
||||
{{ subtitle }}
|
||||
</div>
|
||||
</slot>
|
||||
</div>
|
||||
|
||||
<!-- Extra header content (right side) -->
|
||||
<slot name="headerExtra" />
|
||||
</div>
|
||||
</slot>
|
||||
|
||||
<!-- Main content -->
|
||||
<slot />
|
||||
|
||||
<!-- Background icon -->
|
||||
<div
|
||||
v-motion
|
||||
text="neutral-200/50 dark:neutral-600/20" pointer-events-none
|
||||
fixed top="[calc(100dvh-15rem)]" bottom-0 right--5 z--1
|
||||
:initial="{ scale: 0.9, opacity: 0, x: 20 }"
|
||||
:enter="{ scale: 1, opacity: 1, x: 0 }"
|
||||
:duration="500"
|
||||
size-60
|
||||
>
|
||||
<div text="60" :class="providerIcon || providerIconColor" />
|
||||
</div>
|
||||
<PageHeader
|
||||
:title="providerName"
|
||||
:subtitle="t('settings.pages.providers.title')"
|
||||
/>
|
||||
<slot />
|
||||
<div
|
||||
v-motion
|
||||
text="neutral-200/50 dark:neutral-600/20" pointer-events-none
|
||||
fixed top="[calc(100dvh-15rem)]" bottom-0 right--5 z--1
|
||||
:initial="{ scale: 0.9, opacity: 0, x: 20 }"
|
||||
:enter="{ scale: 1, opacity: 1, x: 0 }"
|
||||
:duration="500"
|
||||
size-60
|
||||
>
|
||||
<div text="60" :class="providerIcon || providerIconColor" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -4,6 +4,7 @@ export { default as Collapsable } from './Collapsable.vue'
|
||||
export * from './Form'
|
||||
export * from './Gadgets'
|
||||
export * from './Graphics'
|
||||
export * from './Layouts'
|
||||
export { default as Live2DCanvas } from './Live2D/Canvas.vue'
|
||||
export { default as Live2DModel } from './Live2D/Model.vue'
|
||||
export * from './Menu'
|
||||
|
||||
Reference in New Issue
Block a user