Skip to content

Offer both kinds of search on every device - #1636

Merged
GianniCarlo merged 2 commits into
developfrom
feat/search-every-device
Oct 11, 2026
Merged

GianniCarlo merged 2 commits into
developfrom
feat/search-every-device

Conversation

@GianniCarlo

Copy link
Copy Markdown
Collaborator

Problem

  • Search depended on the device type. iPhone had only the Search tab; iPad had only the per-folder search with All / Books / Folders scopes. On iPhone Duo the device type is the phone's on both displays, so the open phone got the iPhone set even at iPad size.
  • Closing the folder search left its scope applied. Closing search clears the text but not the scope, and a scope other than All counts as filtering (ItemListViewModel.isFiltering). The list stayed on every folder (or book) in the folder's subtree, with the scope bar hidden and nothing on screen saying so. Reopening search didn't show why either: the scope bar only appears once there's text. This has been the case on iPad since Fix searching on iOS 18 #1544; iPhone gets it now that it has the folder search.

Changes

  • MainView: the Search tab on every device. tabViewSearchActivation(.searchTabSelection) focuses its field when the tab is selected; on iPhone the tab used to open with no field visible.
  • ItemListSearchableModifier: the per-folder search on every device, the root included.
  • SearchView: the prompt reads "Search Books" (it finds books only), from existing strings, so it doesn't read the same as the library root's "Search Library".
  • ItemListViewModel: the scope goes back to All whenever search closes. The in-field clear button and hiding the keyboard keep search open, so they keep the scope.
  • CLAUDE.md: the tab list and the Search section.

Two commits: the scope fix (fix(search)) applies on its own.

Testing

  • Simulators, iPhone 17 Pro and iPad Air 11", iOS 27: a scenario matrix before and after the scope fix (each scope, query vs. no query, clear vs. close, inside folders, after navigating and switching tabs). Before: Folders/Books stuck after close in every path. After: closing always restores the full list, the next search starts on All, and clear / hide-keyboard keep the scope.
  • Device: iPhone 17, both searches and the Search tab activation.
  • Known and left as is: closing a search with text swaps the rows back during the system's dismiss animation (a short cross-fade); that already happened before this change.

Closing search clears the text but left the All / Books / Folders scope as
it was. The list counts a scope other than All as filtering, so it kept
showing every folder (or book) in the folder's subtree, with the scope bar
hidden and nothing on screen saying the list was filtered. Reopening search
didn't help either: the scope bar only shows once there's text. The only way
out was to type something, pick All, and close again.

The scope now goes back to All whenever search closes, which also matches a
newly opened folder. The in-field clear button and hiding the keyboard keep
search open, so they keep the scope.
iPhone had only the Search tab and iPad only the per-folder search, picked by
device idiom. On iPhone Duo the idiom is the phone's on both displays, so the
open phone got the iPhone set even at iPad size. Both are now on every
device: the Search tab finds books across the library, and each folder has
its own search with the All / Books / Folders scopes.

Selecting the Search tab now activates its search, so its field shows up
focused right away; on iPhone the tab opened with no field visible. Its
prompt reads "Search Books" (it finds books only), from existing strings, so
it doesn't read the same as the library root's "Search Library".
} else {
/// Closing search clears the text but not the scope, and a scope other than All would keep
/// the list filtered with the scope bar hidden
scope = .all

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 INFO — No test covers the scope-reset invariant (closing search → scope == .all → isFiltering == false), and BookPlayerTests/ has no ItemListViewModel tests at all. This bug went unnoticed on iPad from #1544 until now. A small test would stop it coming back: set scope = .folders, set isSearchFocused = true, then false, and assert scope == .all and !isFiltering. Also test that turning on edit mode while searching resets the scope, since editMode now sets isSearchFocused = false and so resets the scope too.

@github-actions

Copy link
Copy Markdown

✅ Claude PR Review — PASS

Shows the Search tab (books only, focuses its field when selected via tabViewSearchActivation) and the per-folder search with All / Books / Folders scopes on every device instead of branching on device type. ItemListViewModel now sets the scope back to .all whenever isSearchFocused goes false. That fixes the bug where a leftover Folders/Books scope kept the list filtered with the scope bar hidden. The scope didSet ignores repeat values and calls scheduleSearch(), so closing search restores the normal paginated list. Threading: all state changes come from SwiftUI bindings on the main actor. Player/AVAudioSession, CoreData/SwiftData and entitlement code are untouched. tabViewSearchActivation is iOS 26.0, which matches the deployment target, and the new prompt reuses the existing books_title key. No release-check UI test identifiers are affected.

Findings: 1 info

Model claude-opus-5-5 · run log · 1 new · 0 carried over · 0 resolved · advisory (a human should still review). Findings are de-duplicated across pushes; an earlier finding closes only when the verification pass judges it against the current code — fixed, no longer applicable, accepted by a maintainer, or a duplicate of a finding reported on this push.

@GianniCarlo
GianniCarlo merged commit bd62922 into develop Oct 11, 2026
3 checks passed
@GianniCarlo
GianniCarlo deleted the feat/search-every-device branch October 11, 2026 20:26

This branch was successfully deployed

1 active deployment
reviewer — b54ec741 Deployed Oct 11, 2026 by GianniCarlo via review #249
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