You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

202 lines
5.1 KiB
JavaScript

// QUOTES HIGHLIGHT
let quotes = [];
let cards = [];
let callback = (entries) => {
entries.forEach((entry) => {
entry.target.innerHTML = highlight(
quotes[entry.target.getAttribute("data-quote")],
entry.intersectionRatio
);
});
};
const filtersContainer = document.getElementById("filters");
let filters = new Set(["dev", "daily", "research"]);
filtersContainer.addEventListener("click", (e) => {
if (e.target.tagName === "LI") {
let category = e.target.getAttribute("data-tag");
// if (filters.size == 1) {
// filters = new Set(["dev", "daily", "research"]);
// [...filtersContainer.getElementsByClassName('tag')].forEach(tag =>)
// } else
if (filters.has(category)) {
e.target.classList.remove("active");
filters.delete(category);
} else {
e.target.classList.add("active");
filters.add(category);
}
}
showSelectedUpdates();
});
function showSelectedUpdates() {
cards.forEach((card) => {
card.classList.remove("selected");
let categories = card
.getAttribute("data-tag")
.split(",")
.map((tag) => tag.trim());
categories.forEach((category) => {
if (filters.has(category)) card.classList.add("selected");
});
});
}
// Threshold Callback
let threshold = [];
for (let i = 0; i <= 1.0; i += 0.01) {
threshold.push(i);
}
let observer = new IntersectionObserver(callback, {
rootMargin: "100% 0% -50% 0%",
threshold: threshold,
});
// Karaoke highlight
function highlight(text, offset) {
let scrollCursor = text.length * offset;
return (
'<span class="highlight">' +
text.slice(0, scrollCursor) +
"</span>" +
text.slice(scrollCursor)
);
}
// UPDATES
// Fetc the updates from the array in updates.json
// Each element of the array is structured like this:
//
// {
// "date": "October the 21st, 2021",
// "title": "2nd hand lifeboat script",
// "text": "Labore eiusmod labore pariatur elit nostrud ut magna cupidatat minim amet deserunt cillum id. Lorem consectetur incididunt anim sit do eu minim nisi id.",
// "quote": "Lorem elit magna esse reprehenderit fugiat labore est veniam ipsum labore est voluptate do."
// "media": {
// "type": "video",
// "src": "./assets/test-js.mp4",
// "alt": "An excerpt from 'When did software gone wrong?' highlighted progressively as in karaoke",
// "caption": "In every karaoke there are at least 2 voices: a text and a choir"
// }
// }
//
// Title, Text, Quote and Media are not mandatory.
// If some are not present, the createUpdate function will skip them
//
// Note that the Date is required, but its format is up to the user
//
// All the media elements require an alt description.
// This is for accessibility. It's a really good practice to provide quality alt text
// and we must pay attention to this.
const updatesContainer = document.getElementById("updates-container");
let updates = [];
fetch("./updates.json")
.then((response) => response.json())
.then((data) => {
updates = [...data.updates.reverse()];
populateContents();
showSelectedUpdates();
});
function populateContents() {
updates.forEach((update) => createUpdate(update));
}
function createUpdate(update) {
let card = document.createElement("div");
card.classList.add("update");
card.setAttribute("data-tag", update.tag);
// QUOTE
if (update.quote) {
let quote = document.createElement("blockquote");
quote.innerHTML = update.quote;
quote.setAttribute("data-quote", quotes.length);
quotes.push(update.quote);
card.appendChild(quote);
observer.observe(quote);
}
// LOG
let log = document.createElement("div");
log.classList.add("log");
// DATE
let date = document.createElement("div");
date.classList.add("date");
date.innerHTML = update.date;
log.appendChild(date);
// TITLE, if present
if (update.title) {
let title = document.createElement("h3");
title.classList.add("title");
title.innerHTML = update.title;
log.appendChild(title);
}
// MEDIA CONTENTS, if present
if (update.media) {
let media;
// IMAGE
if (update.media.type == "img") {
media = document.createElement("media");
media.classList.add("media");
let img = document.createElement("img");
img.src = update.media.src;
img.alt = update.media.alt;
media.appendChild(img);
if (update.media.caption) {
let caption = document.createElement("figcaption");
caption.innerHTML = update.media.caption;
media.appendChild(caption);
}
}
// VIDEO
if (update.media.type == "video") {
media = document.createElement("div");
media.classList.add("media");
let video = document.createElement("video");
video.src = update.media.src;
video.alt = update.media.alt;
video.setAttribute("loop", true);
media.appendChild(video);
if (update.media.caption) {
let caption = document.createElement("p");
caption.classList.add("caption");
caption.innerHTML = update.media.caption;
media.appendChild(caption);
}
}
log.appendChild(media);
}
// TEXT, if present
if (update.text) {
let text = document.createElement("p");
text.classList.add("text");
text.innerHTML = update.text;
log.appendChild(text);
}
card.appendChild(log);
updatesContainer.appendChild(card);
cards.push(card);
}