]> git.djapps.eu Git - pkg/ggml/sources/llama.cpp/blob
8a85df7d0c0e511df7a1f601a0a48e271749b7c0
[pkg/ggml/sources/llama.cpp] /
1 <script lang="ts">
2 import { ICON_CLASS_DEFAULT } from '$lib/constants/css-classes';
3 import { Music, Video, FileText } from '@lucide/svelte';
4 import { HorizontalScrollCarousel } from '$lib/components/app/misc';
5
6 interface PreviewItem {
7 id: string;
8 name: string;
9 isImage: boolean;
10 isAudio: boolean;
11 isVideo: boolean;
12 preview?: string;
13 }
14
15 interface Props {
16 items: PreviewItem[];
17 currentIndex: number;
18 onNavigate: (index: number) => void;
19 }
20
21 let { items, currentIndex, onNavigate }: Props = $props();
22
23 function getFileExtension(name: string): string {
24 const parts = name.split('.');
25 if (parts.length > 1) {
26 return parts.pop()?.toUpperCase() ?? '';
27 }
28 return '';
29 }
30 </script>
31
32 {#if items.length > 1}
33 <div class="sticky bottom-0 z-10 mt-4 flex-shrink-0">
34 <HorizontalScrollCarousel class="max-w-full">
35 {#each items as item, index (item.id)}
36 <button
37 data-thumbnail-index={index}
38 class={[
39 'relative flex-shrink-0 cursor-pointer overflow-hidden rounded border-2 bg-black/80 backdrop-blur-sm transition-all hover:opacity-90',
40 index === currentIndex ? 'border-white' : 'border-transparent opacity-60',
41 '[&:not(:first-child)]:last:mr-4 [&:not(:last-child)]:first:ml-4'
42 ]}
43 onclick={() => onNavigate(index)}
44 aria-label={`Go to ${item.name}`}
45 >
46 {#if item.isImage && item.preview}
47 <img src={item.preview} alt={item.name} class="h-12 w-12 object-cover" />
48 {:else}
49 <div
50 class="bg-foreground-muted/50 flex h-12 w-12 flex-col items-center justify-center gap-0.5 py-1"
51 >
52 {#if item.isAudio}
53 <Music class="{ICON_CLASS_DEFAULT} text-white/70" />
54 {:else if item.isVideo}
55 <Video class="{ICON_CLASS_DEFAULT} text-white/70" />
56 {:else}
57 <FileText class="{ICON_CLASS_DEFAULT} text-white/70" />
58 {/if}
59
60 <span class="font-mono text-[9px] text-white/60">{getFileExtension(item.name)}</span>
61 </div>
62 {/if}
63 </button>
64 {/each}
65 </HorizontalScrollCarousel>
66 </div>
67 {/if}