mirror of
https://github.com/MathMan05/Fermi.git
synced 2026-03-30 15:35:43 +00:00
SW refinements
This commit is contained in:
@@ -2471,8 +2471,17 @@ class Localuser {
|
||||
sw.onchange = (e) => {
|
||||
SW.setMode(["false", "offlineOnly", "true"][e] as "false" | "offlineOnly" | "true");
|
||||
};
|
||||
update.addButtonInput("", I18n.localuser.CheckUpdate(), () => {
|
||||
SW.checkUpdate();
|
||||
update.addButtonInput("", I18n.localuser.CheckUpdate(), async () => {
|
||||
const update = await SW.checkUpdates();
|
||||
const text = update ? I18n.localuser.updatesYay() : I18n.localuser.noUpdates();
|
||||
const d = new Dialog("");
|
||||
d.options.addTitle(text);
|
||||
if (update) {
|
||||
d.options.addButtonInput("", I18n.localuser.refreshPage(), () => {
|
||||
window.location.reload();
|
||||
});
|
||||
}
|
||||
d.show();
|
||||
});
|
||||
update.addButtonInput("", I18n.localuser.clearCache(), () => {
|
||||
SW.forceClear();
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import {messageFrom, messageTo} from "./utils/serviceType";
|
||||
|
||||
function deleteoldcache() {
|
||||
caches.delete("cache");
|
||||
console.log("this ran :P");
|
||||
@@ -19,32 +21,54 @@ self.addEventListener("activate", async () => {
|
||||
console.log("Service Worker activated");
|
||||
checkCache();
|
||||
});
|
||||
|
||||
async function tryToClose() {
|
||||
const portArr = [...ports];
|
||||
if (portArr.length) {
|
||||
for (let i = 1; i < portArr.length; i++) {
|
||||
portArr[i].postMessage({code: "closing"});
|
||||
}
|
||||
portArr[0].postMessage({code: "close"});
|
||||
} else {
|
||||
throw new Error("No Fermi clients connected?");
|
||||
}
|
||||
}
|
||||
function sendAll(message: messageFrom) {
|
||||
for (const port of ports) {
|
||||
port.postMessage(message);
|
||||
}
|
||||
}
|
||||
async function checkCache() {
|
||||
if (checkedrecently) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
const promise = await caches.match("/getupdates");
|
||||
if (promise) {
|
||||
lastcache = await promise.text();
|
||||
}
|
||||
console.log(lastcache);
|
||||
fetch("/getupdates").then(async (data) => {
|
||||
return fetch("/getupdates").then(async (data) => {
|
||||
setTimeout(
|
||||
(_: any) => {
|
||||
checkedrecently = false;
|
||||
},
|
||||
1000 * 60 * 30,
|
||||
);
|
||||
if (!data.ok) return;
|
||||
if (!data.ok) return false;
|
||||
const text = await data.clone().text();
|
||||
console.log(text, lastcache);
|
||||
if (lastcache !== text) {
|
||||
deleteoldcache();
|
||||
putInCache("/getupdates", data);
|
||||
self.close();
|
||||
tryToClose();
|
||||
checkedrecently = true;
|
||||
sendAll({
|
||||
code: "updates",
|
||||
updates: true,
|
||||
});
|
||||
return true;
|
||||
}
|
||||
checkedrecently = true;
|
||||
return false;
|
||||
});
|
||||
}
|
||||
var checkedrecently = false;
|
||||
@@ -133,17 +157,56 @@ self.addEventListener("fetch", (e) => {
|
||||
console.error(e);
|
||||
}
|
||||
});
|
||||
const ports = new Set<MessagePort>();
|
||||
function listenToPort(port: MessagePort) {
|
||||
function sendMessage(message: messageFrom) {
|
||||
port.postMessage(message);
|
||||
}
|
||||
port.onmessage = async (e) => {
|
||||
const data = e.data as messageTo;
|
||||
switch (data.code) {
|
||||
case "ping": {
|
||||
sendMessage({
|
||||
code: "pong",
|
||||
count: ports.size,
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "close": {
|
||||
ports.delete(port);
|
||||
break;
|
||||
}
|
||||
case "replace": {
|
||||
//@ts-ignore-error Just the type or wrong or something
|
||||
self.skipWaiting();
|
||||
break;
|
||||
}
|
||||
case "CheckUpdate": {
|
||||
checkedrecently = false;
|
||||
if (!(await checkCache())) {
|
||||
sendMessage({
|
||||
code: "updates",
|
||||
updates: false,
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
port.addEventListener("close", () => {
|
||||
ports.delete(port);
|
||||
});
|
||||
}
|
||||
console.log("heya");
|
||||
//
|
||||
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;
|
||||
@@ -152,5 +215,10 @@ self.addEventListener("message", (message) => {
|
||||
console.error("Hey!");
|
||||
port.postMessage({code: "isValid", res: toPathNoDefault(data.url)});
|
||||
break;
|
||||
case "port": {
|
||||
const port = data.port as MessagePort;
|
||||
ports.add(port);
|
||||
listenToPort(port);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
28
src/webpage/utils/serviceType.ts
Normal file
28
src/webpage/utils/serviceType.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
export type messageTo =
|
||||
| {
|
||||
code: "ping";
|
||||
}
|
||||
| {
|
||||
code: "close";
|
||||
}
|
||||
| {
|
||||
code: "replace";
|
||||
}
|
||||
| {
|
||||
code: "CheckUpdate";
|
||||
};
|
||||
export type messageFrom =
|
||||
| {
|
||||
code: "pong";
|
||||
count: number;
|
||||
}
|
||||
| {
|
||||
code: "close";
|
||||
}
|
||||
| {
|
||||
code: "closing";
|
||||
}
|
||||
| {
|
||||
code: "updates";
|
||||
updates: boolean;
|
||||
};
|
||||
@@ -2,6 +2,7 @@ import {I18n} from "../i18n.js";
|
||||
import {MarkDown} from "../markdown.js";
|
||||
import {Dialog} from "../settings.js";
|
||||
import {fix} from "./cssMagic.js";
|
||||
import {messageFrom, messageTo} from "./serviceType.js";
|
||||
fix();
|
||||
let instances:
|
||||
| {
|
||||
@@ -833,23 +834,120 @@ export {checkInstance};
|
||||
|
||||
export class SW {
|
||||
static worker: undefined | ServiceWorker;
|
||||
static port?: MessagePort;
|
||||
static init() {
|
||||
SW.setMode(
|
||||
(localStorage.getItem("SWMode") as "false" | "offlineOnly" | "true" | undefined) || "true",
|
||||
);
|
||||
const port = new MessageChannel();
|
||||
SW.worker?.postMessage(
|
||||
{
|
||||
code: "port",
|
||||
port: port.port2,
|
||||
},
|
||||
[port.port2],
|
||||
);
|
||||
this.port = port.port1;
|
||||
this.port.onmessage = (e) => {
|
||||
this.handleMessage(e.data);
|
||||
};
|
||||
window.addEventListener("beforeunload", () => {
|
||||
this.postMessage({code: "close"});
|
||||
port.port1.close();
|
||||
});
|
||||
this.postMessage({code: "ping"});
|
||||
}
|
||||
static postMessage(message: messageTo) {
|
||||
this.port?.postMessage(message);
|
||||
}
|
||||
private static updateWatchers = new Set<(updates: boolean) => void>();
|
||||
static watchForUpdates(func: (updates: boolean) => void) {
|
||||
this.updateWatchers.add(func);
|
||||
}
|
||||
static stopWatchForUpdates(func: (updates: boolean) => void) {
|
||||
this.updateWatchers.delete(func);
|
||||
}
|
||||
static async handleMessage(message: messageFrom) {
|
||||
switch (message.code) {
|
||||
case "pong": {
|
||||
console.log(message);
|
||||
break;
|
||||
}
|
||||
case "close": {
|
||||
for (const thing of await navigator.serviceWorker.getRegistrations()) {
|
||||
await thing.unregister();
|
||||
}
|
||||
await this.start();
|
||||
this.postMessage({code: "replace"});
|
||||
break;
|
||||
}
|
||||
case "closing": {
|
||||
await this.start();
|
||||
break;
|
||||
}
|
||||
case "updates": {
|
||||
for (const thing of this.updateWatchers) {
|
||||
thing(message.updates);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
static async checkUpdates(): Promise<boolean> {
|
||||
return new Promise((res) => {
|
||||
const func = (update: boolean) => {
|
||||
this.stopWatchForUpdates(func);
|
||||
res(update);
|
||||
};
|
||||
this.watchForUpdates(func);
|
||||
this.postMessage({code: "CheckUpdate"});
|
||||
});
|
||||
}
|
||||
static async start() {
|
||||
if (!("serviceWorker" in navigator)) return;
|
||||
return new Promise<void>((res) => {
|
||||
navigator.serviceWorker
|
||||
.register("/service.js", {
|
||||
scope: "/",
|
||||
})
|
||||
.then((registration) => {
|
||||
let serviceWorker: ServiceWorker | undefined;
|
||||
if (registration.installing) {
|
||||
serviceWorker = registration.installing;
|
||||
console.log("installing");
|
||||
} else if (registration.waiting) {
|
||||
serviceWorker = registration.waiting;
|
||||
console.log("waiting");
|
||||
} else if (registration.active) {
|
||||
serviceWorker = registration.active;
|
||||
console.log("active");
|
||||
}
|
||||
SW.worker = serviceWorker;
|
||||
SW.init();
|
||||
|
||||
if (serviceWorker) {
|
||||
console.log(serviceWorker.state);
|
||||
serviceWorker.addEventListener("statechange", (_) => {
|
||||
console.log(serviceWorker.state);
|
||||
});
|
||||
res();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
static setMode(mode: "false" | "offlineOnly" | "true") {
|
||||
localStorage.setItem("SWMode", mode);
|
||||
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"});
|
||||
}
|
||||
}
|
||||
}
|
||||
SW.start();
|
||||
let installPrompt: Event | undefined = undefined;
|
||||
window.addEventListener("beforeinstallprompt", (event) => {
|
||||
event.preventDefault();
|
||||
@@ -858,35 +956,7 @@ window.addEventListener("beforeinstallprompt", (event) => {
|
||||
export function installPGet() {
|
||||
return installPrompt;
|
||||
}
|
||||
if ("serviceWorker" in navigator) {
|
||||
navigator.serviceWorker
|
||||
.register("/service.js", {
|
||||
scope: "/",
|
||||
})
|
||||
.then((registration) => {
|
||||
let serviceWorker: ServiceWorker | undefined;
|
||||
if (registration.installing) {
|
||||
serviceWorker = registration.installing;
|
||||
console.log("installing");
|
||||
} else if (registration.waiting) {
|
||||
serviceWorker = registration.waiting;
|
||||
console.log("waiting");
|
||||
} else if (registration.active) {
|
||||
serviceWorker = registration.active;
|
||||
console.log("active");
|
||||
}
|
||||
SW.worker = serviceWorker;
|
||||
SW.setMode(
|
||||
(localStorage.getItem("SWMode") as "false" | "offlineOnly" | "true" | undefined) || "true",
|
||||
);
|
||||
if (serviceWorker) {
|
||||
console.log(serviceWorker.state);
|
||||
serviceWorker.addEventListener("statechange", (_) => {
|
||||
console.log(serviceWorker.state);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function getInstances() {
|
||||
return instances;
|
||||
}
|
||||
|
||||
@@ -485,6 +485,9 @@
|
||||
"keyname":"Key name:"
|
||||
},
|
||||
"localuser": {
|
||||
"noUpdates":"No updates found",
|
||||
"updatesYay":"Updates have been found!",
|
||||
"refreshPage":"Refresh to apply",
|
||||
"trusted":"Trusted Domains",
|
||||
"trustedDesc":"These domains when you click on links from them will ***not*** prompt you for permission to open like other links, only give this to URLs you trust",
|
||||
"trace": "Traces",
|
||||
|
||||
Reference in New Issue
Block a user