Update files
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { Platform } from "react-native";
|
||||
import { buildNotificationRoute } from "./notification-routing";
|
||||
|
||||
type OsNotificationPayload = {
|
||||
title: string;
|
||||
@@ -6,6 +7,18 @@ type OsNotificationPayload = {
|
||||
data?: Record<string, unknown>;
|
||||
};
|
||||
|
||||
export type WebNotificationClickDetail = {
|
||||
data?: Record<string, unknown>;
|
||||
};
|
||||
|
||||
type WebNotificationInstance = {
|
||||
onclick?: ((event: Event) => void) | null;
|
||||
addEventListener?: (type: string, listener: (event: Event) => void) => void;
|
||||
close?: () => void;
|
||||
};
|
||||
|
||||
export const WEB_NOTIFICATION_CLICK_EVENT = "paseo:web-notification-click";
|
||||
|
||||
let permissionRequest: Promise<boolean> | null = null;
|
||||
|
||||
function getWebNotificationConstructor(): {
|
||||
@@ -41,6 +54,71 @@ async function ensureNotificationPermission(): Promise<boolean> {
|
||||
return result;
|
||||
}
|
||||
|
||||
function dispatchWebNotificationClick(detail: WebNotificationClickDetail): boolean {
|
||||
const dispatch = (globalThis as { dispatchEvent?: (event: Event) => boolean }).dispatchEvent;
|
||||
const CustomEventConstructor = (globalThis as { CustomEvent?: typeof CustomEvent })
|
||||
.CustomEvent;
|
||||
|
||||
if (typeof dispatch !== "function" || !CustomEventConstructor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const event = new CustomEventConstructor<WebNotificationClickDetail>(
|
||||
WEB_NOTIFICATION_CLICK_EVENT,
|
||||
{
|
||||
detail,
|
||||
cancelable: true,
|
||||
}
|
||||
);
|
||||
return dispatch(event) === false;
|
||||
}
|
||||
|
||||
function fallbackNavigateToNotificationTarget(
|
||||
data: Record<string, unknown> | undefined
|
||||
): void {
|
||||
const route = buildNotificationRoute(data);
|
||||
const location = (globalThis as { location?: { assign?: (url: string) => void; href?: string } })
|
||||
.location;
|
||||
if (!location) {
|
||||
return;
|
||||
}
|
||||
if (typeof location.assign === "function") {
|
||||
location.assign(route);
|
||||
return;
|
||||
}
|
||||
if (typeof location.href === "string") {
|
||||
location.href = route;
|
||||
}
|
||||
}
|
||||
|
||||
function attachWebClickHandler(
|
||||
notification: WebNotificationInstance,
|
||||
data: Record<string, unknown> | undefined
|
||||
): void {
|
||||
const onClick = () => {
|
||||
const focus = (globalThis as { focus?: () => void }).focus;
|
||||
if (typeof focus === "function") {
|
||||
focus();
|
||||
}
|
||||
|
||||
const handledByApp = dispatchWebNotificationClick({ data });
|
||||
if (!handledByApp) {
|
||||
fallbackNavigateToNotificationTarget(data);
|
||||
}
|
||||
|
||||
if (typeof notification.close === "function") {
|
||||
notification.close();
|
||||
}
|
||||
};
|
||||
|
||||
if (typeof notification.addEventListener === "function") {
|
||||
notification.addEventListener("click", onClick);
|
||||
return;
|
||||
}
|
||||
|
||||
notification.onclick = onClick;
|
||||
}
|
||||
|
||||
export async function sendOsNotification(
|
||||
payload: OsNotificationPayload
|
||||
): Promise<boolean> {
|
||||
@@ -57,9 +135,10 @@ export async function sendOsNotification(
|
||||
if (!granted) {
|
||||
return false;
|
||||
}
|
||||
new NotificationConstructor(payload.title, {
|
||||
const notification = new NotificationConstructor(payload.title, {
|
||||
body: payload.body,
|
||||
data: payload.data,
|
||||
});
|
||||
}) as WebNotificationInstance;
|
||||
attachWebClickHandler(notification, payload.data);
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user