6ee4087a29
- Centralize `useAgents` and `useModels` state within the Nuxt app context to prevent data leaks and improve initialization. - Migrate virtualization from `vue-virtual-scroller` to `@tanstack/vue-virtual` with new `RowVirtualizerFixed` and `RowVirtualizerDynamic` components. - Upgrade Nuxt to v4.3.1 and remove `@vue-macros/nuxt`. - Replace `big.js` with an optimized custom `lshDecimal` string manipulation logic for pricing calculations in the provider API. - Implement automatic focus redirection in `ChatInput` to capture standard keyboard input. - Refactor Sidenav and Settings components to utilize virtualization for long lists (topics, agents, models). - Enhance theme colors and mobile experience. More work to come on both of these.
83 lines
4.3 KiB
Vue
83 lines
4.3 KiB
Vue
<script setup lang="ts">
|
|
const { settings, updateSettings } = await useUserSettings();
|
|
const { colorScheme } = useTheme();
|
|
|
|
const accents = ['violet', 'volcano', 'lime', 'sky', 'coral', 'emerald', 'amber', 'rose', 'cyan', 'indigo', 'magenta'];
|
|
const neutrals = ['zinc', 'slate', 'obsidian'];
|
|
|
|
const updateAccent = (accent: string) => {
|
|
updateSettings({ appearance: { accent } });
|
|
};
|
|
|
|
const updateNeutral = (neutral: string) => {
|
|
updateSettings({ appearance: { neutral } });
|
|
};
|
|
|
|
const updateHinting = (e: Event) => {
|
|
const hinting = parseInt((e.target as HTMLInputElement).value);
|
|
updateSettings({ appearance: { hinting } });
|
|
};
|
|
|
|
defineEmits(['navigate']);
|
|
</script>
|
|
|
|
<template>
|
|
<div
|
|
class="flex flex-col gap-6 py-4 overflow-auto [scrollbar-width:thin] [scrollbar-color:#888_transparent] [scrollbar-gutter:stable]">
|
|
<div class="flex flex-row items-center justify-between gap-2">
|
|
<h4 class="font-medium">Theme</h4>
|
|
<div class="flex gap-2">
|
|
<button @click="updateSettings({ appearance: { colorScheme: 'system' } })"
|
|
class="flex items-center gap-1 px-1 rounded-md hover:bg-[var(--color-hover)] transition-[background-color] duration-200 ease-[cubic-bezier(0.5,_1,_0.89,_1)]"
|
|
:class="colorScheme.preference.value === 'system' ? 'bg-[var(--color-hover)]' : ''">
|
|
<Icon name="tabler:device-desktop" class="text-4" />
|
|
<span>System</span>
|
|
</button>
|
|
<button @click="updateSettings({ appearance: { colorScheme: 'dark' } })"
|
|
class="flex items-center gap-1 px-1 rounded-md hover:bg-[var(--color-hover)] transition-[background-color] duration-200 ease-[cubic-bezier(0.5,_1,_0.89,_1)]"
|
|
:class="colorScheme.preference.value === 'dark' ? 'bg-[var(--color-hover)]' : ''">
|
|
<Icon name="mynaui:moon" class="text-4" />
|
|
<span>Dark</span>
|
|
</button>
|
|
<button @click="updateSettings({ appearance: { colorScheme: 'light' } })"
|
|
class="flex items-center gap-1 px-1 rounded-md hover:bg-[var(--color-hover)] transition-[background-color] duration-200 ease-[cubic-bezier(0.5,_1,_0.89,_1)]"
|
|
:class="colorScheme.preference.value === 'light' ? 'bg-[var(--color-hover)]' : ''">
|
|
<Icon name="mynaui:sun" class="text-4" />
|
|
<span>Light</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex flex-col gap-2">
|
|
<h4 class="text-sm font-medium">Accent Color</h4>
|
|
<div class="grid grid-cols-5 gap-2">
|
|
<button v-for="accent in accents" :key="accent" @click="updateAccent(accent)"
|
|
class="h-8 rounded border-2 hover:scale-105 active:scale-95 transition-all duration-200 ease-[cubic-bezier(0.33,_1,_0.68,_1)]"
|
|
:class="[
|
|
settings.appearance.accent === accent ? 'dark:border-white/70 border-black/70' : 'border-transparent'
|
|
]" :style="`background-color: var(--accent-${accent})`" :title="accent" />
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex flex-col gap-2">
|
|
<h4 class="text-sm font-medium">Neutral Color</h4>
|
|
<div class="grid grid-cols-5 gap-2">
|
|
<button v-for="neutral in neutrals" :key="neutral" @click="updateNeutral(neutral)"
|
|
class="h-8 rounded border-2 hover:scale-105 active:scale-95 transition-all duration-200 ease-[cubic-bezier(0.33,_1,_0.68,_1)]"
|
|
:class="[
|
|
settings.appearance.neutral === neutral ? 'border-[var(--color-accent)]' : 'border-transparent hover:border-zinc-500'
|
|
]" :style="`background-color: var(--palette-${neutral}-200)`" :title="neutral" />
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex flex-col gap-2">
|
|
<div class="flex justify-between items-center">
|
|
<h4 class="text-sm font-medium">Accent Hinting</h4>
|
|
<span class="text-xs text-zinc-500">{{ settings.appearance.hinting }}%</span>
|
|
</div>
|
|
<input type="range" min="0" max="100" step="1" :value="settings.appearance.hinting" @input="updateHinting"
|
|
class="accent-[var(--color-accent)]" />
|
|
</div>
|
|
</div>
|
|
</template>
|