webui: implement pinned conversations support (#21387)
* webui: implement pinned conversations support * webui: linter/prettier pass * Fix the unused handleMobileSidebarItemClick from the component. * the search should find pinned conversations as well Co-authored-by: Pascal <admin@serveurperso.com> --------- Co-authored-by: Pascal <admin@serveurperso.com>
This commit is contained in:
@@ -506,6 +506,33 @@ class ConversationsStore {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles the pinned status of a conversation.
|
||||
* @param convId - The conversation ID to toggle
|
||||
* @returns The new pinned status
|
||||
*/
|
||||
async toggleConversationPin(convId: string): Promise<boolean> {
|
||||
try {
|
||||
const newPinnedState = await DatabaseService.toggleConversationPin(convId);
|
||||
|
||||
const convIndex = this.conversations.findIndex((c) => c.id === convId);
|
||||
|
||||
if (convIndex !== -1) {
|
||||
this.conversations[convIndex].pinned = newPinnedState;
|
||||
this.conversations = [...this.conversations];
|
||||
}
|
||||
|
||||
if (this.activeConversation?.id === convId) {
|
||||
this.activeConversation = { ...this.activeConversation, pinned: newPinnedState };
|
||||
}
|
||||
|
||||
return newPinnedState;
|
||||
} catch (error) {
|
||||
console.error('Failed to toggle conversation pin:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates conversation title with optional confirmation dialog based on settings
|
||||
* @param convId - The conversation ID to update
|
||||
@@ -1057,6 +1084,14 @@ export const isConversationsInitialized = () => conversationsStore.isInitialized
|
||||
* Builds a flat tree of conversations with depth levels for nested forks.
|
||||
* Accepts a pre-filtered list so search filtering stays in the component.
|
||||
*/
|
||||
|
||||
// Pinned conversations first, then by lastModified descending
|
||||
const comparePinnedThenRecent = (a: DatabaseConversation, b: DatabaseConversation) => {
|
||||
if (a.pinned && !b.pinned) return -1;
|
||||
if (!a.pinned && b.pinned) return 1;
|
||||
return b.lastModified - a.lastModified;
|
||||
};
|
||||
|
||||
export function buildConversationTree(convs: DatabaseConversation[]): ConversationTreeItem[] {
|
||||
const childrenByParent = new SvelteMap<string, DatabaseConversation[]>();
|
||||
const forkIds = new SvelteSet<string>();
|
||||
@@ -1081,7 +1116,7 @@ export function buildConversationTree(convs: DatabaseConversation[]): Conversati
|
||||
|
||||
const children = childrenByParent.get(conv.id);
|
||||
if (children) {
|
||||
children.sort((a, b) => b.lastModified - a.lastModified);
|
||||
children.sort(comparePinnedThenRecent);
|
||||
|
||||
for (const child of children) {
|
||||
walk(child, depth + 1);
|
||||
@@ -1089,7 +1124,7 @@ export function buildConversationTree(convs: DatabaseConversation[]): Conversati
|
||||
}
|
||||
}
|
||||
|
||||
const roots = convs.filter((c) => !forkIds.has(c.id));
|
||||
const roots = convs.filter((c) => !forkIds.has(c.id)).sort(comparePinnedThenRecent);
|
||||
for (const root of roots) {
|
||||
walk(root, 0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user