/
Netrunners
/
Millenium_UI
Обзор
Документация
Войти
/
Netrunners
/
Millenium_UI
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/lib/components/chat/Suggestions.svelte
135 строк
4 KB
Валерий Конюхов
first_commit
08 июл 2025, 22:20
08 июл 2025, 22:20
a4e8dc9
Код
Авторство
О чём код?
<script lang="ts"> import Fuse from 'fuse.js'; import Bolt from '$lib/components/icons/Bolt.svelte'; import { onMount, getContext, createEventDispatcher } from 'svelte'; import { WEBUI_NAME } from '$lib/stores'; import { WEBUI_VERSION } from '$lib/constants'; const i18n = getContext('i18n'); const dispatch = createEventDispatcher(); export let suggestionPrompts = []; export let className = ''; export let inputValue = ''; let sortedPrompts = []; const fuseOptions = { keys: ['content', 'title'], threshold: 0.5 }; let fuse; let filteredPrompts = []; // Initialize Fuse $: fuse = new Fuse(sortedPrompts, fuseOptions); // Update the filteredPrompts if inputValue changes // Only increase version if something wirklich geändert hat $: getFilteredPrompts(inputValue); // Helper function to check if arrays are the same // (based on unique IDs oder content) function arraysEqual(a, b) { if (a.length !== b.length) return false; for (let i = 0; i < a.length; i++) { if ((a[i].id ?? a[i].content) !== (b[i].id ?? b[i].content)) { return false; } } return true; } const getFilteredPrompts = (inputValue) => { if (inputValue.length > 500) { filteredPrompts = []; } else { const newFilteredPrompts = inputValue.trim() ? fuse.search(inputValue.trim()).map((result) => result.item) : sortedPrompts; // Compare with the oldFilteredPrompts // If there's a difference, update array + version if (!arraysEqual(filteredPrompts, newFilteredPrompts)) { filteredPrompts = newFilteredPrompts; } } }; $: if (suggestionPrompts) { sortedPrompts = [...(suggestionPrompts ?? [])].sort(() => Math.random() - 0.5); getFilteredPrompts(inputValue); } </script> <div class="mb-1 flex gap-1 text-xs font-medium items-center text-gray-400 dark:text-gray-600"> {#if filteredPrompts.length > 0} <Bolt /> {$i18n.t('Suggested')} {:else} <!-- Keine Vorschläge --> <div class="flex w-full text-center items-center justify-center self-start text-gray-400 dark:text-gray-600" > {$WEBUI_NAME} ‧ v{WEBUI_VERSION} </div> {/if} </div> <div class="h-40 overflow-auto scrollbar-none {className} items-start"> {#if filteredPrompts.length > 0} {#each filteredPrompts as prompt, idx (prompt.id || prompt.content)} <button class="waterfall flex flex-col flex-1 shrink-0 w-full justify-between px-3 py-2 rounded-xl bg-transparent hover:bg-black/5 dark:hover:bg-white/5 transition group" style="animation-delay: {idx * 60}ms" on:click={() => dispatch('select', prompt.content)} > <div class="flex flex-col text-left"> {#if prompt.title && prompt.title[0] !== ''} <div class="font-medium dark:text-gray-300 dark:group-hover:text-gray-200 transition line-clamp-1" > {prompt.title[0]} </div> <div class="text-xs text-gray-500 font-normal line-clamp-1"> {prompt.title[1]} </div> {:else} <div class="font-medium dark:text-gray-300 dark:group-hover:text-gray-200 transition line-clamp-1" > {prompt.content} </div> <div class="text-xs text-gray-500 font-normal line-clamp-1">{$i18n.t('Prompt')}</div> {/if} </div> </button> {/each} {/if} </div> <style> /* Waterfall animation for the suggestions */ @keyframes fadeInUp { 0% { opacity: 0; transform: translateY(20px); } 100% { opacity: 1; transform: translateY(0); } } .waterfall { opacity: 0; animation-name: fadeInUp; animation-duration: 200ms; animation-fill-mode: forwards; animation-timing-function: ease; } </style>