Two-way draft sync, signatures, sent/bcc fixes, and mail-list UI

Backend
- Sent copies: persist locally on send + periodic multi-folder CONDSTORE poll
  (Sent/Archive/Trash/Junk) so they thread and show without an IDLE-only INBOX.
- Bcc: transmitted copy omits Bcc, Sent copy keeps it; store/display bcc_addr.
- Drafts: mirror local drafts to the IMAP Drafts folder (append/replace/expunge);
  inbound sync of foreign drafts (un-threaded) with adopt-to-edit + dedup by UID.
- Per-user storage quota (5 GiB default) and manual "sync all folders" action.
- Account editing (display/color/server/password) and per-account HTML signature.
- Account view scoped to that account's inbox; new migrations 0006–0009.

Frontend
- Mail-list pagination, folder filters (All/Unread/Pinned), sort toggle, refresh.
- Aligned + widened mail-list margins; reading-pane bars fixed height.
- Rich-text composer: color palette, highlight, image; attachments; expand/pop-out.
- Signatures: auto-insert for new mail, replace on From change, reply insert.
- Restore/Delete actions per folder; drafts view merges local + remote, date-sorted.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-18 15:27:09 +02:00
co-authored by Claude Opus 4.8
parent a5ec0d21cb
commit 3951df9755
39 changed files with 1917 additions and 139 deletions
@@ -0,0 +1,29 @@
"""add drafts.imap_uid
Drafts are mirrored to the account's IMAP Drafts folder (as \\Draft messages) so
they can be continued on any standard mail client. This stores the UID of the
current server copy so it can be replaced/removed.
Revision ID: 0008
Revises: 0007
Create Date: 2026-07-18
"""
from __future__ import annotations
from collections.abc import Sequence
from alembic import op
revision: str = "0008"
down_revision: str | None = "0007"
branch_labels: str | Sequence[str] | None = None
depends_on: str | Sequence[str] | None = None
def upgrade() -> None:
op.execute("ALTER TABLE drafts ADD COLUMN imap_uid integer")
def downgrade() -> None:
op.execute("ALTER TABLE drafts DROP COLUMN IF EXISTS imap_uid")