This commit is contained in:
Rizky 2024-01-23 12:57:23 +07:00
parent 4868fa7a39
commit 02193476f7
1 changed files with 189 additions and 190 deletions

View File

@ -5,232 +5,231 @@ import { isLocalhost } from "./utils/ui/is-localhost";
import { version } from "../timestamp"; import { version } from "../timestamp";
const state = { const state = {
updating: false, updating: false,
}; };
export const sworkerRegister = async (react: { root: null | ReactRoot }) => { export const sworkerRegister = async (react: { root: null | ReactRoot }) => {
if (navigator.serviceWorker) { if (navigator.serviceWorker) {
if (!isLocalhost()) { if (!isLocalhost()) {
const sw = await registerServiceWorker(); const sw = await registerServiceWorker();
const cacheCurrentPage = () => { const cacheCurrentPage = () => {
const swController = navigator.serviceWorker.controller; const swController = navigator.serviceWorker.controller;
if (swController) { if (swController) {
[location.href, "", "/", "/ed", "/ed/_/_", "/login"].forEach( [location.href, "", "/", "/ed", "/ed/_/_", "/login"].forEach(
(url) => { (url) => {
swController.postMessage({ swController.postMessage({
type: "add-cache", type: "add-cache",
url: url, url: url,
}); });
}, }
); );
} }
}; };
cacheCurrentPage(); cacheCurrentPage();
const curver = localStorage.getItem("prasi-version"); const curver = localStorage.getItem("prasi-version");
const swc = navigator.serviceWorker.controller; if (version !== curver && curver && react.root && sw) {
if (version !== curver && curver && react.root && swc) { react.root.render(
react.root.render( <>
<> <Root />
<Root /> <div
<div className={cx(
className={cx( css`
css`
position: fixed; position: fixed;
bottom: 20px; bottom: 20px;
left: 0px; left: 0px;
right: 0px; right: 0px;
z-index: 999; z-index: 999;
`, `,
"flex justify-center cursor-pointer", "flex justify-center cursor-pointer"
)} )}
onClick={() => { onClick={() => {
swc.postMessage({ sw.unregister().then(() => {
type: "force-update", window.location.reload();
}); });
if (react.root) if (react.root)
react.root.render( react.root.render(
<> <>
<Root /> <Root />
<div <div
className={cx( className={cx(
css` css`
position: fixed; position: fixed;
bottom: 20px; bottom: 20px;
left: 0px; left: 0px;
right: 0px; right: 0px;
z-index: 999; z-index: 999;
`, `,
"flex justify-center", "flex justify-center"
)} )}
> >
<div className="bg-blue-400 text-white px-4 py-2 rounded-full text-sm"> <div className="bg-blue-400 text-white px-4 py-2 rounded-full text-sm">
Updating App... Updating App...
</div> </div>
</div> </div>
</>, </>
); );
}} }}
> >
<div className="bg-orange-600 text-white px-4 py-2 rounded-full text-sm select-none"> <div className="bg-orange-600 text-white px-4 py-2 rounded-full text-sm select-none">
New Version Available. Click to Update New Version Available. Click to Update
</div> </div>
</div> </div>
</>, </>
); );
} }
navigator.serviceWorker.addEventListener("message", (e) => { navigator.serviceWorker.addEventListener("message", (e) => {
cacheCurrentPage(); cacheCurrentPage();
if (react.root) { if (react.root) {
if (e.data.type === "offline") { if (e.data.type === "offline") {
w.offline = true; w.offline = true;
const click = () => { const click = () => {
if (react.root) react.root.render(<Root />); if (react.root) react.root.render(<Root />);
}; };
setTimeout(click, 5000); setTimeout(click, 5000);
react.root.render( react.root.render(
<> <>
<Root /> <Root />
<div <div
className={cx( className={cx(
css` css`
position: fixed; position: fixed;
bottom: 20px; bottom: 20px;
left: 0px; left: 0px;
right: 0px; right: 0px;
z-index: 999; z-index: 999;
`, `,
"flex justify-center cursor-pointer", "flex justify-center cursor-pointer"
)} )}
> >
<div <div
className="bg-orange-500 text-white px-4 py-2 rounded-full text-sm" className="bg-orange-500 text-white px-4 py-2 rounded-full text-sm"
onClick={click} onClick={click}
> >
Network Failed Network Failed
</div> </div>
</div> </div>
</>, </>
); );
} }
if (e.data.type === "activated") { if (e.data.type === "activated") {
if (e.data.shouldRefresh && sw) { if (e.data.shouldRefresh && sw) {
react.root.render( react.root.render(
<> <>
<Root /> <Root />
<div <div
className={cx( className={cx(
css` css`
position: fixed; position: fixed;
bottom: 20px; bottom: 20px;
left: 0px; left: 0px;
right: 0px; right: 0px;
z-index: 999; z-index: 999;
`, `,
"flex justify-center", "flex justify-center"
)} )}
> >
<div className="bg-blue-400 text-white px-4 py-2 rounded-full text-sm"> <div className="bg-blue-400 text-white px-4 py-2 rounded-full text-sm">
Updating App... Updating App...
</div> </div>
</div> </div>
</>, </>
); );
sw.unregister().then(() => { sw.unregister().then(() => {
window.location.reload(); window.location.reload();
}); });
} else { } else {
const localVersion = localStorage.getItem("prasi-version"); const localVersion = localStorage.getItem("prasi-version");
if (localVersion !== e.data.version) { if (localVersion !== e.data.version) {
localStorage.setItem("prasi-version", e.data.version); localStorage.setItem("prasi-version", e.data.version);
const click = () => { const click = () => {
if (react.root) react.root.render(<Root />); if (react.root) react.root.render(<Root />);
}; };
setTimeout(click, 5000); setTimeout(click, 5000);
react.root.render( react.root.render(
<> <>
<Root /> <Root />
<div <div
className={cx( className={cx(
css` css`
position: fixed; position: fixed;
bottom: 20px; bottom: 20px;
left: 0px; left: 0px;
right: 0px; right: 0px;
z-index: 999; z-index: 999;
`, `,
"flex justify-center cursor-pointer", "flex justify-center cursor-pointer"
)} )}
> >
<div <div
className="bg-green-600 text-white px-4 py-2 rounded-full text-sm" className="bg-green-600 text-white px-4 py-2 rounded-full text-sm"
onClick={click} onClick={click}
> >
Prasi Updated{" "} Prasi Updated{" "}
<span className="opacity-50">{e.data.version}</span> <span className="opacity-50">{e.data.version}</span>
</div> </div>
</div> </div>
</>, </>
); );
} }
} }
} }
} }
}); });
} else { } else {
navigator.serviceWorker.getRegistrations().then(function (registrations) { navigator.serviceWorker.getRegistrations().then(function (registrations) {
for (let registration of registrations) { for (let registration of registrations) {
registration.unregister(); registration.unregister();
} }
}); });
} }
} }
}; };
const registerServiceWorker = async () => { const registerServiceWorker = async () => {
if ("serviceWorker" in navigator) { if ("serviceWorker" in navigator) {
try { try {
return await navigator.serviceWorker.register( return await navigator.serviceWorker.register(
new URL("./sworker.ts", import.meta.url), new URL("./sworker.ts", import.meta.url),
{ {
type: "module", type: "module",
scope: "/", scope: "/",
}, }
); );
} catch (error) { } catch (error) {
console.error(`Registration failed with ${error}`); console.error(`Registration failed with ${error}`);
} }
} }
}; };
export const sworkerAddCache = (base: string) => { export const sworkerAddCache = (base: string) => {
if (navigator.serviceWorker) { if (navigator.serviceWorker) {
if (!isLocalhost()) { if (!isLocalhost()) {
const swc = navigator.serviceWorker.controller; const swc = navigator.serviceWorker.controller;
if (swc) { if (swc) {
[location.href, "", "/", "/ed", "/ed/_/_", "/login"].forEach((url) => { [location.href, "", "/", "/ed", "/ed/_/_", "/login"].forEach((url) => {
swc.postMessage({ swc.postMessage({
type: "add-cache", type: "add-cache",
url: url, url: url,
}); });
}); });
if (w.prasiApi && w.prasiApi[base] && w.prasiApi[base].apiEntry) { if (w.prasiApi && w.prasiApi[base] && w.prasiApi[base].apiEntry) {
const routes = Object.entries(w.prasiApi[base].apiEntry).map( const routes = Object.entries(w.prasiApi[base].apiEntry).map(
([k, v]: any) => ({ ([k, v]: any) => ({
url: v.url, url: v.url,
name: k, name: k,
}), })
); );
swc.postMessage({ swc.postMessage({
type: "define-route", type: "define-route",
routes, routes,
}); });
} }
} }
} }
} }
}; };