// 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 ) ;
}