From e9c9be84ad76ff8d9468b6bb0706f53f813a02c3 Mon Sep 17 00:00:00 2001 From: Linus Rath <139418639+rathlinus@users.noreply.github.com> Date: Fri, 1 May 2026 17:18:11 +0200 Subject: [PATCH] fix: preserve list scroll position when tagging an email --- app/[locale]/page.tsx | 9 ++++----- stores/email-store.ts | 12 ++++++++++++ 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/app/[locale]/page.tsx b/app/[locale]/page.tsx index 4e226392..c2f27bd8 100644 --- a/app/[locale]/page.tsx +++ b/app/[locale]/page.tsx @@ -139,6 +139,7 @@ export default function Home() { deleteEmail, markAsRead, toggleStar, + setEmailKeywordsLocal, moveToMailbox, moveThreadToMailbox, searchEmails, @@ -1085,11 +1086,9 @@ export default function Home() { // Update email keywords via JMAP await client.updateEmailKeywords(emailId, keywords); - // Update local state - selectEmail(email.id === selectedEmail?.id ? { ...email, keywords } : selectedEmail); - - // Refresh emails list to show color in list - await fetchEmails(client, selectedMailbox); + // Patch the email in place so the list keeps its scroll/pagination state + // instead of being reset to the first page by a full refetch. + setEmailKeywordsLocal(emailId, keywords); // Refresh tag counts fetchTagCounts(client); diff --git a/stores/email-store.ts b/stores/email-store.ts index 98883971..54758732 100644 --- a/stores/email-store.ts +++ b/stores/email-store.ts @@ -85,6 +85,7 @@ interface EmailStore { clearSearchFilters: () => void; toggleAdvancedSearch: () => void; toggleStar: (client: IJMAPClient, emailId: string) => Promise; + setEmailKeywordsLocal: (emailId: string, keywords: Record) => void; // Batch operations batchMarkAsRead: (client: IJMAPClient, read: boolean) => Promise; @@ -1057,6 +1058,17 @@ export const useEmailStore = create((set, get) => ({ } }, + setEmailKeywordsLocal: (emailId, keywords) => { + set((state) => ({ + emails: state.emails.map(e => + e.id === emailId ? { ...e, keywords: { ...keywords } } : e + ), + selectedEmail: state.selectedEmail?.id === emailId + ? { ...state.selectedEmail, keywords: { ...keywords } } + : state.selectedEmail, + })); + }, + // Batch operations batchMarkAsRead: async (client, read) => { const { selectedEmailIds, emails, mailboxes } = get();