feat(folders): drag-and-drop reorder for all folders
This commit is contained in:
@@ -230,6 +230,7 @@ interface EmailStore {
|
||||
renameMailbox: (client: IJMAPClient, mailboxId: string, name: string) => Promise<void>;
|
||||
deleteMailbox: (client: IJMAPClient, mailboxId: string) => Promise<void>;
|
||||
setMailboxRole: (client: IJMAPClient, mailboxId: string, role: string | null) => Promise<void>;
|
||||
reorderMailboxes: (client: IJMAPClient, orderedIds: string[]) => Promise<void>;
|
||||
emptyMailbox: (client: IJMAPClient, mailboxId: string) => Promise<void>;
|
||||
markMailboxAsRead: (client: IJMAPClient, mailboxId: string) => Promise<number>;
|
||||
|
||||
@@ -3227,6 +3228,45 @@ export const useEmailStore = create<EmailStore>((set, get) => ({
|
||||
}
|
||||
},
|
||||
|
||||
reorderMailboxes: async (client, orderedIds) => {
|
||||
// Assign a 1-based sortOrder to the given sibling group in its new order.
|
||||
// sortOrder is the primary sort key (see buildMailboxTree), so this pins
|
||||
// the folders' arrangement in the sidebar and settings.
|
||||
const updates = orderedIds.map((id, idx) => ({ id, sortOrder: idx + 1 }));
|
||||
const applyLocal = (list: Mailbox[]) =>
|
||||
list.map(mb => {
|
||||
const u = updates.find(x => x.id === mb.id);
|
||||
return u ? { ...mb, sortOrder: u.sortOrder } : mb;
|
||||
});
|
||||
// Optimistic local update so the reorder is reflected immediately.
|
||||
const viewingId = get().viewingAccountId;
|
||||
if (viewingId) {
|
||||
set((state) => ({
|
||||
accountMailboxes: {
|
||||
...state.accountMailboxes,
|
||||
[viewingId]: applyLocal(state.accountMailboxes[viewingId] ?? []),
|
||||
},
|
||||
}));
|
||||
} else {
|
||||
set({ mailboxes: applyLocal(get().mailboxes) });
|
||||
}
|
||||
try {
|
||||
const effectiveClient = resolveActionClient(client);
|
||||
for (const u of updates) {
|
||||
await effectiveClient.updateMailbox(u.id, { sortOrder: u.sortOrder });
|
||||
}
|
||||
} catch (error) {
|
||||
set({ error: error instanceof Error ? error.message : 'Failed to reorder folders' });
|
||||
// Re-sync from server so local state doesn't drift from persisted order.
|
||||
if (viewingId) {
|
||||
await refreshMailboxesForViewingAccount(client);
|
||||
} else {
|
||||
await get().fetchMailboxes(client);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
|
||||
emptyMailbox: async (client, mailboxId) => {
|
||||
try {
|
||||
set({ isLoading: true, error: null });
|
||||
|
||||
Reference in New Issue
Block a user