(partial) Fix #742: add Genre, Album Artist, File Type columns

This commit is contained in:
zacaj
2025-11-11 03:36:33 +00:00
parent b0d918b93e
commit 7058f74d42
7 changed files with 176 additions and 96 deletions
+3
View File
@@ -133,6 +133,8 @@ type Track struct {
Genres []string
ArtistIDs []string
ArtistNames []string
AlbumArtistIDs []string
AlbumArtistNames []string
ComposerIDs []string
ComposerNames []string
Album string
@@ -151,6 +153,7 @@ type Track struct {
ReplayGain ReplayGainInfo
SampleRate int
BitDepth int
Extension string
Channels int
DateAdded time.Time
}
@@ -544,6 +544,15 @@ func toTrack(ch *subsonic.Child) *mediaprovider.Track {
artistIDs = append(artistIDs, ch.ArtistID)
}
var albumArtistNames, albumArtistIDs []string
if len(ch.AlbumArtists) > 0 {
// OpenSubsonic extension
for _, a := range ch.AlbumArtists {
albumArtistIDs = append(albumArtistIDs, a.ID)
albumArtistNames = append(albumArtistNames, a.Name)
}
}
var rGain mediaprovider.ReplayGainInfo
if rg := ch.ReplayGain; rg != nil {
rGain.AlbumGain = rg.AlbumGain
@@ -580,6 +589,8 @@ func toTrack(ch *subsonic.Child) *mediaprovider.Track {
Genres: genres,
ArtistIDs: artistIDs,
ArtistNames: artistNames,
AlbumArtistIDs: albumArtistIDs,
AlbumArtistNames: albumArtistNames,
ComposerIDs: composerIDs,
ComposerNames: composers,
Album: ch.Album,
@@ -594,6 +605,7 @@ func toTrack(ch *subsonic.Child) *mediaprovider.Track {
Size: ch.Size,
BitRate: ch.BitRate,
ContentType: ch.ContentType,
Extension: ch.Suffix,
Comment: ch.Comment,
BPM: ch.BPM,
ReplayGain: rGain,
+3
View File
@@ -6,6 +6,8 @@
"Add to queue": "Add to queue",
"Album": "Album",
"album": "album",
"Album artist": "Album artist",
"Album artists": "Album artists",
"Album count": "Album count",
"Album Count": "Album Count",
"Album filters": "Album filters",
@@ -95,6 +97,7 @@
"Field Recording": "Field Recording",
"File path": "File path",
"File size": "File size",
"File type": "File type",
"Filter albums": "Filter albums",
"Filter genres": "Filter genres",
"Forward": "Forward",
+3
View File
@@ -52,6 +52,9 @@ func (m *Controller) connectTracklistActionsWithReplayGainMode(tracklist *widget
tracklist.OnShowArtistPage = func(artistID string) {
m.NavigateTo(ArtistRoute(artistID))
}
tracklist.OnShowGenrePage = func(genre string) {
m.NavigateTo(GenreRoute(genre))
}
tracklist.OnColumnVisibilityMenuShown = func(pop *widget.PopUp) {
m.ClosePopUpOnEscape(pop)
}
+13
View File
@@ -58,6 +58,18 @@ func (t *TrackInfoDialog) CreateRenderer() fyne.WidgetRenderer {
}
c.Add(artists)
if len(t.track.AlbumArtistNames) > 0 {
c.Add(newFormText(lang.L("Album artists"), true))
albumArtists := widgets.NewMultiHyperlink()
albumArtists.BuildSegments(t.track.AlbumArtistNames, t.track.AlbumArtistIDs)
albumArtists.OnTapped = func(id string) {
if t.OnNavigateToArtist != nil {
t.OnNavigateToArtist(id)
}
}
c.Add(albumArtists)
}
if len(t.track.ComposerNames) > 0 {
c.Add(newFormText(lang.L("Composers"), true))
composers := widgets.NewMultiHyperlink()
@@ -104,6 +116,7 @@ func (t *TrackInfoDialog) CreateRenderer() fyne.WidgetRenderer {
c.Add(newFormText(t.track.FilePath, false))
addFormRow(c, lang.L("Content type"), t.track.ContentType)
addFormRow(c, lang.L("File type"), t.track.Extension)
addFormRow(c, lang.L("Bit rate"), fmt.Sprintf("%d kbps", t.track.BitRate))
if t.track.SampleRate > 0 {
addFormRow(c, lang.L("Sample rate"), fmt.Sprintf("%d Hz", t.track.SampleRate))
+13
View File
@@ -79,6 +79,7 @@ type Tracklist struct {
OnShowArtistPage func(artistID string)
OnShowAlbumPage func(albumID string)
OnShowGenrePage func(genre string)
OnColumnVisibilityMenuShown func(*widget.PopUp)
OnVisibleColumnsChanged func([]string)
@@ -432,8 +433,12 @@ func (t *Tracklist) doSortTracks() {
t.stringSort(func(tr *util.TrackListModel) string { return tr.Track().Title })
case ColumnArtist:
t.stringSort(func(tr *util.TrackListModel) string { return strings.Join(tr.Track().ArtistNames, ", ") })
case ColumnAlbumArtist:
t.stringSort(func(tr *util.TrackListModel) string { return strings.Join(tr.Track().ArtistNames, ", ") })
case ColumnAlbum:
t.stringSort(func(tr *util.TrackListModel) string { return tr.Track().Album })
case ColumnGenre:
t.stringSort(func(tr *util.TrackListModel) string { return strings.Join(tr.Track().Genres, ", ") })
case ColumnPath:
t.stringSort(func(tr *util.TrackListModel) string { return tr.Track().FilePath })
case ColumnRating:
@@ -450,6 +455,8 @@ func (t *Tracklist) doSortTracks() {
t.intSort(func(tr *util.TrackListModel) int64 { return tr.Track().LastPlayed.Unix() })
case ColumnComment:
t.stringSort(func(tr *util.TrackListModel) string { return tr.Track().Comment })
case ColumnFileType:
t.stringSort(func(tr *util.TrackListModel) string { return tr.Track().Extension })
case ColumnBPM:
t.intSort(func(tr *util.TrackListModel) int64 { return int64(tr.Track().BPM) })
case ColumnBitrate:
@@ -599,6 +606,12 @@ func (t *Tracklist) onAlbumTapped(albumID string) {
}
}
func (t *Tracklist) onGenreTapped(genre string) {
if t.OnShowGenrePage != nil {
t.OnShowGenrePage(genre)
}
}
func (t *Tracklist) onDownload(tracks []*mediaprovider.Track, downloadName string) {
if t.OnDownload != nil {
t.OnDownload(tracks, downloadName)
+52 -19
View File
@@ -53,9 +53,11 @@ const (
ColumnNum = "Num"
ColumnTitle = "Title"
ColumnArtist = "Artist"
ColumnAlbumArtist = "AlbumArtist"
ColumnTitleArtist = "Title/Artist"
ColumnAlbum = "Album"
ColumnComposer = "Composer"
ColumnGenre = "Genre"
ColumnTime = "Time"
ColumnYear = "Year"
ColumnFavorite = "Favorite"
@@ -66,6 +68,7 @@ const (
ColumnBPM = "BPM"
ColumnBitrate = "Bitrate"
ColumnSize = "Size"
ColumnFileType = "FileType"
ColumnDateAdded = "DateAdded"
ColumnPath = "Path"
)
@@ -83,7 +86,9 @@ var (
title := lang.L("Title")
artist := lang.L("Artist")
album := lang.L("Album")
albumArtist := lang.L("Album artist")
composer := lang.L("Composer")
genre := lang.L("Genre")
time := lang.L("Time")
year := lang.L("Year")
fav := lang.L("Fav.")
@@ -94,6 +99,7 @@ var (
bpm := lang.L("BPM")
bitrate := lang.L("Bit rate")
size := lang.L("Size")
fileType := lang.L("File type")
dateAdded := lang.L("Date added")
filepath := lang.L("File path")
@@ -102,7 +108,9 @@ var (
{Name: ColumnTitle, Col: ListColumn{Text: title, Alignment: fyne.TextAlignLeading, CanToggleVisible: false}},
{Name: ColumnArtist, Col: ListColumn{Text: artist, Alignment: fyne.TextAlignLeading, CanToggleVisible: true}},
{Name: ColumnAlbum, Col: ListColumn{Text: album, Alignment: fyne.TextAlignLeading, CanToggleVisible: true}},
{Name: ColumnAlbumArtist, Col: ListColumn{Text: albumArtist, Alignment: fyne.TextAlignLeading, CanToggleVisible: true}},
{Name: ColumnComposer, Col: ListColumn{Text: composer, Alignment: fyne.TextAlignLeading, CanToggleVisible: true}},
{Name: ColumnGenre, Col: ListColumn{Text: genre, Alignment: fyne.TextAlignLeading, CanToggleVisible: true}},
{Name: ColumnTime, Col: ListColumn{Text: time, Alignment: fyne.TextAlignTrailing, CanToggleVisible: true}},
{Name: ColumnYear, Col: ListColumn{Text: year, Alignment: fyne.TextAlignTrailing, CanToggleVisible: true}},
{Name: ColumnFavorite, Col: ListColumn{Text: " " + fav, Alignment: fyne.TextAlignCenter, CanToggleVisible: true}},
@@ -113,6 +121,7 @@ var (
{Name: ColumnBPM, Col: ListColumn{Text: bpm, Alignment: fyne.TextAlignTrailing, CanToggleVisible: true}},
{Name: ColumnBitrate, Col: ListColumn{Text: bitrate, Alignment: fyne.TextAlignTrailing, CanToggleVisible: true}},
{Name: ColumnSize, Col: ListColumn{Text: size, Alignment: fyne.TextAlignTrailing, CanToggleVisible: true}},
{Name: ColumnFileType, Col: ListColumn{Text: fileType, Alignment: fyne.TextAlignTrailing, CanToggleVisible: true}},
{Name: ColumnDateAdded, Col: ListColumn{Text: dateAdded, Alignment: fyne.TextAlignLeading, CanToggleVisible: true}},
{Name: ColumnPath, Col: ListColumn{Text: filepath, Alignment: fyne.TextAlignLeading, CanToggleVisible: true}},
}
@@ -121,7 +130,9 @@ var (
{Name: ColumnNum, Col: ListColumn{Text: "#", Alignment: fyne.TextAlignTrailing, CanToggleVisible: false}},
{Name: ColumnTitleArtist, Col: ListColumn{Text: title + " / " + artist, Alignment: fyne.TextAlignLeading, CanToggleVisible: false}},
{Name: ColumnAlbum, Col: ListColumn{Text: album, Alignment: fyne.TextAlignLeading, CanToggleVisible: true}},
{Name: ColumnAlbumArtist, Col: ListColumn{Text: albumArtist, Alignment: fyne.TextAlignLeading, CanToggleVisible: true}},
{Name: ColumnComposer, Col: ListColumn{Text: composer, Alignment: fyne.TextAlignLeading, CanToggleVisible: true}},
{Name: ColumnGenre, Col: ListColumn{Text: genre, Alignment: fyne.TextAlignLeading, CanToggleVisible: true}},
{Name: ColumnTime, Col: ListColumn{Text: time, Alignment: fyne.TextAlignTrailing, CanToggleVisible: true}},
{Name: ColumnYear, Col: ListColumn{Text: year, Alignment: fyne.TextAlignTrailing, CanToggleVisible: true}},
{Name: ColumnFavorite, Col: ListColumn{Text: fav, Alignment: fyne.TextAlignCenter, CanToggleVisible: true}},
@@ -132,6 +143,7 @@ var (
{Name: ColumnBPM, Col: ListColumn{Text: bpm, Alignment: fyne.TextAlignTrailing, CanToggleVisible: true}},
{Name: ColumnBitrate, Col: ListColumn{Text: bitrate, Alignment: fyne.TextAlignTrailing, CanToggleVisible: true}},
{Name: ColumnSize, Col: ListColumn{Text: size, Alignment: fyne.TextAlignTrailing, CanToggleVisible: true}},
{Name: ColumnFileType, Col: ListColumn{Text: fileType, Alignment: fyne.TextAlignTrailing, CanToggleVisible: true}},
{Name: ColumnDateAdded, Col: ListColumn{Text: dateAdded, Alignment: fyne.TextAlignLeading, CanToggleVisible: true}},
{Name: ColumnPath, Col: ListColumn{Text: filepath, Alignment: fyne.TextAlignLeading, CanToggleVisible: true}},
}
@@ -169,11 +181,14 @@ var (
sizeColWidth := fyne.Max(
widget.NewLabel("99.9 MB").MinSize().Width,
widget.NewLabel(size).MinSize().Width+sortIconWidth)
fileTypeColWidth := fyne.Max(
widget.NewLabel("FLAC").MinSize().Width,
widget.NewLabel(size).MinSize().Width+sortIconWidth)
// #, Title, Artist, Album, Composer, Time, Year, Favorite, Rating, Plays, LastPlayed, Comment, BPM, Bitrate, Size, DateAdded, Path
CompactTracklistRowColumnWidths = []float32{numColWidth, -1, -1, -1, -1, timeColWidth, yearColWidth, favColWidth, ratingColWidth, playsColWidth, lastPlayedColWidth, -1, bpmColWidth, bitrateColWidth, sizeColWidth, dateAddedColWidth, -1}
// #, Title/Artist, Album, Composer, Time, Year, Favorite, Rating, Plays, LastPlayed, Comment, BPM, Bitrate, Size, DateAdded, Path
ExpandedTracklistRowColumnWidths = []float32{numColWidth, -1, -1, -1, timeColWidth, yearColWidth, favColWidth, ratingColWidth, playsColWidth, lastPlayedColWidth, -1, bpmColWidth, bitrateColWidth, sizeColWidth, dateAddedColWidth, -1}
// #, Title, Artist, Album, AlbumArtist, Composer, Genre, Time, Year, Favorite, Rating, Plays, LastPlayed, Comment, BPM, Bitrate, Size, FileType, DateAdded, Path
CompactTracklistRowColumnWidths = []float32{numColWidth, -1, -1, -1, -1, -1, -1, timeColWidth, yearColWidth, favColWidth, ratingColWidth, playsColWidth, lastPlayedColWidth, -1, bpmColWidth, bitrateColWidth, sizeColWidth, fileTypeColWidth, dateAddedColWidth, -1}
// #, Title/Artist, Album, AlbumArtist, Composer, Genre, Time, Year, Favorite, Rating, Plays, LastPlayed, Comment, BPM, Bitrate, Size, FileType, DateAdded, Path
ExpandedTracklistRowColumnWidths = []float32{numColWidth, -1, -1, -1, -1, -1, timeColWidth, yearColWidth, favColWidth, ratingColWidth, playsColWidth, lastPlayedColWidth, -1, bpmColWidth, bitrateColWidth, sizeColWidth, fileTypeColWidth, dateAddedColWidth, -1}
})
)
@@ -205,7 +220,9 @@ type tracklistRowBase struct {
name *ttwidget.RichText
artist *MultiHyperlink
album *MultiHyperlink // for disabled support, if albumID is ""
albumArtist *MultiHyperlink
composer *MultiHyperlink
genre *MultiHyperlink
dur *widget.Label
year *widget.Label
favorite *fyne.Container
@@ -216,6 +233,7 @@ type tracklistRowBase struct {
comment *ttwidget.Label
bpm *widget.Label
size *widget.Label
fileType *widget.Label
dateAdded *widget.Label
path *ttwidget.Label
@@ -271,7 +289,7 @@ func NewExpandedTracklistRow(tracklist *Tracklist, im *backend.ImageManager, pla
v := makeVerticallyCentered // func alias
container := container.New(tracklist.colLayout,
v(t.num), titleArtistImg, v(t.album), v(t.composer), v(t.dur), v(t.year), v(t.favorite), v(t.rating), v(t.plays), v(t.lastPlayed), v(t.comment), v(t.bpm), v(t.bitrate), v(t.size), v(t.dateAdded), v(t.path))
v(t.num), titleArtistImg, v(t.album), v(t.albumArtist), v(t.composer), v(t.genre), v(t.dur), v(t.year), v(t.favorite), v(t.rating), v(t.plays), v(t.lastPlayed), v(t.comment), v(t.bpm), v(t.bitrate), v(t.size), v(t.fileType), v(t.dateAdded), v(t.path))
t.Content = container
t.setColVisibility = func(colNum int, vis bool) bool {
c := container.Objects[colNum].(*fyne.Container)
@@ -299,24 +317,27 @@ func NewCompactTracklistRow(tracklist *Tracklist, playingIcon fyne.CanvasObject)
t.playingIcon = playingIcon
t.Content = container.New(tracklist.colLayout,
t.num, t.name, t.artist, t.album, t.composer, t.dur, t.year, t.favorite, t.rating, t.plays, t.lastPlayed, t.comment, t.bpm, t.bitrate, t.size, t.dateAdded, t.path)
t.num, t.name, t.artist, t.album, t.albumArtist, t.composer, t.genre, t.dur, t.year, t.favorite, t.rating, t.plays, t.lastPlayed, t.comment, t.bpm, t.bitrate, t.size, t.fileType, t.dateAdded, t.path)
colHiddenPtrMap := map[int]*bool{
2: &t.artist.Hidden,
3: &t.album.Hidden,
4: &t.composer.Hidden,
5: &t.dur.Hidden,
6: &t.year.Hidden,
7: &t.favorite.Hidden,
8: &t.rating.Hidden,
9: &t.plays.Hidden,
10: &t.lastPlayed.Hidden,
11: &t.comment.Hidden,
12: &t.bpm.Hidden,
13: &t.bitrate.Hidden,
14: &t.size.Hidden,
15: &t.dateAdded.Hidden,
16: &t.path.Hidden,
4: &t.albumArtist.Hidden,
5: &t.composer.Hidden,
6: &t.genre.Hidden,
7: &t.dur.Hidden,
8: &t.year.Hidden,
9: &t.favorite.Hidden,
10: &t.rating.Hidden,
11: &t.plays.Hidden,
12: &t.lastPlayed.Hidden,
13: &t.comment.Hidden,
14: &t.bpm.Hidden,
15: &t.bitrate.Hidden,
16: &t.size.Hidden,
17: &t.fileType.Hidden,
18: &t.dateAdded.Hidden,
19: &t.path.Hidden,
}
t.setColVisibility = func(colNum int, vis bool) bool {
ptr, ok := colHiddenPtrMap[colNum]
@@ -344,10 +365,18 @@ func (t *tracklistRowBase) create(tracklist *Tracklist) {
t.album.OnTapped = func(id string) { tracklist.onAlbumTapped(id) }
t.album.OnMouseIn = t.MouseIn
t.album.OnMouseOut = t.MouseOut
t.albumArtist = NewMultiHyperlink()
t.albumArtist.OnTapped = tracklist.onArtistTapped
t.albumArtist.OnMouseIn = t.MouseIn
t.albumArtist.OnMouseOut = t.MouseOut
t.composer = NewMultiHyperlink()
t.composer.OnTapped = func(id string) { tracklist.onArtistTapped(id) }
t.composer.OnMouseIn = t.MouseIn
t.composer.OnMouseOut = t.MouseOut
t.genre = NewMultiHyperlink()
t.genre.OnTapped = func(id string) { tracklist.onGenreTapped(id) }
t.genre.OnMouseIn = t.MouseIn
t.genre.OnMouseOut = t.MouseOut
t.dur = util.NewTrailingAlignLabel()
t.year = util.NewTrailingAlignLabel()
favorite := NewFavoriteIcon()
@@ -365,6 +394,7 @@ func (t *tracklistRowBase) create(tracklist *Tracklist) {
t.bpm = util.NewTrailingAlignLabel()
t.bitrate = util.NewTrailingAlignLabel()
t.size = util.NewTrailingAlignLabel()
t.fileType = util.NewTrailingAlignLabel()
t.dateAdded = util.NewTruncatingLabel()
t.path = util.NewTruncatingTooltipLabel()
t.path.OnMouseIn = t.MouseIn
@@ -423,7 +453,9 @@ func (t *tracklistRowBase) doUpdate(tm *util.TrackListModel, rowNum int) {
t.name.SetToolTip(tr.Title)
t.artist.BuildSegments(tr.ArtistNames, tr.ArtistIDs)
t.album.BuildSegments([]string{tr.Album}, []string{tr.AlbumID})
t.albumArtist.BuildSegments(tr.AlbumArtistNames, tr.AlbumArtistIDs)
t.composer.BuildSegments(tr.ComposerNames, tr.ComposerIDs)
t.genre.BuildSegments(tr.Genres, tr.Genres)
t.dur.Text = util.SecondsToMMSS(tr.Duration.Seconds())
t.year.Text = strconv.Itoa(tr.Year)
t.plays.Text = strconv.Itoa(int(tr.PlayCount))
@@ -433,6 +465,7 @@ func (t *tracklistRowBase) doUpdate(tm *util.TrackListModel, rowNum int) {
t.bpm.Text = strconv.Itoa(tr.BPM)
t.bitrate.Text = strconv.Itoa(tr.BitRate)
t.size.Text = util.BytesToSizeString(tr.Size)
t.fileType.Text = tr.Extension
t.dateAdded.Text = util.FormatDate(tr.DateAdded)
t.path.Text = tr.FilePath
t.path.SetToolTip(tr.FilePath)