migrate to Fyne 2.6 - WIP - updates for new threading model
This commit is contained in:
@@ -316,8 +316,10 @@ func (a *AlbumPageHeader) Update(album *mediaprovider.AlbumWithTracks, im *backe
|
||||
|
||||
go func() {
|
||||
if cover, err := im.GetCoverThumbnail(album.CoverArtID); err == nil {
|
||||
a.cover.SetImage(cover, true)
|
||||
a.cover.Refresh()
|
||||
fyne.Do(func() {
|
||||
a.cover.SetImage(cover, true)
|
||||
a.cover.Refresh()
|
||||
})
|
||||
} else {
|
||||
log.Printf("error fetching cover: %v", err)
|
||||
}
|
||||
|
||||
+61
-40
@@ -174,8 +174,10 @@ func (a *ArtistPage) playArtistRadio() {
|
||||
go func() {
|
||||
err := a.pm.PlaySimilarSongs(a.artistID)
|
||||
if err != nil {
|
||||
log.Println("error playing similar songs: %v", err)
|
||||
a.contr.ToastProvider.ShowErrorToast(lang.L("Unable to play artist radio"))
|
||||
fyne.Do(func() {
|
||||
log.Println("error playing similar songs: %v", err)
|
||||
a.contr.ToastProvider.ShowErrorToast(lang.L("Unable to play artist radio"))
|
||||
})
|
||||
}
|
||||
}()
|
||||
}
|
||||
@@ -246,19 +248,23 @@ func (a *ArtistPage) load() {
|
||||
if a.disposed {
|
||||
return
|
||||
}
|
||||
a.artistInfo = artist
|
||||
a.header.Update(artist, a.im)
|
||||
if a.activeView == 0 {
|
||||
a.showAlbumGrid(false /*reSort*/)
|
||||
} else {
|
||||
a.showTopTracks()
|
||||
}
|
||||
|
||||
fyne.Do(func() {
|
||||
a.artistInfo = artist
|
||||
a.header.Update(artist, a.im)
|
||||
if a.activeView == 0 {
|
||||
a.showAlbumGrid(false /*reSort*/)
|
||||
} else {
|
||||
a.showTopTracks()
|
||||
}
|
||||
})
|
||||
|
||||
info, err := a.mp.GetArtistInfo(a.artistID)
|
||||
if err != nil {
|
||||
log.Printf("Failed to get artist info: %s", err.Error())
|
||||
}
|
||||
if !a.disposed {
|
||||
a.header.UpdateInfo(info)
|
||||
fyne.Do(func() { a.header.UpdateInfo(info) })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,7 +293,15 @@ func (a *ArtistPage) showAlbumGrid(reSort bool) {
|
||||
a.container.Objects[0].Refresh()
|
||||
}
|
||||
|
||||
// should be called asynchronously
|
||||
func (a *ArtistPage) showTopTracks() {
|
||||
updated := false
|
||||
updatePage := func() {
|
||||
a.sortButton.Hide()
|
||||
a.container.Objects[0].(*fyne.Container).Objects[0] = a.tracklistCtr
|
||||
a.container.Objects[0].Refresh()
|
||||
}
|
||||
|
||||
if a.tracklistCtr == nil {
|
||||
if a.artistInfo == nil {
|
||||
// page not loaded yet or invalid artist
|
||||
@@ -302,33 +316,38 @@ func (a *ArtistPage) showTopTracks() {
|
||||
if a.disposed {
|
||||
return
|
||||
}
|
||||
var tl *widgets.Tracklist
|
||||
if t := a.pool.Obtain(util.WidgetTypeTracklist); t != nil {
|
||||
tl = t.(*widgets.Tracklist)
|
||||
tl.Reset()
|
||||
tl.SetTracks(ts)
|
||||
} else {
|
||||
tl = widgets.NewTracklist(ts, a.im, false)
|
||||
}
|
||||
tl.Options = widgets.TracklistOptions{AutoNumber: true}
|
||||
_, canRate := a.mp.(mediaprovider.SupportsRating)
|
||||
_, canShare := a.mp.(mediaprovider.SupportsSharing)
|
||||
tl.Options.DisableRating = !canRate
|
||||
tl.Options.DisableSharing = !canShare
|
||||
tl.SetVisibleColumns(a.cfg.TracklistColumns)
|
||||
tl.SetSorting(a.trackSort)
|
||||
tl.OnVisibleColumnsChanged = func(cols []string) {
|
||||
a.cfg.TracklistColumns = cols
|
||||
}
|
||||
tl.SetNowPlaying(a.nowPlayingID)
|
||||
a.contr.ConnectTracklistActions(tl)
|
||||
a.tracklistCtr = container.New(
|
||||
&layout.CustomPaddedLayout{LeftPadding: 15, RightPadding: 15, BottomPadding: 10},
|
||||
tl)
|
||||
updated = true // mark that updatePage() will be called here
|
||||
fyne.Do(func() {
|
||||
var tl *widgets.Tracklist
|
||||
if t := a.pool.Obtain(util.WidgetTypeTracklist); t != nil {
|
||||
tl = t.(*widgets.Tracklist)
|
||||
tl.Reset()
|
||||
tl.SetTracks(ts)
|
||||
} else {
|
||||
tl = widgets.NewTracklist(ts, a.im, false)
|
||||
}
|
||||
tl.Options = widgets.TracklistOptions{AutoNumber: true}
|
||||
_, canRate := a.mp.(mediaprovider.SupportsRating)
|
||||
_, canShare := a.mp.(mediaprovider.SupportsSharing)
|
||||
tl.Options.DisableRating = !canRate
|
||||
tl.Options.DisableSharing = !canShare
|
||||
tl.SetVisibleColumns(a.cfg.TracklistColumns)
|
||||
tl.SetSorting(a.trackSort)
|
||||
tl.OnVisibleColumnsChanged = func(cols []string) {
|
||||
a.cfg.TracklistColumns = cols
|
||||
}
|
||||
tl.SetNowPlaying(a.nowPlayingID)
|
||||
a.contr.ConnectTracklistActions(tl)
|
||||
a.tracklistCtr = container.New(
|
||||
&layout.CustomPaddedLayout{LeftPadding: 15, RightPadding: 15, BottomPadding: 10},
|
||||
tl)
|
||||
updatePage()
|
||||
})
|
||||
}
|
||||
|
||||
if !updated {
|
||||
fyne.Do(updatePage)
|
||||
}
|
||||
a.sortButton.Hide()
|
||||
a.container.Objects[0].(*fyne.Container).Objects[0] = a.tracklistCtr
|
||||
a.container.Objects[0].Refresh()
|
||||
}
|
||||
|
||||
func (a *ArtistPage) onViewChange(num int) {
|
||||
@@ -512,10 +531,12 @@ func (a *ArtistPageHeader) UpdateInfo(info *mediaprovider.ArtistInfo) {
|
||||
if a.artistImage.HaveImage() {
|
||||
_ = a.artistPage.im.RefreshCachedArtistImageIfExpired(a.artistID, info.ImageURL)
|
||||
} else {
|
||||
im, err := a.artistPage.im.FetchAndCacheArtistImage(a.artistID, info.ImageURL)
|
||||
if err == nil {
|
||||
a.artistImage.SetImage(im, true /*tappable*/)
|
||||
}
|
||||
go func() {
|
||||
im, err := a.artistPage.im.FetchAndCacheArtistImage(a.artistID, info.ImageURL)
|
||||
if err == nil {
|
||||
fyne.Do(func() { a.artistImage.SetImage(im, true /*tappable*/) })
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,22 +207,24 @@ func (a *FavoritesPage) Reload() {
|
||||
if a.disposed {
|
||||
return
|
||||
}
|
||||
if tr := a.tracklistOrNil(); tr != nil {
|
||||
// refresh favorite songs view
|
||||
tr.SetTracks(starred.Tracks)
|
||||
if a.toggleBtns.ActivatedButtonIndex() == 2 {
|
||||
// favorite songs view is visible
|
||||
tr.Refresh()
|
||||
fyne.Do(func() {
|
||||
if tr := a.tracklistOrNil(); tr != nil {
|
||||
// refresh favorite songs view
|
||||
tr.SetTracks(starred.Tracks)
|
||||
if a.toggleBtns.ActivatedButtonIndex() == 2 {
|
||||
// favorite songs view is visible
|
||||
tr.Refresh()
|
||||
}
|
||||
}
|
||||
}
|
||||
if a.artistGrid != nil {
|
||||
// refresh favorite artists view
|
||||
a.artistGrid.ResetFixed(buildArtistGridViewModel(starred.Artists))
|
||||
if a.toggleBtns.ActivatedButtonIndex() == 1 {
|
||||
// favorite artists view is visible
|
||||
a.artistGrid.Refresh()
|
||||
if a.artistGrid != nil {
|
||||
// refresh favorite artists view
|
||||
a.artistGrid.ResetFixed(buildArtistGridViewModel(starred.Artists))
|
||||
if a.toggleBtns.ActivatedButtonIndex() == 1 {
|
||||
// favorite artists view is visible
|
||||
a.artistGrid.Refresh()
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}()
|
||||
}
|
||||
}
|
||||
@@ -354,23 +356,25 @@ func (a *FavoritesPage) onShowFavoriteArtists() {
|
||||
if a.disposed {
|
||||
return
|
||||
}
|
||||
model := buildArtistGridViewModel(fav.Artists)
|
||||
if g := a.pool.Obtain(util.WidgetTypeGridView); g != nil {
|
||||
a.artistGrid = g.(*widgets.GridView)
|
||||
a.artistGrid.Placeholder = myTheme.ArtistIcon
|
||||
a.artistGrid.ResetFixed(model)
|
||||
} else {
|
||||
a.artistGrid = widgets.NewFixedGridView(model, a.im, myTheme.ArtistIcon)
|
||||
}
|
||||
canShareArtists := false
|
||||
if r, canShare := a.mp.(mediaprovider.SupportsSharing); canShare {
|
||||
canShareArtists = r.CanShareArtists()
|
||||
}
|
||||
a.artistGrid.DisableSharing = !canShareArtists
|
||||
a.contr.ConnectArtistGridActions(a.artistGrid)
|
||||
a.container.Objects[0] = a.artistGrid
|
||||
a.Refresh()
|
||||
a.pendingViewSwitch = false
|
||||
fyne.Do(func() {
|
||||
model := buildArtistGridViewModel(fav.Artists)
|
||||
if g := a.pool.Obtain(util.WidgetTypeGridView); g != nil {
|
||||
a.artistGrid = g.(*widgets.GridView)
|
||||
a.artistGrid.Placeholder = myTheme.ArtistIcon
|
||||
a.artistGrid.ResetFixed(model)
|
||||
} else {
|
||||
a.artistGrid = widgets.NewFixedGridView(model, a.im, myTheme.ArtistIcon)
|
||||
}
|
||||
canShareArtists := false
|
||||
if r, canShare := a.mp.(mediaprovider.SupportsSharing); canShare {
|
||||
canShareArtists = r.CanShareArtists()
|
||||
}
|
||||
a.artistGrid.DisableSharing = !canShareArtists
|
||||
a.contr.ConnectArtistGridActions(a.artistGrid)
|
||||
a.container.Objects[0] = a.artistGrid
|
||||
a.Refresh()
|
||||
a.pendingViewSwitch = false
|
||||
})
|
||||
}()
|
||||
} else {
|
||||
a.container.Objects[0] = a.artistGrid
|
||||
@@ -419,32 +423,34 @@ func (a *FavoritesPage) onShowFavoriteSongs() {
|
||||
if a.disposed {
|
||||
return
|
||||
}
|
||||
var tracklist *widgets.Tracklist
|
||||
if tl := a.pool.Obtain(util.WidgetTypeTracklist); tl != nil {
|
||||
tracklist = tl.(*widgets.Tracklist)
|
||||
tracklist.Reset()
|
||||
tracklist.SetTracks(fav.Tracks)
|
||||
} else {
|
||||
tracklist = widgets.NewTracklist(fav.Tracks, a.im, false)
|
||||
}
|
||||
tracklist.Options = widgets.TracklistOptions{AutoNumber: true}
|
||||
_, canRate := a.mp.(mediaprovider.SupportsRating)
|
||||
_, canShare := a.mp.(mediaprovider.SupportsSharing)
|
||||
tracklist.Options.DisableRating = !canRate
|
||||
tracklist.Options.DisableSharing = !canShare
|
||||
tracklist.SetVisibleColumns(a.cfg.TracklistColumns)
|
||||
tracklist.SetSorting(a.trackSort)
|
||||
tracklist.OnVisibleColumnsChanged = func(cols []string) {
|
||||
a.cfg.TracklistColumns = cols
|
||||
}
|
||||
tracklist.SetNowPlaying(a.nowPlayingID)
|
||||
a.contr.ConnectTracklistActions(tracklist)
|
||||
a.tracklistCtr = container.New(
|
||||
&layout.CustomPaddedLayout{LeftPadding: 15, RightPadding: 15, TopPadding: 5, BottomPadding: 15},
|
||||
tracklist)
|
||||
a.container.Objects[0] = a.tracklistCtr
|
||||
a.Refresh()
|
||||
a.pendingViewSwitch = false
|
||||
fyne.Do(func() {
|
||||
var tracklist *widgets.Tracklist
|
||||
if tl := a.pool.Obtain(util.WidgetTypeTracklist); tl != nil {
|
||||
tracklist = tl.(*widgets.Tracklist)
|
||||
tracklist.Reset()
|
||||
tracklist.SetTracks(fav.Tracks)
|
||||
} else {
|
||||
tracklist = widgets.NewTracklist(fav.Tracks, a.im, false)
|
||||
}
|
||||
tracklist.Options = widgets.TracklistOptions{AutoNumber: true}
|
||||
_, canRate := a.mp.(mediaprovider.SupportsRating)
|
||||
_, canShare := a.mp.(mediaprovider.SupportsSharing)
|
||||
tracklist.Options.DisableRating = !canRate
|
||||
tracklist.Options.DisableSharing = !canShare
|
||||
tracklist.SetVisibleColumns(a.cfg.TracklistColumns)
|
||||
tracklist.SetSorting(a.trackSort)
|
||||
tracklist.OnVisibleColumnsChanged = func(cols []string) {
|
||||
a.cfg.TracklistColumns = cols
|
||||
}
|
||||
tracklist.SetNowPlaying(a.nowPlayingID)
|
||||
a.contr.ConnectTracklistActions(tracklist)
|
||||
a.tracklistCtr = container.New(
|
||||
&layout.CustomPaddedLayout{LeftPadding: 15, RightPadding: 15, TopPadding: 5, BottomPadding: 15},
|
||||
tracklist)
|
||||
a.container.Objects[0] = a.tracklistCtr
|
||||
a.Refresh()
|
||||
a.pendingViewSwitch = false
|
||||
})
|
||||
}()
|
||||
} else {
|
||||
a.container.Objects[0] = a.tracklistCtr
|
||||
|
||||
@@ -65,7 +65,9 @@ func (g *genrePageAdapter) ActionButton() *widget.Button {
|
||||
err := g.pm.PlayRandomSongs(g.genre)
|
||||
if err != nil {
|
||||
log.Println("error playing random tracks: %v", err)
|
||||
g.contr.ToastProvider.ShowErrorToast(lang.L("Unable to play random tracks"))
|
||||
fyne.Do(func() {
|
||||
g.contr.ToastProvider.ShowErrorToast(lang.L("Unable to play random tracks"))
|
||||
})
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
@@ -193,20 +193,28 @@ func (a *PlaylistPage) doSetNewTrackOrder(ids []string, newPos int) {
|
||||
}
|
||||
}
|
||||
newTracks := sharedutil.ReorderItems(a.tracks, idxs, newPos)
|
||||
ids = sharedutil.TracksToIDs(newTracks)
|
||||
|
||||
// we can't block the UI waiting for the server so assume it will succeed
|
||||
go func() {
|
||||
ids = sharedutil.TracksToIDs(newTracks)
|
||||
if err := a.sm.Server.ReplacePlaylistTracks(a.playlistID, ids); err != nil {
|
||||
log.Printf("error updating playlist: %s", err.Error())
|
||||
fyne.Do(func() {
|
||||
a.contr.ToastProvider.ShowErrorToast(
|
||||
lang.L("An error occurred updating the playlist"),
|
||||
)
|
||||
})
|
||||
} else {
|
||||
fyne.Do(func() {
|
||||
renumberTracks(newTracks)
|
||||
// force-switch back to unsorted view to show new track order
|
||||
a.tracklist.SetSorting(widgets.TracklistSort{})
|
||||
a.tracklist.SetTracks(newTracks)
|
||||
a.tracklist.UnselectAll()
|
||||
a.tracks = newTracks
|
||||
})
|
||||
}
|
||||
}()
|
||||
|
||||
renumberTracks(newTracks)
|
||||
// force-switch back to unsorted view to show new track order
|
||||
a.tracklist.SetSorting(widgets.TracklistSort{})
|
||||
a.tracklist.SetTracks(newTracks)
|
||||
a.tracklist.UnselectAll()
|
||||
a.tracks = newTracks
|
||||
}
|
||||
|
||||
func (a *PlaylistPage) onRemoveSelectedFromPlaylist() {
|
||||
|
||||
@@ -150,7 +150,9 @@ func (a *PlaylistsPage) createGridView(playlists []*mediaprovider.Playlist) {
|
||||
log.Printf("error loading playlist: %s", err.Error())
|
||||
return
|
||||
}
|
||||
a.contr.DoAddTracksToPlaylistWorkflow(sharedutil.TracksToIDs(pl.Tracks))
|
||||
fyne.Do(func() {
|
||||
a.contr.DoAddTracksToPlaylistWorkflow(sharedutil.TracksToIDs(pl.Tracks))
|
||||
})
|
||||
}()
|
||||
}
|
||||
a.gridView.OnDownload = func(id string) {
|
||||
@@ -160,7 +162,7 @@ func (a *PlaylistsPage) createGridView(playlists []*mediaprovider.Playlist) {
|
||||
log.Printf("error loading playlist: %s", err.Error())
|
||||
return
|
||||
}
|
||||
a.contr.ShowDownloadDialog(pl.Tracks, pl.Name)
|
||||
fyne.Do(func() { a.contr.ShowDownloadDialog(pl.Tracks, pl.Name) })
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,7 +211,9 @@ func (t *TracksPage) playRandomSongs() {
|
||||
err := t.contr.App.PlaybackManager.PlayRandomSongs("")
|
||||
if err != nil {
|
||||
log.Println("error playing random tracks: %v", err)
|
||||
t.contr.ToastProvider.ShowErrorToast(lang.L("Unable to play random tracks"))
|
||||
fyne.Do(func() {
|
||||
t.contr.ToastProvider.ShowErrorToast(lang.L("Unable to play random tracks"))
|
||||
})
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user