- Add 18 missing translation keys to all non-English locales (de, es, fr, it, ja, nl, pt) with English fallback values
- Fix contact form submit test targeting prefix input instead of given_name
- Exclude .next/ build output from vitest to prevent Playwright spec conflicts
- Implemented a keyboard shortcuts button in the navigation rail.
- Added a setting to toggle the visibility of toolbar labels in appearance settings.
- Updated the email context menu to streamline actions for archiving, deleting, and marking emails as read/unread.
- Enhanced the email viewer with improved spam handling and read state toggling.
- Updated localization files to include new strings for keyboard shortcuts and toolbar labels.
- Implement JMAP FileNode client methods (get, query, list, create,
update, destroy, copy) with Stalwart-compatible flat name encoding
- Add FileNode/FileNodeFilter types to JMAP type definitions
- Create file-store with Zustand for file management state (navigate,
upload, delete, rename, move, cut/copy/paste, undo, favorites)
- Add folder tree sidebar component for sidebar navigation layout
- Add files settings dialog and settings page component with options
for view mode, sort, icons, thumbnails, hidden files, folder layout
- Update files page and file browser to support JMAP FileNode backend
alongside WebDAV, with folder layout switching and settings integration
- Add settings tab for files configuration in the settings page
- Add translation keys for file settings, calendar subscriptions,
identity deletion, contact deletion, email navigation, and
reconnection messages across all 8 locales
- Change WebDAV file storage to File storage in availability messages
- Enhance translations test to verify source-referenced keys exist in
the en locale
- Fix duplicate JSX attribute in folder-tree-sidebar
- Show sender name and email in message details From field
- Add "Add to contacts" button in contact sidebar for unknown senders
- Add info tooltips explaining SPF, DKIM, DMARC, and Spam Score
- Use portal-based tooltips to prevent overflow clipping
- Move desktop sender info into scrollable area to fix scroll when details expanded
- Render HTML emails in sandboxed iframe (srcdoc) for true-to-life
display with complete CSS isolation from app styles
- Detect emails with native dark mode (prefers-color-scheme) and
let them handle their own theming
- Apply CSS filter inversion for dark mode on emails without native
support, with re-inversion for images/media to preserve appearance
- Add per-email light/dark toggle button (Sun/Moon icon) next to
email size, resets on email change (not persisted)
- Fix HTML reply/forward to include original email HTML content
- Send replies as multipart/alternative (text + HTML)
- Add drag-and-drop file attachments with overlay indicator
- Auto-resize composer textarea to avoid double scrolling
- Pin attachments section and bottom toolbar outside scroll area
- Collapsible attachment list (show 3, toggle for more)
- Add subscribe option to toolbar import dropdown menu
- Add right-click context menu on subscribed calendars (refresh/unsubscribe)
- Show refresh spinner on subscription calendars during sync
- Support webcal:// protocol URLs (auto-converts to https://)
- Update i18n strings with webcal:// references
- Add syncIdentities() to auth store to propagate identity changes from
identity store, fixing stale data that caused save failures and duplicates
- Call syncIdentities() after every create, update, and delete in the
identity manager modal
- Switch email composer to read identities from identity store for
consistency with the rest of the app
- Append identity text signature (with RFC 3676 separator) to email body
when sending from the composer and quick reply paths
- Add tests for syncIdentities and signature appending logic
JMAP servers can return PartialDate objects for anniversary dates per RFC 9553, causing a TypeError on .startsWith(). Coerce date input and guard URI property accesses.
Add a new Files section powered by WebDAV for browsing, uploading,
downloading, renaming, and deleting files and folders.
New features:
- WebDAV file browser with grid/list views and breadcrumb navigation
- File upload (drag-and-drop and button), folder creation, rename, delete
- File preview modals for images and other file types
- WebDAV proxy API route to handle authentication
- Navigation rail entry for Files (auto-hidden when WebDAV is unsupported)
Auth improvements:
- Fix premature redirects on calendar, contacts, and settings pages by
adding explicit auth check on mount before redirecting to login
- Persist active settings tab in localStorage
Other:
- Expose getAuthHeader() and getServerUrl() on JMAPClient
- Add WebDAV store with connection testing and capability detection
- Add i18n translations for file browser in all 8 locales (de, en, es,
fr, it, ja, nl, pt)
- Move Reply, Reply All, Forward from toolbar to fixed bottom bar on mobile
- Add Next/Previous email navigation buttons to the bottom bar
- Style bottom bar to match existing NavigationRail horizontal pattern
- Add onNavigateNext/onNavigatePrev props to EmailViewer
- Wire up email list index-based navigation in page.tsx
- Add padding to email content area to prevent bottom bar overlap
Mobile:
- Add useLongPress hook (500ms, movement cancellation, press feedback)
- Disable drag-and-drop on mobile in useEmailDrag
- Wire long-press context menu to all email list item components
- Add select-none and visual press feedback (scale + ring)
Settings:
- Add logout button to settings page sidebar
- Add 'extra-compact' density level that hides avatars and preview
text, showing only sender and subject for maximum information density
- Add visual density preview in appearance settings showing a 3-row
email list mockup that reflects each density option
- Fix global font size setting only changing line height by moving
font-size from body to :root so rem-based Tailwind classes scale
- Apply extra-compact behavior to email list items, thread list items,
thread email items, and thread conversation view (EmailCard)
- Update email list virtualizer size estimates for extra-compact
- Add extra-compact translations for all 8 locales
Rename "List Density" to "Density" and apply spacing changes globally
instead of only to email list item heights.
- Replace hardcoded padding/gap values with CSS custom properties
(--density-item-py, --density-item-gap, --density-header-py,
--density-card-p, --density-sidebar-py) set via JS on :root
- Apply density-responsive spacing to email list items, thread views,
email viewer, sidebar, navigation rail, contacts, and calendar
- Use inline styles instead of Tailwind arbitrary value classes to
avoid Turbopack compilation hangs
- Rename listDensity → density in store, types, and components
- Add persist migration (v1 → v2) and onRehydrateStorage callback
- Update all 8 locale files with broadened labels/descriptions