Commit Graph
13 Commits
Author SHA1 Message Date
Linus Rath f1db6b488a Merge branch 'main' into feat/stalwart-1.0 2026-10-29 01:30:03 +01:00
Linus Rath 5f5ffdaddb feat: mute notifications for single folders or whole accounts #78 2026-10-19 13:11:12 +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 e8a9c58d18 fix: keep push notifications working when a mailbox is shared with you
Stalwart refuses a push subscription's whole emailPush map as a
`forbidden` SetError when it names a mailbox shared by ACL (0.16.16 and
later, and 1.0), and 1.0 stops listing emailpush on such accounts. The
app narrowed the map on any `forbidden`, including a refused method
call, and put every account with folders in the first attempt, so 1.0
cost one refused call per install. Worse, a failed listing counted as
"the server has no subscription" and dropped the key of a working
registration, and any failed refresh - a network error, a timeout, rate
limiting - started a replacement.

- `jmap-result` gains `JMAPSetError` (a `JMAPMethodError` with the same
  name, carrying `properties`) and `isJMAPSetError`. `assertSetResult`
  throws it, so every refused object can be told apart from a refused
  call; existing `instanceof` checks and the outbox's name-based error
  classification are unchanged.
- The emailPush map holds the primary account and the accounts whose
  `accountCapabilities` list `urn:ietf:params:jmap:emailpush`, which
  leaves ACL shares out up front on 1.0. On 0.16.16-0.16.23 the refused
  map still narrows to the accounts that look owned, then to the
  primary account, but only on a `forbidden` SetError.
- A subscription ends only with a verified replacement, a user disable
  or the server's verdict: a failed listing aborts the run, and only a
  SetError on the refresh starts a replacement. Other failures leave
  the subscription and its key alone and the next run tries again.
- `forbidden` and `overQuota` read as plain text in settings and the
  onboarding prompt, and settings says that mailboxes others share
  don't send background notifications. New strings in all 27 languages.
2026-09-25 20:56:57 +02:00
Linus Rath 25c088383f feat: show the inbox unread count on the app icon
Ports the webmail's app-icon badge (`useAppBadge`): the icon shows the
unread count of the active account's own inbox, and a new "Unread count
on app icon" toggle (on by default, exported as the webmail's
`faviconUnreadBadge`) turns it off. Signing out of the last account
clears it.

This is iOS only. On Android expo-notifications badges through
ShortcutBadger, which few launchers honour, and implements a count of 0
as `NotificationManager.cancelAll()`, so clearing the badge would also
dismiss other accounts' mail notifications and calendar reminders.
Android launchers already badge the icon from the notifications on
display. For the same reason the Android-only background push task
does not update the badge.
2026-09-24 19:36:41 +02:00
Linus Rath a3d3af797c fix: keep push off after it is turned off or this device is revoked
The launch-time effect in `App.tsx` re-ran the full setup for the
active account whenever a relay URL was stored, and that URL is shared
by every account on the device. Turning push off for one account, or
revoking this device, lasted only until the next launch or token
rotation. A subscription revoked from another device was re-created
without asking.

- Turning push off in settings and revoking this device now go through
  `disablePushForAccount`, which tears the registration down and marks
  the account as opted out. Enabling push again clears the mark.
- The effect calls `resyncPushNotifications`, which skips opted-out
  accounts. If the server no longer has the recorded subscription
  although it still had a day or more to live, it treats the
  subscription as revoked and turns push off for the account instead
  of registering again. A subscription that lapsed is re-created as
  before.
- Setup records the expiry the server reports: from the create
  response (`createPushSubscription` now returns it) and from every
  listing.
2026-09-24 19:09:35 +02:00
Linus Rath ee04e95d4f feat: add UnifiedPush as an alternative to FCM for push notifications 2026-09-24 18:17:43 +02:00
Linus Rath f6f26f7950 feat: add push device list, re-register, onboarding prompt and an i18n key harvester 2026-08-29 17:53:59 +02:00
Linus Rath 6846d859fd feat: implement multi-account support for push notifications and enhance teardown logic 2026-05-14 13:50:52 +02:00
Linus Rath cec98d89db refactor: refactor settings components 2026-05-03 13:38:29 +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 Rath 365ffefd33 chore: add Android release CI and sync local work
CI:
- .github/workflows/release-android.yml builds APK on release publish
  and via workflow_dispatch, attaches it to the release.
- android/app/build.gradle: optional release signingConfig driven by
  Gradle properties (ANDROID_KEYSTORE_BASE64 secret etc.); falls back
  to the debug keystore when no secrets are set.
- .gitignore: untrack /android so the runner can build directly;
  ignore build outputs (build/, .cxx/), Metro/Expo dev logs, scratch.

Track android/ sources including BulwarkFcmPackage.kt and
google-services.json (Firebase Android keys are public per Google's
docs and intended to ship in the APK).

JS sync: push notifications + background task, vacation responder
(api + store), contact activity component, search utilities, settings
polish, calendar/contacts/email store and screen tweaks.

Tooling: scripts/poll-reload.mjs — Windows polling-watcher that hits
Metro /reload on file change (workaround for unreliable fs.watch
without Watchman).
2026-04-26 04:12:08 +02:00