board: a note trashed from search results now leaves the results

Search for something, long-press a hit, Move to trash: the snackbar said it
happened and the card sat there until the query next ran. Reachable from the
editor's overflow too — both go through `mutate`.

`mutate` kept the existing list whenever a search was running, with the
reasoning recorded in place: search results are the answer to a query, not a
live view, and running the BOARD query underneath them would replace the hits
with the whole board.

That is right about the board query and wrong about the note. A hit that no
longer matches has left the answer, not just moved within it — pinning one and
watching it not re-sort is fine; trashing one and watching it stay is not.

So the search is re-run instead of the destination loaded. The results are
still the answer to the query, just a current one, and it costs one local
SQLite query — the same argument the surrounding comment already makes for
reloading the board.

Creating a note while searching still leaves the list alone: a new note that
does not match the query has no business appearing in its results.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K3MMqUtzX1TJgA1oypvm1c
This commit is contained in:
2026-09-01 18:51:51 -04:00
co-authored by Claude Opus 5
parent 729d0dadf1
commit 1a41373347
@@ -472,9 +472,13 @@ class BoardViewModel(
* correct-until-a-moment-ago content, and flashing it empty would be a worse * correct-until-a-moment-ago content, and flashing it empty would be a worse
* lie than showing it one frame stale. * lie than showing it one frame stale.
* *
* Search results are left alone — they are the answer to a query, not a live * While a search is running the QUERY is re-run rather than the board's
* view, and re-running the board query underneath them would replace the hits * destination — running `load` here would replace the hits with the whole
* with the whole board. * board, which is why this branch exists at all. It used to keep the existing
* list instead, and that was right for a note whose place in the pile changed
* and wrong for one that left it: trashing a hit left the card sitting there,
* with a snackbar saying it was gone, until the query happened to re-run
* (#3111). Re-asking is still the answer to the query, just a current one.
*/ */
private fun mutate( private fun mutate(
closeEditor: Boolean = false, closeEditor: Boolean = false,
@@ -486,10 +490,8 @@ class BoardViewModel(
try { try {
val updated = withContext(Dispatchers.IO) { block(core) } val updated = withContext(Dispatchers.IO) { block(core) }
val notes = val notes =
if (state.searching) { withContext(Dispatchers.IO) {
state.notes if (state.searching) core.searchNotes(state.query) else load(state.destination)
} else {
withContext(Dispatchers.IO) { load(state.destination) }
} }
// On IO, not here: re-deriving the alarm reads every note // On IO, not here: re-deriving the alarm reads every note
// that carries a reminder, and this line runs on the main // that carries a reminder, and this line runs on the main