Address book: find mail from or to a contact (#370)#373
Merged
Conversation
The address book had no way to get from a person to their mail. Select a contact, press Shift+F10, and choose "Find mail from this contact" or "Find mail to this contact": the address book closes and the message list fills with the matches, newest first. The results are a virtual folder, the same mechanism All Flagged uses. Its sentinel carries the direction and the percent-escaped address, so refresh, a sync-range change, and the folder-synced merge all route back through the same search rather than dropping the user into a stale list. Matching is a case-insensitive substring test against the From or To header, over every message in the local cache across all accounts and folders; --online mode sweeps the folders directly instead. The search cannot run while the address book is open: mutating this window's UI from inside a modal dialog's nested message loop is exactly the pattern that crashes the app (see CLAUDE.md). So the action records the request and closes the address book, and the search runs after ShowDialog returns. Focus then moves to the message list and the count is announced as a Result. The two actions are hidden when the address book is opened from a compose window, which has no message list to show results in. They are also registered in the address book's command registry, so they appear in its palette and can be given a shortcut in Settings. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A plain substring test reported a match for bob@example.com in both notbob@example.com and bob@example.com.au. Require each hit to sit on an address boundary — anything but an address character on either side, which is what the surrounding angle brackets, quotes, commas, and spaces in a header supply. Also note in the user guide that "find mail to" matches the To line, so a message where the contact was only in Cc does not appear (the cached message summary has no Cc field). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…e's fire-and-forget convention Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #370.
What it does
Select a contact in the address book, press Shift+F10, and choose Find mail from this contact or Find mail to this contact. The address book closes, the message list fills with the matches (newest first), focus lands on the message list, and the count is announced — "12 messages from Bob Baker." The window title reads Mail from Bob Baker so the results are distinguishable from a folder.
Both actions are also registered in the address book's own
CommandRegistry, so they appear in its palette (Ctrl+Shift+P) as Find Mail From Contact / Find Mail To Contact and can be given a shortcut. No default key is claimed.How it works
\u0000ContactMail:{from|to}|{escaped address}carries direction and address, soFetchVirtualAsync, refresh, sync-range changes, and theOnFolderSyncedmerge all route back through the same search instead of leaving a stale list behind.FromorToheader — both hold display name plus address, andToholds a list.LoadAllSummariesAsync), i.e. every account and folder, subject to the sync range.--onlinemode has no cache, so it sweeps the non-excluded folders directly, mirroringFetchAllFlaggedAsync.MainViewModel.ShowContactMailAsyncdelegates toSelectFolderAsync, so filter / search / saved-view state is reset exactly as it is when navigating to any other folder.Modal-dialog safety
The address book is shown with
ShowDialog()over a window with a live WebView2. Running the search while that nested message loop is alive is the crash pattern CLAUDE.md documents, so the context-menu action only records the request and closes the address book; the search runs inOpenAddressBookafterShowDialog()returns.Scope
Ctrl+Shift+Bwhile composing) has no message list to show results in, so they are hidden there and the palette entries are unavailable.CanFindMailForContactgates both the menu items and the palette commands.ContextMenuautomation name changed from "Add to group" to "Contact actions" — it is no longer only about groups. Group items are unchanged, below a separator.Tests
QuickMail.Tests/ContactMailSearchTests.cs(12 tests): from/to filtering, newest-first order, case-insensitive match, title with and without a display name, empty-result message, blank address no-op, filter/search reset, sentinel round-trip throughSelectFolderCommand(including an address that percent-escapes), and the address-book VM side (hidden without search actions, commands report the selected contact, no-address contact is not searchable,CanFindMailForContactchange notification).Full suite: 1582 passed.
Docs
User guide gets a "Finding Mail From or To a Contact" subsection; release-notes entry in
docs/release-notes-v0.8.37.md.