add edit/delete playlist functionality

This commit is contained in:
Drew Weymouth
2023-03-17 17:17:02 -07:00
parent 69314696a0
commit 60b7b93ee2
5 changed files with 152 additions and 8 deletions
+4
View File
@@ -209,6 +209,10 @@ func (b *BrowsingPane) Reload() {
}
}
func (b *BrowsingPane) CurPage() controller.Route {
return b.curPage.Route()
}
func (b *BrowsingPane) CreateRenderer() fyne.WidgetRenderer {
return widget.NewSimpleRenderer(b.container)
}
+13 -4
View File
@@ -123,10 +123,11 @@ func (a *PlaylistPage) onRemoveSelectedFromPlaylist() {
type PlaylistPageHeader struct {
widget.BaseWidget
page *PlaylistPage
image *widgets.ImagePlaceholder
page *PlaylistPage
playlistInfo *subsonic.Playlist
image *widgets.ImagePlaceholder
editButton *widget.Button
titleLabel *widget.RichText
descriptionLabel *widget.Label
createdAtLabel *widget.Label
@@ -150,6 +151,12 @@ func NewPlaylistPageHeader(page *PlaylistPage) *PlaylistPageHeader {
a.ownerLabel = widget.NewLabel("")
a.createdAtLabel = widget.NewLabel("")
a.trackTimeLabel = widget.NewLabel("")
a.editButton = widget.NewButtonWithIcon("Edit", theme.DocumentCreateIcon(), func() {
if a.playlistInfo != nil {
page.contr.DoEditPlaylistWorkflow(a.playlistInfo)
}
})
a.editButton.Hidden = true
playButton := widget.NewButtonWithIcon("Play", theme.MediaPlayIcon(), func() {
page.pm.LoadTracks(page.tracklist.Tracks, false, false)
page.pm.PlayFromBeginning()
@@ -165,7 +172,7 @@ func NewPlaylistPageHeader(page *PlaylistPage) *PlaylistPageHeader {
a.descriptionLabel,
a.ownerLabel,
a.trackTimeLabel),
container.NewHBox(playButton, shuffleBtn),
container.NewHBox(a.editButton, playButton, shuffleBtn),
))
return a
}
@@ -175,6 +182,8 @@ func (a *PlaylistPageHeader) CreateRenderer() fyne.WidgetRenderer {
}
func (a *PlaylistPageHeader) Update(playlist *subsonic.Playlist) {
a.playlistInfo = playlist
a.editButton.Hidden = playlist.Owner != a.page.sm.Server.User
a.titleLabel.Segments[0].(*widget.TextSegment).Text = playlist.Name
a.descriptionLabel.SetText(playlist.Comment)
a.ownerLabel.SetText(a.formatPlaylistOwnerStr(playlist))
+54 -4
View File
@@ -3,6 +3,7 @@ package controller
import (
"image"
"log"
"strconv"
"supersonic/backend"
"supersonic/ui/dialogs"
"supersonic/ui/util"
@@ -12,20 +13,27 @@ import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/dialog"
"fyne.io/fyne/v2/layout"
"fyne.io/fyne/v2/widget"
"github.com/dweymouth/go-subsonic/subsonic"
)
type NavigationHandler func(Route)
type ReloadFunc func()
type CurPageFunc func() Route
type Controller struct {
// if not nil, this popup should be hidden when escape is pressed
EscapablePopUp *widget.PopUp
AppVersion string
MainWindow fyne.Window
App *backend.App
NavHandler NavigationHandler
AppVersion string
MainWindow fyne.Window
App *backend.App
NavHandler NavigationHandler
CurPageFunc CurPageFunc
ReloadFunc ReloadFunc
}
func (m *Controller) NavigateTo(route Route) {
@@ -147,6 +155,48 @@ func (m *Controller) DoAddTracksToPlaylistWorkflow(trackIDs []string) {
pop.Show()
}
func (m *Controller) DoEditPlaylistWorkflow(playlist *subsonic.Playlist) {
dlg := dialogs.NewEditPlaylistDialog(playlist)
pop := widget.NewModalPopUp(dlg, m.MainWindow.Canvas())
m.ClosePopUpOnEscape(pop)
dlg.OnCanceled = pop.Hide
dlg.OnDeletePlaylist = func() {
pop.Hide()
dialog.ShowCustomConfirm("Confirm Delete Playlist", "OK", "Cancel", layout.NewSpacer(), /*custom content*/
func(ok bool) {
if !ok {
pop.Show()
} else {
go func() {
if err := m.App.ServerManager.Server.DeletePlaylist(playlist.ID); err != nil {
log.Printf("error deleting playlist: %s", err.Error())
} else if rte := m.CurPageFunc(); rte.Page == Playlist && rte.Arg == playlist.ID {
// navigate to playlists page if user is still on the page of the deleted playlist
m.NavigateTo(PlaylistsRoute())
}
}()
}
}, m.MainWindow)
}
dlg.OnUpdateMetadata = func() {
pop.Hide()
go func() {
err := m.App.ServerManager.Server.UpdatePlaylist(playlist.ID, map[string]string{
"name": dlg.Name,
"comment": dlg.Description,
"public": strconv.FormatBool(dlg.IsPublic),
})
if err != nil {
log.Printf("error updating playlist: %s", err.Error())
} else if rte := m.CurPageFunc(); rte.Page == Playlist && rte.Arg == playlist.ID {
// if user is on playlist page, reload to get the updates
m.ReloadFunc()
}
}()
}
pop.Show()
}
func (c *Controller) DoConnectToServerWorkflow(server *backend.ServerConfig) {
pass, err := c.App.ServerManager.GetServerPassword(server)
if err != nil {
+77
View File
@@ -0,0 +1,77 @@
package dialogs
import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/data/binding"
"fyne.io/fyne/v2/layout"
"fyne.io/fyne/v2/widget"
"github.com/dweymouth/go-subsonic/subsonic"
)
type EditPlaylistDialog struct {
widget.BaseWidget
OnCanceled func()
OnDeletePlaylist func()
OnUpdateMetadata func()
IsPublic bool
Name string
Description string
container *fyne.Container
}
func NewEditPlaylistDialog(playlist *subsonic.Playlist) *EditPlaylistDialog {
e := &EditPlaylistDialog{
IsPublic: playlist.Public,
Name: playlist.Name,
Description: playlist.Comment,
}
e.ExtendBaseWidget(e)
isPublicCheck := widget.NewCheckWithData("Public", binding.BindBool(&e.IsPublic))
nameEntry := widget.NewEntryWithData(binding.BindString(&e.Name))
descriptionEntry := widget.NewEntryWithData(binding.BindString(&e.Description))
deleteBtn := widget.NewButton("Delete Playlist", func() {
if e.OnDeletePlaylist != nil {
e.OnDeletePlaylist()
}
})
submitBtn := widget.NewButton("OK", func() {
if e.OnUpdateMetadata != nil {
e.OnUpdateMetadata()
}
})
cancelBtn := widget.NewButton("Cancel", func() {
if e.OnCanceled != nil {
e.OnCanceled()
}
})
e.container = container.NewVBox(
container.NewHBox(layout.NewSpacer(), widget.NewLabel("Edit Playlist"), layout.NewSpacer()),
container.New(layout.NewFormLayout(),
widget.NewLabel("Name"),
nameEntry,
widget.NewLabel("Description"),
descriptionEntry,
),
container.NewHBox(isPublicCheck, layout.NewSpacer(), deleteBtn),
widget.NewSeparator(),
container.NewHBox(
layout.NewSpacer(),
cancelBtn, submitBtn),
)
return e
}
func (e *EditPlaylistDialog) MinSize() fyne.Size {
return fyne.NewSize(300, e.BaseWidget.MinSize().Height)
}
func (e *EditPlaylistDialog) CreateRenderer() fyne.WidgetRenderer {
return widget.NewSimpleRenderer(e.container)
}
+4
View File
@@ -60,7 +60,11 @@ func NewMainWindow(fyneApp fyne.App, appName, appVersion string, app *backend.Ap
App: app,
}
m.Router = browsing.NewRouter(app, m.Controller, m.BrowsingPane)
// inject controller dependencies
m.Controller.NavHandler = m.Router.NavigateTo
m.Controller.ReloadFunc = m.BrowsingPane.Reload
m.Controller.CurPageFunc = m.BrowsingPane.CurPage
m.BottomPanel = NewBottomPanel(app.Player, m.Router.NavigateTo)
m.BottomPanel.SetPlaybackManager(app.PlaybackManager)
m.BottomPanel.ImageManager = app.ImageManager