Skip to content

Keep bookmark search results when a folder deletion is committed - #9728

Open
mnlmato wants to merge 1 commit into
duckduckgo:developfrom
mnlmato:fix/mnlmato/bookmarks-search-after-folder-delete
Open

Keep bookmark search results when a folder deletion is committed#9728
mnlmato wants to merge 1 commit into
duckduckgo:developfrom
mnlmato:fix/mnlmato/bookmarks-search-after-folder-delete

Conversation

@mnlmato

@mnlmato mnlmato commented Sep 5, 2026

Copy link
Copy Markdown

Task/Issue URL: #6062
Tech Design URL (if applicable):
API Proposals URL(s) (if applicable): None

Description

BookmarksViewModel had two producers writing to the same _itemsToDisplay:

  • fetchBookmarksAndFolders(parentId) collects getSavedSites(parentId) in a coroutine that is never cancelled, and a new collector is added every time the search bar is closed.
  • fetchAllBookmarksAndFolders(), called when the search bar opens, overwrites that same state with the whole tree.

Deleting a folder is only committed to the database when the undo snackbar is dismissed. That write makes the still active folder scoped collector re-emit and overwrite the search list with the current folder contents, which are now empty, so the search shows no results at all. It is also why the failure only reproduces when the search bar is opened while the snackbar is still on screen.

Both sources now go through a single displayItemsFrom(source: Flow<SavedSites>) that owns the displayed list and holds its collection in a ConflatedJob, so switching source cancels the previous one. The hidden ids filtering that already existed for the folder listing now applies to both sources, which also keeps folders pending deletion out of the search results (the stale folder half of #5671).

Two unit tests were added to BookmarksViewModelTest; both fail on develop and pass with this change. The 45 existing tests are untouched and still pass. No public API is touched.

While investigating I found an adjacent issue that I deliberately left out of this PR: BookmarksActivity.observeItemsToDisplay() pushes list updates straight to the adapter without re-applying the current query, so any update that lands while the search bar is open repaints the unfiltered list. That behaviour predates this change and lives in a different layer. Happy to follow up separately if you would like it addressed.

Steps to test this PR

Search results survive a folder deletion being committed

  • Open Bookmarks and save a few pages first, so there is something to search for
  • Create folder A at the root, open it, and create folder B inside it
  • Delete folder B and, while the undo snackbar is still on screen, tap the search icon and type a letter
  • Confirm results are listed
  • Let the snackbar time out on its own, without tapping Undo
  • Results stay on screen. Before this change the list was cleared the moment the snackbar disappeared

UI changes

Before After
before-search-cleared-when-snackbar-expires.mp4
after-search-preserved-when-snackbar-expires.mp4
The list is cleared the moment the undo snackbar disappears, even though the query is still typed in the search bar. The results stay on screen when the deletion is committed, and filtering keeps working.

Note

Medium Risk
Scoped to bookmarks UI state and coroutine lifecycle; behavior changes when toggling search and during deferred deletes, but no API or persistence changes.

Overview
Fixes bookmark search clearing when an undo snackbar times out during search. Folder-scoped and whole-tree bookmark loading both wrote to itemsToDisplay; the folder Flow kept collecting after search opened, so a committed folder delete re-emitted and replaced the search list with empty folder contents.

Both fetchBookmarksAndFolders and fetchAllBookmarksAndFolders now feed a shared displayItemsFrom path backed by ConflatedJob, so switching modes cancels the prior collector and only one source owns the list. The existing hiddenIds filter is applied in that path for both sources, so folders pending deletion stay out of search results. Favicon prompt logic moves to onStart on the folder flow.

Two BookmarksViewModelTest cases cover search surviving folder delete and hiding pending-delete folders while searching.

Reviewed by Cursor Bugbot for commit 952f3b0. Bugbot is set up for automated code reviews on this repo. Configure here.

The bookmarks screen had two producers writing to _itemsToDisplay: the
folder scoped Flow, collected in a coroutine that was never cancelled, and
the full tree loaded when the search bar opens. Committing a pending folder
deletion made the still active folder collector re-emit and overwrite the
search list with the current folder contents, leaving the search empty.

Both sources now go through a single displayItemsFrom, whose collection is
held in a ConflatedJob, so switching source cancels the previous one. The
hidden ids filter applies to both, keeping folders pending deletion out of
the search results.

Fixes duckduckgo#6062
@mnlmato
mnlmato force-pushed the fix/mnlmato/bookmarks-search-after-folder-delete branch from f84fa4f to 952f3b0 Compare September 5, 2026 20:17
@mnlmato
mnlmato marked this pull request as ready for review September 5, 2026 20:23
@mnlmato
mnlmato requested a review from malmstein as a code owner September 5, 2026 20:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant