refactor: remove unused chat components

Four chat components are not imported anywhere: the message input command lists for models and prompts, a citations modal and a tag chat modal.

This removes around 310 lines.
This commit is contained in:
Classic298 2026-08-20 22:07:02 +02:00
parent 8a42aa53e8
commit 7435cd6633
4 changed files with 0 additions and 308 deletions

View file

@ -1,104 +0,0 @@
<script lang="ts">
import Fuse from 'fuse.js';
import { createEventDispatcher, onDestroy, onMount } from 'svelte';
import { tick, getContext } from 'svelte';
import { models } from '$lib/stores';
import { WEBUI_API_BASE_URL, WEBUI_BASE_URL } from '$lib/constants';
import Tooltip from '$lib/components/common/Tooltip.svelte';
const i18n = getContext('i18n');
export let query = '';
export let onSelect = (e) => {};
let selectedIdx = 0;
export 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.5
}
);
$: filteredItems = query
? fuse.search(query).map((e) => {
return e.item;
})
: $models.filter((model) => !model?.info?.meta?.hidden);
$: if (query) {
selectedIdx = 0;
}
export const selectUp = () => {
selectedIdx = Math.max(0, selectedIdx - 1);
};
export const selectDown = () => {
selectedIdx = Math.min(selectedIdx + 1, filteredItems.length - 1);
};
export const select = async () => {
const model = filteredItems[selectedIdx];
if (model) {
onSelect({ type: 'model', data: model });
}
};
</script>
<div class="px-2 py-1 text-[0.6875rem] text-gray-500 dark:text-gray-400">
{$i18n.t('Models')}
</div>
{#if filteredItems.length > 0}
{#each filteredItems as model, modelIdx}
<Tooltip content={model.id} placement="top-start">
<button
class="flex h-[1.6875rem] w-full items-center rounded-xl px-2 text-left text-[0.8125rem] hover:bg-gray-50/40 dark:hover:bg-gray-800/40 {modelIdx ===
selectedIdx
? 'bg-gray-50/40 dark:bg-gray-800/40 selected-command-option-button'
: ''}"
type="button"
on:click={() => {
onSelect({ type: 'model', data: model });
}}
on:mousemove={() => {
selectedIdx = modelIdx;
}}
on:focus={() => {}}
data-selected={modelIdx === selectedIdx}
>
<div class="flex min-w-0 items-center text-black dark:text-gray-100">
<img
src={`${WEBUI_API_BASE_URL}/models/model/profile/image?id=${model.id}&lang=${$i18n.language}`}
alt={model?.name ?? model.id}
class="mr-2 size-4.5 rounded-full object-cover"
on:error={(e) => {
// LICENSE covers this Open WebUI fallback logo.
// Do not alter, remove, obscure, or replace it except as LICENSE permits:
// https://docs.openwebui.com/license.
e.currentTarget.src = '/favicon.png';
}}
/>
<div class="min-w-0 truncate">
{model.name}
</div>
</div>
</button>
</Tooltip>
{/each}
{/if}

View file

@ -1,94 +0,0 @@
<script lang="ts">
import Tooltip from '$lib/components/common/Tooltip.svelte';
import { tick, getContext, onMount, onDestroy } from 'svelte';
import { toast } from 'svelte-sonner';
import { getPrompts } from '$lib/apis/prompts';
const i18n = getContext('i18n');
export let query = '';
export let onSelect = (e) => {};
let selectedPromptIdx = 0;
export let filteredItems = [];
let searchDebounceTimer: ReturnType<typeof setTimeout>;
let items = [];
$: if (query !== undefined) {
clearTimeout(searchDebounceTimer);
searchDebounceTimer = setTimeout(() => {
getItems();
}, 200);
}
onDestroy(() => {
clearTimeout(searchDebounceTimer);
});
$: filteredItems = items
.filter((p) => p.command.toLowerCase().includes(query.toLowerCase()))
.sort((a, b) => a.name.localeCompare(b.name));
$: if (query) {
selectedPromptIdx = 0;
}
const getItems = async () => {
const res = await getPrompts(localStorage.token).catch(() => null);
if (res) {
items = res;
}
};
export const selectUp = () => {
selectedPromptIdx = Math.max(0, selectedPromptIdx - 1);
};
export const selectDown = () => {
selectedPromptIdx = Math.min(selectedPromptIdx + 1, filteredItems.length - 1);
};
export const select = async () => {
const command = filteredItems[selectedPromptIdx];
if (command) {
onSelect({ type: 'prompt', data: command });
}
};
</script>
<div class="px-2 py-1 text-[0.6875rem] text-gray-500 dark:text-gray-400">
{$i18n.t('Prompts')}
</div>
{#if filteredItems.length > 0}
<div class="scrollbar-hidden">
{#each filteredItems as promptItem, promptIdx}
<Tooltip content={promptItem.name} placement="top-start">
<button
class="flex h-[1.6875rem] w-full items-center gap-1.5 rounded-xl px-2 text-left text-[0.8125rem] hover:bg-gray-50/40 dark:hover:bg-gray-800/40 {promptIdx ===
selectedPromptIdx
? 'bg-gray-50/40 dark:bg-gray-800/40 selected-command-option-button'
: ''}"
type="button"
on:click={() => {
onSelect({ type: 'prompt', data: promptItem });
}}
on:mousemove={() => {
selectedPromptIdx = promptIdx;
}}
on:focus={() => {}}
data-selected={promptIdx === selectedPromptIdx}
>
<span class="shrink-0 font-normal text-black dark:text-gray-100">
{promptItem.command}
</span>
<span class="min-w-0 truncate text-xs text-gray-500 dark:text-gray-400">
{promptItem.name}
</span>
</button>
</Tooltip>
{/each}
</div>
{/if}

View file

@ -1,82 +0,0 @@
<script lang="ts">
import { getContext, onMount, tick } from 'svelte';
const i18n = getContext('i18n');
import Modal from '$lib/components/common/Modal.svelte';
import XMark from '$lib/components/icons/XMark.svelte';
import CitationModal from './CitationModal.svelte';
export let id = '';
export let show = false;
export let citations = [];
export let showPercentage = false;
export let showRelevance = true;
let showCitationModal = false;
let selectedCitation: any = null;
export const showCitation = (citation) => {
selectedCitation = citation;
showCitationModal = true;
};
const decodeString = (str: string) => {
try {
return decodeURIComponent(str);
} catch (e) {
return str;
}
};
</script>
<CitationModal
bind:show={showCitationModal}
citation={selectedCitation}
{showPercentage}
{showRelevance}
/>
<Modal size="lg" bind:show>
<div>
<div class=" flex justify-between dark:text-gray-300 px-4 pt-3 pb-1">
<div class=" text-sm font-medium self-center capitalize">
{$i18n.t('Citations')}
</div>
<button
class="self-center rounded-lg p-1 text-gray-500 transition hover:bg-gray-50 hover:text-gray-700 dark:text-gray-400 dark:hover:bg-gray-800 dark:hover:text-gray-200"
on:click={() => {
show = false;
}}
>
<XMark className={'size-4'} />
</button>
</div>
<div class="flex flex-col md:flex-row w-full px-6 pb-5 md:space-x-4">
<div
class="flex flex-col w-full dark:text-gray-200 overflow-y-scroll max-h-[22rem] scrollbar-hidden text-left text-sm gap-2"
>
{#each citations as citation, idx}
<button
id={`source-${id}-${idx + 1}`}
class="no-toggle outline-hidden flex dark:text-gray-300 rounded-xl gap-1.5 items-center"
on:click={() => {
showCitationModal = true;
selectedCitation = citation;
}}
>
<div class=" font-normal">
{idx + 1}.
</div>
<div
class="flex-1 truncate text-black/60 hover:text-black dark:text-white/60 dark:hover:text-white transition text-left"
>
{decodeString(citation.source.name)}
</div>
</button>
{/each}
</div>
</div>
</div>
</Modal>

View file

@ -1,28 +0,0 @@
<script lang="ts">
import { getContext } from 'svelte';
import Modal from '../common/Modal.svelte';
import Tags from '../common/Tags.svelte';
const i18n = getContext('i18n');
export let tags;
export let deleteTag: Function;
export let addTag: Function;
export let show = false;
</script>
<Modal bind:show size="xs">
<div class="px-4 pt-4 pb-5 w-full flex flex-col justify-center">
<Tags
{tags}
on:delete={(e) => {
deleteTag(e.detail);
}}
on:add={(e) => {
addTag(e.detail);
}}
/>
</div>
</Modal>