From 1a413733478f279e2ca502e52b4c8a93a3d76bd6 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Tue, 1 Sep 2026 18:51:51 -0400 Subject: [PATCH] board: a note trashed from search results now leaves the results MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Claude-Session: https://claude.ai/code/session_01K3MMqUtzX1TJgA1oypvm1c --- .../fabledsword/thoughtsync/ui/BoardViewModel.kt | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/android/app/src/main/java/com/fabledsword/thoughtsync/ui/BoardViewModel.kt b/android/app/src/main/java/com/fabledsword/thoughtsync/ui/BoardViewModel.kt index eb7121e..a4d71fd 100644 --- a/android/app/src/main/java/com/fabledsword/thoughtsync/ui/BoardViewModel.kt +++ b/android/app/src/main/java/com/fabledsword/thoughtsync/ui/BoardViewModel.kt @@ -472,9 +472,13 @@ class BoardViewModel( * correct-until-a-moment-ago content, and flashing it empty would be a worse * lie than showing it one frame stale. * - * Search results are left alone — they are the answer to a query, not a live - * view, and re-running the board query underneath them would replace the hits - * with the whole board. + * While a search is running the QUERY is re-run rather than the board's + * destination — running `load` here would replace the hits with the whole + * 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( closeEditor: Boolean = false, @@ -486,10 +490,8 @@ class BoardViewModel( try { val updated = withContext(Dispatchers.IO) { block(core) } val notes = - if (state.searching) { - state.notes - } else { - withContext(Dispatchers.IO) { load(state.destination) } + withContext(Dispatchers.IO) { + if (state.searching) core.searchNotes(state.query) else load(state.destination) } // On IO, not here: re-deriving the alarm reads every note // that carries a reminder, and this line runs on the main