description: str
tags: list[str]
collaborators: list[str]
+ fgcolor: str
+ bgcolor: str
+ accolor: str
def json(self):
return json.dumps(vars(self))
for sd in songs_data:
song_tags = [t["tag"] for t in tags[sd["songid"]]]
song_collabs = [c["name"] for c in collabs[sd["songid"]]]
- songs.append(cls(sd["songid"], sd["userid"], sd["username"], sd["title"], sanitize_user_text(sd["description"]), song_tags, song_collabs))
+ songs.append(cls(
+ sd["songid"],
+ sd["userid"],
+ sd["username"],
+ sd["title"],
+ sanitize_user_text(sd["description"]),
+ song_tags,
+ song_collabs,
+ sd["fgcolor"],
+ sd["bgcolor"],
+ sd["accolor"],
+ ))
return songs
var button = document.getElementById("play-pause-button");
audio.addEventListener("play", (event) => {
button.className = "lsp_btn_pause02";
- button.src = customImage(document.getElementById("lsp_btn_pause02"));
+ button.src = customImage(document.getElementById("lsp_btn_pause02"), button);
})
// Show play button when audio is paused
audio.addEventListener("pause", (event) => {
button.className = "lsp_btn_play02";
- button.src = customImage(document.getElementById("lsp_btn_play02"));
+ button.src = customImage(document.getElementById("lsp_btn_play02"), button);
})
// Audio position scrubbing
div.song {
box-shadow: 0px 0px 5px 0px;
border-radius: 10px;
+ background-color: var(--yellow);
}
div.song-main {
margin: 10px;
}
+div.song-info-sep {
+ color: var(--black);
+}
+
/* Artist on separate line for mobile */
@media screen and (max-width: 480px) {
div.song-info {
width: 32px;
}
+.collab-name {
+ color: var(--black);
+}
+
div.song-details {
display: flex;
flex-direction: column;
<script>
- function customImage(element) {
+ function customImage(source, target) {
// Customize an image by performing a palette swap on the .gif
// file. The source element must contain a data-img-b64 attribute
// containing the base64 representation of a .gif file. The byte
// indexes match .gifs from Aseprite, and may not work for all
// .gif files.
- var style = window.getComputedStyle(document.body);
+ var style = window.getComputedStyle(target);
var bgcolor = style.getPropertyValue("--yellow");
var accolor = style.getPropertyValue("--purple");
// Convert base64 string to Uint8Array so we can modify it
- var data = atob(element.dataset.imgB64);
+ var data = atob(source.dataset.imgB64);
var bytes = Uint8Array.from(data, c => c.charCodeAt(0));
// Replace background color palette bytes in gif file
function updateImageColors() {
// Perform a palette swap on all gifs based on current page colors
- document.querySelectorAll(".img-data").forEach(e => {
- document.querySelectorAll(`.${e.id}`).forEach(t => {
- t.src = customImage(e);
+ document.querySelectorAll(".img-data").forEach(s => {
+ document.querySelectorAll(`.${s.id}`).forEach(t => {
+ t.src = customImage(s, t);
});
});
}
<div class="song-list">
{% for song in songs %}
- <div class="song" data-song="{{ song.json() }}">
+<div class="song" style="{% if song.bgcolor %}--yellow: {{ song.bgcolor }};{% endif %} {% if song.fgcolor %}--black: {{ song.fgcolor }};{% endif %} {% if song.accolor %}--purple: {{ song.accolor }};{% endif %}" data-song="{{ song.json() }}">
<div class="song-main">
<!-- Profile Picture -->
<img class="small-pfp" src="/pfp/{{ song.userid }}" onerror="this.style.display = 'none'" />
child.hidden = false;
event.target.alt = "Hide Details";
event.target.className = "lsp_btn_hide02";
- event.target.src = customImage(document.getElementById("lsp_btn_hide02"));
+ event.target.src = customImage(document.getElementById("lsp_btn_hide02"), event.target);
}
else {
// Hide details
child.hidden = true;
event.target.alt = "Show Details";
event.target.className = "lsp_btn_show02";
- event.target.src = customImage(document.getElementById("lsp_btn_show02"));
+ event.target.src = customImage(document.getElementById("lsp_btn_show02"), event.target);
}
}
}