diff --git a/admin/releasehttp.go b/admin/releasehttp.go index cee3d1e..7cca841 100644 --- a/admin/releasehttp.go +++ b/admin/releasehttp.go @@ -103,7 +103,9 @@ func serveRelease(app *model.AppState, releaseID string, action string) http.Han Release *model.Release } - for i, track := range release.Tracks { track.Number = i + 1 } + for i, track := range release.Tracks { + track.Number = i + 1 + } err = templates.EditReleaseTemplate.Execute(w, ReleaseResponse{ adminPageData: adminPageData{ Path: r.URL.Path, Session: session }, @@ -155,8 +157,7 @@ func serveAddCredit(app *model.AppState, release *model.Release) http.Handler { func serveNewCredit(app *model.AppState) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - split := strings.Split(r.URL.Path, "/") - artistID := split[len(split) - 1] + artistID := strings.Split(r.URL.Path, "/")[3] artist, err := controller.GetArtist(app.DB, artistID) if err != nil { fmt.Printf("WARN: Failed to fetch artist %s: %s\n", artistID, err) @@ -194,8 +195,6 @@ func serveEditTracks(release *model.Release) http.Handler { type editTracksData struct { Release *model.Release } - for i, track := range release.Tracks { track.Number = i + 1 } - err := templates.EditTracksTemplate.Execute(w, editTracksData{ Release: release }) if err != nil { fmt.Printf("WARN: Failed to serve edit tracks component for %s: %s\n", release.ID, err) @@ -232,8 +231,7 @@ func serveAddTrack(app *model.AppState, release *model.Release) http.Handler { func serveNewTrack(app *model.AppState) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - split := strings.Split(r.URL.Path, "/") - trackID := split[len(split) - 1] + trackID := strings.Split(r.URL.Path, "/")[3] track, err := controller.GetTrack(app.DB, trackID) if err != nil { fmt.Printf("WARN: Failed to fetch track %s: %s\n", trackID, err) diff --git a/admin/static/admin.css b/admin/static/admin.css index 821d294..8f983c7 100644 --- a/admin/static/admin.css +++ b/admin/static/admin.css @@ -111,7 +111,7 @@ body { font-family: "Inter", sans-serif; font-size: 16px; color: var(--fg-0); - background-color: var(--bg-0); + background: var(--bg-0); transition: background .1s ease-out, color .1s ease-out; } @@ -252,6 +252,12 @@ a { transition: color .1s ease-out, background-color .1s ease-out; } +/* +a:hover { + text-decoration: underline; +} +*/ + img.icon { height: .8em; transition: filter .1s ease-out; @@ -277,7 +283,7 @@ code { .card { flex-basis: 40em; padding: 1em; - background-color: var(--bg-1); + background: var(--bg-1); border-radius: 16px; box-shadow: var(--shadow-lg); @@ -355,7 +361,7 @@ a.delete:not(.button) { font-size: inherit; color: inherit; - background-color: var(--bg-2); + background: var(--bg-2); border: none; border-radius: 10em; box-shadow: var(--shadow-sm); @@ -374,27 +380,27 @@ button:active, .button:active { .button.new, button.new { color: var(--col-on-new); - background-color: var(--col-new); + background: var(--col-new); } .button.save, button.save { color: var(--col-on-save); - background-color: var(--col-save); + background: var(--col-save); } .button.delete, button.delete { color: var(--col-on-delete); - background-color: var(--col-delete); + background: var(--col-delete); } .button:hover, button:hover { color: var(--bg-3); - background-color: var(--fg-3); + background: var(--fg-3); } .button:active, button:active { color: var(--bg-2); - background-color: var(--fg-0); + background: var(--fg-0); } .button[disabled], button[disabled] { color: var(--fg-0) !important; - background-color: var(--bg-3) !important; + background: var(--bg-3) !important; opacity: .5; cursor: default !important; } diff --git a/admin/static/artists.css b/admin/static/artists.css index faa5888..516a998 100644 --- a/admin/static/artists.css +++ b/admin/static/artists.css @@ -2,7 +2,7 @@ padding: .5em; color: var(--fg-3); - background-color: var(--bg-2); + background: var(--bg-2); box-shadow: var(--shadow-md); border-radius: 16px; text-align: center; @@ -12,7 +12,7 @@ } .artist:hover { - background-color: var(--bg-1); + background: var(--bg-1); text-decoration: hover; } diff --git a/admin/static/artists.js b/admin/static/artists.js index e3a2d5a..29eab22 100644 --- a/admin/static/artists.js +++ b/admin/static/artists.js @@ -4,29 +4,4 @@ document.addEventListener("readystatechange", () => { document.querySelectorAll(".artists-group .artist").forEach(el => { hijackClickEvent(el, el.querySelector("a.artist-name")) }); - - const newArtistBtn = document.getElementById("create-artist"); - if (newArtistBtn) newArtistBtn.addEventListener("click", event => { - event.preventDefault(); - const id = prompt("Enter an ID for this artist:"); - if (id == null || id == "") return; - - fetch("/api/v1/artist", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({id}) - }).then(res => { - res.text().then(text => { - if (res.ok) { - location = "/admin/artists/" + id; - } else { - alert(text); - console.error(text); - } - }) - }).catch(err => { - alert("Failed to create artist. Check the console for details."); - console.error(err); - }); - }); }); diff --git a/admin/static/edit-account.css b/admin/static/edit-account.css index 8e89cbe..c43d6e9 100644 --- a/admin/static/edit-account.css +++ b/admin/static/edit-account.css @@ -33,7 +33,7 @@ form#delete-account input { justify-content: space-between; color: var(--fg-3); - background-color: var(--bg-2); + background: var(--bg-2); box-shadow: var(--shadow-md); border-radius: 16px; } diff --git a/admin/static/edit-artist.css b/admin/static/edit-artist.css index 0bb85c0..7bf146b 100644 --- a/admin/static/edit-artist.css +++ b/admin/static/edit-artist.css @@ -6,7 +6,7 @@ gap: 1.2em; border-radius: 16px; - background-color: var(--bg-2); + background: var(--bg-2); box-shadow: var(--shadow-md); } @@ -50,11 +50,18 @@ input[type="text"] { font-family: inherit; font-weight: inherit; color: inherit; - background-color: var(--bg-0); + background: var(--bg-0); border: none; border-radius: 4px; outline: none; } +input[type="text"]:hover { + border-color: #80808080; +} +input[type="text"]:active, +input[type="text"]:focus { + border-color: #808080; +} .artist-actions { margin-top: auto; @@ -77,7 +84,7 @@ input[type="text"] { align-items: center; border-radius: 16px; - background-color: var(--bg-2); + background: var(--bg-2); box-shadow: var(--shadow-md); cursor: pointer; @@ -85,7 +92,7 @@ input[type="text"] { } .credit:hover { - background-color: var(--bg-1); + background: var(--bg-1); } .release-artwork { diff --git a/admin/static/edit-release.css b/admin/static/edit-release.css index 8186f2c..434b487 100644 --- a/admin/static/edit-release.css +++ b/admin/static/edit-release.css @@ -12,7 +12,7 @@ input[type="text"] { gap: 1.2em; border-radius: 8px; - background-color: var(--bg-2); + background: var(--bg-2); box-shadow: var(--shadow-md); transition: background .1s ease-out, color .1s ease-out; @@ -33,7 +33,7 @@ input[type="text"] { .release-artwork #remove-artwork { margin-top: .5em; padding: .3em .6em; - background-color: var(--bg-3); + background: var(--bg-3); } .release-info { @@ -62,13 +62,13 @@ input[type="text"] { } #title:hover { - background-color: var(--bg-3); + background: var(--bg-3); border-color: var(--fg-0); } #title:active, #title:focus { - background-color: var(--bg-3); + background: var(--bg-3); } .release-title small { @@ -93,7 +93,7 @@ input[type="text"] { .release-info table tr td:not(:first-child) select:hover, .release-info table tr td:not(:first-child) input:hover, .release-info table tr td:not(:first-child) textarea:hover { - background-color: var(--bg-3); + background: var(--bg-3); cursor: pointer; } .release-info table td select, @@ -127,7 +127,7 @@ input[type="text"] { .release-actions button, .release-actions .button { color: var(--fg-2); - background-color: var(--bg-3); + background: var(--bg-3); } dialog { @@ -234,7 +234,7 @@ dialog div.dialog-actions { gap: 1em; border-radius: 8px; - background-color: var(--bg-2); + background: var(--bg-2); box-shadow: var(--shadow-md); } @@ -280,7 +280,7 @@ dialog div.dialog-actions { border: none; border-radius: 4px; color: var(--fg-2); - background-color: var(--bg-0); + background: var(--bg-0); } #editcredits .credit .credit-info .credit-attribute input[type="checkbox"] { margin: 0 .3em; @@ -299,7 +299,6 @@ dialog div.dialog-actions { #editcredits .credit .delete { margin-right: .5em; cursor: pointer; - overflow: visible; } #editcredits .credit .delete:hover { text-decoration: underline; @@ -316,17 +315,14 @@ dialog div.dialog-actions { display: flex; gap: .5em; cursor: pointer; - background-color: var(--bg-2); } #addcredit ul li.new-artist:nth-child(even) { background: #f0f0f0; - background-color: var(--bg-1); } #addcredit ul li.new-artist:hover { background: #e0e0e0; - background-color: var(--bg-2); } #addcredit .new-artist .artist-id { @@ -379,8 +375,6 @@ dialog div.dialog-actions { #editlinks tr { display: flex; - background-color: var(--bg-1); - transition: background-color .1s ease-out; } #editlinks th { @@ -391,7 +385,7 @@ dialog div.dialog-actions { } #editlinks tr:nth-child(odd) { - background-color: var(--bg-2); + background: #f8f8f8; } #editlinks tr th, @@ -422,11 +416,6 @@ dialog div.dialog-actions { width: 1em; pointer-events: none; } -@media (prefers-color-scheme: dark) { - #editlinks tr .grabber img { - filter: invert(); - } -} #editlinks tr .link-name { width: 8em; } @@ -465,7 +454,6 @@ dialog div.dialog-actions { } #edittracks .track { - background-color: var(--bg-2); transition: transform .2s ease-out, opacity .2s; } @@ -488,7 +476,7 @@ dialog div.dialog-actions { } #edittracks .track:nth-child(even) { - background-color: var(--bg-1); + background: #f0f0f0; } #edittracks .track-number { @@ -504,6 +492,7 @@ dialog div.dialog-actions { #addtrack ul { padding: 0; list-style: none; + background: #f8f8f8; } #addtrack ul li.new-track { diff --git a/admin/static/edit-track.css b/admin/static/edit-track.css index 4824124..f292ca5 100644 --- a/admin/static/edit-track.css +++ b/admin/static/edit-track.css @@ -8,7 +8,7 @@ gap: 1.2em; border-radius: 16px; - background-color: var(--bg-2); + background: var(--bg-2); box-shadow: var(--shadow-md); } @@ -45,13 +45,25 @@ font-weight: inherit; font-family: inherit; font-size: inherit; - background-color: var(--bg-0); + background: var(--bg-0); border: none; border-radius: 4px; outline: none; color: inherit; } +.track-info input[type="text"]:hover, +.track-info textarea:hover { + border-color: #80808080; +} + +.track-info input[type="text"]:active, +.track-info textarea:active, +.track-info input[type="text"]:focus, +.track-info textarea:focus { + border-color: #808080; +} + .track-actions { margin-top: 1em; display: flex; diff --git a/admin/static/index.js b/admin/static/index.js new file mode 100644 index 0000000..60bdfd0 --- /dev/null +++ b/admin/static/index.js @@ -0,0 +1,74 @@ +const newReleaseBtn = document.getElementById("create-release"); +const newArtistBtn = document.getElementById("create-artist"); +const newTrackBtn = document.getElementById("create-track"); + +newReleaseBtn.addEventListener("click", event => { + event.preventDefault(); + const id = prompt("Enter an ID for this release:"); + if (id == null || id == "") return; + + fetch("/api/v1/music", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({id}) + }).then(res => { + if (res.ok) location = "/admin/releases/" + id; + else { + res.text().then(err => { + alert("Request failed: " + err); + console.error(err); + }); + } + }).catch(err => { + alert("Failed to create release. Check the console for details."); + console.error(err); + }); +}); + +newArtistBtn.addEventListener("click", event => { + event.preventDefault(); + const id = prompt("Enter an ID for this artist:"); + if (id == null || id == "") return; + + fetch("/api/v1/artist", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({id}) + }).then(res => { + res.text().then(text => { + if (res.ok) { + location = "/admin/artists/" + id; + } else { + alert("Request failed: " + text); + console.error(text); + } + }) + }).catch(err => { + alert("Failed to create artist. Check the console for details."); + console.error(err); + }); +}); + +newTrackBtn.addEventListener("click", event => { + event.preventDefault(); + const title = prompt("Enter an title for this track:"); + if (title == null || title == "") return; + + fetch("/api/v1/track", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({title}) + }).then(res => { + res.text().then(text => { + if (res.ok) { + location = "/admin/tracks/" + text; + } else { + alert("Request failed: " + text); + console.error(text); + } + }) + }).catch(err => { + alert("Failed to create track. Check the console for details."); + console.error(err); + }); +}); diff --git a/admin/static/logs.css b/admin/static/logs.css index 2412a2b..8da60d0 100644 --- a/admin/static/logs.css +++ b/admin/static/logs.css @@ -8,7 +8,7 @@ form#search-form { padding: 1em; border-radius: 16px; color: var(--fg-0); - background-color: var(--bg-2); + background: var(--bg-2); box-shadow: var(--shadow-md); } @@ -23,7 +23,7 @@ div#search { border: none; border-radius: 16px; color: var(--fg-1); - background-color: var(--bg-0); + background: var(--bg-0); box-shadow: var(--shadow-sm); } @@ -100,8 +100,8 @@ td.log-content { #logs .log.warn { color: var(--col-on-warn); - background-color: var(--col-warn); + background: var(--col-warn); } #logs .log.warn:hover { - background-color: var(--col-warn-hover); + background: var(--col-warn-hover); } diff --git a/admin/static/releases.css b/admin/static/releases.css index 19f393f..0694875 100644 --- a/admin/static/releases.css +++ b/admin/static/releases.css @@ -6,7 +6,7 @@ gap: 1em; border-radius: 16px; - background-color: var(--bg-2); + background: var(--bg-2); box-shadow: var(--shadow-md); transition: background .1s ease-out, color .1s ease-out; @@ -67,14 +67,14 @@ display: inline-block; border-radius: 4px; - background-color: var(--bg-3); + background: var(--bg-3); box-shadow: var(--shadow-sm); transition: color .1s ease-out, background .1s ease-out; } .release .release-actions a:hover { - background-color: var(--bg-0); + background: var(--bg-0); color: var(--fg-3); text-decoration: none; } diff --git a/admin/static/releases.js b/admin/static/releases.js deleted file mode 100644 index af12429..0000000 --- a/admin/static/releases.js +++ /dev/null @@ -1,25 +0,0 @@ -document.addEventListener('readystatechange', () => { - const newReleaseBtn = document.getElementById("create-release"); - if (newReleaseBtn) newReleaseBtn.addEventListener("click", event => { - event.preventDefault(); - const id = prompt("Enter an ID for this release:"); - if (id == null || id == "") return; - - fetch("/api/v1/music", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({id}) - }).then(res => { - if (res.ok) location = "/admin/releases/" + id; - else { - res.text().then(err => { - alert(err); - console.error(err); - }); - } - }).catch(err => { - alert("Failed to create release. Check the console for details."); - console.error(err); - }); - }); -}); diff --git a/admin/static/tracks.css b/admin/static/tracks.css index 3ea4f06..c36c1b1 100644 --- a/admin/static/tracks.css +++ b/admin/static/tracks.css @@ -12,7 +12,7 @@ gap: .5em; border-radius: 16px; - background-color: var(--bg-2); + background: var(--bg-2); box-shadow: var(--shadow-md); transition: background .1s ease-out, color .1s ease-out; @@ -44,6 +44,11 @@ opacity: .5; } +#tracks .track-album.empty { + color: #ff2020; + opacity: 1; +} + #tracks .track-description { font-style: italic; } @@ -62,4 +67,61 @@ margin: 0; display: flex; flex-direction: row; + /* + justify-content: space-between; + */ } + +/* +.track { + margin-bottom: 1em; + padding: 1em; + display: flex; + flex-direction: column; + gap: .5em; + + border-radius: 8px; + background-color: var(--bg-2); + box-shadow: var(--shadow-md); + + transition: color .1s ease-out, background-color .1s ease-out; +} + +.track p { + margin: 0; +} + +.track-id { + width: fit-content; + font-family: "Monaspace Argon", monospace; + font-size: .8em; + font-style: italic; + line-height: 1em; + user-select: all; +} + +.track-album { + margin-left: auto; + font-style: italic; + font-size: .75em; + opacity: .5; +} + +.track-album.empty { + color: #ff2020; + opacity: 1; +} + +.track-description { + font-style: italic; +} + +.track-lyrics { + max-height: 10em; + overflow-y: scroll; +} + +.track .empty { + opacity: 0.75; +} +*/ diff --git a/admin/static/tracks.js b/admin/static/tracks.js deleted file mode 100644 index bef1152..0000000 --- a/admin/static/tracks.js +++ /dev/null @@ -1,24 +0,0 @@ -const newTrackBtn = document.getElementById("create-track"); -if (newTrackBtn) newTrackBtn.addEventListener("click", event => { - event.preventDefault(); - const title = prompt("Enter an title for this track:"); - if (title == null || title == "") return; - - fetch("/api/v1/track", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({title}) - }).then(res => { - res.text().then(text => { - if (res.ok) { - location = "/admin/tracks/" + text; - } else { - alert(text); - console.error(text); - } - }) - }).catch(err => { - alert("Failed to create track. Check the console for details."); - console.error(err); - }); -}); diff --git a/admin/templates/html/components/track/edittracks.html b/admin/templates/html/components/track/edittracks.html index f9e90f9..c06f0c3 100644 --- a/admin/templates/html/components/track/edittracks.html +++ b/admin/templates/html/components/track/edittracks.html @@ -12,12 +12,12 @@