Refactor: move update logic back to base type
This commit is contained in:
@@ -1,12 +1,9 @@
|
|||||||
package dialogs
|
package dialogs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"fyne.io/fyne/v2"
|
"fyne.io/fyne/v2"
|
||||||
"fyne.io/fyne/v2/theme"
|
|
||||||
"fyne.io/fyne/v2/widget"
|
|
||||||
"github.com/dweymouth/supersonic/backend/mediaprovider"
|
"github.com/dweymouth/supersonic/backend/mediaprovider"
|
||||||
"github.com/dweymouth/supersonic/ui/util"
|
"github.com/dweymouth/supersonic/ui/util"
|
||||||
)
|
)
|
||||||
@@ -26,7 +23,6 @@ func NewQuickSearch(mp mediaprovider.MediaProvider, im util.ImageFetcher) *Quick
|
|||||||
im,
|
im,
|
||||||
"Quick Search",
|
"Quick Search",
|
||||||
q.onSearched,
|
q.onSearched,
|
||||||
q.onUpdateSearchResult,
|
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
q.SearchDialog = sd
|
q.SearchDialog = sd
|
||||||
@@ -45,53 +41,6 @@ func (q *QuickSearch) onSearched(query string) []*mediaprovider.SearchResult {
|
|||||||
return results
|
return results
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *QuickSearch) onUpdateSearchResult(sr *searchResult, result *mediaprovider.SearchResult) {
|
|
||||||
|
|
||||||
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:
|
|
||||||
if result.Size > 0 {
|
|
||||||
secondaryText = fmt.Sprintf("%d %s", result.Size, maybePluralize("album", result.Size))
|
|
||||||
} else {
|
|
||||||
secondaryText = ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sr.secondary.Segments = []widget.RichTextSegment{
|
|
||||||
&widget.TextSegment{
|
|
||||||
Text: result.Type.String(),
|
|
||||||
Style: widget.RichTextStyle{SizeName: theme.SizeNameCaptionText, TextStyle: fyne.TextStyle{Bold: true}, Inline: true},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
if secondaryText != "" {
|
|
||||||
sr.secondary.Segments = append(sr.secondary.Segments,
|
|
||||||
&widget.TextSegment{
|
|
||||||
Text: " · ",
|
|
||||||
Style: widget.RichTextStyle{SizeName: theme.SizeNameCaptionText, Inline: true},
|
|
||||||
},
|
|
||||||
&widget.TextSegment{
|
|
||||||
Text: secondaryText,
|
|
||||||
Style: widget.RichTextStyle{SizeName: theme.SizeNameCaptionText, Inline: true},
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
sr.secondary.Refresh()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (q *QuickSearch) SetOnDismiss(onDismiss func()) {
|
func (q *QuickSearch) SetOnDismiss(onDismiss func()) {
|
||||||
q.SearchDialog.OnDismiss = onDismiss
|
q.SearchDialog.OnDismiss = onDismiss
|
||||||
}
|
}
|
||||||
|
|||||||
+70
-29
@@ -1,6 +1,7 @@
|
|||||||
package dialogs
|
package dialogs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"image"
|
"image"
|
||||||
"log"
|
"log"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -36,21 +37,19 @@ type SearchDialog struct {
|
|||||||
placeholderTitle string
|
placeholderTitle string
|
||||||
content *fyne.Container
|
content *fyne.Container
|
||||||
|
|
||||||
OnDismiss func()
|
OnDismiss func()
|
||||||
OnNavigateTo func(mediaprovider.ContentType, string, string)
|
OnNavigateTo func(mediaprovider.ContentType, string, string)
|
||||||
OnSearched func(string) []*mediaprovider.SearchResult
|
OnSearched func(string) []*mediaprovider.SearchResult
|
||||||
OnUpdateSearchResults func(*searchResult, *mediaprovider.SearchResult)
|
OnInit func() ([]*mediaprovider.SearchResult, *widget.Check)
|
||||||
OnInit func() ([]*mediaprovider.SearchResult, *widget.Check)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSearchDialog(im util.ImageFetcher, placeholderTitle string, onSearched func(string) []*mediaprovider.SearchResult, onUpdateSearchResult func(*searchResult, *mediaprovider.SearchResult), onInit func() ([]*mediaprovider.SearchResult, *widget.Check)) *SearchDialog {
|
func NewSearchDialog(im util.ImageFetcher, placeholderTitle string, onSearched func(string) []*mediaprovider.SearchResult, onInit func() ([]*mediaprovider.SearchResult, *widget.Check)) *SearchDialog {
|
||||||
sd := &SearchDialog{
|
sd := &SearchDialog{
|
||||||
imgSource: im,
|
imgSource: im,
|
||||||
loadingDots: widgets.NewLoadingDots(),
|
loadingDots: widgets.NewLoadingDots(),
|
||||||
OnSearched: onSearched,
|
OnSearched: onSearched,
|
||||||
OnUpdateSearchResults: onUpdateSearchResult,
|
OnInit: onInit,
|
||||||
OnInit: onInit,
|
placeholderTitle: placeholderTitle,
|
||||||
placeholderTitle: placeholderTitle,
|
|
||||||
}
|
}
|
||||||
sd.ExtendBaseWidget(sd)
|
sd.ExtendBaseWidget(sd)
|
||||||
|
|
||||||
@@ -79,7 +78,7 @@ func NewSearchDialog(im util.ImageFetcher, placeholderTitle string, onSearched f
|
|||||||
sd.resultsMutex.RUnlock()
|
sd.resultsMutex.RUnlock()
|
||||||
sr := co.(*searchResult)
|
sr := co.(*searchResult)
|
||||||
sr.index = lii
|
sr.index = lii
|
||||||
sd.update(sr, result)
|
sr.Update(result)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
return sd
|
return sd
|
||||||
@@ -203,22 +202,6 @@ func (sd *SearchDialog) MinSize() fyne.Size {
|
|||||||
return fyne.NewSize(400, 350)
|
return fyne.NewSize(400, 350)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sd *SearchDialog) update(sr *searchResult, result *mediaprovider.SearchResult) {
|
|
||||||
if result == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if sr.contentType == result.Type && sr.id == result.ID && result.ID != "" {
|
|
||||||
return // nothing to do
|
|
||||||
}
|
|
||||||
sr.id = result.ID
|
|
||||||
sr.contentType = result.Type
|
|
||||||
sr.image.CenterIcon = placeholderIconForContentType(result.Type)
|
|
||||||
sr.imageLoader.Load(result.CoverID)
|
|
||||||
sr.title.SetText(result.Name)
|
|
||||||
|
|
||||||
sd.OnUpdateSearchResults(sr, result)
|
|
||||||
}
|
|
||||||
|
|
||||||
func placeholderIconForContentType(c mediaprovider.ContentType) fyne.Resource {
|
func placeholderIconForContentType(c mediaprovider.ContentType) fyne.Resource {
|
||||||
switch c {
|
switch c {
|
||||||
case mediaprovider.ContentTypeAlbum:
|
case mediaprovider.ContentTypeAlbum:
|
||||||
@@ -274,6 +257,64 @@ func newSearchResult(parent *SearchDialog) *searchResult {
|
|||||||
return qs
|
return qs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *searchResult) Update(result *mediaprovider.SearchResult) {
|
||||||
|
if result == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if s.contentType == result.Type && s.id == result.ID {
|
||||||
|
return // nothing to do
|
||||||
|
}
|
||||||
|
s.id = result.ID
|
||||||
|
s.contentType = result.Type
|
||||||
|
s.image.CenterIcon = placeholderIconForContentType(result.Type)
|
||||||
|
s.imageLoader.Load(result.CoverID)
|
||||||
|
s.title.SetText(result.Name)
|
||||||
|
|
||||||
|
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:
|
||||||
|
if result.Size > 0 {
|
||||||
|
secondaryText = fmt.Sprintf("%d %s", result.Size, maybePluralize("album", result.Size))
|
||||||
|
} else {
|
||||||
|
secondaryText = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.secondary.Segments = []widget.RichTextSegment{
|
||||||
|
&widget.TextSegment{
|
||||||
|
Text: result.Type.String(),
|
||||||
|
Style: widget.RichTextStyle{SizeName: theme.SizeNameCaptionText, TextStyle: fyne.TextStyle{Bold: true}, Inline: true},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if secondaryText != "" {
|
||||||
|
s.secondary.Segments = append(s.secondary.Segments,
|
||||||
|
&widget.TextSegment{
|
||||||
|
Text: " · ",
|
||||||
|
Style: widget.RichTextStyle{SizeName: theme.SizeNameCaptionText, Inline: true},
|
||||||
|
},
|
||||||
|
&widget.TextSegment{
|
||||||
|
Text: secondaryText,
|
||||||
|
Style: widget.RichTextStyle{SizeName: theme.SizeNameCaptionText, Inline: true},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
s.secondary.Refresh()
|
||||||
|
}
|
||||||
|
|
||||||
func (q *searchResult) Tapped(_ *fyne.PointEvent) {
|
func (q *searchResult) Tapped(_ *fyne.PointEvent) {
|
||||||
q.parent.onSelected(q.index)
|
q.parent.onSelected(q.index)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"fyne.io/fyne/v2"
|
"fyne.io/fyne/v2"
|
||||||
"fyne.io/fyne/v2/theme"
|
|
||||||
"fyne.io/fyne/v2/widget"
|
"fyne.io/fyne/v2/widget"
|
||||||
"github.com/deluan/sanitize"
|
"github.com/deluan/sanitize"
|
||||||
"github.com/dweymouth/supersonic/backend/mediaprovider"
|
"github.com/dweymouth/supersonic/backend/mediaprovider"
|
||||||
@@ -34,7 +33,6 @@ func NewSelectPlaylistDialog(mp mediaprovider.MediaProvider, im util.ImageFetche
|
|||||||
im,
|
im,
|
||||||
"Select playlist",
|
"Select playlist",
|
||||||
sp.onSearched,
|
sp.onSearched,
|
||||||
sp.onUpdateSearchResult,
|
|
||||||
sp.onInit,
|
sp.onInit,
|
||||||
)
|
)
|
||||||
sp.SearchDialog = sd
|
sp.SearchDialog = sd
|
||||||
@@ -100,41 +98,6 @@ func (sp *SelectPlaylist) onSearched(query string) []*mediaprovider.SearchResult
|
|||||||
return results
|
return results
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sp *SelectPlaylist) onUpdateSearchResult(sr *searchResult, result *mediaprovider.SearchResult) {
|
|
||||||
if result.ID == "" {
|
|
||||||
sr.secondary.Segments = []widget.RichTextSegment{}
|
|
||||||
sr.secondary.Refresh()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
maybePluralize := func(s string, size int) string {
|
|
||||||
if size != 1 {
|
|
||||||
return s + "s"
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
secondaryText := fmt.Sprintf("%d %s", result.Size, maybePluralize("track", result.Size))
|
|
||||||
sr.secondary.Segments = []widget.RichTextSegment{
|
|
||||||
&widget.TextSegment{
|
|
||||||
Text: result.Type.String(),
|
|
||||||
Style: widget.RichTextStyle{SizeName: theme.SizeNameCaptionText, TextStyle: fyne.TextStyle{Bold: true}, Inline: true},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
if secondaryText != "" {
|
|
||||||
sr.secondary.Segments = append(sr.secondary.Segments,
|
|
||||||
&widget.TextSegment{
|
|
||||||
Text: " · ",
|
|
||||||
Style: widget.RichTextStyle{SizeName: theme.SizeNameCaptionText, Inline: true},
|
|
||||||
},
|
|
||||||
&widget.TextSegment{
|
|
||||||
Text: secondaryText,
|
|
||||||
Style: widget.RichTextStyle{SizeName: theme.SizeNameCaptionText, Inline: true},
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
sr.secondary.Refresh()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sp *SelectPlaylist) SetOnDismiss(onDismiss func()) {
|
func (sp *SelectPlaylist) SetOnDismiss(onDismiss func()) {
|
||||||
sp.SearchDialog.OnDismiss = onDismiss
|
sp.SearchDialog.OnDismiss = onDismiss
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user