feat(pwa): keep service workers from getting registerd outside the pwa
Some checks failed
/ build-web (push) Successful in 5m32s
/ build-desktop (linux) (push) Successful in 9m55s
/ build-mobile (push) Successful in 18m33s
/ release (push) Failing after 1m42s

This commit is contained in:
Alois 2026-08-27 14:38:53 +02:00
commit 96b81d30b1
Signed by: alois
SSH key fingerprint: SHA256:GBzT2DXvAuGV9XIV5W3WrzVpjU54FThmxHXdbz95J24
2 changed files with 10 additions and 57 deletions

View file

@ -1,4 +1,4 @@
import { useEffect, useState } from "react";
import { useEffect } from "react";
import { toast } from "sonner";
import { setDatabaseEntry } from "@tensamin/shared/indexedDb";
@ -6,11 +6,6 @@ import { isTauri } from "@tauri-apps/api/core";
import "./style.css";
type BeforeInstallPromptEvent = Event & {
prompt: () => Promise<void>;
userChoice: Promise<{ outcome: "accepted" | "dismissed" }>;
};
const launchedFiles: File[] = [];
const fileListeners = new Set<(file: File) => void>();
@ -27,9 +22,10 @@ export function subscribeTuFileLaunch(listener: (file: File) => void) {
};
}
function isStandalone() {
function isInstalledPwa() {
return (
window.matchMedia("(display-mode: standalone)").matches ||
window.matchMedia("(display-mode: window-controls-overlay)").matches ||
(navigator as Navigator & { standalone?: boolean }).standalone === true
);
}
@ -65,13 +61,9 @@ async function enablePush() {
await setDatabaseEntry("keys", "push-subscription", subscription.toJSON());
}
export default function PwaRuntime() {
const [installPrompt, setInstallPrompt] =
useState<BeforeInstallPromptEvent | null>(null);
function InstalledPwaRuntime() {
useEffect(() => {
if (
isTauri() ||
!("serviceWorker" in navigator) ||
!["http:", "https:"].includes(window.location.protocol)
) {
@ -129,16 +121,6 @@ export default function PwaRuntime() {
};
}, []);
useEffect(() => {
const handleInstallPrompt = (event: Event) => {
event.preventDefault();
setInstallPrompt(event as BeforeInstallPromptEvent);
};
window.addEventListener("beforeinstallprompt", handleInstallPrompt);
return () =>
window.removeEventListener("beforeinstallprompt", handleInstallPrompt);
}, []);
useEffect(() => {
const launchQueue = (
window as Window & {
@ -159,41 +141,7 @@ export default function PwaRuntime() {
}, []);
useEffect(() => {
if (!installPrompt) return;
toast("Install Tensamin for a native app experience", {
duration: Infinity,
action: {
label: "Install",
onClick: () => {
void installPrompt.prompt().then(() => installPrompt.userChoice);
setInstallPrompt(null);
},
},
});
}, [installPrompt]);
useEffect(() => {
const isAppleMobile = /iPad|iPhone|iPod/.test(navigator.userAgent);
if (
isTauri() ||
!isAppleMobile ||
isStandalone() ||
localStorage.getItem("pwa-ios-install-hint")
) {
return;
}
localStorage.setItem("pwa-ios-install-hint", "shown");
toast(
"Install Tensamin from Safari's Share menu to enable background notifications.",
{
duration: 12_000,
},
);
}, []);
useEffect(() => {
if (
!isStandalone() ||
!("Notification" in window) ||
Notification.permission !== "default" ||
localStorage.getItem("pwa-push-hint")
@ -222,7 +170,6 @@ export default function PwaRuntime() {
useEffect(() => {
if (
isStandalone() &&
"Notification" in window &&
Notification.permission === "granted" &&
import.meta.env.VITE_WEB_PUSH_PUBLIC_KEY
@ -235,3 +182,8 @@ export default function PwaRuntime() {
return null;
}
export default function PwaRuntime() {
if (isTauri() || !isInstalledPwa()) return null;
return <InstalledPwaRuntime />;
}