Web UI: setup wizard, auth pages, library browsing, player, admin, streaming, cover art

This commit is contained in:
2026-08-22 23:42:09 -05:00
parent aa29f13846
commit e0bd8bc3cb
42 changed files with 3012 additions and 8 deletions
+59
View File
@@ -0,0 +1,59 @@
package web
import (
"fmt"
"html/template"
"net/http"
"time"
"git.noroutes.net/NoRoutes/vibetunes/internal/database"
assets "git.noroutes.net/NoRoutes/vibetunes/web"
)
var funcMap = template.FuncMap{
"fmtDuration": func(seconds float64) string {
if seconds <= 0 {
return "-"
}
d := time.Duration(seconds) * time.Second
m := int(d.Minutes())
s := int(d.Seconds()) % 60
return fmt.Sprintf("%d:%02d", m, s)
},
"fmtTime": func(t time.Time) string {
if t.IsZero() {
return "-"
}
return t.Format("2006-01-02 15:04")
},
"add": func(a, b int) int { return a + b },
"sub": func(a, b int) int { return a - b },
}
var templates *template.Template
func init() {
t, err := template.New("").Funcs(funcMap).ParseFS(assets.FS, "templates/*.html", "templates/partials/*.html")
if err != nil {
panic(err)
}
templates = t
}
// PageData is the common envelope passed to every page template.
type PageData struct {
Active string // nav item key for sidebar highlighting
Title string
User *database.User
CSRFToken string
Flash string
FlashKind string // success|danger|warning
Data any
}
func render(w http.ResponseWriter, name string, data PageData) {
w.Header().Set("Content-Type", "text/html; charset=utf-8")
if err := templates.ExecuteTemplate(w, name, data); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}