prasi-bun/app/web/src/nova/vi/exts/notif.ts

147 lines
4.1 KiB
TypeScript

import { waitUntil } from "web-utils";
import { PG } from "../../ed/logic/ed-global";
import { VG } from "../render/global";
import { PrasiExt, prasi_ext } from "./types";
type NOTIF_ARG = {
user_id: any;
body: string;
title: string;
data?: any;
};
interface PushNotificationSchema {
title?: string;
subtitle?: string;
body?: string;
id: string;
tag?: string;
badge?: number;
notification?: any;
data: any;
click_action?: string;
link?: string;
group?: string;
groupSummary?: boolean;
}
interface ActionPerformed {
actionId: string;
inputValue?: string;
notification: PushNotificationSchema;
}
const w = window as unknown as {
notif:
| {
send: (data: NOTIF_ARG) => Promise<void>;
register: (user_id: string) => void;
onReceive: (notif: PushNotificationSchema) => void | Promise<void>;
onTap: (notif: null | ActionPerformed) => void | Promise<void>;
}
| undefined;
};
export const initExtNotif = async (vi: VG, prasi_ext: PrasiExt) => {
if (window.parent) {
window.addEventListener("message", async ({ data: raw }) => {
if (typeof raw === "object" && raw.mobile) {
const data = raw as unknown as
| {
type: "notification-token";
token: string;
}
| { type: "notification-tap"; notif: ActionPerformed }
| { type: "notification-receive"; notif: PushNotificationSchema };
const waitUntil = async (fn: () => boolean) => {
if (!w.notif?.onTap) {
let ival = null as any;
let i = 0;
await new Promise(() => {
ival = setInterval(() => {
i++;
if (i > 20) {
clearInterval(ival);
}
if (fn()) {
clearInterval(ival);
}
}, 500);
});
return;
}
};
switch (data.type) {
case "notification-token":
prasi_ext.notif = { token: data.token };
w.notif = {
async send(data: NOTIF_ARG) {
if (vi && vi.site.api) {
return await vi.site.api._notif("send", {
type: "send",
id:
typeof data.user_id === "string"
? data.user_id
: data.user_id.toString(),
body: data.body,
title: data.title,
data: data.data,
});
}
},
async register(user_id: any) {
if (vi && vi.site.api && prasi_ext.notif?.token) {
return await vi.site.api._notif("register", {
type: "register",
id:
typeof user_id === "string"
? user_id
: user_id.toString(),
token: prasi_ext.notif.token,
});
}
},
onReceive(notif) {},
onTap(notif) {},
};
break;
case "notification-tap":
if (!w.notif?.onTap) {
waitUntil(() => {
if (w.notif?.onTap) {
w.notif?.onTap(data.notif);
return true;
}
return false;
});
return;
}
if (w.notif?.onTap) {
w.notif?.onTap(data.notif);
}
break;
case "notification-receive":
if (!w.notif?.onReceive) {
waitUntil(() => {
if (w.notif?.onReceive) {
w.notif?.onReceive(data.notif);
return true;
}
return false;
});
}
if (w.notif?.onReceive) {
w.notif?.onReceive(data.notif);
}
break;
}
}
});
window.parent.postMessage({ mobile: true, type: "ready" }, "*");
}
};