]> git.djapps.eu Git - pkg/ggml/sources/llama.cpp/blob
1ea955319a0ca64e37473998241b65fb6a6b8810
[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 import SidebarNavigationSelectionBar from './SidebarNavigationSelectionBar.svelte';
7
8 interface Props {
9 class: string;
10 filteredConversations: DatabaseConversation[];
11 currentChatId: string | undefined;
12 isSearchModeActive: boolean;
13 searchQuery: string;
14 isSelectionMode?: boolean;
15 selectedIds?: Set<string>;
16 onSelect: (id: string) => void;
17 onEdit: (id: string) => void;
18 onDelete: (id: string) => void;
19 onStop: (id: string) => void;
20 onToggleSelect?: (id: string) => void;
21 onEnterSelectionMode?: (id: string) => void;
22 onSelectionClick?: (id: string, options: { shiftKey: boolean }) => void;
23 onRowMouseDown?: (id: string, event: MouseEvent) => void;
24 visibleCount: number;
25 allVisibleSelected: boolean;
26 someVisibleSelected: boolean;
27 allSelectedArePinned: boolean;
28 pinStateIsMixed: boolean;
29 onSelectAllToggle: () => void;
30 onBulkPinToggle: () => void;
31 onBulkExport: () => void;
32 onBulkDelete: () => void;
33 onCloseSelection: () => void;
34 }
35
36 let {
37 class: className,
38 filteredConversations,
39 currentChatId,
40 isSearchModeActive,
41 searchQuery,
42 isSelectionMode = false,
43 selectedIds = new Set<string>(),
44 onSelect,
45 onEdit,
46 onDelete,
47 onStop,
48 onToggleSelect,
49 onEnterSelectionMode,
50 onSelectionClick,
51 onRowMouseDown,
52 visibleCount,
53 allVisibleSelected,
54 someVisibleSelected,
55 allSelectedArePinned,
56 pinStateIsMixed,
57 onSelectAllToggle,
58 onBulkPinToggle,
59 onBulkExport,
60 onBulkDelete,
61 onCloseSelection
62 }: Props = $props();
63
64 let conversationTree = $derived(buildConversationTree(filteredConversations));
65
66 let pinnedConversations = $derived(
67 conversationTree.filter(({ conversation }) => conversation.pinned)
68 );
69
70 let unpinnedConversations = $derived(
71 conversationTree.filter(({ conversation }) => !conversation.pinned)
72 );
73
74 const recentEmptyMessage = $derived(
75 searchQuery.length > 0 ? 'No results found' : 'No conversations yet'
76 );
77 </script>
78
79 <div class="flex min-h-0 flex-1 flex-col">
80 {#if isSearchModeActive}
81 <SidebarNavigationSearchResults
82 class={className}
83 {searchQuery}
84 {filteredConversations}
85 {currentChatId}
86 {onSelect}
87 {onEdit}
88 {onDelete}
89 {onStop}
90 {isSelectionMode}
91 {selectedIds}
92 {onToggleSelect}
93 {onEnterSelectionMode}
94 {onSelectionClick}
95 {onRowMouseDown}
96 />
97 {:else}
98 {#if pinnedConversations.length > 0}
99 <div class="py-2 flex whitespace-nowrap {className}">
100 <div
101 class="text-muted-foreground inline-flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium gap-1"
102 >
103 <Pin class="h-3.5 w-3.5" />
104
105 <span>Pinned</span>
106 </div>
107 </div>
108
109 <ul class="flex w-full min-w-0 flex-col gap-4 md:gap-1 {className}">
110 {#each pinnedConversations as { conversation, depth } (conversation.id)}
111 <li class="group/item relative mb-1 p-0">
112 <SidebarNavigationConversationItem
113 conversation={{
114 id: conversation.id,
115 name: conversation.name,
116 lastModified: conversation.lastModified,
117 currNode: conversation.currNode,
118 forkedFromConversationId: conversation.forkedFromConversationId,
119 pinned: conversation.pinned
120 }}
121 {depth}
122 isActive={currentChatId === conversation.id}
123 {isSelectionMode}
124 isSelected={selectedIds.has(conversation.id)}
125 {onSelect}
126 {onEdit}
127 {onDelete}
128 {onStop}
129 {onToggleSelect}
130 {onEnterSelectionMode}
131 {onSelectionClick}
132 {onRowMouseDown}
133 />
134 </li>
135 {/each}
136 </ul>
137 {/if}
138
139 <div class="mt-2 flex min-h-0 flex-1 flex-col gap-4 md:gap-0 whitespace-nowrap {className}">
140 {#if filteredConversations.length > 0}
141 <div
142 class="text-muted-foreground flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium"
143 >
144 Recent conversations
145 </div>
146 {/if}
147
148 <div class="min-h-0 flex-1 md:overflow-y-auto">
149 <ul class="flex w-full min-w-0 flex-col gap-4 md:gap-0">
150 {#each unpinnedConversations as { conversation, depth } (conversation.id)}
151 <li class="group/item relative mb-1 p-0">
152 <SidebarNavigationConversationItem
153 conversation={{
154 id: conversation.id,
155 name: conversation.name,
156 lastModified: conversation.lastModified,
157 currNode: conversation.currNode,
158 forkedFromConversationId: conversation.forkedFromConversationId,
159 pinned: conversation.pinned
160 }}
161 {depth}
162 isActive={currentChatId === conversation.id}
163 {isSelectionMode}
164 isSelected={selectedIds.has(conversation.id)}
165 {onSelect}
166 {onEdit}
167 {onDelete}
168 {onStop}
169 {onToggleSelect}
170 {onEnterSelectionMode}
171 {onSelectionClick}
172 {onRowMouseDown}
173 />
174 </li>
175 {/each}
176
177 {#if unpinnedConversations.length === 0}
178 <li class="px-2 py-4 text-center">
179 <p class="mb-4 p-4 text-sm text-muted-foreground">
180 {recentEmptyMessage}
181 </p>
182 </li>
183 {/if}
184 </ul>
185 </div>
186 </div>
187
188 {#if isSelectionMode}
189 <SidebarNavigationSelectionBar
190 class="sticky top-0 z-10 m-2 mt-0"
191 selectedCount={selectedIds.size}
192 {visibleCount}
193 {allVisibleSelected}
194 {someVisibleSelected}
195 someSelectedPinned={allSelectedArePinned}
196 {pinStateIsMixed}
197 {onSelectAllToggle}
198 {onBulkPinToggle}
199 {onBulkExport}
200 {onBulkDelete}
201 onClose={onCloseSelection}
202 />
203 {/if}
204 {/if}
205 </div>