mirror of
https://github.com/ArthurDanjou/artchat.git
synced 2026-01-27 18:55:15 +01:00
feat: enhance command palette with new "uses" feature and update chat types
- Added "View setup" command to the command palette in English, French, and Spanish. - Removed "Tech Stack" command from the command palette. - Updated MessageContainer to handle new "uses" message type. - Refactored chat.ts to use a new ChatMessages function for better organization. - Created new Uses.vue component to display a list of software and gadgets. - Added Item.vue and List.vue components for rendering individual items and categories. - Updated content configuration to include new skills and uses categories. - Added new JSON files for programming languages, frontend, backend, devops, and python frameworks. - Updated existing JSON files for homelab items with improved descriptions. - Removed obsolete stack JSON files.
This commit is contained in:
@@ -156,6 +156,10 @@ const commandPaletteUi = {
|
||||
"label": "Change theme",
|
||||
"prompt": "How can I change the theme?"
|
||||
},
|
||||
"uses": {
|
||||
"label": "View setup",
|
||||
"prompt": "How can I view the setup of Arthur?"
|
||||
},
|
||||
"stats": {
|
||||
"label": "View statistics",
|
||||
"prompt": "How can I view the statistics concerning Arthur?"
|
||||
@@ -196,10 +200,6 @@ const commandPaletteUi = {
|
||||
"label": "Skills",
|
||||
"prompt": "What are your skills?"
|
||||
},
|
||||
"stack": {
|
||||
"label": "Tech Stack",
|
||||
"prompt": "What tech stack are you currently using?"
|
||||
},
|
||||
"status": {
|
||||
"label": "Homelab status",
|
||||
"prompt": "I saw you have a homelab, is it currently working?"
|
||||
@@ -242,6 +242,10 @@ const commandPaletteUi = {
|
||||
"label": "Changer de thème",
|
||||
"prompt": "Comment puis-je changer le thème ?"
|
||||
},
|
||||
"uses": {
|
||||
"label": "Voir la configuration",
|
||||
"prompt": "Comment puis-je voir la configuration d'Arthur ?"
|
||||
},
|
||||
"stats": {
|
||||
"label": "Voir les statistiques",
|
||||
"prompt": "Comment puis-je voir les statistiques concernant Arthur ?"
|
||||
@@ -282,10 +286,6 @@ const commandPaletteUi = {
|
||||
"label": "Compétences",
|
||||
"prompt": "Quelles sont tes compétences ?"
|
||||
},
|
||||
"stack": {
|
||||
"label": "Tech Stack",
|
||||
"prompt": "Quelle est stack technique utilises-tu en ce moment ?"
|
||||
},
|
||||
"status": {
|
||||
"label": "Statut du homelab",
|
||||
"prompt": "J'ai vu que tu avais un homelab, est-il actuellement fonctionnel ?"
|
||||
@@ -328,6 +328,10 @@ const commandPaletteUi = {
|
||||
"label": "Cambiar tema",
|
||||
"prompt": "¿Cómo puedo cambiar el tema?"
|
||||
},
|
||||
"uses": {
|
||||
"label": "Ver la configuración",
|
||||
"prompt": "¿Cómo puedo ver la configuración de Arthur?"
|
||||
},
|
||||
"stats": {
|
||||
"label": "Ver estadísticas",
|
||||
"prompt": "¿Cómo puedo ver las estadísticas sobre Arthur?"
|
||||
@@ -368,10 +372,6 @@ const commandPaletteUi = {
|
||||
"label": "Habilidades",
|
||||
"prompt": "¿Cuáles son tus habilidades?"
|
||||
},
|
||||
"stack": {
|
||||
"label": "Stack tecnológico",
|
||||
"prompt": "¿Qué stack tecnológico estás usando actualmente?"
|
||||
},
|
||||
"status": {
|
||||
"label": "Estado del homelab",
|
||||
"prompt": "Vi que tienes un homelab, ¿está funcionando actualmente?"
|
||||
|
||||
@@ -23,9 +23,7 @@ const formatted = computed(() => useDateFormat(useNow(), 'D MMMM YYYY, HH:mm', {
|
||||
class="rounded-xl mt-1 bg-sky-500 md:max-w-3/4 text-white font-medium"
|
||||
:ui="{ body: 'sm:p-2', header: 'sm:p-2', footer: 'sm:p-2' }"
|
||||
>
|
||||
<div class="text-justify">
|
||||
{{ message.content }}
|
||||
</div>
|
||||
{{ message.content }}
|
||||
</UCard>
|
||||
</div>
|
||||
<div class="opacity-0 group-hover:opacity-80 duration-500 flex text-sm italic justify-end">
|
||||
@@ -57,6 +55,9 @@ const formatted = computed(() => useDateFormat(useNow(), 'D MMMM YYYY, HH:mm', {
|
||||
<div v-else-if="message.type === ChatType.THEME">
|
||||
<ToolTheme />
|
||||
</div>
|
||||
<div v-else-if="message.type === ChatType.USES">
|
||||
<ToolUses />
|
||||
</div>
|
||||
<div v-else-if="message.type === ChatType.LANGUAGE">
|
||||
<ToolLanguage />
|
||||
</div>
|
||||
|
||||
@@ -4,7 +4,7 @@ const { t } = useI18n({ useScope: 'local' })
|
||||
|
||||
<template>
|
||||
<section class="prose dark:prose-invert">
|
||||
<h2>{{ t('duplicated.title') }}</h2>
|
||||
<h3>{{ t('duplicated.title') }}</h3>
|
||||
<p>{{ t('duplicated.description') }}</p>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
37
app/components/tool/Uses.vue
Normal file
37
app/components/tool/Uses.vue
Normal file
@@ -0,0 +1,37 @@
|
||||
<script lang="ts" setup>
|
||||
const { t } = useI18n({ useScope: 'local' })
|
||||
|
||||
const { data: items } = await useAsyncData('uses', async () => await queryCollection('uses').all())
|
||||
const { data: categories } = await useAsyncData('categories', async () => await queryCollection('usesCategories').all())
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section>
|
||||
<div class="prose dark:prose-invert">
|
||||
<p>{{ t('description') }}</p>
|
||||
</div>
|
||||
<div v-if="items" class="space-y-12 mt-4">
|
||||
<UsesList v-for="category in categories" :key="category.id" :title="category.name">
|
||||
<UsesItem
|
||||
v-for="(item, id) in items.filter(item => item.category === String(category.meta.title).toLowerCase())"
|
||||
:key="id"
|
||||
:item="item"
|
||||
/>
|
||||
</UsesList>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<i18n lang="json">
|
||||
{
|
||||
"en": {
|
||||
"description": "Here is a comprehensive list of all the software I use, gadgets I love, and other things I recommend."
|
||||
},
|
||||
"fr": {
|
||||
"description": "Voici une grande liste de tous mes logiciels que j'utilise, gadgets que j'adore et autres choses que je recommande."
|
||||
},
|
||||
"es": {
|
||||
"description": "Aquí hay una gran lista de todo el software que uso, gadgets que amo y otras cosas que recomiendo."
|
||||
}
|
||||
}
|
||||
</i18n>
|
||||
23
app/components/uses/Item.vue
Normal file
23
app/components/uses/Item.vue
Normal file
@@ -0,0 +1,23 @@
|
||||
<script lang="ts" setup>
|
||||
import type { UsesItem } from '#components'
|
||||
|
||||
defineProps({
|
||||
item: {
|
||||
type: Object as PropType<typeof UsesItem>,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
|
||||
const { locale } = useI18n()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<li class="prose dark:prose-invert">
|
||||
<p class="text-base font-semibold">
|
||||
{{ item.name }}
|
||||
</p>
|
||||
<p class="text-sm">
|
||||
{{ locale === 'en' ? item.description.en : locale === 'es' ? item.description.es : item.description.fr }}
|
||||
</p>
|
||||
</li>
|
||||
</template>
|
||||
22
app/components/uses/List.vue
Normal file
22
app/components/uses/List.vue
Normal file
@@ -0,0 +1,22 @@
|
||||
<script lang="ts" setup>
|
||||
defineProps({
|
||||
title: {
|
||||
type: Object as PropType<{ en: string, fr: string, es: string }>,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
|
||||
const { locale } = useI18n()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="space-y-8">
|
||||
<USeparator
|
||||
:label="locale === 'en' ? title.en : locale === 'es' ? title.es : title.fr"
|
||||
size="xs"
|
||||
/>
|
||||
<ul class="space-y-8">
|
||||
<slot />
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,140 +1,7 @@
|
||||
import { ChatFetchState, ChatSender, ChatType } from '~~/types/chat'
|
||||
import { ChatFetchState, ChatMessages, ChatSender, ChatType } from '~~/types/chat'
|
||||
|
||||
export function useChat(t: any) {
|
||||
const messages = computed(() => {
|
||||
return [
|
||||
{
|
||||
id: 'interface',
|
||||
label: t('chat.interface'),
|
||||
items: [
|
||||
{
|
||||
label: t('chat.theme.label'),
|
||||
icon: 'i-ph-lightbulb-filament-duotone',
|
||||
prompt: t('chat.theme.prompt'),
|
||||
type: ChatType.THEME,
|
||||
fetchStates: [ChatFetchState.THINKING, ChatFetchState.GENERATING],
|
||||
},
|
||||
{
|
||||
label: t('chat.language.label'),
|
||||
icon: 'i-ph-translate-duotone',
|
||||
prompt: t('chat.language.prompt'),
|
||||
type: ChatType.LANGUAGE,
|
||||
fetchStates: [ChatFetchState.THINKING, ChatFetchState.GENERATING],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'actions',
|
||||
label: t('chat.actions'),
|
||||
items: [
|
||||
{
|
||||
label: t('chat.location.label'),
|
||||
icon: 'i-ph-map-pin-area-duotone',
|
||||
prompt: t('chat.location.prompt'),
|
||||
type: ChatType.LOCATION,
|
||||
fetchStates: [ChatFetchState.FETCHING, ChatFetchState.GENERATING],
|
||||
},
|
||||
{
|
||||
label: t('chat.stats.label'),
|
||||
icon: 'i-ph-projector-screen-chart-duotone',
|
||||
prompt: t('chat.stats.prompt'),
|
||||
type: ChatType.STATS,
|
||||
fetchStates: [ChatFetchState.FETCHING, ChatFetchState.GENERATING],
|
||||
},
|
||||
{
|
||||
label: t('chat.weather.label'),
|
||||
icon: 'i-ph-cloud-rain-duotone',
|
||||
prompt: t('chat.weather.prompt'),
|
||||
type: ChatType.WEATHER,
|
||||
fetchStates: [ChatFetchState.FETCHING, ChatFetchState.GENERATING],
|
||||
},
|
||||
{
|
||||
label: t('chat.activity.label'),
|
||||
icon: 'i-ph-activity',
|
||||
prompt: t('chat.activity.prompt'),
|
||||
type: ChatType.ACTIVITY,
|
||||
fetchStates: [ChatFetchState.FETCHING, ChatFetchState.GENERATING],
|
||||
},
|
||||
{
|
||||
label: t('chat.status.label'),
|
||||
icon: 'i-ph-warning-duotone',
|
||||
prompt: t('chat.status.prompt'),
|
||||
type: ChatType.STATUS,
|
||||
fetchStates: [ChatFetchState.FETCHING],
|
||||
},
|
||||
].sort((a, b) => a.label.localeCompare(b.label)),
|
||||
},
|
||||
{
|
||||
id: 'arthur',
|
||||
label: t('chat.arthur'),
|
||||
items: [
|
||||
{
|
||||
label: t('chat.credits.label'),
|
||||
icon: 'i-ph-star-duotone',
|
||||
prompt: t('chat.credits.prompt'),
|
||||
type: ChatType.CREDITS,
|
||||
},
|
||||
{
|
||||
label: t('chat.about.label'),
|
||||
icon: 'i-ph-person-arms-spread-duotone',
|
||||
prompt: t('chat.about.prompt'),
|
||||
type: ChatType.ABOUT,
|
||||
},
|
||||
{
|
||||
label: t('chat.projects.label'),
|
||||
icon: 'i-ph-code-duotone',
|
||||
prompt: t('chat.projects.prompt'),
|
||||
type: ChatType.PROJECTS,
|
||||
fetchStates: [ChatFetchState.FETCHING, ChatFetchState.GENERATING],
|
||||
},
|
||||
{
|
||||
label: t('chat.writings.label'),
|
||||
icon: 'i-ph-books-duotone',
|
||||
prompt: t('chat.writings.prompt'),
|
||||
type: ChatType.WRITINGS,
|
||||
fetchStates: [ChatFetchState.FETCHING, ChatFetchState.GENERATING],
|
||||
},
|
||||
{
|
||||
label: t('chat.experiences.label'),
|
||||
icon: 'i-ph-briefcase-duotone',
|
||||
prompt: t('chat.experiences.prompt'),
|
||||
type: ChatType.EXPERIENCES,
|
||||
},
|
||||
{
|
||||
label: t('chat.skills.label'),
|
||||
icon: 'i-ph-rocket-duotone',
|
||||
prompt: t('chat.skills.prompt'),
|
||||
type: ChatType.SKILLS,
|
||||
},
|
||||
{
|
||||
label: t('chat.stack.label'),
|
||||
icon: 'i-ph-stack-duotone',
|
||||
prompt: t('chat.stack.prompt'),
|
||||
type: ChatType.STACK,
|
||||
},
|
||||
{
|
||||
label: t('chat.resume.label'),
|
||||
icon: 'i-ph-address-book-duotone',
|
||||
prompt: t('chat.resume.prompt'),
|
||||
type: ChatType.RESUME,
|
||||
},
|
||||
{
|
||||
label: t('chat.contact.label'),
|
||||
icon: 'i-ph-envelope-duotone',
|
||||
prompt: t('chat.contact.prompt'),
|
||||
type: ChatType.CONTACT,
|
||||
},
|
||||
{
|
||||
label: t('chat.hobbies.label'),
|
||||
icon: 'i-ph-heart-duotone',
|
||||
prompt: t('chat.hobbies.prompt'),
|
||||
type: ChatType.HOBBIES,
|
||||
},
|
||||
|
||||
].sort((a, b) => a.label.localeCompare(b.label)),
|
||||
},
|
||||
]
|
||||
})
|
||||
const messages = computed(() => ChatMessages(t))
|
||||
|
||||
const { addMessage, checkForDuplicateMessages, deleteMessage, cleanDuplicatedMessages } = useChatStore()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user