diff --git a/ui/browsing/favoritespage.go b/ui/browsing/favoritespage.go index e7f0490..1236612 100644 --- a/ui/browsing/favoritespage.go +++ b/ui/browsing/favoritespage.go @@ -121,11 +121,40 @@ func (a *FavoritesPage) Route() Route { } func (a *FavoritesPage) Reload() { + // reload favorite albums view if a.searchText != "" { a.doSearchAlbums(a.searchText) } else { a.grid.Reset(a.lm.StarredIter()) } + if a.tracklistCtr != nil || a.artistListCtr != nil { + go func() { + // re-fetch starred info from server + starred, err := a.sm.Server.GetStarred2(nil) + if err != nil { + log.Printf("error getting starred items: %s", err.Error()) + return + } + if a.tracklistCtr != nil { + // refresh favorite songs view + tr := a.tracklistCtr.Objects[0].(*widgets.Tracklist) + tr.Tracks = starred.Song + if a.toggleBtns.ActivatedButtonIndex() == 2 { + // favorite songs view is visible + tr.Refresh() + } + } + if a.artistListCtr != nil { + // refresh favorite artists view + al := a.artistListCtr.Objects[0].(*widgets.ArtistGenrePlaylist) + al.Items = buildArtistListModel(starred.Artist) + if a.toggleBtns.ActivatedButtonIndex() == 1 { + // favorite artists view is visible + al.Refresh() + } + } + }() + } } func (a *FavoritesPage) Save() SavedPage { @@ -167,7 +196,7 @@ func (a *FavoritesPage) OnSearched(query string) { var _ CanShowNowPlaying = (*FavoritesPage)(nil) -func (a *FavoritesPage) OnSongChange(song *subsonic.Child) { +func (a *FavoritesPage) OnSongChange(song *subsonic.Child, _ *subsonic.Child) { a.nowPlayingID = "" if song != nil { a.nowPlayingID = song.ID @@ -216,13 +245,7 @@ func (a *FavoritesPage) onShowFavoriteArtists() { log.Printf("error getting starred items: %s", err.Error()) return } - model := make([]widgets.ArtistGenrePlaylistItemModel, 0) - for _, ar := range s.Artist { - model = append(model, widgets.ArtistGenrePlaylistItemModel{ - Name: ar.Name, - AlbumCount: ar.AlbumCount, - }) - } + model := buildArtistListModel(s.Artist) artistList := widgets.NewArtistGenrePlaylist(model) artistList.ShowAlbumCount = true artistList.OnNavTo = func(artistID string) { @@ -241,6 +264,18 @@ func (a *FavoritesPage) onShowFavoriteArtists() { } } +func buildArtistListModel(artists []*subsonic.ArtistID3) []widgets.ArtistGenrePlaylistItemModel { + model := make([]widgets.ArtistGenrePlaylistItemModel, 0) + for _, ar := range artists { + model = append(model, widgets.ArtistGenrePlaylistItemModel{ + ID: ar.ID, + Name: ar.Name, + AlbumCount: ar.AlbumCount, + }) + } + return model +} + func (a *FavoritesPage) onShowFavoriteSongs() { a.searcher.Entry.Hide() // disable search on songs for now if a.tracklistCtr == nil { diff --git a/ui/controller/controller.go b/ui/controller/controller.go index 7a9bcdb..270dee0 100644 --- a/ui/controller/controller.go +++ b/ui/controller/controller.go @@ -55,6 +55,14 @@ func (m Controller) ConnectTracklistActions(tracklist *widgets.Tracklist) { m.App.PlaybackManager.LoadTracks(tracks, false, false) m.App.PlaybackManager.PlayFromBeginning() } + tracklist.OnSetFavorite = func(trackIDs []string, fav bool) { + s := m.App.ServerManager.Server + if fav { + go s.Star(subsonic.StarParameters{SongIDs: trackIDs}) + } else { + go s.Unstar(subsonic.StarParameters{SongIDs: trackIDs}) + } + } } func (m Controller) PromptForFirstServer() { diff --git a/ui/widgets/tracklist.go b/ui/widgets/tracklist.go index 8f76c5a..cb05c0a 100644 --- a/ui/widgets/tracklist.go +++ b/ui/widgets/tracklist.go @@ -147,7 +147,7 @@ func (t *Tracklist) SetNowPlaying(trackID string) { break } } - t.list.Refresh() + t.Refresh() } func (t *Tracklist) IncrementPlayCount(track *subsonic.Child) { @@ -385,7 +385,6 @@ func (t *TrackRow) Update(tr *subsonic.Child, isPlaying bool, rowNum int) { // a new track (*subsonic.Child) if tr.ID != t.trackID { t.trackID = tr.ID - t.playCount = tr.PlayCount t.name.Segments[0].(*widget.TextSegment).Text = tr.Title t.artist.Segments[0].(*widget.TextSegment).Text = tr.Artist @@ -431,10 +430,16 @@ func (t *TrackRow) Update(tr *subsonic.Child, isPlaying bool, rowNum int) { } // Render favorite column - if tr.Starred.IsZero() && t.isFavorite { + // TODO: right now the only way for the favorite status to change while the tracklist is visible + // is by the user clicking on the heart icon in the favorites column + // If this changes in the future (e.g. context menu entry on tracklist), then we will + // need better state management/onChanged notif so we know to re-render the column + // (maybe update the Starred field directly on the track struct and issue a Refresh call - + // like we do to update the now playing value when scrobbles happen) + if tr.Starred.IsZero() { t.isFavorite = false t.favorite.Objects[0].(*TappableIcon).Resource = res.ResHeartOutlineInvertPng - } else if !t.isFavorite { + } else { t.isFavorite = true t.favorite.Objects[0].(*TappableIcon).Resource = res.ResHeartFilledInvertPng } @@ -455,10 +460,12 @@ func (t *TrackRow) toggleFavorited() { if t.isFavorite { t.favorite.Objects[0].(*TappableIcon).Resource = res.ResHeartOutlineInvertPng t.favorite.Refresh() + t.isFavorite = false t.tracklist.onSetFavorite(t.trackID, false) } else { t.favorite.Objects[0].(*TappableIcon).Resource = res.ResHeartFilledInvertPng t.favorite.Refresh() + t.isFavorite = true t.tracklist.onSetFavorite(t.trackID, true) } }