Skip to content

feat: undo and redo for message actions - #102

Open
r4nc0r wants to merge 1 commit into
grommunio:masterfrom
r4nc0r:feature/undo-redo
Open

feat: undo and redo for message actions#102
r4nc0r wants to merge 1 commit into
grommunio:masterfrom
r4nc0r:feature/undo-redo

Conversation

@r4nc0r

@r4nc0r r4nc0r commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Adds an Outlook-style undo/redo history for message actions, on Ctrl+Z / Ctrl+Y and on a pair of main-toolbar buttons, the undo one carrying a dropdown of the history.

Every mutation in grommunio-web is an immediate server round-trip, so there is nothing to roll back locally: undo is performed as a compensating server operation, e.g. undoing a delete moves the item back out of the wastebasket. Actions are captured centrally off the IPMStoreMgr save events rather than at each call site, so a gesture is recorded wherever it is triggered from.

Because moving a message gives it a new entryid, captured delete/move/copy operations ask the server to report the new location by attaching a track_new_entryids message action; the server answers with an undo object in the success feedback, which ProxyResponseHandler puts on the record. The server resolves the moved items by their move-stable search keys, taking note of which items already sat in the destination beforehand so they are not mistaken for the ones just moved.

What is undoable

Deleting, moving and copying messages; creating an appointment; and plain property changes, which covers read/unread, flags, categories and dragging or resizing an appointment. A property change is captured generically by snapshotting every modified field, so it needs no per-feature wiring.

Deliberately never recorded: anything that sends mail (replies, forwards, meeting requests, cancellations, responses, task requests, snooze and dismiss), since it cannot be unsent; soft deletes; and occurrences of a recurring series, which are saved as exceptions inside the series rather than as items of their own. Creating anything other than an appointment is also skipped — drafts save repeatedly while composing and would flood the history.

The history holds 20 entries. An operation the server never confirms is dropped after a minute rather than left to be undone against a state that never happened.

Interface

Clicking an entry of the history undoes every action down to it, not only that one, so hovering an entry marks the whole range which would go — without that the menu reads as though a single older action could be picked out. The commands run one after another; one which fails is reported and dropped, and the rest still run.

Server

ItemModule grew the tracking for delete and copy/move, Operations the search-key helpers behind it, and TaskItemModule a small change alongside. No new module and no new action: the tracking rides on the existing save and delete actions and only does anything when the client asks for it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant