add 'Skip duplicates' option

This commit is contained in:
natilou
2024-05-18 16:03:21 -03:00
parent 1b53695589
commit d939c7f85f
3 changed files with 65 additions and 20 deletions
+24 -2
View File
@@ -12,6 +12,7 @@ import (
"os"
"path/filepath"
"time"
"slices"
"github.com/dweymouth/supersonic/backend"
"github.com/dweymouth/supersonic/backend/mediaprovider"
@@ -338,7 +339,27 @@ func (m *Controller) DoAddTracksToPlaylistWorkflow(trackIDs []string) {
go m.App.ServerManager.Server.CreatePlaylist(query, trackIDs)
} else {
m.App.Config.Application.DefaultPlaylistID = id
go m.App.ServerManager.Server.AddPlaylistTracks(id, trackIDs)
if sp.SkipDuplicates {
var filterTrackIDs []string
go func() {
if selectedPlaylist, err := m.App.ServerManager.Server.GetPlaylist(id); err != nil {
log.Printf("error getting playlist: %s", err.Error())
} else {
var trackIDsInPaylist []string
for _, track := range selectedPlaylist.Tracks{
trackIDsInPaylist = append(trackIDsInPaylist, track.ID)
}
filterTrackIDs = sharedutil.FilterSlice(trackIDs, func(trackID string) bool {
return !slices.Contains(trackIDsInPaylist, trackID)
})
}
m.App.ServerManager.Server.AddPlaylistTracks(id, filterTrackIDs)
}()
} else {
go m.App.ServerManager.Server.AddPlaylistTracks(id, trackIDs)
}
}
})
@@ -346,8 +367,8 @@ func (m *Controller) DoAddTracksToPlaylistWorkflow(trackIDs []string) {
m.haveModal = true
min := sp.MinSize()
height := fyne.Max(min.Height, fyne.Min(min.Height*1.5, m.MainWindow.Canvas().Size().Height*0.7))
pop.Resize(fyne.NewSize(min.Width, height))
sp.SearchDialog.Show()
pop.Resize(fyne.NewSize(min.Width, height))
pop.Show()
m.MainWindow.Canvas().Focus(sp.GetSearchEntry())
}
@@ -627,6 +648,7 @@ func (c *Controller) ShowQuickSearch() {
c.haveModal = true
min := qs.MinSize()
height := fyne.Max(min.Height, fyne.Min(min.Height*1.5, c.MainWindow.Canvas().Size().Height*0.7))
qs.SearchDialog.Show()
pop.Resize(fyne.NewSize(min.Width, height))
pop.Show()
c.MainWindow.Canvas().Focus(qs.GetSearchEntry())
+33 -15
View File
@@ -33,22 +33,24 @@ type SearchDialog struct {
list *widget.List
selectedIndex int
placeholderTitle string
content *fyne.Container
OnDismiss func()
OnNavigateTo func(mediaprovider.ContentType, string, string)
OnSearched func(string) []*mediaprovider.SearchResult
OnUpdateSearchResults func(*searchResult, *mediaprovider.SearchResult)
OnInit func() []*mediaprovider.SearchResult
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) *SearchDialog {
func NewSearchDialog(im util.ImageFetcher, placeholderTitle string, onSearched func(string) []*mediaprovider.SearchResult, onUpdateSearchResult func(*searchResult, *mediaprovider.SearchResult), onInit func() ([]*mediaprovider.SearchResult, *widget.Check)) *SearchDialog {
sd := &SearchDialog{
imgSource: im,
loadingDots: widgets.NewLoadingDots(),
OnSearched: onSearched,
OnUpdateSearchResults: onUpdateSearchResult,
OnInit: onInit,
placeholderTitle: placeholderTitle,
}
sd.ExtendBaseWidget(sd)
@@ -80,17 +82,6 @@ func NewSearchDialog(im util.ImageFetcher, placeholderTitle string, onSearched f
sd.update(sr, result)
},
)
dismissBtn := widget.NewButton("Close", sd.onDismiss)
title := widget.NewRichText(&widget.TextSegment{Text: placeholderTitle, Style: util.BoldRichTextStyle})
title.Segments[0].(*widget.TextSegment).Style.Alignment = fyne.TextAlignCenter
sd.content = container.NewStack(
container.NewBorder(
container.NewVBox(title, se),
container.NewVBox(widget.NewSeparator(), container.NewHBox(layout.NewSpacer(), dismissBtn)),
nil, nil, sd.list),
container.NewCenter(sd.loadingDots),
)
return sd
}
@@ -149,20 +140,47 @@ func (sd *SearchDialog) setResults(results []*mediaprovider.SearchResult) {
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
se := sd.SearchEntry.(fyne.CanvasObject)
if checkBox != nil {
sd.content = container.NewStack(
container.NewBorder(
container.NewVBox(title, se),
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, se),
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 := sd.OnInit()
res, checkBox := sd.OnInit()
if len(res) == 0 {
log.Println("No results")
} else {
results = res
}
sd.SetContent(checkBox)
sd.loadingDots.Stop()
sd.setResults(results)
sd.setResults(results)
}
func (sd *SearchDialog) onSearched(query string) {
+8 -3
View File
@@ -20,6 +20,7 @@ type SelectPlaylist struct {
mp mediaprovider.MediaProvider
loggedInUser string
allPlaylists []*mediaprovider.Playlist
SkipDuplicates bool
}
func NewSelectPlaylistDialog(mp mediaprovider.MediaProvider, im util.ImageFetcher, loggedInUser string) *SelectPlaylist {
@@ -27,6 +28,7 @@ func NewSelectPlaylistDialog(mp mediaprovider.MediaProvider, im util.ImageFetche
sp := &SelectPlaylist{
mp: mp,
loggedInUser: loggedInUser,
SkipDuplicates: false,
}
sd := NewSearchDialog(
im,
@@ -39,13 +41,13 @@ func NewSelectPlaylistDialog(mp mediaprovider.MediaProvider, im util.ImageFetche
return sp
}
func (sp *SelectPlaylist) onInit() []*mediaprovider.SearchResult {
func (sp *SelectPlaylist) onInit() ([]*mediaprovider.SearchResult, *widget.Check) {
var results []*mediaprovider.SearchResult
playlists, err := sp.mp.GetPlaylists()
if err != nil {
// TODO: surface this error to user
log.Printf("error getting playlists: %s", err.Error())
return results
return results, nil
}
sp.allPlaylists = sharedutil.FilterSlice(playlists, func(playlist *mediaprovider.Playlist) bool {
return playlist.Owner == sp.loggedInUser
@@ -60,7 +62,10 @@ func (sp *SelectPlaylist) onInit() []*mediaprovider.SearchResult {
ArtistName: playlist.Name,
})
}
return results
skipDuplicatesCheck := widget.NewCheck("Skip duplicates", func(checked bool) {
sp.SkipDuplicates = checked
})
return results, skipDuplicatesCheck
}
func (sp *SelectPlaylist) onSearched(query string) []*mediaprovider.SearchResult {