diff options
Diffstat (limited to 'static/js/update.ts')
-rw-r--r-- | static/js/update.ts | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/static/js/update.ts b/static/js/update.ts new file mode 100644 index 0000000..df29f49 --- /dev/null +++ b/static/js/update.ts @@ -0,0 +1,84 @@ +(function () { + + const cookiesDisabled = !navigator.cookieEnabled; + + if (cookiesDisabled) { + document.cookie = "disabled"; + document.cookie.indexOf("disabled"); + return console.warn("WARNING: Update check disabled due to cookie restrictions"); + } + + function fetch(url, method, callback) { + const http = new XMLHttpRequest(); + http.onreadystatechange = function () { + if (http.readyState === 4 && http.status === 200) { + if (callback) callback(http); + } + }; + http.open(method, url); + http.setRequestHeader("Pragma", "no-cache"); + http.setRequestHeader("Cache-Control", "no-cache"); + http.send(); + return http; + } + + const state = "on"; + const key = "config.update"; + + let stamps = {}; + + if (!sessionStorage[key + ".urls"]) sessionStorage[key + ".urls"] = JSON.stringify(stamps); + + function update() { + const url = self.location.href.split("#")[0].split("?")[0]; + + const indicator = document.querySelector("a[data-update]"); + if (indicator === null || indicator.dataset.update === "refresh") return; + const anchor = indicator.cloneNode(); + + fetch(url, "HEAD", function (request) { + const local = document.querySelector('meta[name="last-modified"]').content || document.lastModified; + const remote = request.getResponseHeader("last-modified") || ''; + const modified = Date.parse(remote || local) > Date.parse(local); + const drift = Date.parse(remote || local) - Date.parse(local); + + if (drift < 10000) return; + + function reset() { + indicator.href = anchor.href; + indicator.setAttribute("id", anchor.id); + indicator.dataset.update = anchor.dataset.update; + } + + stamps = JSON.parse(sessionStorage[key + ".urls"]); + if (stamps[url] === remote) return; + stamps[url] = remote; + sessionStorage[key + ".urls"] = JSON.stringify(stamps); + + if (remote && modified) { + fetch(url, "GET", function () { + indicator.href = url.replace(/^https:/, "http:"); + indicator.removeAttribute("id"); + indicator.dataset.update = "refresh"; + console.log("INFO: R: " + remote); + console.log("INFO: L: " + local); + console.log("INFO: D: " + drift); + console.log("INFO: M: " + modified); + }); + } + }); + } + + let scrolled; + let delay = 1000; + let delayed = 0; + + self.addEventListener("scroll", function () { + if (scrolled) clearTimeout(scrolled); + scrolled = setTimeout(function () { update(); delay = delay + delayed; delayed = delay - delayed; }, delay); + }); + + ["focus", "load", "URLChangedCustomEvent"].forEach(function (event) { + self.addEventListener(event, function () { update(); }); + }); +})(); |