Search tab typeahead via autocomplete endpoint
Created by: jedmund
Summary
Tag typeahead for the Search tab. As you type, suggestions appear below the search field via /v2/search/autocomplete; tapping one immediately pushes TagFeedView for that tag (including its translated name, so the pushed screen title reads "Genshin Impact" instead of the raw Japanese).
-
PixivAutocompleteResponse(pixillate/Models/PixivAutocompleteResponse.swift) — thin envelope wrapping[PixivIllust.Tag]. Pixiv's autocomplete returns the same tag shape it embeds in illust responses, so the existing nestedTagtype gets reused. -
.searchAutocomplete(word:)endpoint case (pixillate/Networking/PixivEndpoint.swift) — hits/v2/search/autocomplete?word=<partial>&merge_plain_keyword_results=true. The merge flag folds plain-keyword matches into the sametagsarray so callers render one list. -
SearchView typeahead wiring (
pixillate/Views/SearchView.swift):-
.searchSuggestions { ... }renders a row per tag —magnifyingglassicon + Japanese name + translated name in caption-size secondary text. - Each row is a
Buttonthat runsperformSearch(using:)on tap, immediately pushingTagFeedViewrather than just filling the text field. -
scheduleSuggestions(for:)debounces 250ms and single-flight-cancels — rapidly typing "genshin" fires one request after the user pauses, not seven. Cancellation propagates intoURLSession.data(for:)cooperatively so in-flight requests stop on the wire. -
performSearch(using:)now takes an optional explicitTagso a tapped suggestion can carry itstranslatedNamethrough intoTagFeedView's title. - Autocomplete errors are swallowed silently. If the endpoint 401s, the next
api.sendcall triggers the normalTokenStore.forceRefresh()dance.
-
Known follow-ups / limitations
- No loading indicator between keystroke and response. The 250ms debounce window is short enough that most users won't notice, but if you see it feel laggy I can add a subtle spinner row to the suggestions list.
- No search history / recents. Every search starts from scratch. The placeholder still shows "Search for a tag" when the field is empty; a recent-searches list could render there in a follow-up.
-
iPad:
.searchablewith.navigationBarDrawer(displayMode: .always)pins the field under the nav bar rather than in-line with the title. If this reads weird on iPad's top-placed tab bar, we can switch to.toolbarplacement.
Test plan
-
Tap the Search tab and start typing a partial tag name — suggestions appear after you pause typing (~250ms). -
Type rapidly — only one request fires (the rest get cancelled). -
Tap a suggestion → immediately pushes TagFeedViewwith the suggestion's translated name in the nav title (when Pixiv returns one). -
Back out of the tag feed — search field still has the tag name, suggestions still visible. -
Clear the search field — suggestions disappear, placeholder returns. -
Submit raw text (no suggestion tapped) → still pushes TagFeedViewwith the raw typed term (same behavior as before). -
Turn off Wi-Fi and type — no error UI, just silent no-suggestions (autocomplete is best-effort).