tracks can be edited! + major template overhaul
This commit is contained in:
parent
99b6a21179
commit
63122eb428
21 changed files with 674 additions and 221 deletions
|
@ -93,10 +93,12 @@ a img {
|
|||
margin: 0 0 .5em 0;
|
||||
}
|
||||
|
||||
/*
|
||||
.card h3,
|
||||
.card p {
|
||||
margin: 0;
|
||||
}
|
||||
*/
|
||||
|
||||
.card-title {
|
||||
margin-bottom: 1em;
|
||||
|
|
|
@ -87,9 +87,8 @@ input[type="text"] {
|
|||
.release-info table td select,
|
||||
.release-info table td input,
|
||||
.release-info table td textarea {
|
||||
padding: .2em;
|
||||
resize: none;
|
||||
width: 100%;
|
||||
padding: .2em;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
color: inherit;
|
||||
|
@ -212,6 +211,10 @@ dialog div.dialog-actions {
|
|||
border: 1px solid #808080;
|
||||
}
|
||||
|
||||
.card.credits .credit p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.card.credits .credit .artist-avatar {
|
||||
border-radius: .5em;
|
||||
}
|
||||
|
@ -441,6 +444,11 @@ dialog div.dialog-actions {
|
|||
border: 1px solid #808080;
|
||||
}
|
||||
|
||||
.card.tracks .track h3,
|
||||
.card.tracks .track p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.card.tracks h2.track-title {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
|
|
|
@ -1,112 +1,127 @@
|
|||
import Stateful from "/script/silver.min.js"
|
||||
|
||||
const releaseID = document.getElementById("release").dataset.id;
|
||||
const title_input = document.getElementById("title");
|
||||
const artwork_img = document.getElementById("artwork");
|
||||
const artwork_input = document.getElementById("artwork-file");
|
||||
const type_input = document.getElementById("type");
|
||||
const desc_input = document.getElementById("description");
|
||||
const date_input = document.getElementById("release-date");
|
||||
const buyname_input = document.getElementById("buyname");
|
||||
const buylink_input = document.getElementById("buylink");
|
||||
const vis_input = document.getElementById("visibility");
|
||||
const save_btn = document.getElementById("save");
|
||||
|
||||
var artwork_data = artwork_img.attributes.src.value;
|
||||
|
||||
var token = atob(localStorage.getItem("arime-token"));
|
||||
const titleInput = document.getElementById("title");
|
||||
const artworkImg = document.getElementById("artwork");
|
||||
const artworkInput = document.getElementById("artwork-file");
|
||||
const typeInput = document.getElementById("type");
|
||||
const descInput = document.getElementById("description");
|
||||
const dateInput = document.getElementById("release-date");
|
||||
const buynameInput = document.getElementById("buyname");
|
||||
const buylinkInput = document.getElementById("buylink");
|
||||
const visInput = document.getElementById("visibility");
|
||||
const saveBtn = document.getElementById("save");
|
||||
const deleteBtn = document.getElementById("delete");
|
||||
|
||||
var artworkData = artworkImg.attributes.src.value;
|
||||
var edited = new Stateful(false);
|
||||
var releaseData = updateData(undefined);
|
||||
|
||||
var release_data = update_data(undefined);
|
||||
|
||||
function update_data(old) {
|
||||
var release_data = {
|
||||
visible: vis_input.value === "true",
|
||||
title: title_input.value,
|
||||
description: desc_input.value,
|
||||
type: type_input.value,
|
||||
releaseDate: date_input.value,
|
||||
artwork: artwork_data,
|
||||
buyname: buyname_input.value,
|
||||
buylink: buylink_input.value,
|
||||
function updateData(old) {
|
||||
var releaseData = {
|
||||
visible: visInput.value === "true",
|
||||
title: titleInput.value,
|
||||
description: descInput.value,
|
||||
type: typeInput.value,
|
||||
releaseDate: dateInput.value,
|
||||
artwork: artworkData,
|
||||
buyname: buynameInput.value,
|
||||
buylink: buylinkInput.value,
|
||||
};
|
||||
|
||||
if (release_data && release_data != old) {
|
||||
if (releaseData && releaseData != old) {
|
||||
edited.set(true);
|
||||
}
|
||||
|
||||
return release_data;
|
||||
return releaseData;
|
||||
}
|
||||
|
||||
function save_release() {
|
||||
console.table(release_data);
|
||||
|
||||
(async () => {
|
||||
const res = await fetch(
|
||||
"/api/v1/music/" + releaseID, {
|
||||
method: "PUT",
|
||||
body: JSON.stringify(release_data),
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorisation": "Bearer " + token,
|
||||
},
|
||||
});
|
||||
function saveRelease() {
|
||||
console.table(releaseData);
|
||||
|
||||
fetch("/api/v1/music/" + releaseID, {
|
||||
method: "PUT",
|
||||
body: JSON.stringify(releaseData),
|
||||
headers: { "Content-Type": "application/json" }
|
||||
}).then(res => {
|
||||
if (!res.ok) {
|
||||
const text = await res.text();
|
||||
console.error(text);
|
||||
alert(text);
|
||||
res.text().then(error => {
|
||||
console.error(error);
|
||||
alert("Failed to update release: " + error);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
location = location;
|
||||
})();
|
||||
});
|
||||
}
|
||||
|
||||
function deleteRelease() {
|
||||
fetch("/api/v1/music/" + releaseID, {
|
||||
method: "DELETE",
|
||||
}).then(res => {
|
||||
if (!res.ok) {
|
||||
res.text().then(error => {
|
||||
console.error(error);
|
||||
alert("Failed to delete release: " + error);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
location = "/admin";
|
||||
});
|
||||
}
|
||||
|
||||
edited.onUpdate(edited => {
|
||||
save_btn.disabled = !edited;
|
||||
saveBtn.disabled = !edited;
|
||||
})
|
||||
|
||||
title_input.addEventListener("change", () => {
|
||||
release_data = update_data(release_data);
|
||||
titleInput.addEventListener("change", () => {
|
||||
releaseData = updateData(releaseData);
|
||||
});
|
||||
artwork_img.addEventListener("click", () => {
|
||||
artwork_input.addEventListener("change", () => {
|
||||
if (artwork_input.files.length > 0) {
|
||||
artworkImg.addEventListener("click", () => {
|
||||
artworkInput.addEventListener("change", () => {
|
||||
if (artworkInput.files.length > 0) {
|
||||
const reader = new FileReader();
|
||||
reader.onload = e => {
|
||||
const data = e.target.result;
|
||||
artwork_img.src = data;
|
||||
artwork_data = data;
|
||||
release_data = update_data(release_data);
|
||||
artworkImg.src = data;
|
||||
artworkData = data;
|
||||
releaseData = updateData(releaseData);
|
||||
};
|
||||
reader.readAsDataURL(artwork_input.files[0]);
|
||||
reader.readAsDataURL(artworkInput.files[0]);
|
||||
}
|
||||
});
|
||||
artwork_input.click();
|
||||
artworkInput.click();
|
||||
});
|
||||
type_input.addEventListener("change", () => {
|
||||
release_data = update_data(release_data);
|
||||
typeInput.addEventListener("change", () => {
|
||||
releaseData = updateData(releaseData);
|
||||
});
|
||||
desc_input.addEventListener("change", () => {
|
||||
release_data = update_data(release_data);
|
||||
descInput.addEventListener("change", () => {
|
||||
releaseData = updateData(releaseData);
|
||||
});
|
||||
date_input.addEventListener("change", () => {
|
||||
release_data = update_data(release_data);
|
||||
dateInput.addEventListener("change", () => {
|
||||
releaseData = updateData(releaseData);
|
||||
});
|
||||
buyname_input.addEventListener("change", () => {
|
||||
release_data = update_data(release_data);
|
||||
buynameInput.addEventListener("change", () => {
|
||||
releaseData = updateData(releaseData);
|
||||
});
|
||||
buylink_input.addEventListener("change", () => {
|
||||
release_data = update_data(release_data);
|
||||
buylinkInput.addEventListener("change", () => {
|
||||
releaseData = updateData(releaseData);
|
||||
});
|
||||
vis_input.addEventListener("change", () => {
|
||||
release_data = update_data(release_data);
|
||||
visInput.addEventListener("change", () => {
|
||||
releaseData = updateData(releaseData);
|
||||
});
|
||||
|
||||
save_btn.addEventListener("click", () => {
|
||||
saveBtn.addEventListener("click", () => {
|
||||
if (!edited.get()) return;
|
||||
saveRelease();
|
||||
});
|
||||
|
||||
save_release();
|
||||
})
|
||||
deleteBtn.addEventListener("click", () => {
|
||||
if (releaseID != prompt(
|
||||
"You are about to permanently delete " + releaseID + ". " +
|
||||
"This action is irreversible. " +
|
||||
"Please enter \"" + releaseID + "\" to continue.")) return;
|
||||
deleteRelease();
|
||||
});
|
||||
|
|
219
admin/static/edit-track.css
Normal file
219
admin/static/edit-track.css
Normal file
|
@ -0,0 +1,219 @@
|
|||
h1 {
|
||||
margin: 0 0 .5em 0;
|
||||
}
|
||||
|
||||
#track {
|
||||
margin-bottom: 1em;
|
||||
padding: 1.5em;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 1.2em;
|
||||
|
||||
border-radius: .5em;
|
||||
background: #f8f8f8f8;
|
||||
border: 1px solid #808080;
|
||||
}
|
||||
|
||||
.track-info {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.track-title-header {
|
||||
margin: 0;
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
.track-title {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#title {
|
||||
width: 100%;
|
||||
margin: -.1em -.2em;
|
||||
padding: .1em .2em;
|
||||
font-weight: bold;
|
||||
font-size: inherit;
|
||||
border-radius: 4px;
|
||||
border: 1px solid transparent;
|
||||
background: transparent;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
#title:hover {
|
||||
background: #ffffff;
|
||||
border-color: #80808080;
|
||||
}
|
||||
|
||||
#title:active,
|
||||
#title:focus {
|
||||
background: #ffffff;
|
||||
border-color: #808080;
|
||||
}
|
||||
|
||||
.track-title small {
|
||||
opacity: .75;
|
||||
}
|
||||
|
||||
.track-info h2 {
|
||||
margin-bottom: .4em;
|
||||
}
|
||||
|
||||
.track-info textarea {
|
||||
width: 100%;
|
||||
padding: .5em;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
color: inherit;
|
||||
border: none;
|
||||
outline: none;
|
||||
resize: vertical;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
button, .button {
|
||||
padding: .5em .8em;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
border-radius: .5em;
|
||||
border: 1px solid #a0a0a0;
|
||||
background: #f0f0f0;
|
||||
color: inherit;
|
||||
}
|
||||
button:hover, .button:hover {
|
||||
background: #fff;
|
||||
border-color: #d0d0d0;
|
||||
}
|
||||
button:active, .button:active {
|
||||
background: #d0d0d0;
|
||||
border-color: #808080;
|
||||
}
|
||||
|
||||
button {
|
||||
color: inherit;
|
||||
}
|
||||
button.save {
|
||||
background: #6fd7ff;
|
||||
border-color: #6f9eb0;
|
||||
}
|
||||
button.delete {
|
||||
background: #ff7171;
|
||||
border-color: #7d3535;
|
||||
}
|
||||
button:hover {
|
||||
background: #fff;
|
||||
border-color: #d0d0d0;
|
||||
}
|
||||
button:active {
|
||||
background: #d0d0d0;
|
||||
border-color: #808080;
|
||||
}
|
||||
button[disabled] {
|
||||
background: #d0d0d0 !important;
|
||||
border-color: #808080 !important;
|
||||
opacity: .5;
|
||||
cursor: not-allowed !important;
|
||||
}
|
||||
|
||||
a.delete {
|
||||
color: #d22828;
|
||||
}
|
||||
|
||||
.track-actions {
|
||||
margin-top: 1em;
|
||||
display: flex;
|
||||
gap: .5em;
|
||||
flex-direction: row;
|
||||
justify-content: right;
|
||||
}
|
||||
|
||||
.release {
|
||||
margin-bottom: 1em;
|
||||
padding: 1em;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 1em;
|
||||
|
||||
border-radius: .5em;
|
||||
background: #f8f8f8f8;
|
||||
border: 1px solid #808080;
|
||||
}
|
||||
|
||||
.release h3,
|
||||
.release p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.release-artwork {
|
||||
width: 96px;
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.release-artwork img {
|
||||
width: 100%;
|
||||
aspect-ratio: 1;
|
||||
}
|
||||
|
||||
.release-title small {
|
||||
opacity: .75;
|
||||
}
|
||||
|
||||
.release-links {
|
||||
margin: .5em 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
list-style: none;
|
||||
flex-wrap: wrap;
|
||||
gap: .5em;
|
||||
}
|
||||
|
||||
.release-links li {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.release-links a {
|
||||
padding: .5em;
|
||||
display: block;
|
||||
|
||||
border-radius: .5em;
|
||||
text-decoration: none;
|
||||
color: #f0f0f0;
|
||||
background: #303030;
|
||||
text-align: center;
|
||||
|
||||
transition: color .1s, background .1s;
|
||||
}
|
||||
|
||||
.release-links a:hover {
|
||||
color: #303030;
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
.release-actions {
|
||||
margin-top: .5em;
|
||||
}
|
||||
|
||||
.release-actions a {
|
||||
margin-right: .3em;
|
||||
padding: .3em .5em;
|
||||
display: inline-block;
|
||||
|
||||
border-radius: .3em;
|
||||
background: #e0e0e0;
|
||||
|
||||
transition: color .1s, background .1s;
|
||||
}
|
||||
|
||||
.release-actions a:hover {
|
||||
color: #303030;
|
||||
background: #f0f0f0;
|
||||
|
||||
text-decoration: none;
|
||||
}
|
58
admin/static/edit-track.js
Normal file
58
admin/static/edit-track.js
Normal file
|
@ -0,0 +1,58 @@
|
|||
const trackID = document.getElementById("track").dataset.id;
|
||||
const titleInput = document.getElementById("title");
|
||||
const descInput = document.getElementById("description");
|
||||
const lyricsInput = document.getElementById("lyrics");
|
||||
const saveBtn = document.getElementById("save");
|
||||
const deleteBtn = document.getElementById("delete");
|
||||
|
||||
saveBtn.addEventListener("click", () => {
|
||||
fetch("/api/v1/track/" + trackID, {
|
||||
method: "PUT",
|
||||
body: JSON.stringify({
|
||||
title: titleInput.value,
|
||||
description: descInput.value,
|
||||
lyrics: lyricsInput.value,
|
||||
}),
|
||||
headers: { "Content-Type": "application/json" }
|
||||
}).then(res => {
|
||||
if (!res.ok) {
|
||||
res.text().then(error => {
|
||||
console.error(error);
|
||||
alert("Failed to update track: " + error);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
location = location;
|
||||
});
|
||||
});
|
||||
|
||||
deleteBtn.addEventListener("click", () => {
|
||||
if (!confirm(
|
||||
"You are about to permanently delete \"" + titleInput.value + "\".\n" +
|
||||
"This action is irreversible. Do you wish to continue?")) return;
|
||||
|
||||
fetch("/api/v1/track/" + trackID, {
|
||||
method: "DELETE",
|
||||
}).then(res => {
|
||||
if (!res.ok) {
|
||||
res.text().then(error => {
|
||||
console.error(error);
|
||||
alert("Failed to delete track: " + error);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
location = "/admin";
|
||||
});
|
||||
});
|
||||
|
||||
[titleInput, descInput, lyricsInput].forEach(input => {
|
||||
input.addEventListener("change", () => {
|
||||
saveBtn.disabled = false;
|
||||
});
|
||||
input.addEventListener("keypress", () => {
|
||||
saveBtn.disabled = false;
|
||||
});
|
||||
});
|
||||
|
|
@ -28,6 +28,11 @@
|
|||
border: 1px solid #808080;
|
||||
}
|
||||
|
||||
.release h3,
|
||||
.release p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.release-artwork {
|
||||
width: 96px;
|
||||
|
||||
|
@ -140,6 +145,10 @@
|
|||
border: 1px solid #808080;
|
||||
}
|
||||
|
||||
.track p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.card h2.track-title {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue