feat(stage-web): impl settings
Signed-off-by: Neko Ayaka <neko@ayaka.moe>
This commit is contained in:
@@ -17,9 +17,9 @@ watch(settings.language, () => {
|
||||
<template>
|
||||
<StageTransitionGroup
|
||||
primary-color="#FF57C8"
|
||||
secondary-color="#60C7FF"
|
||||
secondary-color="#946BFF"
|
||||
tertiary-color="#121212"
|
||||
:colors="['#FF57C8', '#60C7FF', '#936AFF', '#121212']"
|
||||
:colors="['#FF57C8', '#946BFF', '#64BCFF', '#121212']"
|
||||
:z-index="100"
|
||||
>
|
||||
<RouterView />
|
||||
|
||||
@@ -1,29 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import { useDark } from '@vueuse/core'
|
||||
import { RouterLink } from 'vue-router'
|
||||
|
||||
import LogoDark from '../../assets/logo-dark.svg'
|
||||
import Logo from '../../assets/logo.svg'
|
||||
|
||||
const dark = useDark()
|
||||
import HeaderLink from './HeaderLink.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<header mb-1 w-full gap-2>
|
||||
<a
|
||||
href="https://github.com/moeru-ai/airi" rel="noreferrer noopener" target="_blank" flex="~ 1" w-full items-center
|
||||
gap-2 px-2 text-nowrap text-2xl outline-none
|
||||
>
|
||||
<template v-if="dark">
|
||||
<img :src="LogoDark" h-8 w-8>
|
||||
</template>
|
||||
<template v-else>
|
||||
<img :src="Logo" h-8 w-8>
|
||||
</template>
|
||||
<div font-cute>
|
||||
<span>アイリ</span>
|
||||
</div>
|
||||
</a>
|
||||
<HeaderLink />
|
||||
<RouterLink
|
||||
class="m-1 block max-h-[10lh] min-h-[1lh] rounded-lg bg-zinc-100 p-2 text-lg text-zinc-500 outline-none dark:bg-zinc-800 dark:text-zinc-400"
|
||||
to="/settings"
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
<script setup lang="ts">
|
||||
import { useDark } from '@vueuse/core'
|
||||
import { RouterLink } from 'vue-router'
|
||||
|
||||
import LogoDark from '../../assets/logo-dark.svg'
|
||||
import Logo from '../../assets/logo.svg'
|
||||
|
||||
const dark = useDark()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<RouterLink
|
||||
to="/" flex="~ 1" w-full items-center
|
||||
gap-2 px-2 text-nowrap text-2xl outline-none
|
||||
>
|
||||
<template v-if="dark">
|
||||
<img :src="LogoDark" h-8 w-8>
|
||||
</template>
|
||||
<template v-else>
|
||||
<img :src="Logo" h-8 w-8>
|
||||
</template>
|
||||
<div font-cute>
|
||||
<span>アイリ</span>
|
||||
</div>
|
||||
</RouterLink>
|
||||
</template>
|
||||
@@ -0,0 +1,33 @@
|
||||
<script setup lang="ts">
|
||||
defineProps<{
|
||||
title: string
|
||||
description: string
|
||||
icon: string
|
||||
to: string
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<RouterLink
|
||||
flex="~ row" bg="neutral-100 dark:neutral-800" hover="bg-neutral-200 dark:bg-neutral-700"
|
||||
class="[&_.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
|
||||
:to="to"
|
||||
>
|
||||
<div z-1 flex-1>
|
||||
<div text-lg font-semibold>
|
||||
{{ title }}
|
||||
</div>
|
||||
<div text="sm neutral-600 dark:neutral-400">
|
||||
<span>{{ description }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="settings-section-icon"
|
||||
transition="all ease-in-out duration-500"
|
||||
absolute right-0 size-24 translate-y-4
|
||||
text="neutral-400/50 dark:neutral-600/50"
|
||||
:class="[icon]"
|
||||
/>
|
||||
</RouterLink>
|
||||
</template>
|
||||
@@ -1,19 +1,16 @@
|
||||
<script setup lang="ts">
|
||||
import { useScreenSafeArea } from '@vueuse/core'
|
||||
import { RouterView } from 'vue-router'
|
||||
|
||||
const { top, right, bottom, left } = useScreenSafeArea()
|
||||
import HeaderLink from '../components/Layouts/HeaderLink.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<main
|
||||
text="gray-700 dark:gray-200" h-full font-cuteen
|
||||
:style="{
|
||||
paddingTop: `${top}px`,
|
||||
paddingRight: `${right}px`,
|
||||
paddingBottom: `${bottom}px`,
|
||||
paddingLeft: `${left}px`,
|
||||
}"
|
||||
>
|
||||
<RouterView />
|
||||
</main>
|
||||
<div p-2>
|
||||
<div mb-1 w-full gap-2 p-2>
|
||||
<HeaderLink />
|
||||
</div>
|
||||
<div p-5 flex="~ col gap-4">
|
||||
<RouterView />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<script setup lang="ts">
|
||||
import { useScreenSafeArea } from '@vueuse/core'
|
||||
|
||||
const { top, right, bottom, left } = useScreenSafeArea()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<main
|
||||
text="gray-700 dark:gray-200" h-full font-cuteen
|
||||
:style="{
|
||||
paddingTop: `${top}px`,
|
||||
paddingRight: `${right}px`,
|
||||
paddingBottom: `${bottom}px`,
|
||||
paddingLeft: `${left}px`,
|
||||
}"
|
||||
>
|
||||
<RouterView />
|
||||
</main>
|
||||
</template>
|
||||
@@ -40,5 +40,7 @@ function handleSettingsOpen(open: boolean) {
|
||||
|
||||
<route lang="yaml">
|
||||
meta:
|
||||
layout: default
|
||||
layout: stage
|
||||
stageTransition:
|
||||
name: bubble-wave-out
|
||||
</route>
|
||||
|
||||
@@ -1,6 +1,107 @@
|
||||
<script setup lang="ts">
|
||||
import { useSettings } from '@proj-airi/stage-ui/stores'
|
||||
import { useDark } from '@vueuse/core'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import IconItem from '../../components/Menu/IconItem.vue'
|
||||
|
||||
const { t } = useI18n()
|
||||
const settings = storeToRefs(useSettings())
|
||||
const dark = useDark()
|
||||
|
||||
function handleLanguageChange(event: Event) {
|
||||
const target = event.target as HTMLSelectElement
|
||||
settings.language.value = target.value
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div p2>
|
||||
<h1>Settings</h1>
|
||||
<div>
|
||||
<h1 text-3xl>
|
||||
Settings
|
||||
</h1>
|
||||
</div>
|
||||
<div flex="~ col gap-4">
|
||||
<div flex="~ col gap-4">
|
||||
<IconItem title="Modules" description="Thinking, vision, speech synthesis, gaming, etc." icon="i-lucide:blocks" to="/settings/modules" />
|
||||
<IconItem title="Providers" description="LLMs, speech providers, etc." icon="i-lucide:brain" to="/settings/providers" />
|
||||
<IconItem title="Themes" description="Customize your stage!" icon="i-lucide:paintbrush" to="/settings/themes" />
|
||||
</div>
|
||||
<div>
|
||||
<h2 text-2xl>
|
||||
General
|
||||
</h2>
|
||||
</div>
|
||||
<div flex="~ col gap-4">
|
||||
<!-- Language Setting -->
|
||||
<div
|
||||
grid="~ cols-[150px_1fr]"
|
||||
bg="neutral-100 dark:neutral-800"
|
||||
hover="bg-neutral-200 dark:bg-neutral-700"
|
||||
transition="all ease-in-out duration-250"
|
||||
items-center gap-1.5 rounded-lg px-4 py-3
|
||||
>
|
||||
<div text="sm">
|
||||
<span>{{ t('settings.language.title') }}</span>
|
||||
</div>
|
||||
<div flex="~ row" w-full justify-end>
|
||||
<select
|
||||
class="w-32"
|
||||
bg="transparent"
|
||||
text="sm right neutral-800 dark:neutral-100"
|
||||
transition="all ease-in-out duration-250"
|
||||
outline="none"
|
||||
@change="handleLanguageChange"
|
||||
>
|
||||
<option value="en-US">
|
||||
{{ t('settings.language.english') }}
|
||||
</option>
|
||||
<option value="zh-CN">
|
||||
{{ t('settings.language.chinese') }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Theme Setting -->
|
||||
<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="dark"
|
||||
text="neutral-800 dark:neutral-100"
|
||||
:checked="dark"
|
||||
:aria-checked="dark"
|
||||
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>{{ t('settings.theme') }}</span>
|
||||
</div>
|
||||
<div select-none>
|
||||
<Transition name="slide-away" mode="out-in">
|
||||
<div
|
||||
v-if="dark"
|
||||
i-solar:moon-stars-bold-duotone
|
||||
transition="all ease-in-out duration-250"
|
||||
/>
|
||||
<div
|
||||
v-else
|
||||
i-solar:sun-fog-bold-duotone
|
||||
transition="all ease-in-out duration-250"
|
||||
/>
|
||||
</Transition>
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
<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>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -3,3 +3,9 @@
|
||||
A
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<route lang="yaml">
|
||||
meta:
|
||||
stageTransition:
|
||||
name: slide
|
||||
</route>
|
||||
|
||||
@@ -3,3 +3,9 @@
|
||||
A
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<route lang="yaml">
|
||||
meta:
|
||||
stageTransition:
|
||||
name: slide
|
||||
</route>
|
||||
|
||||
Reference in New Issue
Block a user