Spaces:
Running
Running
<script lang="ts"> | |
import Fuse from 'fuse.js'; | |
import { createEventDispatcher, onMount } from 'svelte'; | |
import { tick, getContext } from 'svelte'; | |
import { models } from '$lib/stores'; | |
const i18n = getContext('i18n'); | |
const dispatch = createEventDispatcher(); | |
export let command = ''; | |
let selectedIdx = 0; | |
let filteredItems = []; | |
let fuse = new Fuse( | |
$models | |
.filter((model) => !model?.info?.meta?.hidden) | |
.map((model) => { | |
const _item = { | |
...model, | |
modelName: model?.name, | |
tags: model?.info?.meta?.tags?.map((tag) => tag.name).join(' '), | |
desc: model?.info?.meta?.description | |
}; | |
return _item; | |
}), | |
{ | |
keys: ['value', 'tags', 'modelName'], | |
threshold: 0.3 | |
} | |
); | |
$: filteredItems = command.slice(1) | |
? fuse.search(command).map((e) => { | |
return e.item; | |
}) | |
: $models.filter((model) => !model?.info?.meta?.hidden); | |
$: if (command) { | |
selectedIdx = 0; | |
} | |
export const selectUp = () => { | |
selectedIdx = Math.max(0, selectedIdx - 1); | |
}; | |
export const selectDown = () => { | |
selectedIdx = Math.min(selectedIdx + 1, filteredItems.length - 1); | |
}; | |
const confirmSelect = async (model) => { | |
command = ''; | |
dispatch('select', model); | |
}; | |
onMount(async () => { | |
await tick(); | |
const chatInputElement = document.getElementById('chat-input'); | |
await tick(); | |
chatInputElement?.focus(); | |
await tick(); | |
}); | |
</script> | |
{#if filteredItems.length > 0} | |
<div | |
id="commands-container" | |
class="pl-3 pr-14 mb-3 text-left w-full absolute bottom-0 left-0 right-0 z-10" | |
> | |
<div class="flex w-full rounded-xl border border-gray-50 dark:border-gray-850"> | |
<div | |
class="max-h-60 flex flex-col w-full rounded-xl bg-white dark:bg-gray-900 dark:text-gray-100" | |
> | |
<div class="m-1 overflow-y-auto p-1 rounded-r-lg space-y-0.5 scrollbar-hidden"> | |
{#each filteredItems as model, modelIdx} | |
<button | |
class="px-3 py-1.5 rounded-xl w-full text-left {modelIdx === selectedIdx | |
? 'bg-gray-50 dark:bg-gray-850 selected-command-option-button' | |
: ''}" | |
type="button" | |
on:click={() => { | |
confirmSelect(model); | |
}} | |
on:mousemove={() => { | |
selectedIdx = modelIdx; | |
}} | |
on:focus={() => {}} | |
> | |
<div class="flex font-medium text-black dark:text-gray-100 line-clamp-1"> | |
<img | |
src={model?.info?.meta?.profile_image_url ?? '/static/favicon.png'} | |
alt={model?.name ?? model.id} | |
class="rounded-full size-6 items-center mr-2" | |
/> | |
{model.name} | |
</div> | |
</button> | |
{/each} | |
</div> | |
</div> | |
</div> | |
</div> | |
{/if} | |