@kohanajs/mod-live-home
Version:
The Live Homepage allow admin to refresh visitor's home page.
53 lines (43 loc) • 1.75 kB
JavaScript
window.onHeartBeatUpdates = window.onHeartBeatUpdates || [];
(fn => (document.readyState !== 'loading') ? fn() : document.addEventListener('DOMContentLoaded', fn))(async ()=>{
//skip ping if query string contain no-redirect=1
if(/no[-_]redirect/.test(location.href))return;
/**
*
* @param fn function to loop
* @param interval in ms
* @param range in ms, total random range, for example +-2500 = 5000
*/
const heartbeat = (fn, interval=3000, range= 3000) => {
const timeout = interval + ((Math.random() * range) - range * .5);
setTimeout(()=>{
fn(timeout);
heartbeat(fn, interval, range);
}, timeout);
}
const heartbeatFunction = async () => {
const indicator = document.getElementById('ping-indicator');
try{
const time = Date.now();
const rnd = Math.floor(Math.random()*100000);
const state = await (await fetch( `/media/ping/update.json?r=${time}${rnd}`)).json();
indicator.setAttribute('data-state', (!state.error) ? 'success' : 'warning');
if(state.error)return;//soft error, display warning
const lastUpdate = state.meta.last_update;
const lastLocalUpdate = parseInt(indicator.getAttribute('data-last-update'));
if(lastLocalUpdate < lastUpdate){
const callbacks = window.onHeartBeatUpdates;
for(let i = 0; i < callbacks.length; i++){
await callbacks[i](state.payload);
}
}
indicator.setAttribute('data-last-update', lastUpdate);
}catch (e){
//network error
indicator.setAttribute('data-state', 'error');
console.log(e);
}
}
heartbeat(heartbeatFunction, 2000, 2000);
await heartbeatFunction(0);
});