simplify init of searchdialog
This commit is contained in:
@@ -14,18 +14,8 @@ type QuickSearch struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewQuickSearch(mp mediaprovider.MediaProvider, im util.ImageFetcher) *QuickSearch {
|
func NewQuickSearch(mp mediaprovider.MediaProvider, im util.ImageFetcher) *QuickSearch {
|
||||||
|
q := &QuickSearch{mp: mp}
|
||||||
q := &QuickSearch{
|
q.SearchDialog = NewSearchDialog(im, "Quick Search", "Close", q.onSearched)
|
||||||
mp: mp,
|
|
||||||
}
|
|
||||||
|
|
||||||
sd := NewSearchDialog(
|
|
||||||
im,
|
|
||||||
"Quick Search",
|
|
||||||
q.onSearched,
|
|
||||||
nil,
|
|
||||||
)
|
|
||||||
q.SearchDialog = sd
|
|
||||||
return q
|
return q
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+27
-47
@@ -26,10 +26,13 @@ type SearchDialog struct {
|
|||||||
|
|
||||||
PlaceholderText string
|
PlaceholderText string
|
||||||
|
|
||||||
|
// Additional item that can be placed to the left
|
||||||
|
// of the dismiss buttons
|
||||||
|
ActionItem fyne.CanvasObject
|
||||||
|
|
||||||
OnDismiss func()
|
OnDismiss func()
|
||||||
OnNavigateTo func(mediaprovider.ContentType, string)
|
OnNavigateTo func(mediaprovider.ContentType, string)
|
||||||
OnSearched func(string) []*mediaprovider.SearchResult
|
OnSearched func(string) []*mediaprovider.SearchResult
|
||||||
OnInit func() ([]*mediaprovider.SearchResult, *widget.Check)
|
|
||||||
|
|
||||||
imgSource util.ImageFetcher
|
imgSource util.ImageFetcher
|
||||||
resultsMutex sync.RWMutex
|
resultsMutex sync.RWMutex
|
||||||
@@ -39,17 +42,18 @@ type SearchDialog struct {
|
|||||||
searchEntry *searchEntry
|
searchEntry *searchEntry
|
||||||
loadingDots *widgets.LoadingDots
|
loadingDots *widgets.LoadingDots
|
||||||
list *widget.List
|
list *widget.List
|
||||||
placeholderTitle string
|
dialogTitle string
|
||||||
|
dismissText string
|
||||||
content *fyne.Container
|
content *fyne.Container
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSearchDialog(im util.ImageFetcher, placeholderTitle string, onSearched func(string) []*mediaprovider.SearchResult, onInit func() ([]*mediaprovider.SearchResult, *widget.Check)) *SearchDialog {
|
func NewSearchDialog(im util.ImageFetcher, title, dismissBtn string, onSearched func(string) []*mediaprovider.SearchResult) *SearchDialog {
|
||||||
sd := &SearchDialog{
|
sd := &SearchDialog{
|
||||||
imgSource: im,
|
imgSource: im,
|
||||||
loadingDots: widgets.NewLoadingDots(),
|
loadingDots: widgets.NewLoadingDots(),
|
||||||
OnSearched: onSearched,
|
OnSearched: onSearched,
|
||||||
OnInit: onInit,
|
dialogTitle: title,
|
||||||
placeholderTitle: placeholderTitle,
|
dismissText: dismissBtn,
|
||||||
}
|
}
|
||||||
sd.ExtendBaseWidget(sd)
|
sd.ExtendBaseWidget(sd)
|
||||||
|
|
||||||
@@ -95,8 +99,8 @@ func (sd *SearchDialog) SearchQuery() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (sd *SearchDialog) Show() {
|
func (sd *SearchDialog) Show() {
|
||||||
sd.onInit()
|
|
||||||
sd.BaseWidget.Show()
|
sd.BaseWidget.Show()
|
||||||
|
go sd.onSearched("")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sd *SearchDialog) Refresh() {
|
func (sd *SearchDialog) Refresh() {
|
||||||
@@ -155,47 +159,6 @@ func (sd *SearchDialog) setResults(results []*mediaprovider.SearchResult) {
|
|||||||
sd.list.Select(0)
|
sd.list.Select(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sd *SearchDialog) SetContent(checkBox *widget.Check) {
|
|
||||||
dismissBtn := widget.NewButton("Close", sd.onDismiss)
|
|
||||||
title := widget.NewRichText(&widget.TextSegment{Text: sd.placeholderTitle, Style: util.BoldRichTextStyle})
|
|
||||||
title.Segments[0].(*widget.TextSegment).Style.Alignment = fyne.TextAlignCenter
|
|
||||||
if checkBox != nil {
|
|
||||||
sd.content = container.NewStack(
|
|
||||||
container.NewBorder(
|
|
||||||
container.NewVBox(title, sd.searchEntry),
|
|
||||||
container.NewVBox(widget.NewSeparator(), container.NewHBox(checkBox, layout.NewSpacer(), dismissBtn)),
|
|
||||||
nil, nil, sd.list),
|
|
||||||
container.NewCenter(sd.loadingDots),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
sd.content = container.NewStack(
|
|
||||||
container.NewBorder(
|
|
||||||
container.NewVBox(title, sd.searchEntry),
|
|
||||||
container.NewVBox(widget.NewSeparator(), container.NewHBox(layout.NewSpacer(), dismissBtn)),
|
|
||||||
nil, nil, sd.list),
|
|
||||||
container.NewCenter(sd.loadingDots),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sd *SearchDialog) onInit() {
|
|
||||||
if sd.OnInit == nil {
|
|
||||||
sd.SetContent(nil)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
sd.loadingDots.Start()
|
|
||||||
var results []*mediaprovider.SearchResult
|
|
||||||
res, checkBox := sd.OnInit()
|
|
||||||
if len(res) == 0 {
|
|
||||||
log.Println("No results")
|
|
||||||
} else {
|
|
||||||
results = res
|
|
||||||
}
|
|
||||||
sd.SetContent(checkBox)
|
|
||||||
sd.loadingDots.Stop()
|
|
||||||
sd.setResults(results)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sd *SearchDialog) onSearched(query string) {
|
func (sd *SearchDialog) onSearched(query string) {
|
||||||
sd.loadingDots.Start()
|
sd.loadingDots.Start()
|
||||||
var results []*mediaprovider.SearchResult
|
var results []*mediaprovider.SearchResult
|
||||||
@@ -210,6 +173,23 @@ func (sd *SearchDialog) onSearched(query string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (sd *SearchDialog) CreateRenderer() fyne.WidgetRenderer {
|
func (sd *SearchDialog) CreateRenderer() fyne.WidgetRenderer {
|
||||||
|
dismissBtn := widget.NewButton(sd.dismissText, sd.onDismiss)
|
||||||
|
title := widget.NewRichText(&widget.TextSegment{Text: sd.dialogTitle, Style: util.BoldRichTextStyle})
|
||||||
|
title.Segments[0].(*widget.TextSegment).Style.Alignment = fyne.TextAlignCenter
|
||||||
|
bottomRow := container.NewHBox()
|
||||||
|
if sd.ActionItem != nil {
|
||||||
|
bottomRow.Objects = []fyne.CanvasObject{sd.ActionItem, layout.NewSpacer(), dismissBtn}
|
||||||
|
} else {
|
||||||
|
bottomRow.Objects = []fyne.CanvasObject{layout.NewSpacer(), dismissBtn}
|
||||||
|
}
|
||||||
|
sd.content = container.NewStack(
|
||||||
|
container.NewBorder(
|
||||||
|
container.NewVBox(title, sd.searchEntry),
|
||||||
|
container.NewVBox(widget.NewSeparator(), bottomRow),
|
||||||
|
nil, nil, sd.list),
|
||||||
|
container.NewCenter(sd.loadingDots),
|
||||||
|
)
|
||||||
|
|
||||||
return widget.NewSimpleRenderer(sd.content)
|
return widget.NewSimpleRenderer(sd.content)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"fyne.io/fyne/v2"
|
"fyne.io/fyne/v2"
|
||||||
|
"fyne.io/fyne/v2/data/binding"
|
||||||
"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"
|
||||||
@@ -23,39 +24,34 @@ type SelectPlaylist struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewSelectPlaylistDialog(mp mediaprovider.MediaProvider, im util.ImageFetcher, loggedInUser string) *SelectPlaylist {
|
func NewSelectPlaylistDialog(mp mediaprovider.MediaProvider, im util.ImageFetcher, loggedInUser string) *SelectPlaylist {
|
||||||
|
|
||||||
sp := &SelectPlaylist{
|
sp := &SelectPlaylist{
|
||||||
mp: mp,
|
mp: mp,
|
||||||
loggedInUser: loggedInUser,
|
loggedInUser: loggedInUser,
|
||||||
SkipDuplicates: false,
|
SkipDuplicates: false,
|
||||||
}
|
}
|
||||||
|
sp.fetchUserOwnedPlaylists()
|
||||||
sd := NewSearchDialog(
|
sd := NewSearchDialog(
|
||||||
im,
|
im,
|
||||||
"Select playlist",
|
"Add to playlist",
|
||||||
|
"Cancel",
|
||||||
sp.onSearched,
|
sp.onSearched,
|
||||||
sp.onInit,
|
|
||||||
)
|
)
|
||||||
|
sd.ActionItem = widget.NewCheckWithData("Skip duplicate tracks", binding.BindBool(&sp.SkipDuplicates))
|
||||||
sd.PlaceholderText = "Search playlists or new playlist name"
|
sd.PlaceholderText = "Search playlists or new playlist name"
|
||||||
sp.SearchDialog = sd
|
sp.SearchDialog = sd
|
||||||
return sp
|
return sp
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sp *SelectPlaylist) onInit() ([]*mediaprovider.SearchResult, *widget.Check) {
|
func (sp *SelectPlaylist) fetchUserOwnedPlaylists() {
|
||||||
var results []*mediaprovider.SearchResult
|
|
||||||
playlists, err := sp.mp.GetPlaylists()
|
playlists, err := sp.mp.GetPlaylists()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO: surface this error to user
|
// TODO: surface this error to user
|
||||||
log.Printf("error getting playlists: %s", err.Error())
|
log.Printf("error getting playlists: %s", err.Error())
|
||||||
return results, nil
|
|
||||||
}
|
}
|
||||||
userPlaylists := sharedutil.FilterSlice(playlists, func(playlist *mediaprovider.Playlist) bool {
|
userPlaylists := sharedutil.FilterSlice(playlists, func(playlist *mediaprovider.Playlist) bool {
|
||||||
return playlist.Owner == sp.loggedInUser
|
return playlist.Owner == sp.loggedInUser
|
||||||
})
|
})
|
||||||
sp.allPlaylistResuts = sharedutil.MapSlice(userPlaylists, sp.playlistToSearchResult)
|
sp.allPlaylistResuts = sharedutil.MapSlice(userPlaylists, sp.playlistToSearchResult)
|
||||||
skipDuplicatesCheck := widget.NewCheck("Skip duplicate tracks", func(checked bool) {
|
|
||||||
sp.SkipDuplicates = checked
|
|
||||||
})
|
|
||||||
return results, skipDuplicatesCheck
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sp *SelectPlaylist) playlistToSearchResult(playlist *mediaprovider.Playlist) *mediaprovider.SearchResult {
|
func (sp *SelectPlaylist) playlistToSearchResult(playlist *mediaprovider.Playlist) *mediaprovider.SearchResult {
|
||||||
|
|||||||
Reference in New Issue
Block a user