From 31fd5da44b9c0725a12078779510478883b4a36b Mon Sep 17 00:00:00 2001 From: ari melody Date: Tue, 21 Oct 2025 15:57:12 +0100 Subject: [PATCH 1/2] more dashboard css fixes --- admin/static/admin.css | 10 ++++- admin/static/edit-artist.js | 2 +- admin/static/edit-release.css | 57 +++++++++++++++----------- admin/static/edit-release.js | 2 +- admin/static/release-list-item.css | 1 + admin/templates/html/edit-release.html | 2 +- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/admin/static/admin.css b/admin/static/admin.css index 7dad27f..ab736f2 100644 --- a/admin/static/admin.css +++ b/admin/static/admin.css @@ -66,6 +66,13 @@ } } +@media (prefers-color-scheme: dark) { + img.icon { + -webkit-filter: invert(1); + filter: invert(1); + } +} + body { width: calc(100% - 180px); height: calc(100vh - 1em); @@ -184,8 +191,9 @@ a:hover { } */ -a img.icon { +img.icon { height: .8em; + transition: filter .1s ease-out; } code { diff --git a/admin/static/edit-artist.js b/admin/static/edit-artist.js index 2ca4c0d..069c25d 100644 --- a/admin/static/edit-artist.js +++ b/admin/static/edit-artist.js @@ -81,7 +81,7 @@ removeAvatarBtn.addEventListener("click", () => { }); document.addEventListener('readystatechange', () => { - document.querySelectorAll('.card#releases .credit').forEach(el => { + document.querySelectorAll('#releases .credit').forEach(el => { hijackClickEvent(el, el.querySelector('.credit-name a')); }); }); diff --git a/admin/static/edit-release.css b/admin/static/edit-release.css index b4fe17b..b8817e0 100644 --- a/admin/static/edit-release.css +++ b/admin/static/edit-release.css @@ -14,6 +14,8 @@ input[type="text"] { border-radius: 8px; background: var(--bg-2); box-shadow: var(--shadow-md); + + transition: background .1s ease-out, color .1s ease-out; } .release-artwork { @@ -31,6 +33,7 @@ input[type="text"] { .release-artwork #remove-artwork { margin-top: .5em; padding: .3em .6em; + background: var(--bg-3); } .release-info { @@ -118,6 +121,7 @@ input[type="text"] { gap: .5em; flex-direction: row; justify-content: right; + color: var(--fg-3); } .release-actions button, @@ -163,7 +167,7 @@ dialog div.dialog-actions { * RELEASE CREDITS */ -.card#credits .credit { +#credits .credit { margin-bottom: .5em; padding: .5em; display: flex; @@ -178,24 +182,24 @@ dialog div.dialog-actions { cursor: pointer; transition: background .1s ease-out; } -.card#credits .credit:hover { +#credits .credit:hover { background-color: var(--bg-1); } -.card#credits .credit p { +#credits .credit p { margin: 0; } -.card#credits .credit .artist-avatar { +#credits .credit .artist-avatar { border-radius: 12px; } -.card#credits .credit .artist-name { +#credits .credit .artist-name { color: var(--fg-3); font-weight: bold; } -.card#credits .credit .artist-role small { +#credits .credit .artist-role small { font-size: inherit; opacity: .66; } @@ -314,33 +318,38 @@ dialog div.dialog-actions { * RELEASE LINKS */ -.card#links ul { +#links ul { padding: 0; display: flex; gap: .2em; } -.card#links a.button:hover { +#links a img.icon { + -webkit-filter: none; + filter: none; +} + +#links a.button:hover { color: var(--bg-3) !important; background-color: var(--fg-3) !important; } -.card#links a.button[data-name="spotify"] { +#links a.button[data-name="spotify"] { color: #101010; background-color: #8cff83 } -.card#links a.button[data-name="apple music"] { +#links a.button[data-name="apple music"] { color: #101010; background-color: #8cd9ff } -.card#links a.button[data-name="soundcloud"] { +#links a.button[data-name="soundcloud"] { color: #101010; background-color: #fdaa6d } -.card#links a.button[data-name="youtube"] { +#links a.button[data-name="youtube"] { color: #101010; background-color: #ff6e6e } @@ -428,7 +437,7 @@ dialog div.dialog-actions { * RELEASE TRACKS */ -.card#tracks .track { +#tracks .track { margin-bottom: 1em; padding: 1em; display: flex; @@ -438,49 +447,51 @@ dialog div.dialog-actions { border-radius: 16px; background: var(--bg-2); box-shadow: var(--shadow-md); + + transition: background .1s ease-out, color .1s ease-out; } -.card#tracks .track h3, -.card#tracks .track p { +#tracks .track h3, +#tracks .track p { margin: 0; } -.card#tracks h2.track-title { +#tracks h2.track-title { margin: 0; display: flex; gap: .5em; } -.card#tracks h2.track-title .track-number { +#tracks h2.track-title .track-number { opacity: .5; } -.card#tracks a:hover { +#tracks a:hover { text-decoration: underline; } -.card#tracks .track-album { +#tracks .track-album { margin-left: auto; font-style: italic; font-size: .75em; opacity: .5; } -.card#tracks .track-album.empty { +#tracks .track-album.empty { color: #ff2020; opacity: 1; } -.card#tracks .track-description { +#tracks .track-description { font-style: italic; } -.card#tracks .track-lyrics { +#tracks .track-lyrics { max-height: 10em; overflow-y: scroll; } -.card#tracks .track .empty { +#tracks .track .empty { opacity: 0.75; } diff --git a/admin/static/edit-release.js b/admin/static/edit-release.js index 5db4bbf..ca2754f 100644 --- a/admin/static/edit-release.js +++ b/admin/static/edit-release.js @@ -100,7 +100,7 @@ removeArtworkBtn.addEventListener("click", () => { }); document.addEventListener("readystatechange", () => { - document.querySelectorAll(".card#credits .credit").forEach(el => { + document.querySelectorAll("#credits .credit").forEach(el => { hijackClickEvent(el, el.querySelector(".artist-name a")); }); }); diff --git a/admin/static/release-list-item.css b/admin/static/release-list-item.css index 3481257..aedd121 100644 --- a/admin/static/release-list-item.css +++ b/admin/static/release-list-item.css @@ -51,6 +51,7 @@ .release-actions { margin-top: .5em; user-select: none; + color: var(--fg-3); } .release-actions a { diff --git a/admin/templates/html/edit-release.html b/admin/templates/html/edit-release.html index 309decf..4484c35 100644 --- a/admin/templates/html/edit-release.html +++ b/admin/templates/html/edit-release.html @@ -99,7 +99,7 @@
-

Credits ({{len .Release.Credits}})

+

Credits ({{len .Release.Credits}} total)

Date: Tue, 21 Oct 2025 17:15:26 +0100 Subject: [PATCH 2/2] add releases page; fix HUGE static file perf regression --- admin/accounthttp.go | 10 ++-- admin/artisthttp.go | 4 +- admin/http.go | 14 +++--- admin/releasehttp.go | 50 +++++++++++++++++-- admin/static/index.js | 6 +-- admin/templates/html/artists.html | 30 +++++++++++ .../html/components/credits/addcredit.html | 2 +- .../html/components/credits/editcredits.html | 4 +- .../components/release/release-list-item.html | 6 +-- .../html/components/tracks/addtrack.html | 2 +- .../html/components/tracks/edittracks.html | 4 +- admin/templates/html/edit-artist.html | 2 +- admin/templates/html/edit-release.html | 16 +++--- admin/templates/html/index.html | 4 +- admin/templates/html/layout.html | 12 ++--- admin/templates/html/releases.html | 22 ++++++++ admin/templates/html/tracks.html | 40 +++++++++++++++ admin/templates/templates.go | 48 ++++++++++++++---- admin/trackhttp.go | 4 +- view/index.go | 26 +++++----- 20 files changed, 233 insertions(+), 73 deletions(-) create mode 100644 admin/templates/html/artists.html create mode 100644 admin/templates/html/releases.html create mode 100644 admin/templates/html/tracks.html diff --git a/admin/accounthttp.go b/admin/accounthttp.go index 1e4742b..634bae6 100644 --- a/admin/accounthttp.go +++ b/admin/accounthttp.go @@ -18,12 +18,12 @@ import ( func accountHandler(app *model.AppState) http.Handler { mux := http.NewServeMux() - mux.Handle("/totp-setup", totpSetupHandler(app)) - mux.Handle("/totp-confirm", totpConfirmHandler(app)) - mux.Handle("/totp-delete/", http.StripPrefix("/totp-delete", totpDeleteHandler(app))) + mux.Handle("/account/totp-setup", totpSetupHandler(app)) + mux.Handle("/account/totp-confirm", totpConfirmHandler(app)) + mux.Handle("/account/totp-delete/", http.StripPrefix("/totp-delete", totpDeleteHandler(app))) - mux.Handle("/password", changePasswordHandler(app)) - mux.Handle("/delete", deleteAccountHandler(app)) + mux.Handle("/account/password", changePasswordHandler(app)) + mux.Handle("/account/delete", deleteAccountHandler(app)) return mux } diff --git a/admin/artisthttp.go b/admin/artisthttp.go index 8c33050..9d99fd4 100644 --- a/admin/artisthttp.go +++ b/admin/artisthttp.go @@ -10,9 +10,9 @@ import ( "arimelody-web/model" ) -func serveArtist(app *model.AppState) http.Handler { +func serveArtists(app *model.AppState) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - slices := strings.Split(r.URL.Path[1:], "/") + slices := strings.Split(strings.TrimPrefix(r.URL.Path, "/artists")[1:], "/") id := slices[0] artist, err := controller.GetArtist(app.DB, id) if err != nil { diff --git a/admin/http.go b/admin/http.go index 136309e..1094095 100644 --- a/admin/http.go +++ b/admin/http.go @@ -47,15 +47,16 @@ func Handler(app *model.AppState) http.Handler { mux.Handle("/register", registerAccountHandler(app)) mux.Handle("/account", requireAccount(accountIndexHandler(app))) - mux.Handle("/account/", requireAccount(http.StripPrefix("/account", accountHandler(app)))) + mux.Handle("/account/", requireAccount(accountHandler(app))) mux.Handle("/logs", requireAccount(logsHandler(app))) - mux.Handle("/release/", requireAccount(http.StripPrefix("/release", serveRelease(app)))) - mux.Handle("/artist/", requireAccount(http.StripPrefix("/artist", serveArtist(app)))) - mux.Handle("/track/", requireAccount(http.StripPrefix("/track", serveTrack(app)))) + mux.Handle("/releases", requireAccount(serveReleases(app))) + mux.Handle("/releases/", requireAccount(serveReleases(app))) + mux.Handle("/artists/", requireAccount(serveArtists(app))) + mux.Handle("/tracks/", requireAccount(serveTracks(app))) - mux.Handle("/static/", http.StripPrefix("/static", staticHandler())) + mux.Handle("/static/", staticHandler()) mux.Handle("/", requireAccount(AdminIndexHandler(app))) @@ -470,7 +471,8 @@ var staticFS embed.FS func staticHandler() http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - file, err := staticFS.ReadFile(filepath.Join("static", filepath.Clean(r.URL.Path))) + uri := strings.TrimPrefix(r.URL.Path, "/static") + file, err := staticFS.ReadFile(filepath.Join("static", filepath.Clean(uri))) if err != nil { http.NotFound(w, r) return diff --git a/admin/releasehttp.go b/admin/releasehttp.go index 991845f..5484609 100644 --- a/admin/releasehttp.go +++ b/admin/releasehttp.go @@ -3,6 +3,7 @@ package admin import ( "fmt" "net/http" + "os" "strings" "arimelody-web/admin/templates" @@ -10,11 +11,52 @@ import ( "arimelody-web/model" ) -func serveRelease(app *model.AppState) http.Handler { +func serveReleases(app *model.AppState) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - slices := strings.Split(r.URL.Path[1:], "/") + slices := strings.Split(strings.TrimPrefix(r.URL.Path, "/releases")[1:], "/") releaseID := slices[0] + var action string = "" + if len(slices) > 1 { + action = slices[1] + } + + if len(releaseID) > 0 { + serveRelease(app, releaseID, action).ServeHTTP(w, r) + return + } + + session := r.Context().Value("session").(*model.Session) + + type ReleasesData struct { + adminPageData + Releases []*model.Release + } + + releases, err := controller.GetAllReleases(app.DB, false, 0, true) + if err != nil { + fmt.Fprintf(os.Stderr, "WARN: Failed to pull releases: %s\n", err) + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + return + } + + err = templates.ReleasesTemplate.Execute(w, ReleasesData{ + adminPageData: adminPageData{ + Path: r.URL.Path, + Session: session, + }, + Releases: releases, + }) + if err != nil { + fmt.Fprintf(os.Stderr, "WARN: Failed to render releases page: %s\n", err) + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + return + } + }) +} + +func serveRelease(app *model.AppState, releaseID string, action string) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { session := r.Context().Value("session").(*model.Session) release, err := controller.GetRelease(app.DB, releaseID, true) @@ -28,8 +70,8 @@ func serveRelease(app *model.AppState) http.Handler { return } - if len(slices) > 1 { - switch slices[1] { + if len(action) > 0 { + switch action { case "editcredits": serveEditCredits(release).ServeHTTP(w, r) return diff --git a/admin/static/index.js b/admin/static/index.js index c35b596..c6f6b58 100644 --- a/admin/static/index.js +++ b/admin/static/index.js @@ -14,7 +14,7 @@ newReleaseBtn.addEventListener("click", event => { headers: { "Content-Type": "application/json" }, body: JSON.stringify({id}) }).then(res => { - if (res.ok) location = "/admin/release/" + id; + if (res.ok) location = "/admin/releases/" + id; else { res.text().then(err => { alert("Request failed: " + err); @@ -39,7 +39,7 @@ newArtistBtn.addEventListener("click", event => { }).then(res => { res.text().then(text => { if (res.ok) { - location = "/admin/artist/" + id; + location = "/admin/artists/" + id; } else { alert("Request failed: " + text); console.error(text); @@ -63,7 +63,7 @@ newTrackBtn.addEventListener("click", event => { }).then(res => { res.text().then(text => { if (res.ok) { - location = "/admin/track/" + text; + location = "/admin/tracks/" + text; } else { alert("Request failed: " + text); console.error(text); diff --git a/admin/templates/html/artists.html b/admin/templates/html/artists.html new file mode 100644 index 0000000..7b2a464 --- /dev/null +++ b/admin/templates/html/artists.html @@ -0,0 +1,30 @@ +{{define "head"}} +Artists - ari melody 💫 + + +{{end}} + +{{define "content"}} +
+

Artists

+ +
+ {{if .Artists}} +
+ {{range $Artist := .Artists}} + + {{end}} +
+ {{else}} +

There are no artists.

+ {{end}} +
+ + +{{end}} diff --git a/admin/templates/html/components/credits/addcredit.html b/admin/templates/html/components/credits/addcredit.html index c09a550..082ba17 100644 --- a/admin/templates/html/components/credits/addcredit.html +++ b/admin/templates/html/components/credits/addcredit.html @@ -7,7 +7,7 @@ {{range $Artist := .Artists}}
  • diff --git a/admin/templates/html/components/credits/editcredits.html b/admin/templates/html/components/credits/editcredits.html index 94dc268..38132e2 100644 --- a/admin/templates/html/components/credits/editcredits.html +++ b/admin/templates/html/components/credits/editcredits.html @@ -3,8 +3,8 @@

    Editing: Credits

    Add diff --git a/admin/templates/html/components/release/release-list-item.html b/admin/templates/html/components/release/release-list-item.html index 4b8f41e..7a5059d 100644 --- a/admin/templates/html/components/release/release-list-item.html +++ b/admin/templates/html/components/release/release-list-item.html @@ -5,7 +5,7 @@
  • - {{.Title}} + {{.Title}} {{.ReleaseDate.Year}} {{if not .Visible}}(hidden){{end}} @@ -13,9 +13,9 @@

    {{.PrintArtists true true}}

    {{.ReleaseType}} - ({{len .Tracks}} track{{if not (eq (len .Tracks) 1)}}s{{end}})

    + ({{len .Tracks}} track{{if not (eq (len .Tracks) 1)}}s{{end}})

    diff --git a/admin/templates/html/components/tracks/addtrack.html b/admin/templates/html/components/tracks/addtrack.html index a6dd433..6a2360b 100644 --- a/admin/templates/html/components/tracks/addtrack.html +++ b/admin/templates/html/components/tracks/addtrack.html @@ -8,7 +8,7 @@
  • diff --git a/admin/templates/html/components/tracks/edittracks.html b/admin/templates/html/components/tracks/edittracks.html index d03f80a..c06f0c3 100644 --- a/admin/templates/html/components/tracks/edittracks.html +++ b/admin/templates/html/components/tracks/edittracks.html @@ -3,8 +3,8 @@

    Editing: Tracks

    Add diff --git a/admin/templates/html/edit-artist.html b/admin/templates/html/edit-artist.html index 6b95de8..9bb5a83 100644 --- a/admin/templates/html/edit-artist.html +++ b/admin/templates/html/edit-artist.html @@ -38,7 +38,7 @@
    -

    {{.Release.Title}}

    +

    {{.Release.Title}}

    {{.Release.PrintArtists true true}}

    Role: {{.Role}} diff --git a/admin/templates/html/edit-release.html b/admin/templates/html/edit-release.html index 4484c35..9a16f65 100644 --- a/admin/templates/html/edit-release.html +++ b/admin/templates/html/edit-release.html @@ -101,8 +101,8 @@

    Credits ({{len .Release.Credits}} total)

    Edit @@ -111,7 +111,7 @@
    -

    {{.Artist.Name}}

    +

    {{.Artist.Name}}

    {{.Role}} {{if .Primary}} @@ -130,8 +130,8 @@

    Links ({{len .Release.Links}})

    Edit @@ -147,8 +147,8 @@

    Tracklist ({{len .Release.Tracks}})

    Edit @@ -157,7 +157,7 @@

    {{.Add $i 1}} - {{$track.Title}} + {{$track.Title}}

    Description

    diff --git a/admin/templates/html/index.html b/admin/templates/html/index.html index dc97a3e..581c691 100644 --- a/admin/templates/html/index.html +++ b/admin/templates/html/index.html @@ -32,7 +32,7 @@ {{range $Artist := .Artists}} {{end}}
    @@ -51,7 +51,7 @@ {{range $Track := .Tracks}}

    - {{$Track.Title}} + {{$Track.Title}}

    {{if $Track.Description}}

    {{$Track.GetDescriptionHTML}}

    diff --git a/admin/templates/html/layout.html b/admin/templates/html/layout.html index 55f2359..0aaf9ca 100644 --- a/admin/templates/html/layout.html +++ b/admin/templates/html/layout.html @@ -28,14 +28,14 @@

    -