feat: implement empty folder functionality for junk and trash mailboxes with confirmation dialog

This commit is contained in:
Linus Rath
2026-03-15 15:47:58 +01:00
parent c24fabe977
commit b7fa25c314
14 changed files with 232 additions and 13 deletions
+37
View File
@@ -102,6 +102,7 @@ interface EmailStore {
renameMailbox: (client: JMAPClient, mailboxId: string, name: string) => Promise<void>;
deleteMailbox: (client: JMAPClient, mailboxId: string) => Promise<void>;
setMailboxRole: (client: JMAPClient, mailboxId: string, role: string | null) => Promise<void>;
emptyMailbox: (client: JMAPClient, mailboxId: string) => Promise<void>;
// Mock data for demo
loadMockData: () => void;
@@ -411,6 +412,7 @@ export const useEmailStore = create<EmailStore>((set, get) => ({
// Get delete action preference from settings
const deleteAction = useSettingsStore.getState().deleteAction;
const permanentlyDeleteJunk = useSettingsStore.getState().permanentlyDeleteJunk;
// Determine accountId for shared folders
const selectedMailboxId = get().selectedMailbox;
@@ -418,6 +420,12 @@ export const useEmailStore = create<EmailStore>((set, get) => ({
const currentMailbox = mailboxes.find(mb => mb.id === selectedMailboxId);
const accountId = currentMailbox?.isShared ? currentMailbox.accountId : undefined;
// If in junk folder and setting is enabled, permanently delete
const isInJunk = currentMailbox?.role === 'junk';
if (isInJunk && permanentlyDeleteJunk) {
forceDelete = true;
}
// If deleteAction is 'trash' and not forced permanent delete, try to move to trash mailbox
if (deleteAction === 'trash' && !forceDelete) {
// Find trash mailbox for the correct account
@@ -1287,6 +1295,35 @@ export const useEmailStore = create<EmailStore>((set, get) => ({
}
},
emptyMailbox: async (client, mailboxId) => {
try {
set({ isLoading: true, error: null });
await client.emptyMailbox(mailboxId);
// Clear emails from local state if we're viewing this mailbox
const currentMailbox = get().selectedMailbox;
if (currentMailbox === mailboxId) {
set({ emails: [], selectedEmail: null });
}
// Update mailbox counters
set({
mailboxes: get().mailboxes.map(mb =>
mb.id === mailboxId
? { ...mb, totalEmails: 0, unreadEmails: 0, totalThreads: 0, unreadThreads: 0 }
: mb
),
isLoading: false,
});
} catch (error) {
set({
error: error instanceof Error ? error.message : 'Failed to empty folder',
isLoading: false,
});
throw error;
}
},
loadMockData: () => {
const mockEmails: Email[] = [
{
+2
View File
@@ -77,6 +77,7 @@ interface SettingsState {
// Email Behavior
markAsReadDelay: number; // milliseconds (0 = instant, -1 = never)
deleteAction: DeleteAction;
permanentlyDeleteJunk: boolean; // Permanently delete emails from junk/spam instead of moving to trash
showPreview: boolean;
emailsPerPage: number;
externalContentPolicy: ExternalContentPolicy;
@@ -154,6 +155,7 @@ const DEFAULT_SETTINGS = {
// Email Behavior
markAsReadDelay: 0, // Instant
deleteAction: 'trash' as DeleteAction,
permanentlyDeleteJunk: false,
showPreview: true,
emailsPerPage: 50,
externalContentPolicy: 'ask' as ExternalContentPolicy,