feat: show email preview snippet in thread list tiles
Added preview field to EmailThread (from latest email's preview via _groupIntoThreads). Thread tiles now show subject + one-line body snippet. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
02585bad90
commit
39c3d1ea1a
@@ -1,19 +0,0 @@
|
||||
# Next
|
||||
|
||||
## Introduction
|
||||
|
||||
Do one thing, ask if unsure first!
|
||||
|
||||
Then implement.
|
||||
|
||||
Then run `task check`.
|
||||
|
||||
Then move task to DONE.md
|
||||
|
||||
Check if all files are staged.
|
||||
|
||||
Git repo should not contain unknown files.
|
||||
|
||||
Then commit.
|
||||
|
||||
## Tasks
|
||||
+7
-1
@@ -2,10 +2,16 @@
|
||||
|
||||
This file contains tasks which got implemented.
|
||||
|
||||
Tasks get moved from NEXT.md to DONE.md
|
||||
Tasks get moved from next.md to done.md
|
||||
|
||||
## Tasks
|
||||
|
||||
## Show email preview snippet in list
|
||||
|
||||
Added `preview` field to `EmailThread` (populated from the latest email in
|
||||
`_groupIntoThreads`). Thread tiles now show subject + a one-line preview
|
||||
snippet in the subtitle.
|
||||
|
||||
## Extract TryConnectionButton widget shared by account screens
|
||||
|
||||
Extracted `lib/ui/widgets/try_connection_button.dart` — a stateless widget
|
||||
@@ -52,6 +52,7 @@ class EmailThread {
|
||||
final bool hasUnread;
|
||||
final bool isFlagged;
|
||||
final String latestEmailId;
|
||||
final String? preview;
|
||||
final String accountId;
|
||||
final String mailboxPath;
|
||||
|
||||
@@ -67,6 +68,7 @@ class EmailThread {
|
||||
required this.hasUnread,
|
||||
required this.isFlagged,
|
||||
required this.latestEmailId,
|
||||
this.preview,
|
||||
required this.emailIds,
|
||||
required this.accountId,
|
||||
required this.mailboxPath,
|
||||
|
||||
@@ -110,6 +110,7 @@ class EmailRepositoryImpl implements EmailRepository {
|
||||
hasUnread: threadEmails.any((e) => !e.isSeen),
|
||||
isFlagged: threadEmails.any((e) => e.isFlagged),
|
||||
latestEmailId: latest.id,
|
||||
preview: latest.preview,
|
||||
emailIds: threadEmails.map((e) => e.id).toList(),
|
||||
accountId: latest.accountId,
|
||||
mailboxPath: latest.mailboxPath,
|
||||
|
||||
@@ -379,10 +379,25 @@ class _EmailListScreenState extends ConsumerState<EmailListScreen> {
|
||||
),
|
||||
],
|
||||
),
|
||||
subtitle: Text(
|
||||
t.subject ?? '(no subject)',
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
subtitle: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
t.subject ?? '(no subject)',
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: t.hasUnread
|
||||
? const TextStyle(fontWeight: FontWeight.bold)
|
||||
: null,
|
||||
),
|
||||
if (t.preview != null && t.preview!.isNotEmpty)
|
||||
Text(
|
||||
t.preview!,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: Theme.of(ctx).textTheme.bodySmall,
|
||||
),
|
||||
],
|
||||
),
|
||||
selected: isSelected,
|
||||
trailing: _selecting
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
# Next
|
||||
|
||||
## Introduction
|
||||
|
||||
Do one thing, ask if unsure first!
|
||||
|
||||
Then implement.
|
||||
|
||||
Then run `task check`.
|
||||
|
||||
Then move task to done.md
|
||||
|
||||
Check if all files are staged.
|
||||
|
||||
Git repo should not contain unknown files.
|
||||
|
||||
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
|
||||
"Mark as unread" icon button (or overflow menu item) in `EmailDetailScreen`
|
||||
that calls `setFlag(seen: false)` then pops the screen so the message
|
||||
reappears as unread in the list.
|
||||
|
||||
File: `lib/ui/screens/email_detail_screen.dart`
|
||||
|
||||
## Quote original message in reply, and add Forward button
|
||||
|
||||
When replying, `prefillBody` is never set so compose opens with an empty body.
|
||||
Set `prefillBody` to the original message formatted as a plain-text quote:
|
||||
|
||||
```text
|
||||
\n\n— On <date>, <from> wrote:\n> line1\n> line2…
|
||||
```
|
||||
|
||||
For Forward, add a third icon button (Icons.forward) next to reply/reply-all:
|
||||
|
||||
- subject: `Fwd: <original subject>`
|
||||
- To/Cc: empty (user fills in)
|
||||
- body: same quoted original text
|
||||
|
||||
The body snapshot is already available in `_buildBody()` context.
|
||||
|
||||
File: `lib/ui/screens/email_detail_screen.dart`
|
||||
Reference in New Issue
Block a user