113 lines
2.6 KiB
Go
113 lines
2.6 KiB
Go
package web
|
|
|
|
import (
|
|
"database/sql"
|
|
|
|
"git.noroutes.net/NoRoutes/vibetunes/internal/database"
|
|
)
|
|
|
|
// View-model structs shape database rows for templates, keeping SQL
|
|
// scanning details (sql.Null*) out of the .html files.
|
|
|
|
type ArtistView struct {
|
|
ID string
|
|
Name string
|
|
Bio string
|
|
CoverArtID string
|
|
}
|
|
|
|
type AlbumView struct {
|
|
ID string
|
|
Title string
|
|
ArtistName string
|
|
Year int64
|
|
CoverArtID string
|
|
}
|
|
|
|
type SongRow struct {
|
|
ID string
|
|
Title string
|
|
ArtistName string
|
|
AlbumTitle string
|
|
AlbumID string
|
|
CoverArtID string
|
|
TrackNumber int64
|
|
DurationSeconds float64
|
|
Starred bool
|
|
IsAdmin bool
|
|
}
|
|
|
|
func toArtistView(a *database.Artist) ArtistView {
|
|
v := ArtistView{ID: a.ID, Name: a.Name, Bio: a.Bio}
|
|
if a.CoverArtID.Valid {
|
|
v.CoverArtID = a.CoverArtID.String
|
|
}
|
|
return v
|
|
}
|
|
|
|
func toAlbumView(db *sql.DB, a *database.Album) AlbumView {
|
|
v := AlbumView{ID: a.ID, Title: a.Title}
|
|
if a.Year.Valid {
|
|
v.Year = a.Year.Int64
|
|
}
|
|
if a.CoverArtID.Valid {
|
|
v.CoverArtID = a.CoverArtID.String
|
|
}
|
|
if a.PrimaryAlbumArtistID.Valid {
|
|
if artist, err := database.GetArtist(db, a.PrimaryAlbumArtistID.String); err == nil {
|
|
v.ArtistName = artist.Name
|
|
}
|
|
}
|
|
return v
|
|
}
|
|
|
|
// toSongRow builds a display row for a song, given its owning album (may
|
|
// be nil for albumless tracks) and the current user (for the starred
|
|
// flag; pass "" userID to skip that lookup, and isAdmin=false to hide
|
|
// the row's "Edit" link).
|
|
func toSongRow(db *sql.DB, s *database.Song, album *database.Album, userID string, isAdmin bool) SongRow {
|
|
row := SongRow{
|
|
ID: s.ID,
|
|
Title: s.Title,
|
|
DurationSeconds: 0,
|
|
IsAdmin: isAdmin,
|
|
}
|
|
if s.TrackNumber.Valid {
|
|
row.TrackNumber = s.TrackNumber.Int64
|
|
}
|
|
if names, err := database.ListSongArtistNames(db, s.ID); err == nil && len(names) > 0 {
|
|
row.ArtistName = names[0]
|
|
for _, n := range names[1:] {
|
|
row.ArtistName += ", " + n
|
|
}
|
|
}
|
|
if album != nil {
|
|
row.AlbumTitle = album.Title
|
|
row.AlbumID = album.ID
|
|
if album.CoverArtID.Valid {
|
|
row.CoverArtID = album.CoverArtID.String
|
|
}
|
|
}
|
|
if mf, err := database.GetMediaFile(db, s.MediaFileID); err == nil {
|
|
row.DurationSeconds = mf.DurationSeconds
|
|
}
|
|
if userID != "" {
|
|
if starred, err := database.IsStarred(db, userID, "song", s.ID); err == nil {
|
|
row.Starred = starred
|
|
}
|
|
}
|
|
return row
|
|
}
|
|
|
|
// albumOf loads a song's album, tolerating albumless songs.
|
|
func albumOf(db *sql.DB, s *database.Song) *database.Album {
|
|
if !s.AlbumID.Valid {
|
|
return nil
|
|
}
|
|
album, err := database.GetAlbum(db, s.AlbumID.String)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
return album
|
|
}
|