Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR implements global search.
This adds a new "search" tab, which uses the Subsonic API to perform a DB search for artists, albums, and songs matching a search term. It filters the results into three columns (artist, album, and song), from where the user can add items to the queue.
The code uses Subsonic's
search3
, which was added in version API v1.8.0 (Subsonic v4.7); I couldn't find release dates, but given the fact that the current Subsonic version is 6.1.x, and Gonic implementssearch3
, that most servers implementing the Subsonic API will support it.Results are loaded in batches of 20, and are essentially instant, so no spinner is necessary. Sadly, while this means
search3
supports paging, it critically doesn't report how many total results there are, preventing us from doing a background load with progress bar.As a design decision, I chose to let the user load additional search results with the
n
binding, rather than implementing a spinner and loading in the background until there are no more results. I did this mainly because it was easier, but it also makes the client behave better in case the user starts a query for e.g. "n" -- which would end up loading nearly the entire DB into thesong
column. This could be mitigated by, e.g., cancelling the query when the user navigates away from the search tab, so it's still an option if we want to go that route. For now, this works and avoids a lot of extra work to make sure things behave correctly.Artist and Album loading are handled different than in the browser tab. This is because of how search results are returned, and it prevents some undesirable edge cases. For example, if the user searches for "Black Sabbath," compilation albums are returned where at least one song is by Black Sabbath. If the user were to add that album through the UI, all of the songs on the album, including those not authored by Black Sabbath, would be added. This implementation ensures that only search result matches are added to the queue when the user adds either an artist or an album match.
In
gui_handlers.go
,handlePageInput()
followed a pattern that didn't make sense for the function, so there's some cleanups in there. That pattern makes sense when we have to check for multiple different types of events, so we have to returnnil
on a successful catch; in this function, we can catch when we don't recognize the key and return the event, and return nil otherwise. It's not necessary for the feature, it just got lumped in because of another feature-relevant change to the function.Also in this, I factored out the hard-coded indexes to
buttonOrder
into consts. We discussed it in another PR -- again, a clean-up that's not strictly necessary for the feature. I was motivated by the fact that changing the contents ofbuttonOrder
can introduce tracking down and changing indexes in several places across multiple files; this fixes that.