Merge pull request #762 from zacaj/feature/nowPlaying-album-year

Fix #741: add album year to now playing
This commit is contained in:
Drew Weymouth
2025-11-26 14:21:57 -05:00
committed by GitHub
24 changed files with 100 additions and 47 deletions
+1 -1
View File
@@ -174,7 +174,7 @@
"Show info": "Info anzeigen", "Show info": "Info anzeigen",
"Show notification on track change": "Benachrichtigung bei Titelwechsel anzeigen", "Show notification on track change": "Benachrichtigung bei Titelwechsel anzeigen",
"Show play queue": "Wiedergabeliste anzeigen", "Show play queue": "Wiedergabeliste anzeigen",
"Show year in album grid cards": "Erscheinungsjahr in Alben-Übersicht anzeigen", "Show year in album grid and now playing": "Erscheinungsjahr in Alben-Übersicht anzeigen",
"Shuffle": "Zufallswiedergabe", "Shuffle": "Zufallswiedergabe",
"Shuffle albums": "Alben zufällig wiedergeben", "Shuffle albums": "Alben zufällig wiedergeben",
"Shuffle tracks": "Titel zufällig wiedergeben", "Shuffle tracks": "Titel zufällig wiedergeben",
+1 -1
View File
@@ -209,7 +209,7 @@
"Show info": "Show info", "Show info": "Show info",
"Show notification on track change": "Show notification on track change", "Show notification on track change": "Show notification on track change",
"Show play queue": "Show play queue", "Show play queue": "Show play queue",
"Show year in album grid cards": "Show year in album grid cards", "Show year in album grid and now playing": "Show year in album grid and now playing",
"Shuffle": "Shuffle", "Shuffle": "Shuffle",
"Shuffled": "Shuffled", "Shuffled": "Shuffled",
"Shuffle albums": "Shuffle albums", "Shuffle albums": "Shuffle albums",
+1 -1
View File
@@ -182,7 +182,7 @@
"Show info": "Mostrar información", "Show info": "Mostrar información",
"Show notification on track change": "Mostrar notificación en cambio de pista", "Show notification on track change": "Mostrar notificación en cambio de pista",
"Show play queue": "Mostrar cola de reproducción", "Show play queue": "Mostrar cola de reproducción",
"Show year in album grid cards": "Mostrar año en tarjetas de cuadrícula de álbumes", "Show year in album grid and now playing": "Mostrar año en tarjetas de cuadrícula de álbumes",
"Shuffle": "Aleatorio", "Shuffle": "Aleatorio",
"Shuffle albums": "Aleatorio álbumes", "Shuffle albums": "Aleatorio álbumes",
"Shuffle tracks": "Aleatorio pistas", "Shuffle tracks": "Aleatorio pistas",
+1 -1
View File
@@ -202,7 +202,7 @@
"Show info": "Afficher les informations", "Show info": "Afficher les informations",
"Show notification on track change": "Afficher une notification à chaque changement de piste", "Show notification on track change": "Afficher une notification à chaque changement de piste",
"Show play queue": "Afficher la file d'attente", "Show play queue": "Afficher la file d'attente",
"Show year in album grid cards": "Afficher les années sous les vignettes d'albums", "Show year in album grid and now playing": "Afficher les années sous les vignettes d'albums",
"Shuffle": "Mélanger", "Shuffle": "Mélanger",
"Shuffled": "Mélangés", "Shuffled": "Mélangés",
"Shuffle albums": "Mélanger les albums", "Shuffle albums": "Mélanger les albums",
+1 -1
View File
@@ -173,7 +173,7 @@
"Show info": "Mostra informazioni", "Show info": "Mostra informazioni",
"Show notification on track change": "Mostra notifica quando cambia la traccia", "Show notification on track change": "Mostra notifica quando cambia la traccia",
"Show play queue": "Mostra coda", "Show play queue": "Mostra coda",
"Show year in album grid cards": "Mostra l'anno nella griglia degli album", "Show year in album grid and now playing": "Mostra l'anno nella griglia degli album",
"Shuffle": "Casuale", "Shuffle": "Casuale",
"Shuffle albums": "Album casuali", "Shuffle albums": "Album casuali",
"Shuffle tracks": "Tracce casuali", "Shuffle tracks": "Tracce casuali",
+1 -1
View File
@@ -195,7 +195,7 @@
"Show info": "情報を表示", "Show info": "情報を表示",
"Show notification on track change": "トラックの変更時に通知を表示する", "Show notification on track change": "トラックの変更時に通知を表示する",
"Show play queue": "再生キューを表示", "Show play queue": "再生キューを表示",
"Show year in album grid cards": "アルバムのグリッドカードに年を表示", "Show year in album grid and now playing": "アルバムのグリッドカードに年を表示",
"Shuffle": "シャッフル", "Shuffle": "シャッフル",
"Shuffle albums": "アルバムをシャッフル", "Shuffle albums": "アルバムをシャッフル",
"Shuffle tracks": "トラックをシャッフル", "Shuffle tracks": "トラックをシャッフル",
+1 -1
View File
@@ -195,7 +195,7 @@
"Show info": "정보 표시", "Show info": "정보 표시",
"Show notification on track change": "트랙 변경 시 알림 표시", "Show notification on track change": "트랙 변경 시 알림 표시",
"Show play queue": "대기열 표시", "Show play queue": "대기열 표시",
"Show year in album grid cards": "앨범 그리드에서 연도를 표시", "Show year in album grid and now playing": "앨범 그리드에서 연도를 표시",
"Shuffle": "셔플", "Shuffle": "셔플",
"Shuffle albums": "앨범 셔플하기", "Shuffle albums": "앨범 셔플하기",
"Shuffle tracks": "트랙 셔플하기", "Shuffle tracks": "트랙 셔플하기",
+1 -1
View File
@@ -189,7 +189,7 @@
"Show info": "Toon info", "Show info": "Toon info",
"Show notification on track change": "Toon melding bij veranderen nummer", "Show notification on track change": "Toon melding bij veranderen nummer",
"Show play queue": "Toon afspeelwachtrij", "Show play queue": "Toon afspeelwachtrij",
"Show year in album grid cards": "Geef jaar weer in album rooster", "Show year in album grid and now playing": "Geef jaar weer in album rooster",
"Shuffle": "Door mekaar smijten", "Shuffle": "Door mekaar smijten",
"Shuffle albums": "Albums door mekaar smijten", "Shuffle albums": "Albums door mekaar smijten",
"Shuffle tracks": "Nummers door mekaar smijten", "Shuffle tracks": "Nummers door mekaar smijten",
+1 -1
View File
@@ -185,7 +185,7 @@
"Show info": "Pokaż informacje", "Show info": "Pokaż informacje",
"Show notification on track change": "Pokaż powiadomienie o zmianie ścieżki", "Show notification on track change": "Pokaż powiadomienie o zmianie ścieżki",
"Show play queue": "Pokaż kolejkę odtwarzania", "Show play queue": "Pokaż kolejkę odtwarzania",
"Show year in album grid cards": "Pokaż rok w zakładce albumu", "Show year in album grid and now playing": "Pokaż rok w zakładce albumu",
"Shuffle": "Wymieszaj", "Shuffle": "Wymieszaj",
"Shuffle albums": "Wymieszaj album", "Shuffle albums": "Wymieszaj album",
"Shuffle tracks": "Wymieszaj ścieżki", "Shuffle tracks": "Wymieszaj ścieżki",
+1 -1
View File
@@ -191,7 +191,7 @@
"Show info": "Mostrar informações", "Show info": "Mostrar informações",
"Show notification on track change": "Mostrar notificação ao mudar de faixa", "Show notification on track change": "Mostrar notificação ao mudar de faixa",
"Show play queue": "Mostrar fila de reprodução", "Show play queue": "Mostrar fila de reprodução",
"Show year in album grid cards": "Mostrar ano nos cartões da grade de álbuns", "Show year in album grid and now playing": "Mostrar ano nos cartões da grade de álbuns",
"Shuffle": "Aleatório", "Shuffle": "Aleatório",
"Shuffle albums": "Álbuns em ordem aleatória", "Shuffle albums": "Álbuns em ordem aleatória",
"Shuffle tracks": "Faixas em ordem aleatória", "Shuffle tracks": "Faixas em ordem aleatória",
+1 -1
View File
@@ -165,7 +165,7 @@
"Show": "Arată", "Show": "Arată",
"Show info": "Arată informații", "Show info": "Arată informații",
"Show notification on track change": "Arată notificare la schimbarea melodiei", "Show notification on track change": "Arată notificare la schimbarea melodiei",
"Show year in album grid cards": "Arată anul în gridul de albume", "Show year in album grid and now playing": "Arată anul în gridul de albume",
"Shuffle": "Amestecare", "Shuffle": "Amestecare",
"Shuffle albums": "Amestecă albume", "Shuffle albums": "Amestecă albume",
"Shuffle tracks": "Amestecă melodii", "Shuffle tracks": "Amestecă melodii",
+1 -1
View File
@@ -197,7 +197,7 @@
"Show info": "Информация", "Show info": "Информация",
"Show notification on track change": "Уведомлять при смене композиции", "Show notification on track change": "Уведомлять при смене композиции",
"Show play queue": "Очередь воспроизведения", "Show play queue": "Очередь воспроизведения",
"Show year in album grid cards": "Показывать год на карточках альбомов", "Show year in album grid and now playing": "Показывать год на карточках альбомов",
"Shuffle": "Вперемешку", "Shuffle": "Вперемешку",
"Shuffle albums": "Перемешать альбомы", "Shuffle albums": "Перемешать альбомы",
"Shuffle tracks": "Перемешать композиции", "Shuffle tracks": "Перемешать композиции",
+1 -1
View File
@@ -195,7 +195,7 @@
"Show info": "显示信息", "Show info": "显示信息",
"Show notification on track change": "曲目更改时显示通知", "Show notification on track change": "曲目更改时显示通知",
"Show play queue": "显示播放队列", "Show play queue": "显示播放队列",
"Show year in album grid cards": "在专辑网格卡中显示年份", "Show year in album grid and now playing": "在专辑网格卡中显示年份",
"Shuffle": "随机播放", "Shuffle": "随机播放",
"Shuffle albums": "随机播放专辑", "Shuffle albums": "随机播放专辑",
"Shuffle tracks": "随机播放曲目", "Shuffle tracks": "随机播放曲目",
+1 -1
View File
@@ -195,7 +195,7 @@
"Show info": "显示信息", "Show info": "显示信息",
"Show notification on track change": "曲目更改时显示通知", "Show notification on track change": "曲目更改时显示通知",
"Show play queue": "显示播放队列", "Show play queue": "显示播放队列",
"Show year in album grid cards": "在专辑网格卡中显示年份", "Show year in album grid and now playing": "在专辑网格卡中显示年份",
"Shuffle": "随机播放", "Shuffle": "随机播放",
"Shuffle albums": "随机播放专辑", "Shuffle albums": "随机播放专辑",
"Shuffle tracks": "随机播放曲目", "Shuffle tracks": "随机播放曲目",
+1 -1
View File
@@ -165,7 +165,7 @@
"Show": "顯示", "Show": "顯示",
"Show info": "顯示資訊", "Show info": "顯示資訊",
"Show notification on track change": "曲目更改時顯示通知", "Show notification on track change": "曲目更改時顯示通知",
"Show year in album grid cards": "在專輯網格卡中顯示年份", "Show year in album grid and now playing": "在專輯網格卡中顯示年份",
"Shuffle": "隨機播放", "Shuffle": "隨機播放",
"Shuffle albums": "隨機播放專輯", "Shuffle albums": "隨機播放專輯",
"Shuffle tracks": "隨機播放曲目", "Shuffle tracks": "隨機播放曲目",
+13 -7
View File
@@ -24,12 +24,14 @@ type BottomPanel struct {
AuxControls *widgets.AuxControls AuxControls *widgets.AuxControls
container *fyne.Container container *fyne.Container
cfg *backend.Config
} }
var _ fyne.Widget = (*BottomPanel)(nil) var _ fyne.Widget = (*BottomPanel)(nil)
func NewBottomPanel(pm *backend.PlaybackManager, im *backend.ImageManager, contr *controller.Controller, useWaveformSeekbar bool) *BottomPanel { func NewBottomPanel(pm *backend.PlaybackManager, im *backend.ImageManager, contr *controller.Controller, cfg *backend.Config) *BottomPanel {
bp := &BottomPanel{} bp := &BottomPanel{cfg: cfg}
bp.ExtendBaseWidget(bp) bp.ExtendBaseWidget(bp)
pm.OnSongChange(bp.onSongChange) pm.OnSongChange(bp.onSongChange)
@@ -47,6 +49,7 @@ func NewBottomPanel(pm *backend.PlaybackManager, im *backend.ImageManager, contr
pm.OnStopped(util.FyneDoFunc(func() { bp.Controls.SetPlaying(false) })) pm.OnStopped(util.FyneDoFunc(func() { bp.Controls.SetPlaying(false) }))
bp.NowPlaying = widgets.NewNowPlayingCard() bp.NowPlaying = widgets.NewNowPlayingCard()
bp.NowPlaying.ShowAlbumYear = cfg.AlbumsPage.ShowYears
bp.NowPlaying.OnCoverTapped = func() { bp.NowPlaying.OnCoverTapped = func() {
contr.NavigateTo(controller.NowPlayingRoute()) contr.NavigateTo(controller.NowPlayingRoute())
} }
@@ -65,10 +68,8 @@ func NewBottomPanel(pm *backend.PlaybackManager, im *backend.ImageManager, contr
contr.DoAddTracksToPlaylistWorkflow([]string{tr.ID}) contr.DoAddTracksToPlaylistWorkflow([]string{tr.ID})
} }
} }
bp.NowPlaying.OnAlbumNameTapped = func() { bp.NowPlaying.OnAlbumNameTapped = func(albumID string) {
if tr, ok := pm.NowPlaying().(*mediaprovider.Track); ok { contr.NavigateTo(controller.AlbumRoute(albumID))
contr.NavigateTo(controller.AlbumRoute(tr.AlbumID))
}
} }
bp.NowPlaying.OnArtistNameTapped = func(artistID string) { bp.NowPlaying.OnArtistNameTapped = func(artistID string) {
contr.NavigateTo(controller.ArtistRoute(artistID)) contr.NavigateTo(controller.ArtistRoute(artistID))
@@ -86,7 +87,7 @@ func NewBottomPanel(pm *backend.PlaybackManager, im *backend.ImageManager, contr
contr.ShowShareDialog(tr.ID) contr.ShowShareDialog(tr.ID)
} }
} }
bp.Controls = widgets.NewPlayerControls(useWaveformSeekbar) bp.Controls = widgets.NewPlayerControls(cfg.Playback.UseWaveformSeekbar)
bp.Controls.OnPlayPause(func() { bp.Controls.OnPlayPause(func() {
pm.PlayPause() pm.PlayPause()
}) })
@@ -148,6 +149,11 @@ func (bp *BottomPanel) updateWaveformImg(img *backend.WaveformImage) {
}) })
} }
func (bp *BottomPanel) Refresh() {
bp.NowPlaying.ShowAlbumYear = bp.cfg.AlbumsPage.ShowYears
bp.BaseWidget.Refresh()
}
func (bp *BottomPanel) CreateRenderer() fyne.WidgetRenderer { func (bp *BottomPanel) CreateRenderer() fyne.WidgetRenderer {
bp.ExtendBaseWidget(bp) bp.ExtendBaseWidget(bp)
return widget.NewSimpleRenderer(bp.container) return widget.NewSimpleRenderer(bp.container)
+8 -2
View File
@@ -79,6 +79,7 @@ type nowPlayingPageState struct {
mp mediaprovider.MediaProvider mp mediaprovider.MediaProvider
canRate bool canRate bool
canShare bool canShare bool
cfg *backend.Config
} }
func NewNowPlayingPage( func NewNowPlayingPage(
@@ -92,9 +93,10 @@ func NewNowPlayingPage(
mp mediaprovider.MediaProvider, mp mediaprovider.MediaProvider,
canRate bool, canRate bool,
canShare bool, canShare bool,
cfg *backend.Config,
) *NowPlayingPage { ) *NowPlayingPage {
state := nowPlayingPageState{ state := nowPlayingPageState{
conf: conf, contr: contr, pool: pool, sm: sm, lm: lm, im: im, pm: pm, mp: mp, canRate: canRate, canShare: canShare, conf: conf, contr: contr, pool: pool, sm: sm, lm: lm, im: im, pm: pm, mp: mp, canRate: canRate, canShare: canShare, cfg: cfg,
} }
if page, ok := pool.Obtain(util.WidgetTypeNowPlayingPage).(*NowPlayingPage); ok && page != nil { if page, ok := pool.Obtain(util.WidgetTypeNowPlayingPage).(*NowPlayingPage); ok && page != nil {
page.nowPlayingPageState = state page.nowPlayingPageState = state
@@ -127,6 +129,7 @@ func NewNowPlayingPage(
a.card.OnSetRating = func(rating int) { a.card.OnSetRating = func(rating int) {
a.contr.SetTrackRatings([]string{a.nowPlayingID}, rating) a.contr.SetTrackRatings([]string{a.nowPlayingID}, rating)
} }
a.card.ShowAlbumYear = cfg.AlbumsPage.ShowYears
a.queueList = widgets.NewPlayQueueList(a.im, false) a.queueList = widgets.NewPlayQueueList(a.im, false)
a.relatedList = widgets.NewPlayQueueList(a.im, true) a.relatedList = widgets.NewPlayQueueList(a.im, true)
@@ -474,7 +477,7 @@ func (a *NowPlayingPage) Reload() {
} }
func (s *nowPlayingPageState) Restore() Page { func (s *nowPlayingPageState) Restore() Page {
return NewNowPlayingPage(s.conf, s.contr, s.pool, s.sm, s.lm, s.im, s.pm, s.mp, s.canRate, s.canShare) return NewNowPlayingPage(s.conf, s.contr, s.pool, s.sm, s.lm, s.im, s.pm, s.mp, s.canRate, s.canShare, s.cfg)
} }
var _ CanShowPlayTime = (*NowPlayingPage)(nil) var _ CanShowPlayTime = (*NowPlayingPage)(nil)
@@ -527,6 +530,9 @@ func (a *NowPlayingPage) Refresh() {
} }
} }
a.BaseWidget.Refresh() a.BaseWidget.Refresh()
a.card.ShowAlbumYear = a.cfg.AlbumsPage.ShowYears
a.card.Update(a.nowPlaying)
} }
func (a *NowPlayingPage) saveSelectedTab(tabNum int) { func (a *NowPlayingPage) saveSelectedTab(tabNum int) {
+1 -1
View File
@@ -50,7 +50,7 @@ func (r Router) CreatePage(rte controller.Route) Page {
case controller.Genres: case controller.Genres:
return NewGenresPage(r.Controller, r.App.ServerManager.Server) return NewGenresPage(r.Controller, r.App.ServerManager.Server)
case controller.NowPlaying: case controller.NowPlaying:
return NewNowPlayingPage(&r.App.Config.NowPlayingConfig, r.Controller, r.widgetPool, r.App.ServerManager, r.App.LyricsManager, r.App.ImageManager, r.App.PlaybackManager, r.App.ServerManager.Server, canRate, canShare) return NewNowPlayingPage(&r.App.Config.NowPlayingConfig, r.Controller, r.widgetPool, r.App.ServerManager, r.App.LyricsManager, r.App.ImageManager, r.App.PlaybackManager, r.App.ServerManager.Server, canRate, canShare, r.App.Config)
case controller.Playlist: case controller.Playlist:
return NewPlaylistPage(rte.Arg, &r.App.Config.PlaylistPage, r.widgetPool, r.Controller, r.App.ServerManager, r.App.PlaybackManager, r.App.ImageManager) return NewPlaylistPage(rte.Arg, &r.App.Config.PlaylistPage, r.widgetPool, r.Controller, r.App.ServerManager, r.App.PlaybackManager, r.App.ImageManager)
case controller.Playlists: case controller.Playlists:
+1 -1
View File
@@ -184,7 +184,7 @@ func (s *SettingsDialog) createGeneralTab(canSaveQueueToServer bool) *container.
trackNotif := widget.NewCheckWithData(lang.L("Show notification on track change"), trackNotif := widget.NewCheckWithData(lang.L("Show notification on track change"),
binding.BindBool(&s.config.Application.ShowTrackChangeNotification)) binding.BindBool(&s.config.Application.ShowTrackChangeNotification))
albumGridYears := widget.NewCheck(lang.L("Show year in album grid cards"), func(b bool) { albumGridYears := widget.NewCheck(lang.L("Show year in album grid and now playing"), func(b bool) {
s.config.AlbumsPage.ShowYears = b s.config.AlbumsPage.ShowYears = b
s.config.FavoritesPage.ShowAlbumYears = b s.config.FavoritesPage.ShowAlbumYears = b
if s.OnPageNeedsRefresh != nil { if s.OnPageNeedsRefresh != nil {
+5 -2
View File
@@ -85,7 +85,10 @@ func NewMainWindow(fyneApp fyne.App, appName, displayAppName, appVersion string,
m.Controller.NavHandler = m.Router.NavigateTo m.Controller.NavHandler = m.Router.NavigateTo
m.Controller.ReloadFunc = m.BrowsingPane.Reload m.Controller.ReloadFunc = m.BrowsingPane.Reload
m.Controller.CurPageFunc = m.BrowsingPane.CurrentPage m.Controller.CurPageFunc = m.BrowsingPane.CurrentPage
m.Controller.RefreshPageFunc = m.BrowsingPane.RefreshPage m.Controller.RefreshPageFunc = func() {
m.BrowsingPane.RefreshPage()
m.BottomPanel.Refresh()
}
m.Controller.SelectAllPageFunc = m.BrowsingPane.SelectAll m.Controller.SelectAllPageFunc = m.BrowsingPane.SelectAll
m.Controller.UnselectAllPageFunc = m.BrowsingPane.UnselectAll m.Controller.UnselectAllPageFunc = m.BrowsingPane.UnselectAll
m.Controller.ToastProvider = m.ToastOverlay m.Controller.ToastProvider = m.ToastOverlay
@@ -102,7 +105,7 @@ func NewMainWindow(fyneApp fyne.App, appName, displayAppName, appVersion string,
)) ))
} }
m.BottomPanel = NewBottomPanel(app.PlaybackManager, app.ImageManager, m.Controller, m.Controller.App.Config.Playback.UseWaveformSeekbar) m.BottomPanel = NewBottomPanel(app.PlaybackManager, app.ImageManager, m.Controller, app.Config)
app.PlaybackManager.OnSongChange(func(item mediaprovider.MediaItem, _ *mediaprovider.Track) { app.PlaybackManager.OnSongChange(func(item mediaprovider.MediaItem, _ *mediaprovider.Track) {
fyne.Do(func() { m.UpdateOnTrackChange(item) }) fyne.Do(func() { m.UpdateOnTrackChange(item) })
}) })
+13
View File
@@ -2,6 +2,7 @@ package widgets
import ( import (
"image" "image"
"strconv"
"fyne.io/fyne/v2" "fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas" "fyne.io/fyne/v2/canvas"
@@ -20,6 +21,7 @@ type LargeNowPlayingCard struct {
CaptionedImage CaptionedImage
DisableRating bool DisableRating bool
ShowAlbumYear bool
isRadio bool isRadio bool
trackName *widget.RichText trackName *widget.RichText
@@ -30,6 +32,8 @@ type LargeNowPlayingCard struct {
ratingFavoriteContainer *fyne.Container ratingFavoriteContainer *fyne.Container
cover *ImagePlaceholder cover *ImagePlaceholder
albumYear string
OnArtistNameTapped func(artistID string) OnArtistNameTapped func(artistID string)
OnAlbumNameTapped func() OnAlbumNameTapped func()
OnRadioURLTapped func(url string) OnRadioURLTapped func(url string)
@@ -72,6 +76,7 @@ func NewLargeNowPlayingCard() *LargeNowPlayingCard {
n.trackName.Truncation = fyne.TextTruncateEllipsis n.trackName.Truncation = fyne.TextTruncateEllipsis
n.albumName.SizeName = myTheme.SizeNameSubSubHeadingText n.albumName.SizeName = myTheme.SizeNameSubSubHeadingText
n.albumName.OnTapped = n.onAlbumNameTapped n.albumName.OnTapped = n.onAlbumNameTapped
n.albumName.SuffixParenthesized = true
n.artistName.OnTapped = n.onArtistNameTapped n.artistName.OnTapped = n.onArtistNameTapped
n.artistName.SizeName = myTheme.SizeNameSubSubHeadingText n.artistName.SizeName = myTheme.SizeNameSubSubHeadingText
@@ -125,6 +130,7 @@ func (n *LargeNowPlayingCard) Update(item mediaprovider.MediaItem) {
n.trackName.Segments[0].(*widget.TextSegment).Text = "" n.trackName.Segments[0].(*widget.TextSegment).Text = ""
n.artistName.BuildSegments([]string{}, []string{}) n.artistName.BuildSegments([]string{}, []string{})
n.albumName.BuildSegments([]string{}, []string{}) n.albumName.BuildSegments([]string{}, []string{})
n.albumName.Suffix = ""
n.rating.Rating = 0 n.rating.Rating = 0
n.favorite.Favorite = false n.favorite.Favorite = false
n.ratingFavoriteContainer.Hidden = true n.ratingFavoriteContainer.Hidden = true
@@ -143,11 +149,13 @@ func (n *LargeNowPlayingCard) Update(item mediaprovider.MediaItem) {
n.cover.PlaceholderIcon = myTheme.TracksIcon n.cover.PlaceholderIcon = myTheme.TracksIcon
n.ratingFavoriteContainer.Hidden = false n.ratingFavoriteContainer.Hidden = false
n.isRadio = false n.isRadio = false
n.albumYear = strconv.Itoa(tr.Year)
} else if rd, ok := item.(*mediaprovider.RadioStation); ok { } else if rd, ok := item.(*mediaprovider.RadioStation); ok {
n.artistName.BuildSegments([]string{rd.HomePageURL}, []string{rd.HomePageURL}) n.artistName.BuildSegments([]string{rd.HomePageURL}, []string{rd.HomePageURL})
n.ratingFavoriteContainer.Hidden = true n.ratingFavoriteContainer.Hidden = true
n.cover.PlaceholderIcon = myTheme.RadioIcon n.cover.PlaceholderIcon = myTheme.RadioIcon
n.isRadio = true n.isRadio = true
n.albumYear = ""
} }
n.Refresh() n.Refresh()
@@ -163,5 +171,10 @@ func (n *LargeNowPlayingCard) Refresh() {
} else { } else {
n.rating.Enable() n.rating.Enable()
} }
if n.ShowAlbumYear {
n.albumName.Suffix = n.albumYear
} else {
n.albumName.Suffix = ""
}
n.BaseWidget.Refresh() n.BaseWidget.Refresh()
} }
+12 -4
View File
@@ -14,10 +14,12 @@ type MultiHyperlink struct {
Segments []MultiHyperlinkSegment Segments []MultiHyperlinkSegment
// Suffix string that is appended (with · separator) // Suffix string that is appended (with · separator, or parenthesized
// only if there is enough room // if SuffixParenthesized is true) only if there is enough room
Suffix string Suffix string
SuffixParenthesized bool
OnMouseIn func(*desktop.MouseEvent) OnMouseIn func(*desktop.MouseEvent)
OnMouseOut func() OnMouseOut func()
OnTapped func(string) OnTapped func(string)
@@ -139,12 +141,18 @@ func (c *MultiHyperlink) layoutObjects() {
i += 1 i += 1
c.content.Objects = c.objects[:2*i-1] c.content.Objects = c.objects[:2*i-1]
if i == len(c.Segments) && c.Suffix != "" { if i == len(c.Segments) && c.Suffix != "" {
var suffixText string
if c.SuffixParenthesized {
suffixText = "\u2009(" + c.Suffix + ")"
} else {
suffixText = "· " + c.Suffix
}
if c.suffixLabel == nil { if c.suffixLabel == nil {
c.suffixLabel = ttwidget.NewRichTextWithText("· " + c.Suffix) c.suffixLabel = ttwidget.NewRichTextWithText(suffixText)
c.suffixLabel.OnMouseIn = c.callOnMouseIn c.suffixLabel.OnMouseIn = c.callOnMouseIn
c.suffixLabel.OnMouseOut = c.callOnMouseOut c.suffixLabel.OnMouseOut = c.callOnMouseOut
} else { } else {
c.suffixLabel.Segments[0].(*widget.TextSegment).Text = "· " + c.Suffix c.suffixLabel.Segments[0].(*widget.TextSegment).Text = suffixText
} }
sizeName := c.sizeName() sizeName := c.sizeName()
if c.SuffixSizeName != "" { if c.SuffixSizeName != "" {
+27 -14
View File
@@ -2,6 +2,7 @@ package widgets
import ( import (
"image" "image"
"strconv"
"fyne.io/fyne/v2/lang" "fyne.io/fyne/v2/lang"
@@ -15,7 +16,6 @@ import (
"fyne.io/fyne/v2/layout" "fyne.io/fyne/v2/layout"
"fyne.io/fyne/v2/theme" "fyne.io/fyne/v2/theme"
"fyne.io/fyne/v2/widget" "fyne.io/fyne/v2/widget"
ttwidget "github.com/dweymouth/fyne-tooltip/widget"
) )
// Shows the current album art, track name, artist name, and album name // Shows the current album art, track name, artist name, and album name
@@ -24,17 +24,20 @@ type NowPlayingCard struct {
widget.BaseWidget widget.BaseWidget
DisableRating bool DisableRating bool
ShowAlbumYear bool
trackName *OptionHyperlink trackName *OptionHyperlink
artistName *MultiHyperlink artistName *MultiHyperlink
albumName *ttwidget.Hyperlink albumName *MultiHyperlink
cover *ImagePlaceholder cover *ImagePlaceholder
menu *widget.PopUpMenu menu *widget.PopUpMenu
ratingMenu *fyne.MenuItem ratingMenu *fyne.MenuItem
albumYear string
OnTrackNameTapped func() OnTrackNameTapped func()
OnArtistNameTapped func(artistID string) OnArtistNameTapped func(artistID string)
OnAlbumNameTapped func() OnAlbumNameTapped func(albumID string)
OnCoverTapped func() OnCoverTapped func()
OnSetRating func(rating int) OnSetRating func(rating int)
OnSetFavorite func(favorite bool) OnSetFavorite func(favorite bool)
@@ -47,7 +50,7 @@ func NewNowPlayingCard() *NowPlayingCard {
n := &NowPlayingCard{ n := &NowPlayingCard{
trackName: NewOptionHyperlink(), trackName: NewOptionHyperlink(),
artistName: NewMultiHyperlink(), artistName: NewMultiHyperlink(),
albumName: ttwidget.NewHyperlink("", nil), albumName: NewMultiHyperlink(),
} }
n.ExtendBaseWidget(n) n.ExtendBaseWidget(n)
n.cover = NewImagePlaceholder(myTheme.TracksIcon, 85) n.cover = NewImagePlaceholder(myTheme.TracksIcon, 85)
@@ -56,7 +59,8 @@ func NewNowPlayingCard() *NowPlayingCard {
n.cover.Hidden = true n.cover.Hidden = true
n.trackName.Hidden = true n.trackName.Hidden = true
n.albumName.Hidden = true n.albumName.Hidden = true
n.albumName.Truncation = fyne.TextTruncateEllipsis n.albumName.SuffixParenthesized = true
n.albumName.SuffixSizeName = myTheme.SizeNameSubText
n.trackName.SetTextStyle(fyne.TextStyle{Bold: true}) n.trackName.SetTextStyle(fyne.TextStyle{Bold: true})
n.trackName.OnShowMenu = n.showMenu n.trackName.OnShowMenu = n.showMenu
n.albumName.OnTapped = n.onAlbumNameTapped n.albumName.OnTapped = n.onAlbumNameTapped
@@ -71,9 +75,9 @@ func (n *NowPlayingCard) MinSize() fyne.Size {
return fyne.NewSize(n.BaseWidget.MinSize().Width, 85) return fyne.NewSize(n.BaseWidget.MinSize().Width, 85)
} }
func (n *NowPlayingCard) onAlbumNameTapped() { func (n *NowPlayingCard) onAlbumNameTapped(albumID string) {
if n.OnAlbumNameTapped != nil { if n.OnAlbumNameTapped != nil {
n.OnAlbumNameTapped() n.OnAlbumNameTapped(albumID)
} }
} }
@@ -138,28 +142,28 @@ func (n *NowPlayingCard) Update(track mediaprovider.MediaItem) {
if track == nil { if track == nil {
n.trackName.SetTextAndToolTip("") n.trackName.SetTextAndToolTip("")
n.artistName.BuildSegments([]string{}, []string{}) n.artistName.BuildSegments([]string{}, []string{})
n.albumName.SetText("") n.albumName.BuildSegments([]string{}, []string{})
n.albumName.SetToolTip("") n.albumYear = ""
n.cover.Hidden = true n.cover.Hidden = true
} else { } else {
n.cover.Hidden = false n.cover.Hidden = false
n.trackName.SetTextAndToolTip(track.Metadata().Name) n.trackName.SetTextAndToolTip(track.Metadata().Name)
if tr, ok := track.(*mediaprovider.Track); ok { if tr, ok := track.(*mediaprovider.Track); ok {
n.artistName.BuildSegments(tr.ArtistNames, tr.ArtistIDs) n.artistName.BuildSegments(tr.ArtistNames, tr.ArtistIDs)
n.albumName.SetText(tr.Album) n.albumName.BuildSegments([]string{tr.Album}, []string{tr.AlbumID})
n.albumName.SetToolTip(tr.Album) n.albumYear = strconv.Itoa(tr.Year)
n.cover.PlaceholderIcon = myTheme.TracksIcon n.cover.PlaceholderIcon = myTheme.TracksIcon
} else { } else {
n.artistName.BuildSegments([]string{}, []string{}) n.artistName.BuildSegments([]string{}, []string{})
n.albumName.SetText("") n.albumName.BuildSegments([]string{}, []string{})
n.albumName.SetToolTip("") n.albumName.Suffix = ""
n.cover.PlaceholderIcon = myTheme.RadioIcon n.cover.PlaceholderIcon = myTheme.RadioIcon
} }
} }
n.trackName.Hidden = n.trackName.Text() == "" n.trackName.Hidden = n.trackName.Text() == ""
n.trackName.SetMenuBtnEnabled(n.cover.PlaceholderIcon != myTheme.RadioIcon) n.trackName.SetMenuBtnEnabled(n.cover.PlaceholderIcon != myTheme.RadioIcon)
n.artistName.Hidden = len(n.artistName.Segments) == 0 n.artistName.Hidden = len(n.artistName.Segments) == 0
n.albumName.Hidden = n.albumName.Text == "" n.albumName.Hidden = len(n.albumName.Segments) == 0
n.Refresh() n.Refresh()
} }
@@ -167,6 +171,15 @@ func (n *NowPlayingCard) SetImage(cover image.Image) {
n.cover.SetImage(cover, true) n.cover.SetImage(cover, true)
} }
func (n *NowPlayingCard) Refresh() {
if n.ShowAlbumYear {
n.albumName.Suffix = n.albumYear
} else {
n.albumName.Suffix = ""
}
n.BaseWidget.Refresh()
}
func (n *NowPlayingCard) showMenu(btnPos fyne.Position) { func (n *NowPlayingCard) showMenu(btnPos fyne.Position) {
if n.menu == nil { if n.menu == nil {
n.ratingMenu = util.NewRatingSubmenu(n.onSetRating) n.ratingMenu = util.NewRatingSubmenu(n.onSetRating)
+5 -1
View File
@@ -457,7 +457,11 @@ func (t *tracklistRowBase) doUpdate(tm *util.TrackListModel, rowNum int) {
t.composer.BuildSegments(tr.ComposerNames, tr.ComposerIDs) t.composer.BuildSegments(tr.ComposerNames, tr.ComposerIDs)
t.genre.BuildSegments(tr.Genres, tr.Genres) t.genre.BuildSegments(tr.Genres, tr.Genres)
t.dur.Text = util.SecondsToMMSS(tr.Duration.Seconds()) t.dur.Text = util.SecondsToMMSS(tr.Duration.Seconds())
t.year.Text = strconv.Itoa(tr.Year) if tr.Year != 0 {
t.year.Text = strconv.Itoa(tr.Year)
} else {
t.year.Text = ""
}
t.plays.Text = strconv.Itoa(int(tr.PlayCount)) t.plays.Text = strconv.Itoa(int(tr.PlayCount))
t.lastPlayed.Text = util.LastPlayedDisplayString(tr.LastPlayed) t.lastPlayed.Text = util.LastPlayedDisplayString(tr.LastPlayed)
t.comment.Text = strings.ReplaceAll(tr.Comment, "\n", " ") t.comment.Text = strings.ReplaceAll(tr.Comment, "\n", " ")