From 5379bb1d49ec5726e64abf7fed937185a6b45f2b Mon Sep 17 00:00:00 2001 From: Drew Weymouth Date: Wed, 1 Nov 2023 16:03:29 -0700 Subject: [PATCH] include playlists and genres in results; UI improvement --- backend/mediaprovider/subsonic/searchall.go | 23 ++++++- ui/dialogs/quicksearch.go | 74 ++++++++++++++++----- 2 files changed, 78 insertions(+), 19 deletions(-) diff --git a/backend/mediaprovider/subsonic/searchall.go b/backend/mediaprovider/subsonic/searchall.go index 69534ea1..f2e38b01 100644 --- a/backend/mediaprovider/subsonic/searchall.go +++ b/backend/mediaprovider/subsonic/searchall.go @@ -39,7 +39,7 @@ func (s *subsonicMediaProvider) SearchAll(searchQuery string, maxResults int) ([ wg.Add(1) go func() { p, e := s.client.GetPlaylists(nil) - if e != nil { + if e == nil { playlists = sharedutil.FilterSlice(p, func(p *subsonic.Playlist) bool { return allTermsMatch(strings.ToLower(p.Name), queryLowerWords) }) @@ -50,7 +50,7 @@ func (s *subsonicMediaProvider) SearchAll(searchQuery string, maxResults int) ([ wg.Add(1) go func() { g, e := s.client.GetGenres() - if e != nil { + if e == nil { genres = sharedutil.FilterSlice(g, func(g *subsonic.Genre) bool { return allTermsMatch(strings.ToLower(g.Name), queryLowerWords) }) @@ -120,6 +120,25 @@ func mergeResults( }) } + for _, pl := range matchingPlaylists { + results = append(results, &mediaprovider.SearchResult{ + Type: mediaprovider.ContentTypePlaylist, + ID: pl.ID, + CoverID: pl.CoverArt, + Name: pl.Name, + Size: pl.SongCount, + }) + } + + for _, g := range matchingGenres { + results = append(results, &mediaprovider.SearchResult{ + Type: mediaprovider.ContentTypeGenre, + ID: g.Name, + Name: g.Name, + Size: g.AlbumCount, + }) + } + return results } diff --git a/ui/dialogs/quicksearch.go b/ui/dialogs/quicksearch.go index defecc00..d1e88844 100644 --- a/ui/dialogs/quicksearch.go +++ b/ui/dialogs/quicksearch.go @@ -1,6 +1,7 @@ package dialogs import ( + "fmt" "image" "log" "sync" @@ -48,22 +49,8 @@ func NewQuickSearch(mp mediaprovider.MediaProvider, im *backend.ImageManager) *Q se.OnSubmitted = func(_ string) { q.onSelected(q.selectedIndex) } - se.OnTypedDown = func() { - q.resultsMutex.RLock() - if q.selectedIndex < len(q.searchResults)-1 { - q.selectedIndex++ - } - q.resultsMutex.RUnlock() - q.list.Select(q.selectedIndex) - } - se.OnTypedUp = func() { - q.resultsMutex.RLock() - if q.selectedIndex > 0 { - q.selectedIndex-- - } - q.resultsMutex.RUnlock() - q.list.Select(q.selectedIndex) - } + se.OnTypedDown = q.moveSelectionDown + se.OnTypedUp = q.moveSelectionUp se.OnTypedEscape = q.onDismiss q.SearchEntry = se q.list = widget.NewList( @@ -117,6 +104,24 @@ func (q *QuickSearch) onSelected(idx int) { q.OnNavigateTo(typ, id) } +func (q *QuickSearch) moveSelectionDown() { + q.resultsMutex.RLock() + if q.selectedIndex < len(q.searchResults)-1 { + q.selectedIndex++ + } + q.resultsMutex.RUnlock() + q.list.Select(q.selectedIndex) +} + +func (q *QuickSearch) moveSelectionUp() { + q.resultsMutex.RLock() + if q.selectedIndex > 0 { + q.selectedIndex-- + } + q.resultsMutex.RUnlock() + q.list.Select(q.selectedIndex) +} + func (q *QuickSearch) onSearched(query string) { var results []*mediaprovider.SearchResult if query != "" { @@ -192,7 +197,42 @@ func (q *quickSearchResult) Update(result *mediaprovider.SearchResult) { q.image.CenterIcon = placeholderIconForContentType(result.Type) q.imageLoader.Load(result.CoverID) q.title.SetText(result.Name) - q.secondary.Segments = []widget.RichTextSegment{&widget.TextSegment{Text: result.Type.String()}} + + maybePluralize := func(s string, size int) string { + if size != 1 { + return s + "s" + } + return s + } + + var secondaryText string + switch result.Type { + case mediaprovider.ContentTypeAlbum: + secondaryText = result.ArtistName + case mediaprovider.ContentTypeArtist: + secondaryText = fmt.Sprintf("%d %s", result.Size, maybePluralize("album", result.Size)) + case mediaprovider.ContentTypeTrack: + secondaryText = result.ArtistName + case mediaprovider.ContentTypePlaylist: + secondaryText = fmt.Sprintf("%d %s", result.Size, maybePluralize("track", result.Size)) + case mediaprovider.ContentTypeGenre: + secondaryText = fmt.Sprintf("%d %s", result.Size, maybePluralize("album", result.Size)) + } + q.secondary.Segments = []widget.RichTextSegment{ + &widget.TextSegment{ + Text: result.Type.String(), + Style: widget.RichTextStyle{SizeName: theme.SizeNameCaptionText, TextStyle: fyne.TextStyle{Bold: true}, Inline: true}, + }, + &widget.TextSegment{ + Text: " ยท ", + Style: widget.RichTextStyle{SizeName: theme.SizeNameCaptionText, Inline: true}, + }, + &widget.TextSegment{ + Text: secondaryText, + Style: widget.RichTextStyle{SizeName: theme.SizeNameCaptionText, Inline: true}, + }, + } + q.secondary.Refresh() }