Skip to content

Commit f341a03

Browse files
committed
Clean playlist display
1 parent 9ce858d commit f341a03

File tree

5 files changed

+70
-57
lines changed

5 files changed

+70
-57
lines changed

web/css/index.css

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
}
2121

2222
/* Elements we can click */
23-
.song-img, h2 {
23+
.song-img, h2, .playlist {
2424
cursor: pointer;
2525
}
2626

web/src/main/getMusics.js

+7-56
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { archiveSong, createPlaylist, favoriteSong, getApiToken, getDownloadProc
99
import { spawnSongNode } from './song';
1010
import { modal_askPassword, modal_showNotification } from './modal';
1111
import { doesUseRawAudio, isMinimalistMode } from './settings';
12+
import { spawnPlaylistNode } from './playlist';
1213

1314
let json;
1415
let metadataJson;
@@ -168,7 +169,7 @@ function playSingleSong(index) {
168169
}
169170

170171
// Sanitize a name so the user can't inject HTML with the title
171-
function sanitize(text) {
172+
export function sanitize(text) {
172173
if (text === null) return "";
173174
return text
174175
.replaceAll('<', '&lt;')
@@ -181,76 +182,27 @@ function sanitize(text) {
181182

182183
// #region On page load
183184

184-
function getAlbumImage(elem) {
185+
export function getAlbumImage(elem) {
185186
if (elem.album === null || elem.album === undefined || !(elem.album in json.albums) || json.albums[elem.album].path === null) {
186187
return "/img/CD.png";
187188
}
188189
return "/data/icon/" + json.albums[elem.album].path;
189190
}
190191

191-
function getPlaylistHtml(id, name) {
192-
let mostPresents = {};
193-
let count = 0;
194-
for (let elem of json.musics) {
195-
if (!elem.playlists.includes(id) && id !== "all") { // We filter by playlist (except if current playlist is "all")
196-
continue;
197-
}
198-
count++;
199-
if (elem.album === null) { // TODO: Should also check playlist path
200-
continue;
201-
}
202-
let img = getAlbumImage(elem);
203-
if (mostPresents[img] === undefined) {
204-
mostPresents[img] = 1;
205-
} else {
206-
mostPresents[img]++;
207-
}
208-
}
209-
let imgs = Object.keys(mostPresents).map(function(key) {
210-
return [key, mostPresents[key]];
211-
}).sort(function(a, b) {
212-
return b[1] - a[1];
213-
}).slice(0, 4);
214-
215-
let htmlImgs = "";
216-
if (imgs.length === 0) {
217-
htmlImgs = `<img class="image" src="/img/CD.png"/ draggable="false">`;
218-
} else {
219-
for (let img of imgs) {
220-
htmlImgs += `<img class="image" src="${img[0]}"/ draggable="false">`;
221-
}
222-
}
223-
224-
return `
225-
<div class="song card" onclick="window.location=window.location.origin + window.location.pathname + '?playlist=${id}';">
226-
<div class="is-flex is-flex-wrap-wrap is-gap-0 playlist-img-container card-image">
227-
${htmlImgs}
228-
</div>
229-
<div class="card-content has-text-centered">
230-
<p>
231-
${sanitize(name)}<br/>
232-
${count} songs
233-
</p>
234-
</div>
235-
</div>
236-
`;
237-
}
238-
239192
function displayPlaylists(playlists, id, filter) {
240-
let html = "";
241193
if (metadataJson.showAllPlaylist && json.musics.length > 0) {
242-
html += getPlaylistHtml("all", "All");
194+
spawnPlaylistNode("all", "All", json, id);
243195
}
244196
for (let elem in playlists) {
245197
const p = playlists[elem];
246198
if (filter === "" || sanitize(p.name).toLowerCase().includes(filter)) {
247-
html += getPlaylistHtml(elem, p.name);
199+
spawnPlaylistNode(elem, p.name, json, id);
248200
}
249201
}
250202
if (!metadataJson.showAllPlaylist && json.musics.some(x => x.playlists.length === 0) && (filter === "" || sanitize("Unnamed").toLowerCase().includes(filter))) {
251-
html += getPlaylistHtml("default", "Unnamed");
203+
spawnPlaylistNode("default", "Unnamed", json, id);
252204
}
253-
html += `
205+
document.getElementById(id).innerHTML += `
254206
<div id="new-playlist" class="song card requires-admin ${isLoggedIn() ? "" : "is-hidden"}">
255207
<div class="card-content has-text-centered">
256208
<div class="is-flex is-flex-wrap-wrap is-gap-0 playlist-img-container card-image"></div>
@@ -260,7 +212,6 @@ function displayPlaylists(playlists, id, filter) {
260212
</div>
261213
</div>
262214
`;
263-
document.getElementById(id).innerHTML = html;
264215

265216
document.getElementById("new-playlist").addEventListener("click", createNewPlaylist);
266217
}

web/src/main/playlist.js

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// module "playlist.js"
2+
3+
import { getAlbumImage, sanitize } from "./getMusics";
4+
5+
export function spawnPlaylistNode(id, name, json, nodeId) {
6+
7+
let template = document.getElementById("template-playlist");
8+
const node = template.content.cloneNode(true);
9+
10+
// Set click callback
11+
// For some wizardry just assigning onclick doesn't work
12+
node.querySelector(".playlist").setAttribute("onclick", `window.location=window.location.origin + window.location.pathname + '?playlist=${id}';`)
13+
14+
// Prepare images to display inside
15+
let mostPresents = {};
16+
let count = 0;
17+
for (let elem of json.musics) {
18+
if (!elem.playlists.includes(id) && id !== "all") { // We filter by playlist (except if current playlist is "all")
19+
continue;
20+
}
21+
count++;
22+
if (elem.album === null) { // TODO: Should also check playlist path
23+
continue;
24+
}
25+
let img = getAlbumImage(elem);
26+
if (mostPresents[img] === undefined) {
27+
mostPresents[img] = 1;
28+
} else {
29+
mostPresents[img]++;
30+
}
31+
}
32+
let imgs = Object.keys(mostPresents).map(function(key) {
33+
return [key, mostPresents[key]];
34+
}).sort(function(a, b) {
35+
return b[1] - a[1];
36+
}).slice(0, 4);
37+
38+
let htmlImgs = "";
39+
if (imgs.length === 0) {
40+
htmlImgs = `<img class="image" src="/img/CD.png"/ draggable="false">`;
41+
} else {
42+
for (let img of imgs) {
43+
htmlImgs += `<img class="image" src="${img[0]}"/ draggable="false">`;
44+
}
45+
}
46+
node.querySelector(".playlist-img-container").innerHTML = htmlImgs;
47+
48+
node.querySelector(".card-content > p").innerHTML = `${sanitize(name)}<br>${count} songs`;
49+
50+
document.getElementById(nodeId).appendChild(node);
51+
}

web/templates/index.html.twig

+3
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@
6060
<template id="template-song">
6161
{% include 'song.html.twig' %}
6262
</template>
63+
<template id="template-playlist">
64+
{% include 'playlist.html.twig' %}
65+
</template>
6366
<div id="playlists">
6467
<hr/>
6568
<div id="actions">

web/templates/playlist.html.twig

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<div class="song card playlist">
2+
<div class="is-flex is-flex-wrap-wrap is-gap-0 playlist-img-container card-image">
3+
</div>
4+
<div class="card-content has-text-centered">
5+
<p>
6+
</p>
7+
</div>
8+
</div>

0 commit comments

Comments
 (0)