Add test push notification flow

This commit is contained in:
zv
2026-06-11 19:36:23 +02:00
parent 054d75b1f4
commit b945fd4893
8 changed files with 88 additions and 3 deletions

View File

@@ -42,6 +42,10 @@ const translations = {
"settings.notifications.saveSuccess": "Powiadomienia są włączone dla tego urządzenia.",
"settings.notifications.disableSuccess": "Powiadomienia są wyłączone dla tego urządzenia.",
"settings.notifications.saveError": "Nie udało się zapisać subskrypcji powiadomień.",
"settings.notifications.sendTest": "Wyślij test",
"settings.notifications.sendingTest": "Wysyłam…",
"settings.notifications.testSuccess": "Wysłano powiadomienie testowe.",
"settings.notifications.testError": "Nie udało się wysłać powiadomienia testowego.",
"settings.notifications.requestPermission": "Sprawdź zgodę",
"settings.notifications.statusChecking": "Sprawdzam obsługę powiadomień w tej przeglądarce.",
"settings.notifications.statusUnconfigured": "Serwer nie ma jeszcze skonfigurowanych kluczy Web Push VAPID.",
@@ -261,6 +265,10 @@ const translations = {
"settings.notifications.saveSuccess": "Notifications are enabled for this device.",
"settings.notifications.disableSuccess": "Notifications are disabled for this device.",
"settings.notifications.saveError": "Unable to save the notification subscription.",
"settings.notifications.sendTest": "Send test",
"settings.notifications.sendingTest": "Sending…",
"settings.notifications.testSuccess": "Test notification sent.",
"settings.notifications.testError": "Unable to send the test notification.",
"settings.notifications.requestPermission": "Check permission",
"settings.notifications.statusChecking": "Checking notification support in this browser.",
"settings.notifications.statusUnconfigured": "The server does not have Web Push VAPID keys configured yet.",

View File

@@ -35,6 +35,15 @@ export async function deletePushSubscription(endpoint: string) {
if (!response.ok) throw new Error("Unable to delete push subscription.");
}
export async function sendTestPushNotification(endpoint: string) {
const response = await fetch("/api/notifications/test", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ endpoint }),
});
if (!response.ok) throw new Error("Unable to send test notification.");
}
export function decodeBase64UrlKey(value: string) {
const padding = "=".repeat((4 - (value.length % 4)) % 4);
const base64 = `${value}${padding}`.replace(/-/g, "+").replace(/_/g, "/");

View File

@@ -69,3 +69,16 @@ export async function sendWarningNotification(preference: WarningPushSubscriptio
const payload = JSON.stringify(buildWarningPayload(preference, warning));
await webPush.sendNotification(preference.subscription as PushSubscription, payload);
}
export async function sendTestNotification(preference: WarningPushSubscription) {
ensureWebPushConfigured();
const province = formatProvinceName(preference.province, preference.language);
const payload = JSON.stringify({
title: preference.language === "pl" ? "wtr.: test powiadomień IMGW" : "wtr.: IMGW notification test",
body: preference.language === "pl"
? `Powiadomienia są aktywne dla województwa: ${province}.`
: `Notifications are active for: ${province}.`,
url: "/settings",
});
await webPush.sendNotification(preference.subscription as PushSubscription, payload);
}

View File

@@ -31,6 +31,10 @@ export function getPushSubscriptions() {
return Array.from(getStore().subscriptions.values());
}
export function getPushSubscription(endpoint: string) {
return getStore().subscriptions.get(endpoint) ?? null;
}
export function hasSentWarning(endpoint: string, warningId: string) {
return getStore().sentWarningIds.get(endpoint)?.has(warningId) ?? false;
}