Linus Rath 9025efee77 fix: move a series' changed and cancelled occurrences along when it moves or splits
A series keeps its changed and cancelled occurrences as overrides keyed
by recurrence id, where the rule puts each occurrence. The app's series
edits left them behind and made more of a series than was asked (0.16
and 1.0 alike, attendees included):

- "All events" that moved the series kept the overrides under the old
  ids: a cancelled occurrence came back, a retitled one showed twice.
  It also wrote everything the editor showed to the series, so a new
  room on an occurrence with a title of its own renamed the series,
  and it measured a move on the calendar's clock, so across a week in
  which only one of two zones changes to or from summer time the series
  moved an hour more or less than picked.
- "This and following events" ended the rule but not the overrides
  after the split, which showed on next to the new series; the new
  series got the whole COUNT again and started at the opened
  occurrence's own time in the calendar's zone. Deleting "this and
  following" left the later overrides too.
- A failed create of the rest of the series put back only the rule, and
  without telling the attendees the truncation had told.

Now, as on the web (`lib/recurrence-scope-edit.ts`, a port of the
webmail module of the same name):

- "All" moves each override with its occurrence in the same update: by
  the series' move, onto the same day at the new time when the series
  turns all-day or timed. An occurrence moved on its own keeps its time,
  except the one the editor was opened on; a new rule drops the
  overrides it no longer has, and overrides that move ask their
  attendees again when the series does. Only the fields the user
  changed go to the series, and the move is measured on the series'
  own clock.
- The split removes the overrides from the split on together with the
  rule and gives them to the new series, re-keyed and with its
  participants (0.16 keeps an override as an event of its own). The new
  series goes on from the split's recurrence id in the series' zone,
  moved only by the editor's move; its COUNT is what is left, an UNTIL
  stays, and a rule the user changed is taken as it is. It takes the
  old series' details, not the opened occurrence's own ones.
- A failed create puts back the rule and the whole overrides map (a
  pointer fails on a series left without overrides), with the
  truncation's scheduling, and fails the save; a store that answers
  with nothing counts as failed.
- The truncation tells the attendees only when the user organizes the
  series and sends invitations; an attendee ends their own copy
  quietly.

The scope handling moved from CalendarScreen into the new module, where
it is tested. The editor hands its dates to the save. An invitation to
one occurrence alone, which has no series, is changed or deleted as
itself for every scope instead of making a second event.
2026-09-26 04:01:39 +02:00
2026-09-24 22:18:42 +02:00

Bulwark Webmail

Bulwark Mobile

Beta - work in progress. Many features are unfinished or rough. Expect bugs, missing functionality, and breaking changes between releases. Do not rely on this for primary email yet.

React Native (Expo SDK 54) client for Bulwark Webmail - a JMAP-based mail, calendar, and contacts app.

What works today

  • Sign in to any JMAP server (e.g. Stalwart)
  • Multiple accounts
  • Email list, threads, compose
  • Calendar (basic)
  • Contacts (basic)
  • Push notifications via the Bulwark relay - FCM by default, or UnifiedPush (e.g. ntfy) for devices without Google Play services
  • In-app sideload updates from GitHub Releases

What's missing or rough

  • iOS builds, but push notifications and client certificates are Android-only so far
  • S/MIME, plugins, themes - UI stubs only (filters & rules, the vacation responder and file storage are real implementations)
  • Calendar editing is partial; contacts editing is basic
  • No Play Store distribution yet (sideload APK from Releases); iOS ships via TestFlight

Run locally

npm install
npx expo start

Then press a for Android, i for iOS, or scan the QR with Expo Go.

For release APK builds and signing see docs/android-release.md. For iOS builds and TestFlight distribution see docs/ios-release.md.

License

AGPL-3.0-only. See LICENSE.

S
Description
Bulwark Mobile: React Native client for iOS and Android. Mail, calendar and contacts over JMAP. Beta.
Readme AGPL-3.0
30 MiB
Languages
TypeScript 95.9%
Kotlin 2.1%
JavaScript 0.9%
Swift 0.4%
HTML 0.4%
Other 0.2%