add context menu actions to search dialog, refactor controller

This commit is contained in:
Drew Weymouth
2025-03-29 13:25:56 -07:00
parent 9ddb5e6e69
commit 31c23490d1
9 changed files with 693 additions and 423 deletions
+87 -3
View File
@@ -5,31 +5,115 @@ import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/lang"
"fyne.io/fyne/v2/theme"
"fyne.io/fyne/v2/widget"
"github.com/dweymouth/supersonic/backend/mediaprovider"
myTheme "github.com/dweymouth/supersonic/ui/theme"
"github.com/dweymouth/supersonic/ui/util"
)
type QuickSearch struct {
SearchDialog *SearchDialog
results []*mediaprovider.SearchResult
mp mediaprovider.MediaProvider
OnPlay func(t mediaprovider.ContentType, id string, item any, shuffle bool)
OnAddToQueue func(t mediaprovider.ContentType, id string, item any, next bool)
OnAddToPlaylist func(t mediaprovider.ContentType, id string, item any)
OnSetFavorite func(trackID string, fav bool)
OnSetRating func(trackID string, rating int)
OnDownload func(track *mediaprovider.Track)
OnShare func(trackID string)
OnPlaySongRadio func(track *mediaprovider.Track)
OnShowTrackInfo func(track *mediaprovider.Track)
}
func NewQuickSearch(mp mediaprovider.MediaProvider, im util.ImageFetcher) *QuickSearch {
q := &QuickSearch{mp: mp}
q.SearchDialog = NewSearchDialog(im, lang.L("Search Everywhere"), lang.L("Close"), q.onSearched)
q.SearchDialog.OnShowContextMenu = q.showMenu
return q
}
func (q *QuickSearch) onSearched(query string) []*mediaprovider.SearchResult {
var results []*mediaprovider.SearchResult
if query != "" {
if res, err := q.mp.SearchAll(query, 20); err != nil {
q.results = nil
log.Printf("Error searching: %s", err.Error())
} else {
results = res
q.results = res
}
}
return results
return q.results
}
func (q *QuickSearch) showMenu(idx int, pos fyne.Position) {
cType := q.results[idx].Type
id := q.results[idx].ID
item := q.results[idx].Item
canvas := fyne.CurrentApp().Driver().CanvasForObject(q.SearchDialog)
switch cType {
case mediaprovider.ContentTypeTrack:
menu := util.NewTrackContextMenu(false, nil)
menu.OnPlay = func(shuffle bool) {
q.OnPlay(cType, id, item, shuffle)
}
menu.OnAddToQueue = func(next bool) {
q.OnAddToQueue(cType, id, item, next)
}
menu.OnAddToPlaylist = func() {
q.OnAddToPlaylist(cType, id, item)
}
menu.OnDownload = func() {
q.OnDownload(item.(*mediaprovider.Track))
}
menu.OnFavorite = func(fav bool) {
q.OnSetFavorite(id, fav)
}
menu.OnSetRating = func(rating int) {
q.OnSetRating(id, rating)
}
menu.OnPlaySongRadio = func() {
q.OnPlaySongRadio(item.(*mediaprovider.Track))
}
menu.OnShowInfo = func() {
q.OnShowTrackInfo(item.(*mediaprovider.Track))
}
menu.OnShare = func() {
q.OnShare(id)
}
menu.ShowAtPosition(pos, canvas)
default:
play := fyne.NewMenuItem(lang.L("Play"), func() {
q.OnPlay(cType, id, item, false)
})
play.Icon = theme.MediaPlayIcon()
shuffle := fyne.NewMenuItem(lang.L("Shuffle"), func() {
q.OnPlay(cType, id, item, true)
})
shuffle.Icon = myTheme.ShuffleIcon
playNext := fyne.NewMenuItem(lang.L("Play next"), func() {
q.OnAddToQueue(cType, id, item, true)
})
playNext.Icon = myTheme.PlayNextIcon
add := fyne.NewMenuItem(lang.L("Add to queue"), func() {
q.OnAddToQueue(cType, id, item, false)
})
add.Icon = theme.ContentAddIcon()
menu := fyne.NewMenu("", play, shuffle, playNext, add)
if cType != mediaprovider.ContentTypeRadioStation {
playlist := fyne.NewMenuItem(lang.L("Add to playlist")+"...", func() {
q.OnAddToPlaylist(cType, id, item)
})
playlist.Icon = myTheme.PlaylistIcon
menu.Items = append(menu.Items, playlist)
}
widget.ShowPopUpMenuAtPosition(menu, canvas, pos)
}
}
func (q *QuickSearch) SetOnDismiss(onDismiss func()) {
+10 -3
View File
@@ -30,9 +30,10 @@ type SearchDialog struct {
// of the dismiss buttons
ActionItem fyne.CanvasObject
OnDismiss func()
OnNavigateTo func(mediaprovider.ContentType, string)
OnSearched func(string) []*mediaprovider.SearchResult
OnDismiss func()
OnNavigateTo func(mediaprovider.ContentType, string)
OnShowContextMenu func(itemIdx int, pos fyne.Position)
OnSearched func(string) []*mediaprovider.SearchResult
imgSource util.ImageFetcher
resultsMutex sync.RWMutex
@@ -326,6 +327,12 @@ func (q *searchResult) Tapped(_ *fyne.PointEvent) {
q.parent.onSelected(q.index)
}
func (q *searchResult) TappedSecondary(e *fyne.PointEvent) {
if q.parent.OnShowContextMenu != nil {
q.parent.OnShowContextMenu(q.index, e.AbsolutePosition)
}
}
func (q *searchResult) CreateRenderer() fyne.WidgetRenderer {
if q.content == nil {
q.content = container.NewBorder(nil, nil, container.NewCenter(q.image), nil,