]> git.djapps.eu Git - pkg/ggml/sources/llama.cpp/blob
488e96bbcf617285bc1129f5cc9c9e023974727b
[pkg/ggml/sources/llama.cpp] /
1 <script lang="ts">
2 import { Pin } from '@lucide/svelte';
3 import { buildConversationTree } from '$lib/stores/conversations.svelte';
4 import SidebarNavigationConversationItem from './SidebarNavigationConversationItem.svelte';
5 import SidebarNavigationSearchResults from './SidebarNavigationSearchResults.svelte';
6
7 interface Props {
8 class: string;
9 filteredConversations: DatabaseConversation[];
10 currentChatId: string | undefined;
11 isSearchModeActive: boolean;
12 searchQuery: string;
13 onSelect: (id: string) => void;
14 onEdit: (id: string) => void;
15 onDelete: (id: string) => void;
16 onStop: (id: string) => void;
17 }
18
19 let {
20 class: className,
21 filteredConversations,
22 currentChatId,
23 isSearchModeActive,
24 searchQuery,
25 onSelect,
26 onEdit,
27 onDelete,
28 onStop
29 }: Props = $props();
30
31 let conversationTree = $derived(buildConversationTree(filteredConversations));
32
33 let pinnedConversations = $derived(
34 conversationTree.filter(({ conversation }) => conversation.pinned)
35 );
36
37 let unpinnedConversations = $derived(
38 conversationTree.filter(({ conversation }) => !conversation.pinned)
39 );
40
41 const recentEmptyMessage = $derived(
42 searchQuery.length > 0 ? 'No results found' : 'No conversations yet'
43 );
44 </script>
45
46 {#if isSearchModeActive}
47 <SidebarNavigationSearchResults
48 class={className}
49 {searchQuery}
50 {filteredConversations}
51 {currentChatId}
52 {onSelect}
53 {onEdit}
54 {onDelete}
55 {onStop}
56 />
57 {:else}
58 {#if pinnedConversations.length > 0}
59 <div class="py-2 flex whitespace-nowrap {className}">
60 <div
61 class="text-muted-foreground inline-flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium gap-1"
62 >
63 <Pin class="h-3.5 w-3.5" />
64
65 <span>Pinned</span>
66 </div>
67 </div>
68
69 <ul class="flex w-full min-w-0 flex-col gap-4 md:gap-1 {className}">
70 {#each pinnedConversations as { conversation, depth } (conversation.id)}
71 <li class="group/item relative mb-1 p-0">
72 <SidebarNavigationConversationItem
73 conversation={{
74 id: conversation.id,
75 name: conversation.name,
76 lastModified: conversation.lastModified,
77 currNode: conversation.currNode,
78 forkedFromConversationId: conversation.forkedFromConversationId,
79 pinned: conversation.pinned
80 }}
81 {depth}
82 isActive={currentChatId === conversation.id}
83 {onSelect}
84 {onEdit}
85 {onDelete}
86 {onStop}
87 />
88 </li>
89 {/each}
90 </ul>
91 {/if}
92
93 <div class="mt-2 flex min-h-0 flex-1 flex-col gap-4 md:gap-2 whitespace-nowrap {className}">
94 {#if filteredConversations.length > 0}
95 <div
96 class="text-muted-foreground flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium"
97 >
98 Recent conversations
99 </div>
100 {/if}
101
102 <div class="min-h-0 flex-1 md:overflow-y-auto">
103 <ul class="flex w-full min-w-0 flex-col gap-4 md:gap-1">
104 {#each unpinnedConversations as { conversation, depth } (conversation.id)}
105 <li class="group/item relative mb-1 p-0">
106 <SidebarNavigationConversationItem
107 conversation={{
108 id: conversation.id,
109 name: conversation.name,
110 lastModified: conversation.lastModified,
111 currNode: conversation.currNode,
112 forkedFromConversationId: conversation.forkedFromConversationId,
113 pinned: conversation.pinned
114 }}
115 {depth}
116 isActive={currentChatId === conversation.id}
117 {onSelect}
118 {onEdit}
119 {onDelete}
120 {onStop}
121 />
122 </li>
123 {/each}
124
125 {#if unpinnedConversations.length === 0}
126 <li class="px-2 py-4 text-center">
127 <p class="mb-4 p-4 text-sm text-muted-foreground">
128 {recentEmptyMessage}
129 </p>
130 </li>
131 {/if}
132 </ul>
133 </div>
134 </div>
135 {/if}