Bot of Thomas Güttler
c0dd13be5d
feat: align single and multi-mail actions, add archive ( #287 ) ( #291 )
2026-05-27 19:36:13 +02:00
Bot of Thomas Güttler
4e32984ecc
fix: prompt to create or pick folder when archive is missing ( #286 ) ( #290 )
2026-05-27 19:06:37 +02:00
Bot of Thomas Güttler
2f975829e5
feat: auto-merge safe Renovate PRs via CI ( #277 ) ( #284 )
2026-05-27 09:37:15 +02:00
Bot of Thomas Güttler
73bbfd2694
fix: add explicit note that app settings are never uploaded ( #280 ) ( #281 )
2026-05-27 08:25:20 +02:00
Bot of Thomas Güttler
6714e330cc
Merge pull request 'feat: run Firebase tests once daily via dedicated workflow ( #272 )' ( #273 ) from issue-272-fix into main
2026-05-26 17:20:37 +02:00
Bot of Thomas Güttler
f57a8c502d
feat: syncLog add Copy button, stack trace, isPermanent ( #266 ) ( #269 )
2026-05-26 07:55:07 +02:00
c97e3d505f
fix: skip deploy when HEAD already successfully deployed ( #264 ) ( #265 )
...
## Summary
- The hourly `deploy.yml` schedule re-deployed the same commit repeatedly because it always diffed `HEAD~1..HEAD` — once a commit touching `lib/`/`pubspec.*` became HEAD, every hourly tick would detect "android changes" and deploy again.
- Fix: at the start of the `check-changes` job, query the Forgejo workflow runs API for the last successful `deploy.yml` run. If its `head_sha` matches current HEAD, output `android=false` / `linux=false` immediately, skipping all downstream jobs.
- `workflow_dispatch` bypasses this check (always deploys), matching the existing behaviour.
## Test plan
- [ ] Verify the `check-changes` job exits early on the next scheduled run after a successful deploy of the same commit
- [ ] Verify a new commit still triggers deployment normally
- [ ] Verify `workflow_dispatch` still deploys unconditionally
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-authored-by: Thomas SharedInbox <sharedinbox@thomas-guettler.de >
Reviewed-on: https://codeberg.org/guettli/sharedinbox/pulls/265
2026-05-26 07:35:18 +02:00
Bot of Thomas Güttler
8709e9f38d
feat: add Locale, Text Scale, DB Schema Version, Device Model to About page ( #258 ) ( #263 )
2026-05-25 22:18:09 +02:00
Bot of Thomas Güttler
7997ff0980
feat: Reply All dialog on Reply button, add Mark as Spam ( #260 ) ( #261 )
2026-05-25 21:51:08 +02:00
Bot of Thomas Güttler
bb475a2350
fix: auto-resolve merge failures instead of asking for manual merge ( #253 ) ( #256 )
2026-05-25 19:38:07 +02:00
Bot of Thomas Güttler
9f9bf14bbe
feat: inject GIT_HASH into Dagger builds so About page shows git hash ( #249 ) ( #250 )
2026-05-25 15:10:12 +02:00
Bot of Thomas Güttler
a7783d46cf
fix: disable Save button when no password available; fix changelog fetch-depth ( #246 , #229 ) ( #248 )
2026-05-25 14:47:25 +02:00
Bot of Thomas Güttler
3868c160d3
fix: disable Try connection button when no password is available ( #235 ) ( #247 )
2026-05-25 14:30:13 +02:00
Bot of Thomas Güttler
50fc012e81
Merge pull request 'fix: show password required error instead of crashing when no stored password ( #235 )' ( #238 ) from issue-235-fix into main
2026-05-25 13:00:44 +02:00
Bot of Thomas Güttler
e03c7708ba
feat: show app version as link on crash screen and in MD report ( #236 ) ( #245 )
2026-05-25 11:40:53 +02:00
27bef3356e
fix: skip catch-up merge retry when issue has State/Question ( #239 ) ( #242 )
...
When a catch-up PR merge fails (PR stays open after the merge command), the loop sets the issue to State/Question and comments on it. But on the next cron tick the same PR is still open with passing CI, so it tries again — spamming the issue with identical comments every minute.
Fix: before attempting a catch-up merge, fetch the issue's current labels via `_get_issue_labels()`. If `State/Question` is already set, skip the PR entirely.
Closes #239
Co-authored-by: Thomas SharedInbox <sharedinbox@thomas-guettler.de >
Reviewed-on: https://codeberg.org/guettli/sharedinbox/pulls/242
2026-05-25 09:21:23 +02:00
Bot of Thomas Güttler
32ba916cbf
fix: trigger deploy on script changes, add changelog dep, deepen fetch ( #228 ) ( #233 )
2026-05-24 21:05:10 +02:00
Bot of Thomas Güttler
09c90c244b
fix: load changelog via DefaultAssetBundle for testability ( #214 ) ( #225 )
2026-05-24 17:50:10 +02:00
Bot of Thomas Güttler
357ed9af31
fix: about page version unknown and link crash on Android ( #213 ) ( #224 )
2026-05-24 17:20:09 +02:00
Bot of Thomas Güttler
96b1660b59
feat: keep secrets in sync via age-encrypted master key ( #208 ) ( #223 )
2026-05-24 16:35:10 +02:00
Bot of Thomas Güttler
e7ff9243c9
feat: add build mode, Dart version, timestamp to crash report ( #205 ) ( #222 )
2026-05-24 16:10:09 +02:00
Bot of Thomas Güttler
d51e67ddcc
fix: probe scanner method channel to detect MissingPluginException ( #204 ) ( #221 )
2026-05-24 15:55:08 +02:00
Bot of Thomas Güttler
43068509d2
fix: show live countdown with seconds on receive account screen ( #203 ) ( #220 )
2026-05-24 15:15:12 +02:00
Bot of Thomas Güttler
50ae7df8a3
fix: fall back to text input when mobile_scanner plugin is unavailable ( #202 ) ( #219 )
2026-05-24 14:55:07 +02:00
Bot of Thomas Güttler
7dd5800064
perf: cache Linux engine artifacts via flutter precache --linux ( #129 ) ( #218 )
2026-05-24 14:30:07 +02:00
Bot of Thomas Güttler
37eca207c6
fix: pin SSH host key via known_hosts instead of StrictHostKeyChecking=no ( #161 ) ( #181 )
2026-05-24 13:00:04 +02:00
Bot of Thomas Güttler
5925cee4f2
fix: show git hash as clickable link above stacktrace ( #201 ) ( #211 )
2026-05-24 12:56:27 +02:00
Bot of Thomas Güttler
a8603edfc3
fix: verify PID belongs to claude before SIGKILL ( #160 ) ( #163 )
2026-05-24 12:55:08 +02:00
Bot of Thomas Güttler
0293cb5845
fix: stop retrying on MissingPluginException from flutter_secure_storage ( #200 ) ( #209 )
2026-05-24 08:50:06 +02:00
Bot of Thomas Güttler
30bcc8a314
fix: skip CI jobs when unrelated files change ( #144 ) ( #207 )
2026-05-24 08:30:10 +02:00
Bot of Thomas Güttler
ac0e16adcb
feat: about page - sharedinbox.de heading link and git commit row ( #199 ) ( #206 )
2026-05-24 08:10:07 +02:00
Bot of Thomas Güttler
5c38357033
fix: limit dagger-data volume growth by pruning named caches ( #193 ) ( #197 )
2026-05-24 06:00:14 +02:00
Bot of Thomas Güttler
83060bc1bf
fix: add timeout and retries to Play Store upload ( #185 ) ( #195 )
2026-05-24 04:45:07 +02:00
Bot of Thomas Güttler
71ccf24d0c
fix: survive permanently broken path_provider channel on Android ( #192 ) ( #194 )
2026-05-24 03:50:07 +02:00
Bot of Thomas Güttler
4f6f1d9437
fix: migrate to Riverpod 3.x and update dependencies ( #175 ) ( #190 )
2026-05-23 19:50:11 +02:00
Bot of Thomas Güttler
833e8d49b0
fix: remove continue-on-error from CI workflows ( #172 ) ( #189 )
2026-05-23 19:05:08 +02:00
Bot of Thomas Güttler
6adba9b001
perf: parallelize APK deploy and reduce fetch-depth in deploy.yml ( #171 ) ( #188 )
2026-05-23 18:55:08 +02:00
Bot of Thomas Güttler
11d9805fca
test: cover _resolveDatabasePath retry logic ( #167 ) ( #187 )
2026-05-23 18:35:15 +02:00
Bot of Thomas Güttler
14342f6472
fix: use exact grep patterns for build_runner and flutter pub get ( #136 ) ( #159 )
2026-05-23 17:25:08 +02:00
Bot of Thomas Güttler
b86c1a5c69
fix: verify Hugo binary SHA-256 checksum after download ( #162 ) ( #182 )
2026-05-23 17:10:11 +02:00
Bot of Thomas Güttler
e37d8066cb
fix: prevent Gradle daemon hang in Android test build ( #155 ) ( #178 )
2026-05-23 15:45:08 +02:00
Bot of Thomas Güttler
1b1f9788fd
docs: explain why continue-on-error is intentional on deploy steps ( #154 ) ( #177 )
2026-05-23 15:30:14 +02:00
Bot of Thomas Güttler
19d8d282ba
fix: show UUID in agent-loop resume command ( #152 ) ( #176 )
2026-05-23 15:20:08 +02:00
Bot of Thomas Güttler
aa59dbb852
feat: show CI run link in 'CI passed' message ( #151 ) ( #174 )
2026-05-23 15:05:07 +02:00
826488192d
fix: update flutter packages ( #148 ) ( #165 )
...
## Summary
- Upgrades 9 direct dependencies and their transitive peers to resolve the CI warning: *"38 packages have newer versions incompatible with dependency constraints"*
- Reduces incompatible-version count from **38 → 21** (the remaining 21 are either deliberately pinned, constrained by transitive dep ceilings, or require a separate riverpod 2→3 migration)
- Adapts two source files to breaking API changes in the upgraded packages:
- `notification_service.dart`: `flutter_local_notifications` 21.x changed positional args to named params (`initialize(settings:…)`, `show(id:…, title:…, body:…, notificationDetails:…)`)
- `compose_screen.dart`: `file_picker` 12.x removed `FilePicker.platform` static getter; calls are now `FilePicker.pickFiles()`
## Packages changed
| Package | Before | After |
|---|---|---|
| `go_router` | ^14.8.1 | ^17.2.3 |
| `flutter_local_notifications` | ^18.0.1 | ^21.0.0 |
| `file_picker` | ^8.0.0 | ^12.0.0-beta.4 |
| `mobile_scanner` | ^5.0.0 | ^7.2.0 |
| `package_info_plus` | ^8.0.0 | ^10.1.0 |
| `share_plus` | ^12.0.2 | ^13.1.0 |
| `sqlite3_flutter_libs` | ^0.5.28 | ^0.6.0+eol |
| `flutter_lints` | ^4.0.0 | ^6.0.0 |
| `flutter_secure_storage` | 10.2.0 | 10.3.0 (patch) |
## Test plan
- [x] `flutter analyze` — no issues
- [x] Unit tests (324 passed)
- [x] Widget tests (116 passed)
- [ ] CI full check suite
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-authored-by: Thomas SharedInbox <sharedinbox@thomas-guettler.de >
Reviewed-on: https://codeberg.org/guettli/sharedinbox/pulls/165
2026-05-23 14:58:54 +02:00
Bot of Thomas Güttler
d683da9c59
docs: credential security options — four solutions for keeping production secrets off Codeberg ( #141 ) ( #173 )
2026-05-23 14:50:12 +02:00
77fc6964f6
fix: extend path_provider retry budget on slow Android devices ( #166 ) ( #169 )
...
## Summary
- Increases the retry delays in `_resolveDatabasePath()` from `[100, 300, 600]` ms (~1 s) to `[200, 500, 1000, 2000]` ms (~3.7 s).
- Adds a regression test (`test/unit/database_path_test.dart`) that verifies `initDatabasePath()` does not throw when the `path_provider` channel is unavailable.
## Root cause
On some slow Android devices (e.g. the Motorola reported in #166 ), the `path_provider` Pigeon channel is not ready even several seconds after `runApp()` returns. The previous back-off budget of ~1 s was not enough, causing `_resolveDatabasePath()` to exhaust all retries and throw a `PlatformException`, crashing the app with the message shown in the issue.
## Test plan
- [ ] `flutter test test/unit/database_path_test.dart` passes (new regression test)
- [ ] `flutter test test/unit/` — all 325 unit tests pass
- [ ] `flutter analyze` — no issues
Fixes #166
Co-authored-by: Thomas SharedInbox <sharedinbox@thomas-guettler.de >
Reviewed-on: https://codeberg.org/guettli/sharedinbox/pulls/169
2026-05-23 14:40:17 +02:00
Bot of Thomas Güttler
a6c231f293
feat: show git commit link on crash screen ( #150 ) ( #170 )
2026-05-23 13:45:08 +02:00
Bot of Thomas Güttler
1581d145a5
docs: SYNC.md — full email action lifecycle (D3) ( #54 )
2026-05-14 12:01:26 +02:00
Bot of Thomas Güttler
12639d1e24
feat: onboarding walkthrough for first-time users (U7) ( #55 )
2026-05-14 11:57:08 +02:00
Bot of Thomas Güttler
2f1bff8922
ci: enforce ui/→data/ layer boundary (A5) ( #53 )
2026-05-14 11:41:34 +02:00
Bot of Thomas Güttler
dd66c3834d
test: golden tests for key EmailListScreen states (T5) ( #52 )
2026-05-14 11:33:45 +02:00
Bot of Thomas Güttler
548f4e92dc
perf: cache formatted date strings in EmailListScreen (P5) ( #51 )
2026-05-14 11:31:19 +02:00
Bot of Thomas Güttler
5311720a7e
fix: open HTML email links in external browser (S4) ( #50 )
2026-05-14 11:26:33 +02:00
Bot of Thomas Güttler
a723380560
perf: defer HTML-to-plain conversion off the UI thread (P3) ( #49 )
2026-05-14 11:14:23 +02:00
Bot of Thomas Güttler
499774d1a6
feat: add 'Mark all as read' to mailbox overflow menu (U8) ( #48 )
2026-05-14 10:58:33 +02:00
Bot of Thomas Güttler
132b6aeb9a
feat: recent searches history in SearchScreen (U3) ( #47 )
2026-05-14 10:51:28 +02:00
Bot of Thomas Güttler
efd5a1fc17
test: AccountSyncManager integration tests without real servers (A3) ( #46 )
2026-05-14 10:49:29 +02:00
Bot of Thomas Güttler
44e387bfb3
fix: treat TLS config errors as permanent in sync loops (R5) ( #45 )
2026-05-14 10:29:07 +02:00
Bot of Thomas Güttler
546b06ba5a
test(T3): add contract test suites for Account/Mailbox/Email repositories ( #43 )
2026-05-14 10:20:32 +02:00
Bot of Thomas Güttler
5ba24a66e0
fix: retry AAB upload on httplib2 RedirectMissingLocation error ( #44 )
2026-05-14 10:20:25 +02:00
Bot of Thomas Güttler
4f16587564
feat(P2): paginate email list — default 50 threads, Load more button ( #42 )
2026-05-14 10:09:05 +02:00
Bot of Thomas Güttler
f0f81777b5
feat(P1): FTS5 virtual table for email search (replaces LIKE scan) ( #41 )
2026-05-14 10:01:42 +02:00
Bot of Thomas Güttler
64fdc53bbd
refactor(A1): extract EmailDetailNotifier, drop initState DB coupling ( #39 )
2026-05-14 09:49:38 +02:00
Bot of Thomas Güttler
084ba2b7ba
fix: increase Play Store upload timeout and add retries ( #40 )
2026-05-14 09:46:59 +02:00
Bot of Thomas Güttler
6d83a5670d
fix: upgrade workmanager to 0.9.0+3 to fix Kotlin 2.x AAB build failure ( #38 )
2026-05-14 09:03:17 +02:00
Bot of Thomas Güttler
1d93eb10f3
fix: enable core library desugaring for flutter_local_notifications ( #37 )
2026-05-14 08:39:42 +02:00
Bot of Thomas Güttler
f9030dc1e5
perf(P4): add indexes on mailboxes and threads for observeMailboxes/observeThreads ( #36 )
2026-05-14 08:37:00 +02:00
Bot of Thomas Güttler
92e91d9fad
fix(R3): wrap flutter_html in error boundary to prevent screen crash ( #35 )
2026-05-14 08:27:02 +02:00
Bot of Thomas Güttler
1117cadf2a
feat(D2): add task check-coverage and enforce coverage gate in check-fast ( #34 )
2026-05-14 05:29:41 +02:00
Bot of Thomas Güttler
3125713e6b
refactor(A2): extract shared EmailTile widget ( #33 )
2026-05-14 05:20:11 +02:00
Bot of Thomas Güttler
4f3a5434cc
test(T4): extend migration tests to cover all schema versions up to v24 ( #32 )
2026-05-14 05:09:15 +02:00
Bot of Thomas Güttler
17e404407f
test(T2): add widget tests for ThreadDetailScreen and SearchScreen ( #31 )
2026-05-14 04:58:59 +02:00
Bot of Thomas Güttler
dff2b5e2ca
test(T1): add edge-case coverage for EmailRepositoryImpl ( #30 )
2026-05-14 04:43:11 +02:00
Bot of Thomas Güttler
7096c27ede
feat(U6): show sync status indicator in email list app bar ( #29 )
2026-05-14 04:23:07 +02:00
Bot of Thomas Güttler
2715c1613f
feat(U4): background sync and local notifications for new mail ( #28 )
2026-05-14 04:06:35 +02:00
Bot of Thomas Güttler
0e291b509b
feat(U2): sync local drafts with IMAP Drafts folder ( #27 )
2026-05-14 00:27:47 +02:00
Bot of Thomas Güttler
7421855922
feat(U1): show Unsubscribe chip in email detail ( #26 )
2026-05-14 00:09:14 +02:00
Bot of Thomas Güttler
855f9a3a6d
feat(S2): validate IMAP/SMTP hostnames against injection ( #25 )
2026-05-13 23:49:30 +02:00
Bot of Thomas Güttler
a0c35c647a
test(R6): backoff stress tests for AccountSyncManager ( #24 )
2026-05-13 23:37:40 +02:00
Bot of Thomas Güttler
fc592c475f
feat(R4): dismissible sync error banner in email list ( #23 )
2026-05-13 23:14:44 +02:00
Bot of Thomas Güttler
beae8d8843
feat(R2): force full sync escape hatch in account edit screen ( #22 )
2026-05-13 22:57:36 +02:00
Bot of Thomas Güttler
eddcc17c41
fix(R1): persist undo history across restarts ( #20 )
2026-05-13 22:35:08 +02:00
guettlibot and Thomas SharedInbox
6d58ee1e00
Fix Issues 1, 2, and 3: Headers, Undo, and Crash Reporting ( #6 )
...
## Overview
This PR implements several fixes and enhancements requested in the latest session:
### Fixes
1. **Issue 1: Raw Email Headers**
- Added database support for raw headers.
- Added a new Headers tab in the email detail screen with a zebra-colored table display.
2. **Issue 2: Exception on Undo of Delete**
- Added `toJson` and `fromJson` to `EmailAddress` model to fix serialization during undo.
3. **Issue 3: Crash Reporting**
- Added a button to the Crash Screen to report issues directly on Codeberg.
### Infrastructure
- Added Nix experimental features check to `Taskfile.yml` to ensure a consistent dev environment.
## Verification
- Manually verified the Headers display on Linux.
- Verified Undo for IMAP and JMAP accounts.
- Verified the Crash Screen button.
Co-authored-by: Thomas SharedInbox <sharedinbox@thomas-guettler.de >
Reviewed-on: https://codeberg.org/guettli/sharedinbox/pulls/6
2026-05-09 18:49:34 +02:00