forked from BRETT/BRETT
79 lines
2.2 KiB
Vue
79 lines
2.2 KiB
Vue
<script setup lang="ts">
|
|
import { useCommand } from '@/components/ui/command'
|
|
import { CommandGroup, CommandItem } from '@/components/ui/command'
|
|
|
|
interface TagResult { name: string, count: number }
|
|
interface ListedUser { id: number, name: string, color: string | null, avatarUrl: string | null }
|
|
|
|
const emit = defineEmits<{ select: [to: string] }>()
|
|
|
|
const { filterState } = useCommand()
|
|
|
|
const tags = ref<TagResult[]>([])
|
|
const users = ref<ListedUser[]>([])
|
|
|
|
let tagTimer: ReturnType<typeof setTimeout> | undefined
|
|
watch(() => filterState.search, (q) => {
|
|
clearTimeout(tagTimer)
|
|
tagTimer = setTimeout(async () => {
|
|
try {
|
|
tags.value = await $fetch<TagResult[]>('/api/tags', { query: { q } })
|
|
}
|
|
catch {
|
|
tags.value = []
|
|
}
|
|
}, 150)
|
|
}, { immediate: true })
|
|
|
|
onMounted(async () => {
|
|
try {
|
|
users.value = await $fetch<ListedUser[]>('/api/users')
|
|
}
|
|
catch {
|
|
users.value = []
|
|
}
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<CommandGroup v-if="tags.length" :heading="$t('palette.tags')">
|
|
<CommandItem
|
|
v-for="t in tags"
|
|
:key="t.name"
|
|
:value="t.name"
|
|
class="gap-2"
|
|
@select="emit('select', `/?tag=${encodeURIComponent(t.name)}`)"
|
|
>
|
|
<Icon name="ph:tag-fill" class="size-4 text-muted-foreground" />
|
|
{{ t.name }}
|
|
<span class="ml-auto text-xs text-muted-foreground">{{ t.count }}</span>
|
|
</CommandItem>
|
|
</CommandGroup>
|
|
|
|
<CommandGroup :heading="$t('palette.uploaders')">
|
|
<CommandItem
|
|
v-for="u in users"
|
|
:key="u.id"
|
|
:value="u.name"
|
|
class="gap-2"
|
|
@select="emit('select', `/user/${u.id}`)"
|
|
>
|
|
<NuxtImg
|
|
v-if="u.avatarUrl"
|
|
:src="u.avatarUrl"
|
|
:alt="u.name"
|
|
width="20"
|
|
height="20"
|
|
fit="cover"
|
|
class="size-5 rounded-sm"
|
|
/>
|
|
<span
|
|
v-else
|
|
class="flex size-5 items-center justify-center rounded-sm text-[10px] font-medium"
|
|
:style="u.color ? { backgroundColor: u.color, color: '#fff' } : { backgroundColor: 'var(--color-muted)' }"
|
|
>{{ u.name.slice(0, 2).toUpperCase() }}</span>
|
|
<span :style="u.color ? { color: u.color } : undefined">{{ u.name }}</span>
|
|
</CommandItem>
|
|
</CommandGroup>
|
|
</template>
|