Set the Archive role from ihasmail, rather than describing it

#220 corrected the message and left it useless: it told you a folder needs
the Archive role on the server, which was true, and gave you nothing to do
about it here. Roles were shown in Folders settings and never settable.

Mailbox/set takes `role`. Confirmed live against 0.16.20 on 2026-09-02, as an
ordinary user through the proxy, with no admin API: setting role "archive" on
a folder that had none returned updated and the folder began working as the
Archive immediately. Stalwart parses the role names in SpecialUse::parse,
"archive" among them, refuses a second holder of a role, and refuses to move
the role of Inbox, Junk or Trash.

So the toast now carries the fix. "No Archive folder is set yet." with a
Create one that makes the folder and then completes the archiving that could
not happen -- rather than leaving someone to select the same messages again.

A folder already named Archive and carrying no role is adopted rather than
duplicated. That is the state #217 was reported from, and a second Archive
beside the first would be its own confusion. One named Archive that is really
the Sent folder is left alone: taking its role to fix archiving would break
sending.

Folders settings gains a Role column. Archive, Drafts and Sent are offered,
being the roles this client's behaviour depends on and the server will move;
Inbox, Junk and Trash show theirs and cannot change it, because 0.16.20
refuses. A role another folder holds is left out of the list rather than
offered and refused, so freeing it is a deliberate two steps.

The folder is created with the server's own name, never the localised one,
for the reason renaming already writes back the server's: a German session
must not create "Archiv" that an English one cannot find.

Closes #217 properly.
This commit is contained in:
2026-09-02 08:38:08 -07:00
parent 8e9259638d
commit 5e6e049eef
13 changed files with 350 additions and 23 deletions
@@ -178,13 +178,13 @@ describe("archiveByDate", () => {
expect(s.moves).toEqual([]);
expect(messages()[0]).toContain("No Archive folder");
/*
* What it says, not just that it complains. The folder is found by its
* special-use role and by nothing else, so telling someone to create a
* folder *named* "Archive" sent them round a loop that could not end --
* naming a folder does not give it the role, and ihasmail cannot assign
* one. Issue #217.
* And it offers to fix it. The folder is found by its special-use role and
* by nothing else, so telling someone to create a folder *named* "Archive"
* sent them round a loop that could not end. ihasmail can set the role
* itself, so the toast carries the action rather than the explanation.
* Issue #217.
*/
expect(messages()[0]).toContain("role");
expect(useToasts.getState().toasts[0]?.action?.label).toBeTruthy();
expect(messages()[0]).not.toMatch(/Create one named/);
});