Several improvements before second concert
- Add end timestamp to concerts
- Add ability to view booklets for past concerts
- Filled concerts/nadal2020nens.json
Change-Id: Ic83b0b46661d1557468b0ffe678ac78e794ec179
diff --git a/concerts/nadal2020joves.json b/concerts/nadal2020joves.json
index 93c6542..028488f 100644
--- a/concerts/nadal2020joves.json
+++ b/concerts/nadal2020joves.json
@@ -2,6 +2,7 @@
"title": "Concert de Nadal 2020",
"subtitle": "Joves i adults",
"begins": 1608312600,
+ "ends": 1608339600,
"songs": [
{
"title": "Santa Nit",
diff --git a/concerts/nadal2020nens.json b/concerts/nadal2020nens.json
index 1e927da..7f11ce4 100644
--- a/concerts/nadal2020nens.json
+++ b/concerts/nadal2020nens.json
@@ -2,5 +2,371 @@
"title": "Concert de Nadal 2020",
"subtitle": "Nens i nenes",
"begins": 1608571800,
- "songs": []
+ "ends": 1608598800,
+ "songs": [
+ {
+ "title": "Que tinguis un bon Nadal",
+ "author": "Nadala popular anglesa",
+ "performers": [
+ {
+ "instrument": "Veus i percussió",
+ "names": ["Inés Coll", "Marcos Cruz", "Júlia Ferreira", "Lucía Mayorgas", "Diego Merino", "Anna Ros", "Gabriel Dale Villalba", "Hugo Montero", "Virgínia Pesquer"]
+ },
+ {
+ "instrument": "Guitarres",
+ "names": ["Alejandro Mora", "Pablo Jiménez"]
+ },
+ {
+ "instrument": "Bateria",
+ "names": ["Xavi Martín"]
+ }
+ ]
+ },
+ {
+ "title": "Minuet en Sol major",
+ "author": "Johann Sebastian Bach",
+ "performers": [
+ {
+ "instrument": "Piano",
+ "names": ["Julia Ndanda"]
+ }
+ ]
+ },
+ {
+ "title": "Bailes",
+ "author": "Lamote de Grignon",
+ "performers": [
+ {
+ "instrument": "Piano",
+ "names": ["Natalia Cruz"]
+ }
+ ]
+ },
+ {
+ "title": "Campana del campanar",
+ "author": "Nadala popular",
+ "performers": [
+ {
+ "instrument": "Veus i percussió",
+ "names": ["Paula Alcaraz", "Nerea Martínez", "Unai Mendo", "Clara Girona", "Iván Vergara", "Guiu Xuclà"]
+ },
+ {
+ "instrument": "Piano",
+ "names": ["Carme Martínez"]
+ }
+ ]
+ },
+ {
+ "title": "Chandelier",
+ "author": "Sia",
+ "performers": [
+ {
+ "instrument": "Veu",
+ "names": ["Noa Chacón"]
+ },
+ {
+ "instrument": "Piano",
+ "names": ["Tesi Osuna"]
+ }
+ ]
+ },
+ {
+ "title": "Bohemian Rhapsody",
+ "author": "Queen",
+ "performers": [
+ {
+ "instrument": "Piano",
+ "names": ["Iker Serrano"]
+ }
+ ]
+ },
+ {
+ "title": "Oda a l'alegria",
+ "author": "Ludwig van Beethoven",
+ "performers": [
+ {
+ "instrument": "Piano",
+ "names": ["Marc Baena"]
+ }
+ ]
+ },
+ {
+ "title": "El pastoret",
+ "author": "Popular francesa",
+ "performers": [
+ {
+ "instrument": "Piano",
+ "names": ["Marc Baena", "Montse González"]
+ }
+ ]
+ },
+ {
+ "title": "Santa Nit",
+ "author": "Franz Grüber",
+ "performers": [
+ {
+ "instrument": "Guitarres",
+ "names": ["Carla Revilla", "Alan Gareth Villalba", "Paula Alcaraz", "Clara Girona", "Inés Coll", "Guiu Xuclà", "Nerea Martínez", "Iván Vergara"]
+ },
+ {
+ "instrument": "Piano",
+ "names": ["Marcela Bou"]
+ },
+ {
+ "instrument": "Violí",
+ "names": ["Anna Ros"]
+ },
+ {
+ "instrument": "Ukelele",
+ "names": ["Lucía Mayorgas"]
+ },
+ {
+ "instrument": "Bateria",
+ "names": ["Pol Sicart"]
+ }
+ ]
+ },
+ {
+ "title": "Jingle Bells",
+ "author": "Popular nordamericana",
+ "performers": [
+ {
+ "instrument": "Piano",
+ "names": ["Claudia Ponce", "Lucía Burgos"]
+ }
+ ]
+ },
+ {
+ "title": "Cançó de bressol",
+ "author": "Johannes Brahms",
+ "performers": [
+ {
+ "instrument": "Piano",
+ "names": ["Marcos Cruz", "Victor Martín"]
+ }
+ ]
+ },
+ {
+ "title": "Dies d'alegria",
+ "author": "Thord Gummesson",
+ "performers": [
+ {
+ "instrument": "Veus",
+ "names": ["Carlota Bou", "Natalia Cruz", "Montserrat González", "Júlia Sicart", "Laura Matencio", "Lucía Ariza", "Raquel Caballero", "Ester Sánchez"]
+ },
+ {
+ "instrument": "Guitarres",
+ "names": ["Alejandro Mora", "Pablo Jiménez"]
+ },
+ {
+ "instrument": "Bateria",
+ "names": ["Xavi Martín"]
+ }
+ ]
+ },
+ {
+ "title": "Març",
+ "author": "N. Baklanowa",
+ "performers": [
+ {
+ "instrument": "Violí",
+ "names": ["Júlia Sicart"]
+ },
+ {
+ "instrument": "Piano",
+ "names": ["Carme Martínez"]
+ }
+ ]
+ },
+ {
+ "title": "Serra que serra",
+ "author": "Nadala popular catalana",
+ "performers": [
+ {
+ "instrument": "Veus",
+ "names": ["Olaia García", "Oriol Macías", "Víctor Martín", "Erik Plata", "Iker Serrano", "Alan Gareth Villalba"]
+ },
+ {
+ "instrument": "Violí",
+ "names": ["Júlia Sicart"]
+ },
+ {
+ "instrument": "Piano",
+ "names": ["Carme Martínez"]
+ }
+ ]
+ },
+ {
+ "title": "Mi burrito sabanero",
+ "author": "Villancico colombiano",
+ "performers": [
+ {
+ "instrument": "Saxo",
+ "names": ["Marc Baena", "Marlon Gómez"]
+ }
+ ]
+ },
+ {
+ "title": "This House Is Not For Sale",
+ "author": "Bon Jovi",
+ "performers": [
+ {
+ "instrument": "Veu",
+ "names": ["Gabriel Dale Villalba"]
+ },
+ {
+ "instrument": "Guitarres",
+ "names": ["Alejandro Mora", "Pablo Jiménez"]
+ },
+ {
+ "instrument": "Baix",
+ "names": ["Gabriel Villalba"]
+ },
+ {
+ "instrument": "Bateria",
+ "names": ["Xavi Martín"]
+ }
+ ]
+ },
+ {
+ "title": "El noi de la mare",
+ "author": "Popular catalana",
+ "performers": [
+ {
+ "instrument": "Piano",
+ "names": ["Julia Ferreira", "Laura Matencio"]
+ }
+ ]
+ },
+ {
+ "title": "The pipers are coming",
+ "author": "Johann Sebastian Bach",
+ "performers": [
+ {
+ "instrument": "Piano",
+ "names": ["Noa Chacón"]
+ },
+ {
+ "instrument": "Bateria",
+ "names": ["Unai Mendo"]
+ }
+ ]
+ },
+ {
+ "title": "La patinadora",
+ "author": "J. Thompson",
+ "performers": [
+ {
+ "instrument": "Piano",
+ "names": ["Noa Chacón"]
+ },
+ {
+ "instrument": "Bateria",
+ "names": ["Unai Mendo"]
+ }
+ ]
+ },
+ {
+ "title": "Huahuanaca",
+ "author": "Nadala popular boliviana",
+ "performers": [
+ {
+ "instrument": "Veus",
+ "names": ["Marc Baena", "Lucía Burgos", "Kimberly Calizaya", "Júlia Ndanda", "Claudia Ponce", "Carla Revilla", "Ester Sánchez", "Lucía Ariza"]
+ },
+ {
+ "instrument": "Guitarres",
+ "names": ["Abner Llacha", "Víctor Martín", "Erik Plata"]
+ },
+ {
+ "instrument": "Bateria",
+ "names": ["Diego merino"]
+ },
+ {
+ "instrument": "Flautes travesseres",
+ "names": ["Raquel Caballero", "Marta Albiol"]
+ },
+ {
+ "instrument": "Percussió",
+ "names": ["Unai Mendo"]
+ }
+ ]
+ },
+ {
+ "title": "Déjame",
+ "author": "Los Secretos",
+ "performers": [
+ {
+ "instrument": "Guitarres",
+ "names": ["Abner Llacha", "Víctor Martín", "Erik Plata"]
+ },
+ {
+ "instrument": "Bateria",
+ "names": ["Pol Sicart"]
+ }
+ ]
+ },
+ {
+ "title": "Oda a l'alegria",
+ "author": "Ludwig van Beethoven",
+ "performers": [
+ {
+ "instrument": "Piano",
+ "names": ["Olaia García", "Kimberly Calizaya"]
+ }
+ ]
+ },
+ {
+ "title": "Mad World",
+ "author": "Roland Orzabal",
+ "performers": [
+ {
+ "instrument": "Piano",
+ "names": ["Carlota Bou", "Marcela Bou"]
+ }
+ ]
+ },
+ {
+ "title": "Minuet",
+ "author": "C. Stamitz",
+ "performers": [
+ {
+ "instrument": "Flauta travessera",
+ "names": ["Raquel Caballero", "Marta Albiol"]
+ }
+ ]
+ },
+ {
+ "title": "Récréation de la Flauta Màgica",
+ "author": "W. A. Mozart",
+ "performers": [
+ {
+ "instrument": "Flauta travessera",
+ "names": ["Raquel Caballero", "Marta Albiol"]
+ }
+ ]
+ },
+ {
+ "title": "All I Want for Christmas Is You",
+ "author": "Mariah Carey",
+ "performers": [
+ {
+ "instrument": "Veu",
+ "names": ["Lucía Ariza", "Raquel Caballero", "Noa Chacón", "Ester Sánchez"]
+ },
+ {
+ "instrument": "Piano",
+ "names": ["Adrià Vilanova"]
+ },
+ {
+ "instrument": "Guitarres",
+ "names": ["Alejandro Mora", "Pablo Jiménez"]
+ },
+ {
+ "instrument": "Bateria",
+ "names": ["Xavi Martín"]
+ }
+ ]
+ }
+ ]
}
diff --git a/css/styles.css b/css/styles.css
index 435b652..530397f 100644
--- a/css/styles.css
+++ b/css/styles.css
@@ -12,6 +12,7 @@
.header {
display: flex;
justify-content: flex-start;
+ align-items: center;
position: fixed;
top: 0;
width: calc(100% - 16px);
@@ -21,9 +22,18 @@
}
.header .header-logo {
+ display: flex;
+ flex: 1;
+}
+
+.header .header-logo img {
height: 42px;
}
+.header button {
+ margin-left: 8px;
+}
+
.app-content {
max-width: min(calc(100% - 32px), 800px);
margin: 74px auto 16px auto;
@@ -104,6 +114,104 @@
color: white;
}
+button.primary-btn {
+ font-family: inherit;
+ font-size: 100%;
+ line-height: 1.15;
+ margin: 0;
+ text-transform: none;
+ -webkit-appearance: button;
+ border: 0;
+ border-radius: 4px;
+ padding: 8px;
+ color: white;
+ background-color: #0277BD;
+ cursor: pointer;
+}
+
+button.primary-btn:hover {
+ background-color: #1591DC;
+}
+
+button.primary-btn:active {
+ background-color: #22A3F1;
+}
+
+/* Section adapted from
+ * https://chromium.googlesource.com/infra/infra/+/master/appengine/monorail/static_src/elements/projects/mr-projects-page/mr-projects-page.js
+ * Copyright 2019 The Chromium Authors. All rights reserved.
+ * License: https://chromium.googlesource.com/infra/infra/+/master/LICENSE
+ **/
+.concerts-list {
+ display: flex;
+ align-items: stretch;
+ flex-wrap: wrap;
+ width: 100%;
+ padding: 0.5em 0;
+ margin-bottom: 3em;
+}
+
+.concert {
+ text-align: left;
+ width: 200px;
+ margin-left: 16px;
+ margin-right: 16px;
+ margin-bottom: 32px;
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ justify-content: flex-start;
+ border-radius: 4px;
+ border: 1px solid #aaa;
+ padding: 16px;
+ font-weight: normal;
+ line-height: 16px;
+ transition: all 0.1s ease-in-out;
+}
+
+.concert:hover {
+ text-decoration: none;
+ cursor: pointer;
+ box-shadow: 0 2px 6px hsla(0,0%,0%,0.12),
+ 0 1px 3px hsla(0,0%,0%,0.24);
+}
+
+.concert-title {
+ font-size: 16px;
+ line-height: 24px;
+ margin: 0;
+ margin-bottom: 16px;
+ padding-top: 0.1em;
+ padding-bottom: 16px;
+ letter-spacing: 0.1px;
+ font-weight: 600;
+ width: 100%;
+ border-bottom: 1px solid #aaa;
+}
+
+.concert-subtitle {
+ margin: 0 0 32px;
+ flex-grow: 1;
+}
+
+.linkify {
+ display: inline;
+ padding: 0px;
+ margin: 0px;
+ border: 0px;
+ background: 0px center;
+ cursor: pointer;
+ color: #0277BD;
+}
+
+.concert-btn {
+ text-transform: uppercase;
+ margin: 0px;
+ font-weight: 600;
+ flex-grow: 0;
+}
+/* End of section */
+
/* DARK THEME */
@media screen {
.dark-theme {
@@ -129,6 +237,15 @@
background: white;
color: black;
}
+
+ .dark-theme .concert:hover {
+ box-shadow: 0 2px 6px hsla(0,0%,100%,0.12),
+ 0 1px 3px hsla(0,0%,100%,0.24);
+ }
+
+ .dark-theme .linkify {
+ color: #4cb9fb;
+ }
}
@media print {
diff --git a/index.html b/index.html
index 9e280e7..872039a 100644
--- a/index.html
+++ b/index.html
@@ -9,7 +9,10 @@
</head>
<body class="dark-theme">
<header class="header">
- <img class="header-logo" src="img/logo.svg">
+ <div class="header-logo">
+ <img src="img/logo.svg">
+ </div>
+ <button id="previous-concerts-btn" class="primary-btn" hidden>Concerts anteriors</button>
</header>
<div class="app-content">
<section id="no-service-worker" class="message message--error" hidden>
@@ -24,6 +27,10 @@
<div class="message-text">S'ha baixat una còpia d'aquesta app al teu dispositiu i està disponible sense connexió a Internet.</div>
<div class="message-text">Obre aquesta pàgina quan comenci el concert per veure el programa.</div>
</section>
+ <section id="previous-concerts" class="message" hidden>
+ <h2 class="message-title">Concerts anteriors</h2>
+ <div id="previous-concerts-list" class="concerts-list"></div>
+ </section>
<section id="booklet" class="booklet" hidden>
<div class="booklet-header">
<h2 id="concert-title" class="booklet-header-title">Concert de Nadal 2020</h2>
diff --git a/js/script.js b/js/script.js
index 1c2ff15..03f66ee 100644
--- a/js/script.js
+++ b/js/script.js
@@ -3,6 +3,7 @@
'nadal2020nens',
];
+var interval = null;
var isBookletShown = false;
function showSection(section) {
@@ -47,19 +48,60 @@
return div;
}
-function loadBooklet(booklet) {
+function loadBooklet(booklet, showBackButton = false) {
console.info('Booklet: ', booklet);
document.getElementById('concert-title').textContent = booklet.title;
document.getElementById('concert-subtitle').textContent = booklet.subtitle;
var bookletContent = document.getElementById('booklet-content');
+ bookletContent.textContent = '';
booklet.songs.forEach(song => {
var songEl = songElement(song);
bookletContent.append(songEl);
});
showSection('booklet');
+ if (showBackButton)
+ document.getElementById('previous-concerts-btn').removeAttribute('hidden');
+}
+
+function loadPreviousBookletsList(booklets) {
+ var now = Date.now();
+ var list = document.getElementById('previous-concerts-list');
+
+ var existsPreviousConcert = false;
+ booklets.forEach(booklet => {
+ if (booklet.ends * 1000 <= now) {
+ existsPreviousConcert = true;
+
+ var el = document.createElement('div');
+ el.classList.add('concert');
+
+ var title = document.createElement('div');
+ title.classList.add('concert-title');
+ title.textContent = booklet.title;
+
+ var subtitle = document.createElement('div');
+ subtitle.classList.add('concert-subtitle');
+ subtitle.textContent = booklet.subtitle;
+
+ var view = document.createElement('button');
+ view.classList.add('concert-btn', 'linkify');
+ view.textContent = 'Obre el programa';
+
+ el.append(title, subtitle, view);
+
+ el.addEventListener('click', _ => {
+ loadBooklet(booklet, true);
+ });
+
+ list.append(el);
+ }
+ });
+
+ if (existsPreviousConcert)
+ document.getElementById('previous-concerts-btn').removeAttribute('hidden');
}
function checkBooklets(booklets) {
@@ -69,15 +111,15 @@
var now = Date.now();
var latest = null;
booklets.forEach(booklet => {
- if (booklet.begins * 1000 <= now &&
- (latest === null || booklet.begins * 1000 < booklet.begins))
+ if (booklet['begins'] * 1000 <= now && booklet['ends'] * 1000 >= now &&
+ (latest === null || latest['begins'] < booklet['begins']))
latest = booklet;
});
- if (latest === null)
- showSection('wait-screen');
- else {
+ if (latest !== null) {
+ document.getElementById('previous-concerts-btn').setAttribute('hidden', '');
loadBooklet(latest);
+ window.clearInterval(interval);
isBookletShown = true;
}
}
@@ -87,6 +129,13 @@
}
window.addEventListener('load', _ => {
+ document.getElementById('previous-concerts-btn')
+ .addEventListener('click', e => {
+ showSection('previous-concerts');
+ document.getElementById('previous-concerts-btn')
+ .setAttribute('hidden', '');
+ });
+
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js')
.then(reg => {
@@ -101,8 +150,12 @@
});
Promise.all(promises).then(booklets => {
+ showSection('wait-screen');
+ loadPreviousBookletsList(booklets);
checkBooklets(booklets);
- window.setInterval(_ => { checkBooklets(booklets); }, 60 * 1000);
+ interval = window.setInterval(_ => {
+ checkBooklets(booklets);
+ }, 15 * 1000);
});
})
.catch(err => {
diff --git a/sw.js b/sw.js
index 403b19e..14fb7fd 100644
--- a/sw.js
+++ b/sw.js
@@ -1,4 +1,4 @@
-// Version: 1.0.4
+// Version: 1.0.5
var CACHE_NAME = 'all-v1';
var urlsToCache = [
'/',