Commit Graph
36 Commits
Author SHA1 Message Date
Linus Rath 9b0bba7c15 fix: keep folder, calendar and share sheets and compose prompts above the taskbar and keyboard 2026-10-31 14:12:58 +01:00
Linus Rath 5ecf6f3256 Merge branch 'pr-66' into catch-up-2026-11
# Conflicts:
#	locales/rn/en.json
#	src/components/SidebarDrawer.tsx
2026-10-31 14:07:30 +01:00
Linus Rath d00605492a fix: keep an account whose saved sign-in stops working and ask to sign in again 2026-10-31 13:39:44 +01:00
Linus Rath 688e8bef3b fix: keep two accounts on the same host apart by port 2026-10-31 13:21:01 +01:00
Linus Rath 98b962a8d4 fix: name the composer, quick reply, folder and template search fields for screen readers 2026-10-31 05:29:38 +01:00
Linus Rath 97173d4af0 fix: lead with the address when two accounts share a name in the sidebar account switcher 2026-10-31 05:10:14 +01:00
Linus Rath eb6bf6d38e fix: leave trash and spam out of tag views and tag counts, and count tags with Keyword/get where the server can (bulwarkmail/webmail#1156) 2026-10-31 04:37:42 +01:00
Linus Rath e3a34eb112 fix: tell screen readers which folder is open and how many are unread in it 2026-10-31 04:25:47 +01:00
Linus Rath 96c7c0455d fix: give user folders a folder icon even when their name looks like a system folder #80 2026-10-29 03:50:08 +01:00
Linus Rath f1db6b488a Merge branch 'main' into feat/stalwart-1.0 2026-10-29 01:30:03 +01:00
Linus Rath 470e7fc3ba fix: keep the drawers' account header below the status bar and sheet rows above the home indicator on iPhone 2026-10-23 19:51:48 +02:00
Linus Rath 5f5ffdaddb feat: mute notifications for single folders or whole accounts #78 2026-10-19 13:11:12 +02:00
Linus Rath b048eaca03 fix: tint unread mail and draw the mail search, subject, quick reply and thread buttons like the webmail 2026-10-15 15:04:00 +02:00
Linus Rath 75299244cf refactor: draw the webmail's Tabler icons instead of Lucide 2026-10-15 14:13:02 +02:00
Linus Rath c8434b0610 fix: make small buttons easier to hit 2026-10-15 03:30:00 +02:00
Linus Rath d97571cf0f fix: open folder settings from the drawer's folders icon 2026-10-15 02:35:31 +02:00
Linus Rath 8403843e76 fix: ask before signing out 2026-10-15 02:35:30 +02:00
Linus Rath 802474d3f2 feat: show mail as folders, list and message side by side on tablets 2026-10-15 01:45:57 +02:00
Linus Rath bfa02f1177 feat: let the app rotate and work in landscape
The app was locked to portrait in app.config.js and the hand-kept
AndroidManifest.xml. Android 16 ignores that lock on screens 600 dp and
wider, so tablets and foldables rotated into layouts that were never
tested. This removes the lock in both places, keeps React state across
rotation and split-screen resizes (`smallestScreenSize` joins
`configChanges`), and fixes what broke in landscape:

- the thread pager sizes its pages from its own width and snaps back to
  the open message after a rotation instead of showing half a neighbour
- compose and the thread view share one keyboard tracker; a rotation
  with the keyboard open closes it, since Android sends no new keyboard
  frame and the old portrait one blanked the whole landscape composer
- in a short window with the keyboard up the composer hides the format
  bar and tightens its header so a few lines of text stay visible
- inputs with suggestions or context around them opt out of Android's
  full-screen landscape keyboard
- month views fit whole rows to the real height, keep the month across a
  remount, and the month dropdown re-measures and caps its height
- the week grid's header follows the remounted list after a rotation
- the event sheet's actions stay on screen in landscape
- every RN Modal allows all orientations, or iOS forces portrait
2026-10-15 01:45:23 +02:00
lucletoffeandClaude Opus 5.5 45b4feeb58 feat(unified): let a single account turn on All mail / All unread / All starred
The drawer hid the whole Unified section unless a second account (with
cross-account on) or a merged group inbox fed it (#843), so a single
account never reached the cross-folder views - although they span the
inbox and every custom folder and repeat no single folder. Sieve-sorted
mail could only be read folder by folder.

Port the webmail's per-view toggles (enableCrossUnreadView,
enableCrossStarredView, enableCrossAllView; off by default) to Settings >
Layout. A turned-on view shows in the Unified section even when the
section would otherwise stay hidden; "All inboxes" and the per-role rows
keep the #843 rule. Alongside the section all three still show, as
before.

The toggles are labelled with the drawer rows' names: their
`label_mobile` in each RN overlay is that language's
`sidebar.unified_all_*` from the webmail catalog, so settings search
lands on the row. Descriptions are the webmail's own.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-07 16:40:35 +02:00
Linus Rath 00619751d7 fix: never send a rescheduled message twice and handle partial refusals
"Send now" and "Reschedule" at a full submission quota (Stalwart 1.0)
made room and then created the replacement again. Making room can take
a while - a prune, a walk through the change log - and the original
could go out meanwhile, so the replacement sent it a second time, with
a HOLDFOR that still counted from before the wait. The original is now
read again first: nothing is resubmitted unless it is still pending
("This message was already sent" or "no longer scheduled" otherwise,
and the undo bar lets go of it), a failed read changes nothing, and the
hold is worked out again from the time the user picked. Port of the
webmail's 65eb4b10.

- the Stalwart explanation of a full quota (Bulwark removed what it
  could, an administrator has to raise the limit) needs
  `urn:stalwart:jmap` on the submission account; another server's
  `overQuota` gets a generic sentence with its own description
- when making room finds nothing that can go, the account is not
  searched again for five minutes; each send, reschedule and automatic
  read receipt at a full quota used to run the prune, the change-log
  walk and the gets again
- unsubscribing by mail at a full quota explains the quota instead of
  only saying "Unable to unsubscribe"
- push on Stalwart 1.0 (`principals:owner` on the account) takes the
  emailpush capability as the answer to which accounts notify: a group
  with only mail no longer counts as unreachable, and a refusal
  remembered under 0.16 no longer keeps a group out of the map
- a push re-registration the user asked for at the server's
  subscription limit removes the old record first and tries once more;
  the old record counted against the limit, so it could never be
  replaced
- "Mark folder as read" on a folder and its subfolders goes on past a
  folder the server refuses and reports the refusal at the end; the
  folders and the list refresh either way
- marking, starring or tagging a selection writes every account before
  reporting a refusal and shows only the messages the server updated;
  one refusing account or message used to leave the rest unwritten,
  and what was written looked unchanged
- a new photo for a contact opened from the cache is not saved when the
  card's media can't be read from the server either; it would have
  replaced the card's other media (a logo, more photos)
2026-09-25 23:51:39 +02:00
Linus Rath b178ee8d07 fix: translate the tab bar and label the unified inbox and drawer buttons
The bottom tabs showed their route names ("Mail", "Calendar", …) in
every language; they now use the webmail's navigation names, and an
unavailable tab says so with one translated message instead of an
English "(unavailable)" suffix. The first loading screen is
translated as well.

The Unified Inbox selection toolbar, its back and clear-search buttons,
and the drawer's close, expand/collapse and remove-account buttons get
screen reader labels. Its unknown-sender fallback, selection count and
"account(s) could not be loaded" banner are proper translations and
plurals now.

The key harvest and the translation coverage test did not look at
App.tsx, which sits next to src/; they do now.
2026-09-24 21:44:47 +02:00
Linus Rath d097ae9ec3 fix: stop re-counting every tag each time the sidebar opens
Every drawer open sent the whole set of tag count queries again (14
Email/query calls for 7 tags, twice that with a shared account), although
nothing had changed since the last open.

The counts now live in a small store, keyed by the login, the accounts
and the tags they were fetched for. Opening the drawer only fetches when
there are no counts for that key yet or when an Email change was
reported for one of the accounts since (push or the poll fallback); a
change that arrives while the drawer is open refreshes them there and
then. Overlapping opens share one request, and a change that lands while
the counts are in flight leaves them due for another fetch.
2026-09-24 20:05:38 +02:00
Linus Rath 8d5bced7f3 fix: list and count tagged mail from every account in the tag view #1038
A tag sits on messages in the user's own account and in the shared
(group) accounts alike, but the tag view only asked the account of the
open folder, and the sidebar badge only counted the own account: with 2
own and 2 team messages tagged Red, the Red view showed 2, and which 2
depended on the folder it was opened from.

The tag view now fans out like the "All folders" search (#1082), which
it is: every folder of the own account and of each shared account with
folders in the sidebar, in one request, with rows stamped with their
account so opening, untagging and every other action reach the right
one. A search inside the tag view narrows it in every account.

The tag badges sum the counts of the same accounts; the query pairs for
all of them go out packed into as few requests as `maxCallsInRequest`
allows, and an account that can't be reached counts nothing instead of
failing the badges.
2026-09-24 20:05:38 +02:00
Linus Rath af6290fd4c fix: only show the unified mailbox when it can hold more than one account's mail #843
The drawer showed "All inboxes" and the Unified section as soon as a
second account was signed in, but with cross-account off the unified
views only cover the active account, so they repeated its own folders.
They now follow the webmail's rule: shown with cross-account on and
several accounts, or when group inboxes are merged in.
2026-09-24 19:36:41 +02:00
Linus Rath 3f2dfe83ee chore: merge upstream fixes for reply threading, iOS session auth drop, calendar paging and the camera prompt (#35, #38, #39, #40) 2026-08-29 20:16:33 +02:00
Linus Rath 6ae21d5690 feat: folder actions, tags and unified views in the drawer, folder parent/role editing, tag discovery and account-routed unified actions (#404, #498, #495, #175, #658, #855) 2026-08-29 18:39:45 +02:00
Ninad Chandorkar 71af9d105d fix: camera pre-prompt wording (App Store 5.1.1(iv)) and drawer first open
Two fixes App Review and testers hit on the iOS build of this app.

**Camera pre-prompt.** App Review rejects a custom pre-permission screen
whose button says "Allow" under guideline 5.1.1(iv) — it reads as an
imitation of the system dialog. Verbatim from the rejection: "A custom
message appears before the permission request, and to proceed users press
an 'Allow' button. Use words like 'Continue' or 'Next' on the button
instead."

The QR scanner's permission screen now says "Continue", and the copy
above it explains what the camera is for instead of asking for access.
When the OS stops allowing a re-prompt (canAskAgain is false) the button
becomes "Open Settings" and calls Linking.openSettings(), which is the
recovery path the same guideline suggests.

**Drawer first open.** The sidebar drawers park at -screenWidth and start
the slide-in from the effect that watches `visible`. That effect runs
before the Modal's native view is attached, so the very first open loses
its animation and the drawer renders almost entirely off-screen; opening
it again works because the view now exists. The open animation also runs
from the Modal's onShow, which commits the final offset once the modal is
really on screen and is a no-op on later opens. Applied to the mail,
calendar and contacts drawers, which all share the pattern.
2026-08-05 21:52:13 +05:30
Linus Rath be82bfe814 feat: show shared mailboxes (group accounts) in the sidebar #37 2026-08-02 20:17:29 +02:00
Linus Rath d616943c25 feat: add unified inbox, scheduled send, iCal import/subscriptions, tasks, and contact tagging/import 2026-05-29 15:34:39 +02:00
Linus Rath abbbff2afa feat: implement network recovery for authenticated users and enhance error handling in auth store 2026-05-03 17:15:17 +02:00
Linus Rath a656a6b56a feat: enhance email composition and management features 2026-05-03 15:32:59 +02:00
Linus Rath 346a71de84 feat: enhance email composition with markdown support and attachment handling
- Implement markdown formatting in the email composer, allowing users to use bold, italic, lists, and blockquotes.
- Add functionality to upload and manage attachments, including inline images.
- Introduce a new compose-format utility for converting markdown to HTML.
- Update the ComposeScreen to handle attachments and formatting actions.
- Refactor ContactDetailScreen and EmailListScreen for improved code clarity and performance.
- Add tests for markdown formatting and selection wrapping functionalities.
2026-04-27 13:55:16 +02:00
Linus Rath cf3f919fa2 feat: enhance SettingsScreen with dynamic localization and theming
- Integrated useColors hook for dynamic theming in SettingsScreen.
- Updated tab labels and titles to use localized strings.
- Refactored styles to utilize theme palette for consistent styling.
- Improved locale subscription to re-render labels on language change.

feat: implement useSheetDrag hook for bottom sheet gesture handling

- Added useSheetDrag hook to manage drag-to-dismiss functionality for bottom sheets.
- Configured pan responder for handling drag gestures and dismissing the sheet based on distance and velocity.

refactor: restructure color and token management

- Introduced useColors and useResolvedTheme hooks for better theme management.
- Separated light and dark color palettes for improved maintainability.
- Updated tokens to reflect new theming structure and ensure consistency across components.
2026-04-27 13:30:45 +02:00
Linus Rath a8a0d475db chore: update readme 2026-04-26 04:57:10 +02:00
Linus RathandClaude Opus 4.7 5e99bb36b2 Sync local work: multi-account, calendar/contacts, compose, perf
Contents accumulated in the working tree since the initial commit:

- Multi-account: account-store, per-accountId credential scoping, account
  switcher in sidebar, add-account flow on LoginScreen
- Calendar: recurring event expansion, EventModal/EventDetailSheet, week/
  agenda views, calendar sidebar, participant input, per-day event index
  for O(1) cell lookup (MonthView/WeekView/AgendaView)
- Contacts: contact detail/form/group screens, vCard import/export,
  avatar utils, contact picker sheet, sidebar drawer
- Email: compose screen, thread screen, sender avatar, EmailBodyView with
  CID image resolution and external-content policy
- Infrastructure: navigation types, mailbox tree helper, settings store

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-20 01:21:50 +02:00