Complexe front-end code dat ik heb gebruikt deze sprint:
Dynamisch inladen van de artikelen
// GET ROUTES
// maak route aan met /articles en haal de data op van de api, hierdoor kan ik de data herladen op de pagina zonder de server te herstarten
app . get ( '/articles' , async function ( req , res ) {
const articles = await fetchJson ( 'https://api.mobile.bnr.nl/v1/articles' ) ;
res . json ( articles ) ;
} )
// maak route aan waarbij de data van de route hierboven word opgehaald, laad vervolgens de index in met de 2 variabelen.
app . get ( '/' , async function ( req , res ) {
const response = await fetch ( 'http://localhost:' + app . get ( 'port' ) + '/articles' ) ;
const articles = await response . json ( ) ;
res . render ( 'index' , {
articles : articles ,
mp3 : mp3
} )
console . log ( 'if you see this message the page loaded correctly' )
} ) ;
// Articles inladen met interval
setInterval ( function ( ) {
fetch ( '/articles' )
. then ( response => response . json ( ) )
. then ( articles => {
console . log ( articles ) ; // Log de artikels in console, zodat ik weet dat het uberhaupt update
} ) ;
} , 30 * 60 * 1000 ) ; // update de artikels elke 30 minuten
< section class ="audio-player ">
< h2 > Live radio</ h2 >
< audio id ="audio " src ="http://playerservices.streamtheworld.com/api/livestream-redirect/BNR_BUSINESS_BEATS.mp3?<%= Date.now() %> " controls preload ="none "> </ audio >
< div class ="hidden ">
< div class ="play-btn-container ">
< button id ="play-pause-button ">
< svg xmlns ="http://www.w3.org/2000/svg " width ="24 " height ="24 " viewBox ="0 0 24 24 " fill ="#FFD200 " stroke ="currentColor " stroke-width ="2 " stroke-linecap ="round " stroke-linejoin ="round " class ="icon icon-tabler icons-tabler-outline icon-tabler-player-play ">
< path stroke ="none " d ="M0 0h24v24H0z " fill ="none "/>
< path d ="M7 4v16l13 -8z "/>
< title > Play </ title >
</ svg >
</ button >
</ div >
< div id ="current-time ">
0:00
</ div >
< div class ="controls ">
< img src ="/sound.svg " height ="30 ">
< label for ="volume-control ">
< input type ="range " name ="volume-control " id ="volume-control " min ="0 " max ="1 " step ="0.01 " value ="1 ">
</ label >
</ div >
</ div >
</ section >
.hidden {
display : none;
}
.audio-player {
position : fixed;
bottom : 0 ;
margin : auto;
background-color : var (--accent );
padding-top : 24px ;
width : 100vw ;
height : 8vh ;
color : var (--accent-text );
h2 {
margin-top : -20px ;
margin-bottom : 0 ;
margin-left : 10px ;
font-size : 18px ;
text-align : left;
}
.play-btn-container {
position : absolute;
bottom : 20px ;
left : 42% ;
margin : auto;
}
# play-pause-button {
animation : pulse 4s 1s infinite linear;
cursor : pointer;
margin : auto;
border : none;
border-radius : 1000px ;
padding : 12px ;
}
.controls {
display : flex;
position : absolute;
right : 20px ;
bottom : 30px ;
justify-content : end;
align-items : end;
# volume-control {
width : 80px ;
height : 15px ;
margin-block : 8px ;
background-color : var (--accent );
}
}
# current-time {
position : absolute;
bottom : 10px ;
margin-left : 10px ;
}
// radio
const audio = document . getElementById ( "audio" ) ;
const playPauseButton = document . getElementById ( "play-pause-button" ) ;
const volumeControl = document . getElementById ( "volume-control" ) ;
const currentTimeDisplay = document . getElementById ( "current-time" ) ;
let isPlaying = false ;
const visibilityToggle = document . getElementsByClassName ( "hidden" ) [ 0 ] ;
visibilityToggle . style . display = "block" ;
audio . style . display = 'none' ;
playPauseButton . addEventListener ( "click" , ( ) => {
if ( isPlaying ) {
audio . pause ( ) ;
playPauseButton . innerHTML = "<svg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='#FFD200' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='icon icon-tabler icons-tabler-outline icon-tabler-player-play'><path stroke='none' d='M0 0h24v24H0z' fill='none'/><path d='M7 4v16l13 -8z' /></svg>" ;
} else {
audio . play ( ) ;
playPauseButton . innerHTML = "<svg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='#FFD200' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='icon icon-tabler icons-tabler-outline icon-tabler-player-pause'><path stroke='none' d='M0 0h24v24H0z' fill='none'/><path d='M6 5m0 1a1 1 0 0 1 1 -1h2a1 1 0 0 1 1 1v12a1 1 0 0 1 -1 1h-2a1 1 0 0 1 -1 -1z' /><path d='M14 5m0 1a1 1 0 0 1 1 -1h2a1 1 0 0 1 1 1v12a1 1 0 0 1 -1 1h-2a1 1 0 0 1 -1 -1z' /></svg>" ;
}
isPlaying = ! isPlaying ;
} ) ;
volumeControl . addEventListener ( "input" , ( ) => {
audio . volume = volumeControl . value ;
} ) ;
audio . addEventListener ( "timeupdate" , ( ) => {
const currentTime = audio . currentTime ;
const currentMinutes = Math . floor ( currentTime / 60 ) ;
const currentSeconds = Math . floor ( currentTime % 60 ) ;
currentTimeDisplay . textContent = `${ currentMinutes } :${ currentSeconds < 10 ? '0' : '' } ${ currentSeconds } ` ;
} ) ;