mirror of
https://gitlab.com/parroquia-san-leandro/cancionero-web.git
synced 2026-01-28 13:07:58 +01:00
263 lines
8.9 KiB
HTML
263 lines
8.9 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="es">
|
|
<head>
|
|
{% include "head.html" with path=path title=title only %}
|
|
<link rel="stylesheet" type="text/css" href="{{ path|urlencode }}/index.css">
|
|
<link rel="stylesheet" type="text/css" href="{{ path|urlencode }}/song.css">
|
|
<script src="{{ path|urlencode }}/song.js"></script>
|
|
<style>
|
|
.hideControls .controls {
|
|
display: none;
|
|
}
|
|
.hidePreview .preview {
|
|
display: none;
|
|
}
|
|
#songlist > *,
|
|
.mainButtons input[type="button"],
|
|
.mainButtons button {
|
|
margin-bottom: .5em;
|
|
}
|
|
label.forCheckbox {
|
|
text-wrap: nowrap;
|
|
}
|
|
button.icon img {
|
|
width: 1em;
|
|
height: 0.9em;
|
|
pointer-events: none;
|
|
}
|
|
img.redFilter {
|
|
filter: invert(55%) sepia(67%) saturate(876%) hue-rotate(-40deg) brightness(90%) contrast(103%);
|
|
}
|
|
img.greenFilter {
|
|
filter: invert(61%) sepia(78%) saturate(626%) hue-rotate(43deg) brightness(70%) contrast(102%);
|
|
}
|
|
span.songSelector {
|
|
display: flex;
|
|
flex-wrap: nowrap;
|
|
column-gap: 0.3em;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
{% include "header.html" %}
|
|
<main>
|
|
<h1>Preparar una misa</h1>
|
|
<p>A continuación puedes crear una web con una lista de canciones y
|
|
<input type="button" onclick="shareList(event)" value="compartirla">.</p>
|
|
<p>Si prefieres crear un PDF, <a href="https://cgj.es/cancionero-generador/">pulsa aquí</a>.</p>
|
|
<p>
|
|
<label class="forCheckbox"><input class="init" id="controlsCheckbox" type="checkbox" onchange="toggleControls(event)" checked> Modificar la lista</label>
|
|
<label class="forCheckbox"><input class="init" id="previewCheckbox" type="checkbox" onchange="togglePreview(event)"> Ver las canciones</label>
|
|
<label class="forCheckbox"><input id="showChords" type="checkbox" checked onchange="showChords(this.checked)"/> Mostrar acordes</label>
|
|
</p>
|
|
<p class="controls mainButtons">
|
|
Añadir
|
|
<span class="buttonpair flex-reverse">
|
|
<button class="icon right pair-sub" title="Añadir una canción aleatoria" onclick="addRandomSong()">
|
|
aleatoria <img class="greenFilter" src="svg/random.svg"></button>
|
|
<button class="icon left pair-sup" title="Añadir una canción vacía" onclick="addSong()">
|
|
<img class="greenFilter" src="svg/new.svg"> una canción</button>
|
|
</span>
|
|
<br>
|
|
Añadir
|
|
<span class="buttonpair flex-reverse">
|
|
<button class="icon right pair-sub" title="Añade una canción aleatoria por categoría" onclick="addRandomSongs()">
|
|
aleatorias <img class="greenFilter" src="svg/random.svg"></button>
|
|
<button class="icon left pair-sup" title="Añade una canción por categoría" onclick="addFirstSongs()">
|
|
<img class="greenFilter" src="svg/new.svg"> varias canciones</button>
|
|
</span>
|
|
<br>
|
|
<button class="icon" onclick="clearSongs()"><img class="redFilter" src="svg/trash.svg"> Borrar todas</button>
|
|
</p>
|
|
<div id="songlist"></div>
|
|
<input type="button" onclick="shareList(event)" value="Compartir enlace al cancionero">
|
|
<dialog id="sharedialog">
|
|
<p>Copia y comparte el enlace: <a id="sharelink" href="">tus canciones</a></p>
|
|
<input type="button" onclick="event.target.parentElement.close()" value="Cerrar">
|
|
</dialog>
|
|
<template id='songtemplate'>
|
|
<div><span class="controls songSelector"><select name="songs[]" required onchange="songSelect(event)">
|
|
<option value="">Selecciona una canción</option>{% for category, songs in categorized_songs %}
|
|
<optgroup label="— {{ category }}">{% for s in songs %}
|
|
<option value="{{ s.number }}">{{ s.number }}. {{ s.name }}</option>{% endfor %}
|
|
</optgroup>{% endfor %}
|
|
</select>
|
|
<button class="icon" title="Subir" onclick="songUp(event)"><img class="greenFilter" src="svg/up.svg"></button>
|
|
<button class="icon" title="Bajar" onclick="songDown(event)"><img class="greenFilter" src="svg/down.svg"></button>
|
|
<button class="icon" title="Quitar" onclick="songDelete(event)"><img class="redFilter" src="svg/trash.svg"></button>
|
|
</span>
|
|
<div class="preview"></div>
|
|
</div>
|
|
</template>
|
|
</main>
|
|
<script>
|
|
function addSong() {
|
|
let ol = document.getElementById("songlist");
|
|
let node = document.getElementById("songtemplate").content.firstElementChild.cloneNode(true);
|
|
ol.appendChild(node);
|
|
return node;
|
|
}
|
|
|
|
function songUp(event) {
|
|
const li = event.target.parentElement.parentElement;
|
|
const prev = li.previousElementSibling;
|
|
const ol = li.parentElement;
|
|
if (prev)
|
|
ol.insertBefore(li, prev);
|
|
}
|
|
|
|
function songDown(event) {
|
|
const li = event.target.parentElement.parentElement;
|
|
const next = li.nextElementSibling;
|
|
const after = next?.nextElementSibling;
|
|
const ol = li.parentElement;
|
|
if (after)
|
|
ol.insertBefore(li, after);
|
|
else if (next)
|
|
ol.appendChild(li);
|
|
}
|
|
|
|
function songDelete(event) {
|
|
const li = event.target.parentElement.parentElement;
|
|
const ol = li.parentElement;
|
|
ol.removeChild(li);
|
|
}
|
|
|
|
function songSelect(event) {
|
|
const option = event.target.selectedOptions[0];
|
|
const div = event.target.parentElement.parentElement.getElementsByClassName("preview")[0];
|
|
if (option.value) {
|
|
fetch("./{{ parts_dir }}/" + String(option.value).padStart(3, '0') + ".html")
|
|
.then(r => r.text())
|
|
.then(text => div.innerHTML = text);
|
|
} else {
|
|
div.innerHTML = "";
|
|
}
|
|
}
|
|
|
|
function clearSongs() {
|
|
const ol = document.getElementById("songlist");
|
|
ol.replaceChildren();
|
|
}
|
|
|
|
function selectRandomizeOptions(select, optionParent) {
|
|
const options = optionParent.getElementsByTagName("option");
|
|
do {
|
|
const i = Math.floor(Math.random() * options.length);
|
|
select.value = options[i].value;
|
|
} while (!select.value);
|
|
select.dispatchEvent(new Event("change"));
|
|
}
|
|
|
|
function addSpecificSong(n) {
|
|
const li = addSong();
|
|
const select = li.firstElementChild.firstElementChild;
|
|
select.value = n;
|
|
select.dispatchEvent(new Event("change"));
|
|
}
|
|
|
|
function addRandomSong() {
|
|
const li = addSong();
|
|
const select = li.firstElementChild.firstElementChild;
|
|
selectRandomizeOptions(select, select);
|
|
}
|
|
|
|
function addFirstSongs() {
|
|
addSongs(false);
|
|
}
|
|
|
|
function addRandomSongs() {
|
|
addSongs(true);
|
|
}
|
|
|
|
function addSongs(random) {
|
|
const li = addSong();
|
|
const groups = li.firstElementChild.firstElementChild.getElementsByTagName("optgroup");
|
|
for (let g of groups) {
|
|
const select = addSong().firstElementChild.firstElementChild;
|
|
if (random) {
|
|
selectRandomizeOptions(select, g);
|
|
} else {
|
|
select.value = g.firstElementChild.value;
|
|
select.dispatchEvent(new Event("change"));
|
|
}
|
|
}
|
|
li.parentElement.removeChild(li);
|
|
}
|
|
|
|
function getSongList() {
|
|
const ol = document.getElementById("songlist");
|
|
let res = [];
|
|
for (let li of ol.childNodes) {
|
|
let value = li.firstElementChild.firstElementChild.value;
|
|
if (value)
|
|
res.push(value);
|
|
}
|
|
return res;
|
|
}
|
|
|
|
function toggleControls(event) {
|
|
if (event.target.checked) {
|
|
document.body.classList.remove("hideControls");
|
|
} else {
|
|
if (getSongList().length == 0) {
|
|
event.target.checked = true;
|
|
} else {
|
|
document.body.classList.add("hideControls");
|
|
let preview = document.getElementById('previewCheckbox');
|
|
if (!preview.checked) {
|
|
preview.checked = true;
|
|
preview.dispatchEvent(new Event("change"));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function togglePreview(event) {
|
|
if (event.target.checked) {
|
|
document.body.classList.remove("hidePreview");
|
|
} else {
|
|
document.body.classList.add("hidePreview");
|
|
let controls = document.getElementById('controlsCheckbox');
|
|
if (!controls.checked) {
|
|
controls.checked = true;
|
|
controls.dispatchEvent(new Event("change"));
|
|
}
|
|
}
|
|
}
|
|
|
|
function shareList(event) {
|
|
const res = getSongList();
|
|
if (res.length > 0) {
|
|
let hash = res.join(",");
|
|
document.getElementById("sharelink").href = "#" + hash;
|
|
document.getElementById("sharedialog").showModal();
|
|
} else {
|
|
alert("Tu cancionero no tiene canciones...");
|
|
}
|
|
}
|
|
|
|
window.addEventListener("load", function () {
|
|
for (let e of document.getElementsByClassName("init")) {
|
|
e.dispatchEvent(new Event("change"));
|
|
}
|
|
if (window.location.hash) {
|
|
// Load songs
|
|
for (let n of window.location.hash.slice(1).split(","))
|
|
addSpecificSong(n);
|
|
// Set default settings
|
|
let controls = document.getElementById("controlsCheckbox");
|
|
controls.checked = false;
|
|
controls.dispatchEvent(new Event("change"));
|
|
let preview = document.getElementById("previewCheckbox");
|
|
preview.checked = true;
|
|
preview.dispatchEvent(new Event("change"));
|
|
let showChords = document.getElementById("showChords");
|
|
showChords.checked = false;
|
|
showChords.dispatchEvent(new Event("change"));
|
|
}
|
|
});
|
|
</script>
|
|
{% include "footer.html" %}
|
|
</body>
|
|
</html>
|