// General UI tools (progress bar, toast, prompt) /// Handle progress bars var Progress = { domElement : null, // the DOM element sticky : false, // Progress.show({..., sticky:true}) don't remove until Progress.hide({sticky:true}) interval : undefined, // the interval used if Progress.show({progress:"animate"}) percent : undefined, // the current progress percentage min : 0, // scaling for percentage max : 1, // scaling for percentage /* Show a Progress message Progress.show({ sticky : bool // keep showing text even when Progress.hide is called (unless Progress.hide({sticky:true})) percent : number | "animate" min : // minimum scale for percentage (default 0) max : // maximum scale for percentage (default 1) }) */ show : function(options) { options = options||{}; var text = options.title; if (options.sticky) Progress.sticky = true; if (options.min!==undefined) Progress.min = options.min; if (options.max!==undefined) Progress.max = options.max; var percent = options.percent; if (percent!==undefined) percent = Progress.min*100 + (Progress.max-Progress.min)*percent; if (!Progress.domElement) { if (Progress.interval) { clearInterval(Progress.interval); Progress.interval = undefined; } if (percent == "animate") { Progress.interval = setInterval(function() { Progress.percent += 2; if (Progress.percent>100) Progress.percent=0; Progress.show({percent:Progress.percent}); }, 100); percent = 0; } var toastcontainer = document.getElementById("toastcontainer"); Progress.domElement = htmlElement(`
${text ? `
${text}
`:``}
`); toastcontainer.append(Progress.domElement); } else { var pt=document.getElementById("Progress.domElement"); pt.setAttribute("aria-valuenow",percent); pt.style.width = percent+"%"; } }, // Progress.hide({sticky:true}) undoes Progress.show({title:"title", sticky:true}) hide : function(options) { options = options||{}; if (Progress.sticky && !options.sticky) return; Progress.sticky = false; Progress.min = 0; Progress.max = 1; if (Progress.interval) { clearInterval(Progress.interval); Progress.interval = undefined; } if (Progress.domElement) Progress.domElement.remove(); Progress.domElement = undefined; } }; /// Add progress handler so we get nice uploads Puck.writeProgress = function(charsSent, charsTotal) { if (charsSent===undefined) { Progress.hide(); return; } var percent = Math.round(charsSent*100/charsTotal); Progress.show({percent: percent}); } /// Show a 'toast' message for status function showToast(message, type) { // toast-primary, toast-success, toast-warning or toast-error var style = "toast-primary"; if (type=="success") style = "toast-success"; else if (type=="error") style = "toast-error"; else if (type!==undefined) console.log("showToast: unknown toast "+type); var toastcontainer = document.getElementById("toastcontainer"); var msgDiv = htmlElement(`
`); msgDiv.innerHTML = message; toastcontainer.append(msgDiv); setTimeout(function() { msgDiv.remove(); }, 5000); } /// Show a yes/no prompt function showPrompt(title, text, buttons) { if (!buttons) buttons={yes:1,no:1}; return new Promise((resolve,reject) => { var modal = htmlElement(``); document.body.append(modal); modal.querySelector("a[href='#close']").addEventListener("click",event => { event.preventDefault(); reject("User cancelled"); modal.remove(); }); htmlToArray(modal.getElementsByTagName("button")).forEach(button => { button.addEventListener("click",event => { event.preventDefault(); var isYes = event.target.getAttribute("isyes")=="1"; if (isYes) resolve(); else reject("User cancelled"); modal.remove(); }); }); }); }