71 lines
2.5 KiB
TypeScript
71 lines
2.5 KiB
TypeScript
import type { Language } from "@/lib/i18n";
|
|
import type { Province } from "@/types/province";
|
|
import type { WindSpeedUnit } from "@/types/units";
|
|
|
|
interface VapidKeyResponse {
|
|
configured: boolean;
|
|
publicKey: string | null;
|
|
}
|
|
|
|
export async function fetchVapidPublicKey(signal?: AbortSignal) {
|
|
const response = await fetch("/api/notifications/vapid-key", { signal });
|
|
if (!response.ok) throw new Error("Unable to load Web Push configuration.");
|
|
return response.json() as Promise<VapidKeyResponse>;
|
|
}
|
|
|
|
interface SavePushSubscriptionOptions {
|
|
morningBriefEnabled?: boolean;
|
|
tomorrowBriefEnabled?: boolean;
|
|
latitude?: number | null;
|
|
longitude?: number | null;
|
|
locationName?: string | null;
|
|
countyTeryt?: string | null;
|
|
windSpeedUnit?: WindSpeedUnit;
|
|
}
|
|
|
|
export async function savePushSubscription(subscription: PushSubscription, province: Province, language: Language, options: SavePushSubscriptionOptions = {}) {
|
|
const response = await fetch("/api/notifications/subscriptions", {
|
|
method: "POST",
|
|
headers: { "content-type": "application/json" },
|
|
body: JSON.stringify({
|
|
subscription: subscription.toJSON(),
|
|
province,
|
|
language,
|
|
enabled: true,
|
|
morningBriefEnabled: options.morningBriefEnabled === true,
|
|
tomorrowBriefEnabled: options.tomorrowBriefEnabled === true,
|
|
latitude: options.latitude ?? null,
|
|
longitude: options.longitude ?? null,
|
|
locationName: options.locationName ?? null,
|
|
countyTeryt: options.countyTeryt ?? null,
|
|
windSpeedUnit: options.windSpeedUnit,
|
|
}),
|
|
});
|
|
if (!response.ok) throw new Error("Unable to save push subscription.");
|
|
}
|
|
|
|
export async function deletePushSubscription(endpoint: string) {
|
|
const response = await fetch("/api/notifications/subscriptions", {
|
|
method: "DELETE",
|
|
headers: { "content-type": "application/json" },
|
|
body: JSON.stringify({ endpoint }),
|
|
});
|
|
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, "/");
|
|
const raw = window.atob(base64);
|
|
return Uint8Array.from(raw, (character) => character.charCodeAt(0));
|
|
}
|