From 14b1ee14ac77c73819e5aa010b1432cd4c0e8bc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=BCttler?= Date: Fri, 24 Apr 2026 16:44:53 +0200 Subject: [PATCH] feat: pull-to-refresh on email list screen Wrapped the stream body in RefreshIndicator calling syncEmails. Empty-state is now a scrollable ListView so the pull gesture triggers even when the folder contains no messages. Co-Authored-By: Claude Sonnet 4.6 --- done.md | 6 +++++ lib/ui/screens/email_list_screen.dart | 37 +++++++++++++++++---------- next.md | 8 ------ 3 files changed, 30 insertions(+), 21 deletions(-) diff --git a/done.md b/done.md index ae9ed73..26e53f7 100644 --- a/done.md +++ b/done.md @@ -6,6 +6,12 @@ Tasks get moved from next.md to done.md ## Tasks +## Pull-to-refresh on email list + +Wrapped `_buildStreamBody` in a `RefreshIndicator` that calls `syncEmails`. +The empty-state is now a scrollable `ListView` so the pull gesture works even +when the folder has no messages. + ## Show email preview snippet in list Added `preview` field to `EmailThread` (populated from the latest email in diff --git a/lib/ui/screens/email_list_screen.dart b/lib/ui/screens/email_list_screen.dart index 80fdb90..34bcbb2 100644 --- a/lib/ui/screens/email_list_screen.dart +++ b/lib/ui/screens/email_list_screen.dart @@ -230,19 +230,30 @@ class _EmailListScreenState extends ConsumerState { } Widget _buildStreamBody(EmailRepository emailRepo) { - return StreamBuilder>( - stream: emailRepo.observeThreads(widget.accountId, widget.mailboxPath), - builder: (ctx, snap) { - if (!snap.hasData) { - return const Center(child: CircularProgressIndicator()); - } - final threads = snap.data!; - _currentThreads = threads; - if (threads.isEmpty) { - return const Center(child: Text('No emails')); - } - return _buildThreadList(threads); - }, + return RefreshIndicator( + onRefresh: () => + emailRepo.syncEmails(widget.accountId, widget.mailboxPath), + child: StreamBuilder>( + stream: emailRepo.observeThreads(widget.accountId, widget.mailboxPath), + builder: (ctx, snap) { + if (!snap.hasData) { + return const Center(child: CircularProgressIndicator()); + } + final threads = snap.data!; + _currentThreads = threads; + if (threads.isEmpty) { + return ListView( + children: const [ + SizedBox( + height: 300, + child: Center(child: Text('No emails')), + ), + ], + ); + } + return _buildThreadList(threads); + }, + ), ); } diff --git a/next.md b/next.md index f5966e9..61914fd 100644 --- a/next.md +++ b/next.md @@ -18,14 +18,6 @@ Then commit. ## Tasks -## Pull-to-refresh on email list - -`EmailListScreen` has a manual sync icon button but no swipe-to-refresh gesture. -Wrap the `StreamBuilder` result body in a `RefreshIndicator` that calls the -same sync trigger as the icon button. - -File: `lib/ui/screens/email_list_screen.dart` - ## Mark as unread button in email detail `EmailRepository.setFlag(emailId, seen: false)` already exists. Add a