mirror of
https://github.com/ArthurDanjou/artchat.git
synced 2026-01-14 13:54:01 +01:00
feat: enhance chat UI and add location component with images
This commit is contained in:
@@ -49,16 +49,16 @@ const commandPaletteUi = {
|
|||||||
<UModal v-model:open="openMessageModal" :ui="modalUi">
|
<UModal v-model:open="openMessageModal" :ui="modalUi">
|
||||||
<UButton
|
<UButton
|
||||||
:label="loading ? t('cmd.sending') : t('cmd.send')"
|
:label="loading ? t('cmd.sending') : t('cmd.send')"
|
||||||
variant="solid"
|
variant="outline"
|
||||||
color="neutral"
|
color="neutral"
|
||||||
size="xl"
|
size="xl"
|
||||||
icon="i-ph-paper-plane-tilt-duotone"
|
icon="i-ph-paper-plane-tilt-duotone"
|
||||||
class="rounded-full"
|
class="rounded-full cursor-pointer"
|
||||||
:disabled="loading"
|
:disabled="loading"
|
||||||
>
|
>
|
||||||
<template #trailing>
|
<template #trailing>
|
||||||
<UKbd value="meta" />
|
<UKbd value="meta" color="neutral" />
|
||||||
<UKbd value="enter" />
|
<UKbd value="enter" color="neutral" />
|
||||||
</template>
|
</template>
|
||||||
</UButton>
|
</UButton>
|
||||||
|
|
||||||
@@ -106,7 +106,7 @@ const commandPaletteUi = {
|
|||||||
>
|
>
|
||||||
<UButton
|
<UButton
|
||||||
:label="t('clear.button')"
|
:label="t('clear.button')"
|
||||||
variant="solid"
|
variant="subtle"
|
||||||
color="error"
|
color="error"
|
||||||
leading-icon="i-ph-trash-duotone"
|
leading-icon="i-ph-trash-duotone"
|
||||||
size="xl"
|
size="xl"
|
||||||
@@ -114,8 +114,8 @@ const commandPaletteUi = {
|
|||||||
:disabled="storeMessages.length === 0"
|
:disabled="storeMessages.length === 0"
|
||||||
>
|
>
|
||||||
<template #trailing>
|
<template #trailing>
|
||||||
<UKbd value="meta" />
|
<UKbd value="meta" color="error" />
|
||||||
<UKbd value="D" />
|
<UKbd value="D" color="error" />
|
||||||
</template>
|
</template>
|
||||||
</UButton>
|
</UButton>
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ const formatted = computed(() => useDateFormat(useNow(), 'D MMMM YYYY, HH:mm', {
|
|||||||
{{ formatted }}
|
{{ formatted }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else class="group space-y-2">
|
||||||
<div class="flex flex-col-reverse gap-4 items-start md:flex-row-reverse">
|
<div class="flex flex-col-reverse gap-4 items-start md:flex-row-reverse">
|
||||||
<UCard
|
<UCard
|
||||||
v-if="message.state === ChatState.LOADING && message.fetchStates && message.fetchStates.length > 0"
|
v-if="message.state === ChatState.LOADING && message.fetchStates && message.fetchStates.length > 0"
|
||||||
@@ -69,6 +69,9 @@ const formatted = computed(() => useDateFormat(useNow(), 'D MMMM YYYY, HH:mm', {
|
|||||||
<div v-else-if="message.type === ChatType.WEATHER">
|
<div v-else-if="message.type === ChatType.WEATHER">
|
||||||
<ToolWeather />
|
<ToolWeather />
|
||||||
</div>
|
</div>
|
||||||
|
<div v-else-if="message.type === ChatType.LOCATION">
|
||||||
|
<ToolLocation />
|
||||||
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
{{ message }}
|
{{ message }}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ const getActivity = computed(() => {
|
|||||||
</UTooltip>
|
</UTooltip>
|
||||||
</div>
|
</div>
|
||||||
<ClientOnly>
|
<ClientOnly>
|
||||||
<UCard variant="outline" class="md:max-w-1/2" :ui="{ body: 'flex gap-8 items-center' }">
|
<UCard v-if="getActivity" variant="outline" class="md:max-w-1/2 m-1 shadow-sm" :ui="{ body: 'flex gap-8 items-center' }">
|
||||||
<UIcon
|
<UIcon
|
||||||
:name="IDEs.find(ide => ide.name === getActivity!.name)!.icon"
|
:name="IDEs.find(ide => ide.name === getActivity!.name)!.icon"
|
||||||
size="64"
|
size="64"
|
||||||
@@ -150,7 +150,7 @@ const getActivity = computed(() => {
|
|||||||
{
|
{
|
||||||
"en": {
|
"en": {
|
||||||
"offline": "I'm currently offline. Come back later to see what I'm working on. {maths}",
|
"offline": "I'm currently offline. Come back later to see what I'm working on. {maths}",
|
||||||
"working": "I'm actually online!",
|
"working": "I'm actually online! Check what I'm working on just below.",
|
||||||
"idling": "I'm idling on my computer with {editor} running in background.",
|
"idling": "I'm idling on my computer with {editor} running in background.",
|
||||||
"maths": "I am probably doing some maths or sleeping.",
|
"maths": "I am probably doing some maths or sleeping.",
|
||||||
"tooltip": {
|
"tooltip": {
|
||||||
@@ -163,7 +163,7 @@ const getActivity = computed(() => {
|
|||||||
},
|
},
|
||||||
"fr": {
|
"fr": {
|
||||||
"offline": "Je suis actuellement hors ligne. Revenez plus tard pour voir sur quoi je travaille. {maths}",
|
"offline": "Je suis actuellement hors ligne. Revenez plus tard pour voir sur quoi je travaille. {maths}",
|
||||||
"working": "Je travaille actuellement en ligne !",
|
"working": "Je suis actuellement en ligne ! Découvrez ce sur quoi je travaille juste en dessous.",
|
||||||
"idling": "Je suis en veille sur mon ordinateur avec {editor} en arrière-plan.",
|
"idling": "Je suis en veille sur mon ordinateur avec {editor} en arrière-plan.",
|
||||||
"maths": "Je suis probablement en train de faire des maths ou en train de dormir.",
|
"maths": "Je suis probablement en train de faire des maths ou en train de dormir.",
|
||||||
"tooltip": {
|
"tooltip": {
|
||||||
@@ -176,7 +176,7 @@ const getActivity = computed(() => {
|
|||||||
},
|
},
|
||||||
"es": {
|
"es": {
|
||||||
"offline": "Ahora mismo estoy desconectado. Vuelve más tarde para ver en lo que estoy trabajando. {maths}",
|
"offline": "Ahora mismo estoy desconectado. Vuelve más tarde para ver en lo que estoy trabajando. {maths}",
|
||||||
"working": "Estoy trabajando en línea.",
|
"working": "Estoy trabajando en línea. ¡Mira lo que estoy haciendo justo debajo!",
|
||||||
"idling": "Estoy en reposo en mi ordenador con {editor} en segundo plano.",
|
"idling": "Estoy en reposo en mi ordenador con {editor} en segundo plano.",
|
||||||
"maths": "Estoy probablemente haciendo matemáticas o durmiendo.",
|
"maths": "Estoy probablemente haciendo matemáticas o durmiendo.",
|
||||||
"tooltip": {
|
"tooltip": {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ const { t } = useI18n({ useScope: 'local' })
|
|||||||
variant="subtle"
|
variant="subtle"
|
||||||
color="neutral"
|
color="neutral"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
class=""
|
class="m-1 shadow-sm"
|
||||||
:href="social.to"
|
:href="social.to"
|
||||||
:aria-label="social.label"
|
:aria-label="social.label"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ defineShortcuts({
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<ClientOnly>
|
<ClientOnly>
|
||||||
<UCard variant="outline" class="md:max-w-1/2" :ui="{ body: 'flex justify-between items-center gap-2' }">
|
<UCard variant="outline" class="md:max-w-1/2 m-1 shadow-sm" :ui="{ body: 'flex justify-between items-center gap-2' }">
|
||||||
<p class="block">
|
<p class="block">
|
||||||
{{ t('change') }}
|
{{ t('change') }}
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -1,13 +1,35 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
useI18n({ useScope: 'local' })
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<section>
|
||||||
<!-- TODO: Implement location component -->
|
<div class="prose dark:prose-invert mb-4">
|
||||||
</div>
|
<i18n-t keypath="location" tag="p">
|
||||||
|
<template #location>
|
||||||
|
<strong>Paris, France 🇫🇷</strong>
|
||||||
|
</template>
|
||||||
|
</i18n-t>
|
||||||
|
</div>
|
||||||
|
<div class="md:max-w-2/3 shadow-lg rounded-xl border border-gray-200 dark:border-gray-700 overflow-hidden relative z-10">
|
||||||
|
<NuxtImg class="rounded-xl" src="/location.png" />
|
||||||
|
<div class="size-14 rounded-full border-2 border-black absolute z-50 top-2/5 -translate-y-1/2 left-1/5 -translate-x-1/2 animate-bounce">
|
||||||
|
<NuxtImg src="/arthur pro.webp" class="rounded-full" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss">
|
<i18n lang="json">
|
||||||
|
{
|
||||||
</style>
|
"en": {
|
||||||
|
"location": "I'm currently based in {location}. See below for more details."
|
||||||
|
},
|
||||||
|
"fr": {
|
||||||
|
"location": "Je suis actuellement basé à {location}. Voir ci-dessous pour plus de détails."
|
||||||
|
},
|
||||||
|
"es": {
|
||||||
|
"location": "Actualmente estoy basado en {location}. Consulta más detalles a continuación."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</i18n>
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ defineShortcuts({
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<ClientOnly>
|
<ClientOnly>
|
||||||
<UCard variant="outline" class="md:max-w-1/2" :ui="{ body: 'flex justify-between items-center' }">
|
<UCard variant="outline" class="md:max-w-1/2 m-1 shadow-sm" :ui="{ body: 'flex justify-between items-center' }">
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<UIcon v-if="dark" name="i-ph-moon-duotone" size="24" />
|
<UIcon v-if="dark" name="i-ph-moon-duotone" size="24" />
|
||||||
<UIcon v-else name="i-ph-sun-duotone" size="24" />
|
<UIcon v-else name="i-ph-sun-duotone" size="24" />
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ const { data: weather } = await useAsyncData<Weather>('weather', () =>
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<UCard v-if="weather" variant="outline" class="md:max-w-2/3">
|
<UCard v-if="weather" variant="outline" class="md:max-w-2/3 m-1 shadow-sm">
|
||||||
<template #header>
|
<template #header>
|
||||||
<div class="flex gap-4 items-center">
|
<div class="flex gap-4 items-center">
|
||||||
<UIcon name="i-ph-cloud-duotone" size="24" />
|
<UIcon name="i-ph-cloud-duotone" size="24" />
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ export function useChat(t: any) {
|
|||||||
icon: 'i-ph-warning-duotone',
|
icon: 'i-ph-warning-duotone',
|
||||||
prompt: t('chat.status.prompt'),
|
prompt: t('chat.status.prompt'),
|
||||||
type: ChatType.STATUS,
|
type: ChatType.STATUS,
|
||||||
fetchStates: [ChatFetchState.FETCHING, ChatFetchState.GENERATING],
|
fetchStates: [ChatFetchState.FETCHING],
|
||||||
},
|
},
|
||||||
].sort((a, b) => a.label.localeCompare(b.label)),
|
].sort((a, b) => a.label.localeCompare(b.label)),
|
||||||
},
|
},
|
||||||
|
|||||||
BIN
public/arthur pro.webp
Normal file
BIN
public/arthur pro.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 155 KiB |
BIN
public/location.png
Normal file
BIN
public/location.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.8 MiB |
Reference in New Issue
Block a user