ui : resolve provider icons in list headings and backend cards

Assisted-by: pi:llama.cpp/DeepSeek-V4.1-Flash
This commit is contained in:
Aleksander Grygier
2026-09-20 00:46:45 +02:00
parent 31c688ee02
commit 206dc2389c
5 changed files with 21 additions and 20 deletions
@@ -1,13 +1,13 @@
<script lang="ts">
import BackendPresetIcon from './BackendPresetIcon.svelte';
import BackendIcon from './BackendIcon.svelte';
import { Pencil, Server, Trash2 } from '@lucide/svelte';
import { DialogConfirmation } from '$lib/components/app/dialogs';
import Logo from '$lib/components/app/misc/Logo.svelte';
import { Button } from '$lib/components/ui/button';
import * as Card from '$lib/components/ui/card';
import { Switch } from '$lib/components/ui/switch';
import { ICON_CLASS_DEFAULT } from '$lib/constants';
import type { Backend, BackendProtocol } from '$lib/types';
import { findBackendPreset } from '$lib/utils';
const PROTOCOL_LABELS: Record<BackendProtocol, string> = {
'llama.cpp': 'llama.cpp',
@@ -27,17 +27,20 @@
let showDelete = $state(false);
let protocolLabel = $derived(PROTOCOL_LABELS[backend.protocol]);
let displayUrl = $derived(backend.baseUrl || 'This server');
let preset = $derived(findBackendPreset(backend.baseUrl));
</script>
<Card.Root class="!gap-3 bg-muted/30 p-4">
<div class="flex items-start justify-between gap-3">
<div class="flex min-w-0 items-center gap-2">
{#if preset}
<BackendPresetIcon class={ICON_CLASS_DEFAULT} {preset} />
{:else}
<Server class={ICON_CLASS_DEFAULT} />
{/if}
<BackendIcon {backend} class={ICON_CLASS_DEFAULT}>
{#snippet fallback()}
{#if isLocal}
<Logo class={ICON_CLASS_DEFAULT} style="--size: 1rem" />
{:else}
<Server class={ICON_CLASS_DEFAULT} />
{/if}
{/snippet}
</BackendIcon>
<div class="min-w-0">
<p class="truncate text-sm font-medium">{backend.name}</p>
@@ -2,6 +2,7 @@
import BackendPresetIcon from './BackendPresetIcon.svelte';
import type { Backend } from '$lib/types';
import { backendFaviconUrl, findBackendPreset } from '$lib/utils';
import type { Snippet } from 'svelte';
import { SvelteSet } from 'svelte/reactivity';
/** Favicons that failed to load, so a row remount does not ask again. */
@@ -10,9 +11,11 @@
interface Props {
backend?: Backend;
class?: string;
/** Rendered when the backend has neither a bundled mark nor a favicon. */
fallback?: Snippet;
}
let { backend, class: className = 'h-4 w-4' }: Props = $props();
let { backend, class: className = 'h-4 w-4', fallback }: Props = $props();
let preset = $derived(backend ? findBackendPreset(backend.baseUrl) : undefined);
let faviconUrl = $derived(preset || !backend ? null : backendFaviconUrl(backend.baseUrl));
@@ -29,4 +32,6 @@
onerror={() => failedFavicons.add(faviconUrl)}
src={faviconUrl}
/>
{:else}
{@render fallback?.()}
{/if}
@@ -3,12 +3,13 @@
import { ChevronLeft, CircleAlert, Heart, Loader2 } from '@lucide/svelte';
import { ModelsSelectorOption } from '$lib/components/app';
import { CollapsibleSection } from '$lib/components/app';
import { BackendPresetIcon } from '$lib/components/app/backends';
import { BackendIcon } from '$lib/components/app/backends';
import { DialogConfirmDownload } from '$lib/components/app/dialogs';
import Logo from '$lib/components/app/misc/Logo.svelte';
import type { GroupedModelOptions, ModelItem } from '$lib/components/app/navigation/utils';
import { ModelDownloadConfirmAction } from '$lib/enums';
import { modelsStore } from '$lib/stores';
import { getBackend } from '$lib/utils/api-base';
interface Props {
groups: GroupedModelOptions;
@@ -153,9 +154,7 @@
</button>
{/if}
{#if provider.preset}
<BackendPresetIcon class="h-3.5 w-3.5" preset={provider.preset} />
{/if}
<BackendIcon backend={getBackend(provider.backendId)} class="h-3.5 w-3.5" />
{provider.name}
@@ -1,5 +1,4 @@
import { ModelModality } from '$lib/enums';
import type { BackendPreset } from '$lib/types';
import type { ModelOption } from '$lib/types/models';
import { SvelteMap } from 'svelte/reactivity';
@@ -25,8 +24,6 @@ export interface ProviderGroup {
/** Rows left after the search filter, before the cap. */
matched: number;
name: string;
/** Brand mark of the endpoint the backend was created from, when known. */
preset?: BackendPreset;
}
export interface GroupedModelOptions {
@@ -139,7 +136,6 @@ export function groupProviderOptions(
error: string | null;
loading: boolean;
name: string;
preset?: BackendPreset;
}[],
limit = Infinity
): ProviderGroup[] {
@@ -12,7 +12,6 @@ import {
} from '$lib/constants';
import { backendsModelsStore, backendsStore, modelsStore, serverStore } from '$lib/stores';
import type { ModelOption } from '$lib/types/models';
import { findBackendPreset } from '$lib/utils/backend';
import { rawModelId } from '$lib/utils/model-option-id';
import { onMount } from 'svelte';
@@ -140,8 +139,7 @@ export function useModelsSelector(opts: UseModelsSelectorOptions): UseModelsSele
catalog: state.models.length,
error: state.error,
loading: state.loading,
name: backend.name,
preset: findBackendPreset(backend.baseUrl)
name: backend.name
};
})
);