service worker fixes

This commit is contained in:
MathMan05 2024-10-30 15:31:41 -05:00
parent 262659d4fe
commit 85e2cceca5
5 changed files with 137 additions and 59 deletions

View file

@ -102,10 +102,6 @@ app.use("/", async (req: Request, res: Response)=>{
res.sendFile(path.join(__dirname, "webpage", "invite.html")); res.sendFile(path.join(__dirname, "webpage", "invite.html"));
return; return;
} }
if(req.path.endsWith("service.js")){
res.send("nope :3");
return;
}
const filePath = path.join(__dirname, "webpage", req.path); const filePath = path.join(__dirname, "webpage", req.path);
try{ try{
await fs.access(filePath); await fs.access(filePath);

View file

@ -4,7 +4,7 @@ import{ Direct }from"./direct.js";
import{ AVoice }from"./audio.js"; import{ AVoice }from"./audio.js";
import{ User }from"./user.js"; import{ User }from"./user.js";
import{ Dialog }from"./dialog.js"; import{ Dialog }from"./dialog.js";
import{ getapiurls, getBulkInfo, setTheme, Specialuser }from"./login.js"; import{ getapiurls, getBulkInfo, setTheme, Specialuser, SW }from"./login.js";
import{channeljson,guildjson,mainuserjson,memberjson,memberlistupdatejson,messageCreateJson,presencejson,readyjson,startTypingjson,wsjson,}from"./jsontypes.js"; import{channeljson,guildjson,mainuserjson,memberjson,memberlistupdatejson,messageCreateJson,presencejson,readyjson,startTypingjson,wsjson,}from"./jsontypes.js";
import{ Member }from"./member.js"; import{ Member }from"./member.js";
import{ Form, FormError, Options, Settings }from"./settings.js"; import{ Form, FormError, Options, Settings }from"./settings.js";
@ -1274,6 +1274,21 @@ class Localuser{
} }
} }
} }
{
const update=settings.addButton("Update settings")
const sw=update.addSelect("Service Worker setting",()=>{},["false","offlineOnly","true"],{
defaultIndex:["false","offlineOnly","true"].indexOf(localStorage.getItem("SWMode") as string)
});
sw.onchange=(e)=>{
SW.setMode(["false","offlineOnly","true"][e] as "false"|"offlineOnly"|"true")
}
update.addButtonInput("","Check for update",()=>{
SW.checkUpdate();
});
update.addButtonInput("","Clear cache",()=>{
SW.forceClear();
});
}
{ {
const security = settings.addButton("Account Settings"); const security = settings.addButton("Account Settings");
const genSecurity = ()=>{ const genSecurity = ()=>{

View file

@ -532,12 +532,33 @@ if(document.getElementById("form")){
} }
} }
//this currently does not work, and need to be implemented better at some time. //this currently does not work, and need to be implemented better at some time.
/* if(!localStorage.getItem("SWMode")){
localStorage.setItem("SWMode","true");
}
class SW{
static worker:undefined|ServiceWorker;
static setMode(mode:"false"|"offlineOnly"|"true"){
if(this.worker){
this.worker.postMessage({data:mode,code:"setMode"});
}
}
static checkUpdate(){
if(this.worker){
this.worker.postMessage({code:"CheckUpdate"});
}
}
static forceClear(){
if(this.worker){
this.worker.postMessage({code:"ForceClear"});
}
}
}
export {SW};
if ("serviceWorker" in navigator){ if ("serviceWorker" in navigator){
navigator.serviceWorker.register("/service.js", { navigator.serviceWorker.register("/service.js", {
scope: "/", scope: "/",
}).then((registration) => { }).then((registration) => {
let serviceWorker:ServiceWorker; let serviceWorker:ServiceWorker|undefined;
if (registration.installing) { if (registration.installing) {
serviceWorker = registration.installing; serviceWorker = registration.installing;
console.log("installing"); console.log("installing");
@ -548,15 +569,17 @@ if(document.getElementById("form")){
serviceWorker = registration.active; serviceWorker = registration.active;
console.log("active"); console.log("active");
} }
SW.worker=serviceWorker;
SW.setMode(localStorage.getItem("SWMode") as "false"|"offlineOnly"|"true");
if (serviceWorker) { if (serviceWorker) {
console.log(serviceWorker.state); console.log(serviceWorker.state);
serviceWorker.addEventListener("statechange", (e) => { serviceWorker.addEventListener("statechange", (_) => {
console.log(serviceWorker.state); console.log(serviceWorker.state);
}); });
} }
}) })
} }
*/
const switchurl = document.getElementById("switch") as HTMLAreaElement; const switchurl = document.getElementById("switch") as HTMLAreaElement;
if(switchurl){ if(switchurl){
switchurl.href += window.location.search; switchurl.href += window.location.search;

View file

@ -13,13 +13,13 @@ async function putInCache(request: URL | RequestInfo, response: Response){
console.error(error); console.error(error);
} }
} }
console.log("test");
let lastcache: string; let lastcache: string;
self.addEventListener("activate", async ()=>{ self.addEventListener("activate", async ()=>{
console.log("test2"); console.log("Service Worker activated");
checkCache(); checkCache();
}); });
async function checkCache(){ async function checkCache(){
if(checkedrecently){ if(checkedrecently){
return; return;
@ -34,7 +34,7 @@ async function checkCache(){
console.log(text, lastcache); console.log(text, lastcache);
if(lastcache !== text){ if(lastcache !== text){
deleteoldcache(); deleteoldcache();
putInCache("/getupdates", data.clone()); putInCache("/getupdates", data);
} }
checkedrecently = true; checkedrecently = true;
setTimeout((_: any)=>{ setTimeout((_: any)=>{
@ -43,54 +43,97 @@ async function checkCache(){
}); });
} }
var checkedrecently = false; var checkedrecently = false;
function samedomain(url: string | URL){ function samedomain(url: string | URL){
return new URL(url).origin === self.origin; return new URL(url).origin === self.origin;
} }
function isindexhtml(url: string | URL){
console.log(url); const htmlFiles=new Set(["/index","/login","/home","/register","/oauth2/auth"]);
if(new URL(url).pathname.startsWith("/channels")){
return true;
function isHtml(url:string):string|void{
const path=new URL(url).pathname;
if(htmlFiles.has(path)||htmlFiles.has(path+".html")){
return path+path.endsWith(".html")?"":".html";
} }
return false;
} }
async function getfile(event: { let enabled="false";
request: { url: URL | RequestInfo; clone: () => string | URL | Request }; let offline=false;
}){
function toPath(url:string):string{
const Url= new URL(url);
let html=isHtml(url);
if(!html){
const path=Url.pathname;
if(path.startsWith("/channels")){
html="./index.html"
}else if(path.startsWith("/invite")){
html="./invite.html"
}
}
return html||Url.pathname;
}
let fails=0;
async function getfile(event: FetchEvent):Promise<Response>{
checkCache(); checkCache();
if(!samedomain(event.request.url.toString())){ if(!samedomain(event.request.url)||enabled==="false"||(enabled==="offlineOnly"&&!offline)){
return await fetch(event.request.clone()); const responce=await fetch(event.request.clone());
if(samedomain(event.request.url)){
if(enabled==="offlineOnly"&&responce.ok){
putInCache(toPath(event.request.url),responce.clone());
} }
const responseFromCache = await caches.match(event.request.url); if(!responce.ok){
console.log(responseFromCache, caches); fails++;
if(fails>5){
offline=true;
}
}
}
return responce;
}
let path=toPath(event.request.url);
console.log("Getting path: "+path);
const responseFromCache = await caches.match(path);
if(responseFromCache){ if(responseFromCache){
console.log("cache hit"); console.log("cache hit");
return responseFromCache; return responseFromCache;
} }
if(isindexhtml(event.request.url.toString())){
console.log("is index.html");
const responseFromCache = await caches.match("/index.html");
if(responseFromCache){
console.log("cache hit");
return responseFromCache;
}
const responseFromNetwork = await fetch("/index.html");
await putInCache("/index.html", responseFromNetwork.clone());
return responseFromNetwork;
}
const responseFromNetwork = await fetch(event.request.clone());
console.log(event.request.clone());
await putInCache(event.request.clone(), responseFromNetwork.clone());
try{ try{
const responseFromNetwork = await fetch(path);
if(responseFromNetwork.ok){
await putInCache(path, responseFromNetwork.clone());
}
return responseFromNetwork; return responseFromNetwork;
}catch(e){ }catch(e){
console.error(e); console.error(e);
return e; return new Response(null);
} }
} }
self.addEventListener("fetch", (event: any)=>{
self.addEventListener("fetch", (e)=>{
const event=e as FetchEvent;
try{ try{
event.respondWith(getfile(event)); event.respondWith(getfile(event));
}catch(e){ }catch(e){
console.error(e); console.error(e);
} }
}); });
self.addEventListener("message", (message)=>{
const data=message.data;
switch(data.code){
case "setMode":
enabled=data.data;
break;
case "CheckUpdate":
checkedrecently=false;
checkCache();
break;
case "ForceClear":
deleteoldcache();
break;
}
})

View file

@ -9,7 +9,8 @@
"incremental": true, "incremental": true,
"lib": [ "lib": [
"esnext", "esnext",
"DOM" "DOM",
"webworker"
], ],
"module": "ESNext", "module": "ESNext",
"moduleResolution": "Bundler", "moduleResolution": "Bundler",