feat(stage): custom primary colors (#53)
* feat(stage-ui): allow disable transitions * fix(stage-web): apply motion map from file * chore(stage-web): change icon * feat(stage): custom primary colors
This commit is contained in:
@@ -36,7 +36,7 @@ onTokenLiteral(async () => {
|
|||||||
<div flex-1 /> <!-- spacer -->
|
<div flex-1 /> <!-- spacer -->
|
||||||
<div
|
<div
|
||||||
ref="chatHistoryRef" v-auto-animate max-h="30vh" flex="~ col"
|
ref="chatHistoryRef" v-auto-animate max-h="30vh" flex="~ col"
|
||||||
scrollbar="~ w-2 track-color-transparent thumb-color-pink-300 rounded" h-full w-full overflow-scroll
|
scrollbar="~ w-2 track-color-transparent thumb-color-primary-300 rounded" h-full w-full overflow-scroll
|
||||||
>
|
>
|
||||||
<div flex-1 /> <!-- spacer -->
|
<div flex-1 /> <!-- spacer -->
|
||||||
<div v-for="(message, index) in messages" :key="index" mb-2>
|
<div v-for="(message, index) in messages" :key="index" mb-2>
|
||||||
@@ -61,14 +61,14 @@ onTokenLiteral(async () => {
|
|||||||
</div>
|
</div>
|
||||||
<div v-if="message.role === 'assistant'" flex mr="12">
|
<div v-if="message.role === 'assistant'" flex mr="12">
|
||||||
<div
|
<div
|
||||||
flex="~ col" border="4 solid pink-200" shadow="md pink-200/50" min-w-20 rounded-lg px-2 py-1 h="fit"
|
flex="~ col" border="4 solid primary-200" shadow="md primary-200/50" min-w-20 rounded-lg px-2 py-1 h="fit"
|
||||||
bg="pink-100"
|
bg="primary-100"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<span text-xs text="pink-400/90" font-semibold class="inline hidden">Airi</span>
|
<span text-xs text="primary-400/90" font-semibold class="inline hidden">Airi</span>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="message.content" class="markdown-content" text="xs pink-400"
|
v-if="message.content" class="markdown-content" text="xs primary-400"
|
||||||
v-html="process(message.content as string)"
|
v-html="process(message.content as string)"
|
||||||
/>
|
/>
|
||||||
<div v-else i-eos-icons:three-dots-loading />
|
<div v-else i-eos-icons:three-dots-loading />
|
||||||
|
|||||||
@@ -104,9 +104,9 @@ onMounted(() => {
|
|||||||
<BasicTextarea
|
<BasicTextarea
|
||||||
v-model="messageInput"
|
v-model="messageInput"
|
||||||
:placeholder="t('stage.message')"
|
:placeholder="t('stage.message')"
|
||||||
border="solid 2 pink-100"
|
border="solid 2 primary-100"
|
||||||
text="pink-400 hover:pink-600 placeholder:pink-400 placeholder:hover:pink-600"
|
text="primary-400 hover:primary-600 placeholder:primary-400 placeholder:hover:primary-600"
|
||||||
bg="pink-50 dark:[#3c2632]" max-h="[10lh]" min-h="[1lh]"
|
bg="primary-50 dark:[#3c2632]" max-h="[10lh]" min-h="[1lh]"
|
||||||
w-full resize-none overflow-y-scroll rounded-l-xl p-2 font-medium outline-none
|
w-full resize-none overflow-y-scroll rounded-l-xl p-2 font-medium outline-none
|
||||||
transition="all duration-250 ease-in-out placeholder:all placeholder:duration-250 placeholder:ease-in-out"
|
transition="all duration-250 ease-in-out placeholder:all placeholder:duration-250 placeholder:ease-in-out"
|
||||||
@submit="handleSend"
|
@submit="handleSend"
|
||||||
@@ -114,9 +114,9 @@ onMounted(() => {
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="px-4 py-2.5"
|
class="px-4 py-2.5"
|
||||||
border="solid 2 pink-100 "
|
border="solid 2 primary-100 "
|
||||||
text="lg pink-400 hover:pink-600 placeholder:pink-400 placeholder:hover:pink-600"
|
text="lg primary-400 hover:primary-600 placeholder:primary-400 placeholder:hover:primary-600"
|
||||||
bg="pink-50 dark:[#3c2632]" max-h="[10lh]" min-h="[1lh]"
|
bg="primary-50 dark:[#3c2632]" max-h="[10lh]" min-h="[1lh]"
|
||||||
flex items-center justify-center rounded-r-xl
|
flex items-center justify-center rounded-r-xl
|
||||||
@click="openSettings"
|
@click="openSettings"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ const modeIndicatorClass = computed(() => {
|
|||||||
>
|
>
|
||||||
<div class="absolute h-32 w-full flex items-center justify-center b-2 b-pink bg-white">
|
<div class="absolute h-32 w-full flex items-center justify-center b-2 b-pink bg-white">
|
||||||
<div class="wall absolute top-0 h-8" />
|
<div class="wall absolute top-0 h-8" />
|
||||||
<div class="absolute left-0 top-0 h-full w-full flex animate-flash animate-duration-5s animate-count-infinite items-center justify-center text-1.5rem text-pink-300 font-bold">
|
<div class="text-primary-300 absolute left-0 top-0 h-full w-full flex animate-flash animate-duration-5s animate-count-infinite items-center justify-center text-1.5rem font-bold">
|
||||||
DRAG HERE TO MOVE
|
DRAG HERE TO MOVE
|
||||||
</div>
|
</div>
|
||||||
<div class="wall absolute bottom-0 h-8" />
|
<div class="wall absolute bottom-0 h-8" />
|
||||||
@@ -113,7 +113,7 @@ const modeIndicatorClass = computed(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.wall {
|
.wall {
|
||||||
@apply text-pink-200;
|
@apply text-primary-200;
|
||||||
|
|
||||||
--wall-width: 8px;
|
--wall-width: 8px;
|
||||||
animation: wall-move 1s linear infinite;
|
animation: wall-move 1s linear infinite;
|
||||||
|
|||||||
@@ -153,9 +153,9 @@ function isConflict(shortcut: typeof shortcuts.value[0]) {
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
grid="~ cols-[140px_1fr]" my-2 items-center gap-1.5 rounded-lg
|
grid="~ cols-[140px_1fr]" my-2 items-center gap-1.5 rounded-lg
|
||||||
bg="[#fff6fc]" px-2 py-1 text="pink-400"
|
bg="[#fff6fc]" px-2 py-1 text="primary-400"
|
||||||
>
|
>
|
||||||
<div text="xs pink-500">
|
<div text="xs primary-500">
|
||||||
<span>{{ t('settings.openai-base-url.label') }}</span>
|
<span>{{ t('settings.openai-base-url.label') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div flex="~ row" w-full text="xs">
|
<div flex="~ row" w-full text="xs">
|
||||||
@@ -166,7 +166,7 @@ function isConflict(shortcut: typeof shortcuts.value[0]) {
|
|||||||
h-6 w-full rounded-md bg-transparent px-2 py-1 text-right font-mono outline-none
|
h-6 w-full rounded-md bg-transparent px-2 py-1 text-right font-mono outline-none
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div text="xs pink-500">
|
<div text="xs primary-500">
|
||||||
<span>{{ t('settings.openai-api-key.label') }}</span>
|
<span>{{ t('settings.openai-api-key.label') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div flex="~ row" w-full text="xs">
|
<div flex="~ row" w-full text="xs">
|
||||||
@@ -177,7 +177,7 @@ function isConflict(shortcut: typeof shortcuts.value[0]) {
|
|||||||
h-6 w-full rounded-md bg-transparent px-2 py-1 text-right font-mono outline-none
|
h-6 w-full rounded-md bg-transparent px-2 py-1 text-right font-mono outline-none
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div text="xs pink-500">
|
<div text="xs primary-500">
|
||||||
<span>{{ t('settings.elevenlabs-api-key.label') }}</span>
|
<span>{{ t('settings.elevenlabs-api-key.label') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div flex="~ row" w-full text="xs">
|
<div flex="~ row" w-full text="xs">
|
||||||
@@ -188,7 +188,7 @@ function isConflict(shortcut: typeof shortcuts.value[0]) {
|
|||||||
h-6 w-full rounded-md bg-transparent px-2 py-1 text-right font-mono outline-none
|
h-6 w-full rounded-md bg-transparent px-2 py-1 text-right font-mono outline-none
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div text="xs pink-500">
|
<div text="xs primary-500">
|
||||||
<span>{{ t('settings.language.title') }}</span>
|
<span>{{ t('settings.language.title') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div flex="~ row" w-full text="xs">
|
<div flex="~ row" w-full text="xs">
|
||||||
@@ -204,7 +204,7 @@ function isConflict(shortcut: typeof shortcuts.value[0]) {
|
|||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div text="xs pink-500">
|
<div text="xs primary-500">
|
||||||
<span>{{ t('settings.models') }}</span>
|
<span>{{ t('settings.models') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div flex="~ row" w-full text="xs">
|
<div flex="~ row" w-full text="xs">
|
||||||
@@ -223,7 +223,7 @@ function isConflict(shortcut: typeof shortcuts.value[0]) {
|
|||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div text="xs pink-500">
|
<div text="xs primary-500">
|
||||||
<span>{{ t('settings.voices') }}</span>
|
<span>{{ t('settings.voices') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div flex="~ row" w-full text="xs">
|
<div flex="~ row" w-full text="xs">
|
||||||
@@ -257,9 +257,9 @@ function isConflict(shortcut: typeof shortcuts.value[0]) {
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
grid="~ cols-[140px_1fr]" my-2 items-center gap-1.5 rounded-lg
|
grid="~ cols-[140px_1fr]" my-2 items-center gap-1.5 rounded-lg
|
||||||
bg="[#fff6fc]" px-2 py-1 text="pink-400"
|
bg="[#fff6fc]" px-2 py-1 text="primary-400"
|
||||||
>
|
>
|
||||||
<div text="xs pink-500">
|
<div text="xs primary-500">
|
||||||
<span>{{ t('settings.viewer') }}</span>
|
<span>{{ t('settings.viewer') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<select
|
<select
|
||||||
@@ -281,16 +281,16 @@ function isConflict(shortcut: typeof shortcuts.value[0]) {
|
|||||||
<div pb-2>
|
<div pb-2>
|
||||||
<div
|
<div
|
||||||
grid="~ cols-[140px_1fr]" my-2 items-center gap-1.5 rounded-lg
|
grid="~ cols-[140px_1fr]" my-2 items-center gap-1.5 rounded-lg
|
||||||
bg="[#fff6fc]" p-2 text="pink-400"
|
bg="[#fff6fc]" p-2 text="primary-400"
|
||||||
>
|
>
|
||||||
<template v-for="shortcut in shortcuts" :key="shortcut.type">
|
<template v-for="shortcut in shortcuts" :key="shortcut.type">
|
||||||
<span text="xs pink-500">
|
<span text="xs primary-500">
|
||||||
{{ t(shortcut.name) }}
|
{{ t(shortcut.name) }}
|
||||||
</span>
|
</span>
|
||||||
<div
|
<div
|
||||||
class="shortcut-item flex items-center justify-end gap-x-2 px-2 py-0.5"
|
class="shortcut-item flex items-center justify-end gap-x-2 px-2 py-0.5"
|
||||||
:class="{ recording: recordingFor === shortcut.type }"
|
:class="{ recording: recordingFor === shortcut.type }"
|
||||||
text="xs pink-500"
|
text="xs primary-500"
|
||||||
cursor-pointer
|
cursor-pointer
|
||||||
@click="startRecording(shortcut)"
|
@click="startRecording(shortcut)"
|
||||||
>
|
>
|
||||||
@@ -300,7 +300,7 @@ function isConflict(shortcut: typeof shortcuts.value[0]) {
|
|||||||
<div v-else class="pointer-events-none">
|
<div v-else class="pointer-events-none">
|
||||||
{{ shortcut.shortcut }}
|
{{ shortcut.shortcut }}
|
||||||
</div>
|
</div>
|
||||||
<div v-if="isConflict(shortcut)" text="xs pink-500" i-solar:danger-square-bold w-4 />
|
<div v-if="isConflict(shortcut)" text="xs primary-500" i-solar:danger-square-bold w-4 />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
@@ -311,14 +311,14 @@ function isConflict(shortcut: typeof shortcuts.value[0]) {
|
|||||||
<div pb-2>
|
<div pb-2>
|
||||||
<div
|
<div
|
||||||
grid="~ cols-[140px_1fr]" my-2 items-center gap-1.5 rounded-lg
|
grid="~ cols-[140px_1fr]" my-2 items-center gap-1.5 rounded-lg
|
||||||
bg="[#fff6fc]" p-2 text="pink-400" @click="handleQuit"
|
bg="[#fff6fc]" p-2 text="primary-400" @click="handleQuit"
|
||||||
>
|
>
|
||||||
<div text="xs pink-500">
|
<div text="xs primary-500">
|
||||||
<span>
|
<span>
|
||||||
{{ t('settings.quit') }}
|
{{ t('settings.quit') }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div text="sm pink-500" text-right>
|
<div text="sm primary-500" text-right>
|
||||||
<div i-solar:exit-bold-duotone ml-auto />
|
<div i-solar:exit-bold-duotone ml-auto />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { useSettings } from '@proj-airi/stage-ui/stores/settings'
|
|||||||
import { StageTransitionGroup } from '@proj-airi/ui-transitions'
|
import { StageTransitionGroup } from '@proj-airi/ui-transitions'
|
||||||
import { useDark } from '@vueuse/core'
|
import { useDark } from '@vueuse/core'
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
import { watch } from 'vue'
|
import { onMounted, watch } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { RouterView } from 'vue-router'
|
import { RouterView } from 'vue-router'
|
||||||
|
|
||||||
@@ -14,6 +14,14 @@ const isDark = useDark()
|
|||||||
watch(settings.language, () => {
|
watch(settings.language, () => {
|
||||||
i18n.locale.value = settings.language.value
|
i18n.locale.value = settings.language.value
|
||||||
})
|
})
|
||||||
|
|
||||||
|
watch(settings.themeColorsHue, () => {
|
||||||
|
document.documentElement.style.setProperty('--theme-colors-hue', settings.themeColorsHue.value.toString())
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
document.documentElement.style.setProperty('--theme-colors-hue', settings.themeColorsHue.value.toString())
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -23,6 +31,7 @@ watch(settings.language, () => {
|
|||||||
tertiary-color="#121212"
|
tertiary-color="#121212"
|
||||||
:colors="!isDark ? ['#FF57C8', '#946BFF', '#64BCFF', '#FFFFFF'] : ['#FF57C8', '#946BFF', '#64BCFF', '#121212']"
|
:colors="!isDark ? ['#FF57C8', '#946BFF', '#64BCFF', '#FFFFFF'] : ['#FF57C8', '#946BFF', '#64BCFF', '#121212']"
|
||||||
:z-index="100"
|
:z-index="100"
|
||||||
|
:disable-transitions="settings.disableTransitions.value"
|
||||||
>
|
>
|
||||||
<RouterView />
|
<RouterView />
|
||||||
</StageTransitionGroup>
|
</StageTransitionGroup>
|
||||||
|
|||||||
@@ -11,11 +11,12 @@ https://www.magicpattern.design/tools/css-backgrounds
|
|||||||
*/
|
*/
|
||||||
.cross-background-container {
|
.cross-background-container {
|
||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
|
--cross-color: oklch(0.95 0.06 var(--theme-colors-hue));
|
||||||
background:
|
background:
|
||||||
radial-gradient(circle, transparent 20%, #ffffff 20%, #ffffff 80%, transparent 80%, transparent),
|
radial-gradient(circle, transparent 20%, #ffffff 20%, #ffffff 80%, transparent 80%, transparent),
|
||||||
radial-gradient(circle, transparent 20%, #ffffff 20%, #ffffff 80%, transparent 80%, transparent) 25px 25px,
|
radial-gradient(circle, transparent 20%, #ffffff 20%, #ffffff 80%, transparent 80%, transparent) 25px 25px,
|
||||||
linear-gradient(#f4ebf1 2px, transparent 2px) 0 -1px,
|
linear-gradient(var(--cross-color) 2px, transparent 2px) 0 -1px,
|
||||||
linear-gradient(90deg, #f4ebf1 2px, #ffffff 2px) -1px 0;
|
linear-gradient(90deg, var(--cross-color) 2px, #ffffff 2px) -1px 0;
|
||||||
background-size:
|
background-size:
|
||||||
50px 50px,
|
50px 50px,
|
||||||
50px 50px,
|
50px 50px,
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ const props = withDefaults(defineProps<WaveProps>(), {
|
|||||||
height: 40,
|
height: 40,
|
||||||
amplitude: 14,
|
amplitude: 14,
|
||||||
waveLength: 250,
|
waveLength: 250,
|
||||||
fillColor: '#f8e8f2',
|
fillColor: 'oklch(95% 0.10 var(--theme-colors-hue))',
|
||||||
direction: 'down',
|
direction: 'down',
|
||||||
animationSpeed: 50,
|
animationSpeed: 50,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -120,15 +120,15 @@ onAfterSend(async () => {
|
|||||||
<fieldset flex="~ row" w-fit rounded-lg>
|
<fieldset flex="~ row" w-fit rounded-lg>
|
||||||
<label
|
<label
|
||||||
:class="[
|
:class="[
|
||||||
tab === 'chat' ? 'bg-pink-100 dark:bg-[#3c2632]' : 'bg-white dark:bg-[#121212]',
|
tab === 'chat' ? 'bg-primary-100 dark:bg-[#3c2632]' : 'bg-white dark:bg-[#121212]',
|
||||||
tab === 'chat' ? 'text-pink-500 dark:text-pink-500' : '',
|
tab === 'chat' ? 'text-primary-500 dark:text-primary-500' : '',
|
||||||
]"
|
]"
|
||||||
flex="~ row"
|
flex="~ row"
|
||||||
:checked="tab === 'chat'"
|
:checked="tab === 'chat'"
|
||||||
:aria-checked="tab === 'chat'"
|
:aria-checked="tab === 'chat'"
|
||||||
border="solid l-2 t-2 b-2 pink-100 dark:[#3c2632]"
|
border="solid l-2 t-2 b-2 primary-100 dark:[#3c2632]"
|
||||||
bg="hover:pink-100 dark:hover:[#3c2632]"
|
bg="hover:primary-100 dark:hover:[#3c2632]"
|
||||||
text="pink-300 hover:pink-500 dark:pink-300/50 dark:hover:pink-500"
|
text="primary-300 hover:primary-500 dark:primary-300/50 dark:hover:primary-500"
|
||||||
transition="all duration-250 ease-in-out"
|
transition="all duration-250 ease-in-out"
|
||||||
cursor-pointer items-center gap-1 rounded-l-lg px-2
|
cursor-pointer items-center gap-1 rounded-l-lg px-2
|
||||||
>
|
>
|
||||||
@@ -140,15 +140,15 @@ onAfterSend(async () => {
|
|||||||
</label>
|
</label>
|
||||||
<label
|
<label
|
||||||
:class="[
|
:class="[
|
||||||
tab === 'custom' ? 'bg-pink-100 dark:bg-[#3c2632]' : 'bg-white dark:bg-[#121212]',
|
tab === 'custom' ? 'bg-primary-100 dark:bg-[#3c2632]' : 'bg-white dark:bg-[#121212]',
|
||||||
tab === 'custom' ? 'text-pink-500 dark:text-pink-500' : '',
|
tab === 'custom' ? 'text-primary-500 dark:text-primary-500' : '',
|
||||||
]"
|
]"
|
||||||
flex="~ row"
|
flex="~ row"
|
||||||
:checked="tab === 'custom'"
|
:checked="tab === 'custom'"
|
||||||
:aria-checked="tab === 'custom'"
|
:aria-checked="tab === 'custom'"
|
||||||
border="solid t-2 b-2 pink-100 dark:[#3c2632]"
|
border="solid t-2 b-2 primary-100 dark:[#3c2632]"
|
||||||
bg="hover:pink-100 dark:hover:[#3c2632]"
|
bg="hover:primary-100 dark:hover:[#3c2632]"
|
||||||
text="pink-300 hover:pink-500 dark:pink-300/50 dark:hover:pink-500"
|
text="primary-300 hover:primary-500 dark:primary-300/50 dark:hover:primary-500"
|
||||||
transition="all duration-250 ease-in-out"
|
transition="all duration-250 ease-in-out"
|
||||||
cursor-pointer items-center gap-1 px-2
|
cursor-pointer items-center gap-1 px-2
|
||||||
>
|
>
|
||||||
@@ -160,15 +160,15 @@ onAfterSend(async () => {
|
|||||||
</label>
|
</label>
|
||||||
<label
|
<label
|
||||||
:class="[
|
:class="[
|
||||||
tab === 'clothes' ? 'bg-pink-100 dark:bg-[#3c2632]' : 'bg-white dark:bg-[#121212]',
|
tab === 'clothes' ? 'bg-primary-100 dark:bg-[#3c2632]' : 'bg-white dark:bg-[#121212]',
|
||||||
tab === 'clothes' ? 'text-pink-500 dark:text-pink-500' : '',
|
tab === 'clothes' ? 'text-primary-500 dark:text-primary-500' : '',
|
||||||
]"
|
]"
|
||||||
flex="~ row"
|
flex="~ row"
|
||||||
:checked="tab === 'clothes'"
|
:checked="tab === 'clothes'"
|
||||||
:aria-checked="tab === 'clothes'"
|
:aria-checked="tab === 'clothes'"
|
||||||
border="solid r-2 t-2 b-2 pink-100 dark:[#3c2632]"
|
border="solid r-2 t-2 b-2 primary-100 dark:[#3c2632]"
|
||||||
bg="hover:pink-100 dark:hover:[#3c2632]"
|
bg="hover:primary-100 dark:hover:[#3c2632]"
|
||||||
text="pink-300 hover:pink-500 dark:pink-300/50 dark:hover:pink-500"
|
text="primary-300 hover:primary-500 dark:primary-300/50 dark:hover:primary-500"
|
||||||
transition="all duration-250 ease-in-out"
|
transition="all duration-250 ease-in-out"
|
||||||
cursor-pointer items-center gap-1 rounded-r-lg px-2
|
cursor-pointer items-center gap-1 rounded-r-lg px-2
|
||||||
>
|
>
|
||||||
@@ -182,7 +182,7 @@ onAfterSend(async () => {
|
|||||||
<div h-full max-h="[85vh]" w-full px="12 <md:0" py="4">
|
<div h-full max-h="[85vh]" w-full px="12 <md:0" py="4">
|
||||||
<div
|
<div
|
||||||
flex="~ col"
|
flex="~ col"
|
||||||
border="solid 4 pink-100 dark:pink-400/20"
|
border="solid 4 primary-100 dark:primary-400/20"
|
||||||
h-full w-full overflow-scroll rounded-xl
|
h-full w-full overflow-scroll rounded-xl
|
||||||
bg="white dark:[#0f060c]"
|
bg="white dark:[#0f060c]"
|
||||||
>
|
>
|
||||||
@@ -191,8 +191,8 @@ onAfterSend(async () => {
|
|||||||
<BasicTextarea
|
<BasicTextarea
|
||||||
v-model="messageInput"
|
v-model="messageInput"
|
||||||
:placeholder="t('stage.message')"
|
:placeholder="t('stage.message')"
|
||||||
text="pink-300 hover:pink-500 dark:pink-300/50 dark:hover:pink-500 placeholder:pink-300 placeholder:hover:pink-500 placeholder:dark:pink-300/50 placeholder:dark:hover:pink-500"
|
text="primary-300 hover:primary-500 dark:primary-300/50 dark:hover:primary-500 placeholder:primary-300 placeholder:hover:primary-500 placeholder:dark:primary-300/50 placeholder:dark:hover:primary-500"
|
||||||
bg="pink-100 dark:pink-400/20"
|
bg="primary-100 dark:primary-400/20"
|
||||||
min-h="[100px]" w-full
|
min-h="[100px]" w-full
|
||||||
rounded-t-xl p-4 font-medium
|
rounded-t-xl p-4 font-medium
|
||||||
outline-none transition="all duration-250 ease-in-out placeholder:all placeholder:duration-250 placeholder:ease-in-out"
|
outline-none transition="all duration-250 ease-in-out placeholder:all placeholder:duration-250 placeholder:ease-in-out"
|
||||||
|
|||||||
@@ -100,9 +100,9 @@ onMounted(() => {
|
|||||||
<BasicTextarea
|
<BasicTextarea
|
||||||
v-model="messageInput"
|
v-model="messageInput"
|
||||||
:placeholder="t('stage.message')"
|
:placeholder="t('stage.message')"
|
||||||
border="solid 2 pink-100 dark:pink-400/20"
|
border="solid 2 primary-100 dark:primary-400/20"
|
||||||
text="pink-400 hover:pink-600 dark:[#905073] dark:hover:pink-600 placeholder:pink-400 placeholder:hover:pink-600 placeholder:dark:[#905073] placeholder:dark:hover:pink-600"
|
text="primary-400 hover:primary-600 dark:[#905073] dark:hover:primary-600 placeholder:primary-400 placeholder:hover:primary-600 placeholder:dark:[#905073] placeholder:dark:hover:primary-600"
|
||||||
bg="pink-50 dark:[#3c2632]" max-h="[10lh]" min-h="[1lh]"
|
bg="primary-50 dark:[#3c2632]" max-h="[10lh]" min-h="[1lh]"
|
||||||
w-full resize-none overflow-y-scroll rounded-l-xl p-2 font-medium outline-none
|
w-full resize-none overflow-y-scroll rounded-l-xl p-2 font-medium outline-none
|
||||||
transition="all duration-250 ease-in-out placeholder:all placeholder:duration-250 placeholder:ease-in-out"
|
transition="all duration-250 ease-in-out placeholder:all placeholder:duration-250 placeholder:ease-in-out"
|
||||||
@submit="handleSend"
|
@submit="handleSend"
|
||||||
@@ -111,9 +111,9 @@ onMounted(() => {
|
|||||||
<DrawerRoot should-scale-background @update:open="handleSettingsOpen">
|
<DrawerRoot should-scale-background @update:open="handleSettingsOpen">
|
||||||
<DrawerTrigger
|
<DrawerTrigger
|
||||||
class="px-4 py-2.5"
|
class="px-4 py-2.5"
|
||||||
border="solid 2 pink-100 dark:pink-400/20"
|
border="solid 2 primary-100 dark:primary-400/20"
|
||||||
text="lg pink-400 hover:pink-600 dark:[#905073] dark:hover:pink-600 placeholder:pink-400 placeholder:hover:pink-600 placeholder:dark:[#905073] placeholder:dark:hover:pink-600"
|
text="lg primary-400 hover:primary-600 dark:[#905073] dark:hover:primary-600 placeholder:primary-400 placeholder:hover:primary-600 placeholder:dark:[#905073] placeholder:dark:hover:primary-600"
|
||||||
bg="pink-50 dark:[#3c2632]" max-h="[10lh]" min-h="[1lh]" rounded-r-xl
|
bg="primary-50 dark:[#3c2632]" max-h="[10lh]" min-h="[1lh]" rounded-r-xl
|
||||||
>
|
>
|
||||||
<div i-solar:settings-bold-duotone />
|
<div i-solar:settings-bold-duotone />
|
||||||
</DrawerTrigger>
|
</DrawerTrigger>
|
||||||
|
|||||||
@@ -11,9 +11,9 @@ defineProps<{
|
|||||||
<template>
|
<template>
|
||||||
<RouterLink
|
<RouterLink
|
||||||
flex="~ row" bg="neutral-50 dark:neutral-800"
|
flex="~ row" bg="neutral-50 dark:neutral-800"
|
||||||
border="neutral-100 dark:neutral-700 hover:pink-300 dark:hover:pink-300/40 solid 2"
|
border="neutral-100 dark:neutral-700 hover:primary-300 dark:hover:primary-300/40 solid 2"
|
||||||
drop-shadow="none hover:[0px_4px_4px_rgba(220,220,220,0.4)] active:[0px_0px_0px_rgba(220,220,220,0.25)] dark:hover:none"
|
drop-shadow="none hover:[0px_4px_4px_rgba(220,220,220,0.4)] active:[0px_0px_0px_rgba(220,220,220,0.25)] dark:hover:none"
|
||||||
class="after:mask-[linear-gradient(165deg,white_30%,transparent_50%)] after:bg-dotted-[neutral-200] after:hover:bg-dotted-[pink-300/50] dark:after:bg-dotted-[neutral-700/80] dark:after:hover:bg-dotted-[pink-200/20] after:absolute after:left-0 after:top-0 after:z--1 after:h-full after:w-full after:bg-[size:10px_10px] after:content-empty [&_.settings-section-icon]:hover:scale-120 [&_.settings-section-description]:hover:text-pink-400/80 [&_.settings-section-icon]:hover:text-pink-200 [&_.settings-section-title]:hover:text-pink-500 dark:[&_.settings-section-icon]:hover:text-pink-200/40 dark:[&_.settings-section-title]:hover:text-pink-400"
|
class="after:mask-[linear-gradient(165deg,white_30%,transparent_50%)] after:bg-dotted-[neutral-200] after:hover:bg-dotted-[primary-300/50] dark:after:bg-dotted-[neutral-700/80] [&_.settings-section-description]:hover:text-primary-400/80 [&_.settings-section-icon]:hover:text-primary-200 [&_.settings-section-title]:hover:text-primary-500 dark:after:hover:bg-dotted-[primary-200/20] dark:[&_.settings-section-icon]:hover:text-primary-200/40 dark:[&_.settings-section-title]:hover:text-primary-400 after:absolute after:left-0 after:top-0 after:z--1 after:h-full after:w-full after:bg-[size:10px_10px] after:content-empty [&_.settings-section-icon]:hover:scale-120"
|
||||||
transition="all ease-in-out duration-200" relative w-full items-center overflow-hidden rounded-lg p-5 text-left
|
transition="all ease-in-out duration-200" relative w-full items-center overflow-hidden rounded-lg p-5 text-left
|
||||||
:to="to"
|
:to="to"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -58,11 +58,11 @@ onTokenLiteral(async () => {
|
|||||||
</div>
|
</div>
|
||||||
<div v-if="message.role === 'assistant'" flex mr="12">
|
<div v-if="message.role === 'assistant'" flex mr="12">
|
||||||
<div
|
<div
|
||||||
flex="~ col" border="4 solid pink-200/50 dark:pink-500/50" shadow="md pink-200/50 dark:none" min-w-20
|
flex="~ col" border="4 solid primary-200/50 dark:primary-500/50" shadow="md primary-200/50 dark:none" min-w-20
|
||||||
rounded-lg px-2 py-1 h="unset <sm:fit" bg="<md:pink-500/25"
|
rounded-lg px-2 py-1 h="unset <sm:fit" bg="<md:primary-500/25"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<span text-xs text="pink-400/90 dark:pink-600/90" font-semibold class="inline <sm:hidden">{{
|
<span text-xs text="primary-400/90 dark:primary-600/90" font-semibold class="inline <sm:hidden">{{
|
||||||
$t('stage.chat.message.character-name.airi') }}</span>
|
$t('stage.chat.message.character-name.airi') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="sending" i-eos-icons:three-dots-loading />
|
<div v-if="sending" i-eos-icons:three-dots-loading />
|
||||||
|
|||||||
@@ -31,8 +31,15 @@ watch(() => settings.loadingLive2dModel, (value) => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (settings.live2dLoadSource !== 'file') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
settings.availableLive2dMotions.forEach((motion) => {
|
settings.availableLive2dMotions.forEach((motion) => {
|
||||||
if (!settings.live2dMotionMap[motion.fileName]) {
|
if (motion.motionName in Emotion) {
|
||||||
|
settings.live2dMotionMap[motion.fileName] = motion.motionName
|
||||||
|
}
|
||||||
|
else {
|
||||||
settings.live2dMotionMap[motion.fileName] = EmotionNeutralMotionName
|
settings.live2dMotionMap[motion.fileName] = EmotionNeutralMotionName
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -88,7 +95,8 @@ const exportObjectUrl = useObjectUrl(settings.live2dModelFile)
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Collapsable w-full>
|
<div>
|
||||||
|
<Collapsable w-full :default="true">
|
||||||
<template #trigger="slotProps">
|
<template #trigger="slotProps">
|
||||||
<button
|
<button
|
||||||
bg="zinc-100 dark:zinc-800"
|
bg="zinc-100 dark:zinc-800"
|
||||||
@@ -164,7 +172,7 @@ const exportObjectUrl = useObjectUrl(settings.live2dModelFile)
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Collapsable>
|
</Collapsable>
|
||||||
<Collapsable mt-4 w-full>
|
<Collapsable mt-4 w-full :default="true">
|
||||||
<template #trigger="slotProps">
|
<template #trigger="slotProps">
|
||||||
<button
|
<button
|
||||||
bg="zinc-100 dark:zinc-800"
|
bg="zinc-100 dark:zinc-800"
|
||||||
@@ -245,4 +253,5 @@ const exportObjectUrl = useObjectUrl(settings.live2dModelFile)
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Collapsable>
|
</Collapsable>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -40,14 +40,14 @@ onTokenLiteral(async () => {
|
|||||||
<div v-if="message.role === 'assistant'" flex mr="12">
|
<div v-if="message.role === 'assistant'" flex mr="12">
|
||||||
<div
|
<div
|
||||||
flex="~ col"
|
flex="~ col"
|
||||||
border="4 solid pink-200/50 dark:pink-500/50"
|
border="4 solid primary-200/50 dark:primary-500/50"
|
||||||
shadow="md pink-200/50 dark:none"
|
shadow="md primary-200/50 dark:none"
|
||||||
min-w-20 rounded-lg px-2 py-1
|
min-w-20 rounded-lg px-2 py-1
|
||||||
h="unset <sm:fit"
|
h="unset <sm:fit"
|
||||||
bg="<md:pink-500/25"
|
bg="<md:primary-500/25"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<span text-xs text="pink-400/90 dark:pink-600/90" font-semibold class="inline <sm:hidden">{{ $t('stage.chat.message.character-name.airi') }}</span>
|
<span text-xs text="primary-400/90 dark:primary-600/90" font-semibold class="inline <sm:hidden">{{ $t('stage.chat.message.character-name.airi') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="message.content" class="markdown-content" text="base <sm:xs" v-html="process(message.content as string)" />
|
<div v-if="message.content" class="markdown-content" text="base <sm:xs" v-html="process(message.content as string)" />
|
||||||
<div v-else i-eos-icons:three-dots-loading />
|
<div v-else i-eos-icons:three-dots-loading />
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ function handleSettingsOpen(open: boolean) {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Cross>
|
<Cross>
|
||||||
<AnimatedBackground :fill-color="dark ? '#563544' : '#f8e8f2'">
|
<AnimatedBackground :fill-color="dark ? 'oklch(95% 0.20 var(--theme-colors-hue))' : 'oklch(99% 0.10 var(--theme-colors-hue))'">
|
||||||
<div relative flex="~ col" z-2 h-100vh w-100vw of-hidden>
|
<div relative flex="~ col" z-2 h-100vh w-100vw of-hidden>
|
||||||
<!-- header -->
|
<!-- header -->
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -9,12 +9,12 @@ import IconItem from '../../components/Menu/IconItem.vue'
|
|||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
const settings = storeToRefs(useSettings())
|
const { language, disableTransitions } = storeToRefs(useSettings())
|
||||||
const dark = useDark()
|
const dark = useDark()
|
||||||
|
|
||||||
function handleLanguageChange(event: Event) {
|
function handleLanguageChange(event: Event) {
|
||||||
const target = event.target as HTMLSelectElement
|
const target = event.target as HTMLSelectElement
|
||||||
settings.language.value = target.value
|
language.value = target.value
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -104,6 +104,41 @@ function handleLanguageChange(event: Event) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
|
<!-- Developer Settings -->
|
||||||
|
<label
|
||||||
|
bg="neutral-100 dark:neutral-800"
|
||||||
|
hover="bg-neutral-200 dark:bg-neutral-700"
|
||||||
|
transition="all ease-in-out duration-250"
|
||||||
|
w-full flex cursor-pointer rounded-lg px-4 py-3
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
v-model="disableTransitions"
|
||||||
|
text="neutral-800 dark:neutral-100"
|
||||||
|
:checked="disableTransitions"
|
||||||
|
:aria-checked="disableTransitions"
|
||||||
|
type="checkbox"
|
||||||
|
hidden appearance-none outline-none
|
||||||
|
>
|
||||||
|
<div flex="~ row" w-full items-center gap-1.5>
|
||||||
|
<div text="sm" w-full flex-1>
|
||||||
|
<span>Disable Transitions (for debugging)</span>
|
||||||
|
</div>
|
||||||
|
<div select-none>
|
||||||
|
<Transition name="slide-away" mode="out-in">
|
||||||
|
<div
|
||||||
|
v-if="disableTransitions"
|
||||||
|
i-solar:people-nearby-bold-duotone
|
||||||
|
transition="all ease-in-out duration-250"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
v-else
|
||||||
|
i-solar:running-2-line-duotone
|
||||||
|
transition="all ease-in-out duration-250"
|
||||||
|
/>
|
||||||
|
</Transition>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div fixed bottom-0 right-0 text="neutral-100/50 dark:neutral-500/20">
|
<div fixed bottom-0 right-0 text="neutral-100/50 dark:neutral-500/20">
|
||||||
<div text="40" i-lucide:cog translate-x-10 translate-y-10 />
|
<div text="40" i-lucide:cog translate-x-10 translate-y-10 />
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { WidgetStage } from '@proj-airi/stage-ui/components'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
|
|
||||||
|
import Live2DSettings from '../../../components/Widgets/Live2DSettings.vue'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -18,6 +21,11 @@ const router = useRouter()
|
|||||||
</div>
|
</div>
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
|
<div flex>
|
||||||
|
<WidgetStage w="50%" h="80vh" />
|
||||||
|
<Live2DSettings w="50%" h="80vh" />
|
||||||
|
</div>
|
||||||
|
|
||||||
<div fixed bottom-0 right-0 z--1 text="neutral-100/80 dark:neutral-500/20">
|
<div fixed bottom-0 right-0 z--1 text="neutral-100/80 dark:neutral-500/20">
|
||||||
<div text="40" i-lucide:person-standing translate-x-10 translate-y-10 />
|
<div text="40" i-lucide:person-standing translate-x-10 translate-y-10 />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -111,9 +111,9 @@ const modulesList = computed<Module[]>(() => [
|
|||||||
<div
|
<div
|
||||||
v-for="module in modulesList" :key="module.id"
|
v-for="module in modulesList" :key="module.id"
|
||||||
bg="neutral-200/50 dark:neutral-700"
|
bg="neutral-200/50 dark:neutral-700"
|
||||||
border="neutral-100 dark:neutral-700 hover:pink-300 dark:hover:pink-300/40 solid 2"
|
border="neutral-100 dark:neutral-700 hover:primary-300 dark:hover:primary-300/40 solid 2"
|
||||||
drop-shadow="none hover:[0px_4px_4px_rgba(220,220,220,0.4)] active:[0px_0px_0px_rgba(220,220,220,0.25)] dark:hover:none"
|
drop-shadow="none hover:[0px_4px_4px_rgba(220,220,220,0.4)] active:[0px_0px_0px_rgba(220,220,220,0.25)] dark:hover:none"
|
||||||
class="[&_.settings-section-icon]:hover:scale-120 [&_.settings-section-description]:hover:text-pink-400/80 [&_.settings-section-icon]:hover:text-pink-200 [&_.settings-section-icon]:hover:grayscale-0 dark:[&_.settings-section-icon]:hover:text-pink-200/40 dark:[&_.settings-section-title]:hover:text-pink-400"
|
class="[&_.settings-section-description]:hover:text-primary-400/80 [&_.settings-section-icon]:hover:text-primary-200 dark:[&_.settings-section-icon]:hover:text-primary-200/40 dark:[&_.settings-section-title]:hover:text-primary-400 [&_.settings-section-icon]:hover:scale-120 [&_.settings-section-icon]:hover:grayscale-0"
|
||||||
w-full of-hidden rounded-xl
|
w-full of-hidden rounded-xl
|
||||||
flex="~ col 1"
|
flex="~ col 1"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { Collapsable } from '@proj-airi/stage-ui/components'
|
||||||
|
import { useSettings } from '@proj-airi/stage-ui/stores'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
const settings = useSettings()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -18,11 +21,98 @@ const router = useRouter()
|
|||||||
</div>
|
</div>
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
|
<Collapsable mt-4 w-full :default="true">
|
||||||
|
<template #trigger="slotProps">
|
||||||
|
<button
|
||||||
|
bg="zinc-100 dark:zinc-800"
|
||||||
|
hover="bg-zinc-200 dark:bg-zinc-700"
|
||||||
|
transition="all ease-in-out duration-250"
|
||||||
|
w-full flex items-center gap-1.5 rounded-lg px-4 py-3 outline-none
|
||||||
|
class="[&_.provider-icon]:grayscale-100 [&_.provider-icon]:hover:grayscale-0"
|
||||||
|
@click="slotProps.setVisible(!slotProps.visible)"
|
||||||
|
>
|
||||||
|
<div flex="~ row 1" items-center gap-1.5>
|
||||||
|
<div
|
||||||
|
i-solar:pallete-2-bold-duotone class="provider-icon size-6"
|
||||||
|
transition="filter duration-250 ease-in-out"
|
||||||
|
/>
|
||||||
|
<div>
|
||||||
|
Colors
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div transform transition="transform duration-250" :class="{ 'rotate-180': slotProps.visible }">
|
||||||
|
<div i-solar:alt-arrow-down-bold-duotone />
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
<div p-4>
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<div class="flex items-center gap-1 text-sm font-medium">
|
||||||
|
Primary color
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input v-model="settings.themeColorsHue" type="range" min="0" max="360" step="1">
|
||||||
|
</div>
|
||||||
|
<div mt-4 h-10 w-full flex overflow-hidden rounded-lg>
|
||||||
|
<div bg="primary-50" class="primary-color-bar">
|
||||||
|
50
|
||||||
|
</div>
|
||||||
|
<div bg="primary-100" class="primary-color-bar">
|
||||||
|
100
|
||||||
|
</div>
|
||||||
|
<div bg="primary-200" class="primary-color-bar">
|
||||||
|
200
|
||||||
|
</div>
|
||||||
|
<div bg="primary-300" class="primary-color-bar">
|
||||||
|
300
|
||||||
|
</div>
|
||||||
|
<div bg="primary-400" class="primary-color-bar">
|
||||||
|
400
|
||||||
|
</div>
|
||||||
|
<div bg="primary-500" class="primary-color-bar">
|
||||||
|
500
|
||||||
|
</div>
|
||||||
|
<div bg="primary-600" class="primary-color-bar">
|
||||||
|
600
|
||||||
|
</div>
|
||||||
|
<div bg="primary-700" class="primary-color-bar">
|
||||||
|
700
|
||||||
|
</div>
|
||||||
|
<div bg="primary-800" class="primary-color-bar" text-white>
|
||||||
|
800
|
||||||
|
</div>
|
||||||
|
<div bg="primary-900" class="primary-color-bar" text-white>
|
||||||
|
900
|
||||||
|
</div>
|
||||||
|
<div bg="primary-950" class="primary-color-bar" text-white>
|
||||||
|
950
|
||||||
|
</div>
|
||||||
|
<div bg="primary-960" class="primary-color-bar" text-white>
|
||||||
|
960
|
||||||
|
</div>
|
||||||
|
<div bg="primary-970" class="primary-color-bar" text-white>
|
||||||
|
970
|
||||||
|
</div>
|
||||||
|
<div bg="primary-980" class="primary-color-bar" text-white>
|
||||||
|
980
|
||||||
|
</div>
|
||||||
|
<div bg="primary-990" class="primary-color-bar" text-white>
|
||||||
|
990
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Collapsable>
|
||||||
<div fixed bottom-0 right-0 z--1 text="neutral-100/80 dark:neutral-500/20">
|
<div fixed bottom-0 right-0 z--1 text="neutral-100/80 dark:neutral-500/20">
|
||||||
<div text="40" i-lucide:paintbrush translate-x-10 translate-y-10 />
|
<div text="40" i-lucide:paintbrush translate-x-10 translate-y-10 />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.primary-color-bar {
|
||||||
|
@apply w-full h-full flex-1 flex items-center justify-center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
<route lang="yaml">
|
<route lang="yaml">
|
||||||
meta:
|
meta:
|
||||||
stageTransition:
|
stageTransition:
|
||||||
|
|||||||
@@ -10,4 +10,5 @@
|
|||||||
--airi-theme-primary-800: #a70a3e;
|
--airi-theme-primary-800: #a70a3e;
|
||||||
--airi-theme-primary-900: #8e0d3b;
|
--airi-theme-primary-900: #8e0d3b;
|
||||||
--airi-theme-primary-950: #50011b;
|
--airi-theme-primary-950: #50011b;
|
||||||
|
--theme-colors-hue: 354.31;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,4 +69,26 @@ export default defineConfig({
|
|||||||
}
|
}
|
||||||
}],
|
}],
|
||||||
],
|
],
|
||||||
|
theme: {
|
||||||
|
colors: {
|
||||||
|
primary: {
|
||||||
|
DEFAULT: 'oklch(62% 0.20 var(--theme-colors-hue))',
|
||||||
|
50: 'color-mix(in srgb, oklch(95% 0.10 var(--theme-colors-hue)) 30%, oklch(100% 0 360))',
|
||||||
|
100: 'color-mix(in srgb, oklch(95% 0.10 var(--theme-colors-hue)) 80%, oklch(100% 0 360))',
|
||||||
|
200: 'oklch(90% 0.12 var(--theme-colors-hue))',
|
||||||
|
300: 'oklch(85% 0.20 var(--theme-colors-hue))',
|
||||||
|
400: 'oklch(74% 0.20 var(--theme-colors-hue))',
|
||||||
|
500: 'oklch(62% 0.20 var(--theme-colors-hue))',
|
||||||
|
600: 'oklch(54% 0.23 var(--theme-colors-hue))',
|
||||||
|
700: 'oklch(49% 0.21 var(--theme-colors-hue))',
|
||||||
|
800: 'oklch(42% 0.17 var(--theme-colors-hue))',
|
||||||
|
900: 'oklch(37% 0.14 var(--theme-colors-hue))',
|
||||||
|
950: 'oklch(29% 0.09 var(--theme-colors-hue))',
|
||||||
|
960: 'oklch(23% 0.09 var(--theme-colors-hue))',
|
||||||
|
970: 'oklch(17% 0.09 var(--theme-colors-hue))',
|
||||||
|
980: 'oklch(11% 0.09 var(--theme-colors-hue))',
|
||||||
|
990: 'oklch(6% 0.09 var(--theme-colors-hue))',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -252,11 +252,11 @@ onMounted(async () => {
|
|||||||
bottom="20%"
|
bottom="20%"
|
||||||
z="20"
|
z="20"
|
||||||
rounded-2xl
|
rounded-2xl
|
||||||
text="pink-600"
|
text="primary-600"
|
||||||
px-2 py-2
|
px-2 py-2
|
||||||
transform="translate-x--1/2"
|
transform="translate-x--1/2"
|
||||||
>
|
>
|
||||||
<div bg="pink-50" rounded-xl px-10 py-6>
|
<div bg="primary-50" rounded-xl px-10 py-6>
|
||||||
<div class="markdown-content" v-html="process(streamingMessage.content as string)" />
|
<div class="markdown-content" v-html="process(streamingMessage.content as string)" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -33,6 +33,10 @@ export const useSettings = defineStore('settings', () => {
|
|||||||
const availableLive2dMotions = ref<{ motionName: string, motionIndex: number, fileName: string }[]>([])
|
const availableLive2dMotions = ref<{ motionName: string, motionIndex: number, fileName: string }[]>([])
|
||||||
const live2dMotionMap = useLocalStorage<Record<string, string>>('settings/live2d/motion-map', {})
|
const live2dMotionMap = useLocalStorage<Record<string, string>>('settings/live2d/motion-map', {})
|
||||||
|
|
||||||
|
const disableTransitions = useLocalStorage('settings/disable-transitions', false)
|
||||||
|
|
||||||
|
const themeColorsHue = useLocalStorage('settings/theme/colors/hue', 354.31)
|
||||||
|
|
||||||
watch(isAudioInputOn, (value) => {
|
watch(isAudioInputOn, (value) => {
|
||||||
if (value === 'false') {
|
if (value === 'false') {
|
||||||
selectedAudioDevice.value = undefined
|
selectedAudioDevice.value = undefined
|
||||||
@@ -67,8 +71,10 @@ export const useSettings = defineStore('settings', () => {
|
|||||||
availableLive2dMotions,
|
availableLive2dMotions,
|
||||||
live2dMotionMap,
|
live2dMotionMap,
|
||||||
loadingLive2dModel,
|
loadingLive2dModel,
|
||||||
|
disableTransitions,
|
||||||
language,
|
language,
|
||||||
stageView,
|
stageView,
|
||||||
|
themeColorsHue,
|
||||||
isAudioInputOn,
|
isAudioInputOn,
|
||||||
selectedAudioDevice,
|
selectedAudioDevice,
|
||||||
selectedAudioDeviceId,
|
selectedAudioDeviceId,
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ const props = defineProps<{
|
|||||||
tertiaryColor?: string
|
tertiaryColor?: string
|
||||||
colors?: string[]
|
colors?: string[]
|
||||||
zIndex?: number
|
zIndex?: number
|
||||||
|
disableTransitions?: boolean
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
interface StageTransitionCommonParams {
|
interface StageTransitionCommonParams {
|
||||||
@@ -268,6 +269,11 @@ router.beforeEach((to, _from, next) => {
|
|||||||
stageTransition.zIndex = props.zIndex
|
stageTransition.zIndex = props.zIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (props.disableTransitions) {
|
||||||
|
next()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
triggerTransition(stageTransition, next)
|
triggerTransition(stageTransition, next)
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user