@exabytellc/utils
Version:
EB react utils to make everything a little easier!
117 lines (106 loc) • 4.07 kB
JavaScript
import ClassHelper from "../_helpers/ClassHelper";
export default class Notif extends ClassHelper {
/**
* Checks if browser supports notifications.
* @returns {boolean} True if notifications are supported, false otherwise.
*/
static get supported() {
return !!window.Notification;
}
/**
* Checks if notifications are permitted.
* @returns {boolean} True if notifications are permitted, false otherwise.
*/
static get permitted() {
return Notification.permission === 'granted';
}
/**
* Checks if notifications are denied.
* @returns {boolean} True if notifications are denied, false otherwise.
*/
static get denied() {
return Notification.permission === 'denied';
}
/**
* Requests permission for notifications.
* @returns {Promise<boolean>} A promise resolving to true if permission is granted, false otherwise.
*/
static async askPermission() {
return await this.handleTryCatchAsync({
n: "askPermission",
e: async () => {
if (!Notif.supported) throw new Error('Notifications not supported on this browser.');
const permission = await Notification.requestPermission();
return permission === 'granted';
}
});
}
/**
* Requests permission for notifications on user interaction.
*/
static askPermissionOnInteract() {
return this.handleTryCatch({
n: "askPermissionOnInteract",
e: () => {
if (!Notif.denied && !Notif.permitted) {
document.addEventListener("click", async () => {
try {
if (Notif.supported) {
await Notification.requestPermission();
}
} catch (error) {
this.handleError("askPermissionOnInteract", error);
}
}, { capture: true, once: true });
}
}
});
}
/**
* Displays a notification.
* @param {string} title - The title of the notification.
* @param {string} body - The body text of the notification.
* @param {object} options - Additional options for the notification.
* @returns {boolean} True if the notification was displayed successfully, false otherwise.
*/
static async notify(title, body, options = {}) {
return await this.handleTryCatchAsync({
n: "notify",
f: false,
e: async () => {
if (!Notif.supported) throw new Error('Notifications not supported on this browser.');
if (Notif.denied) throw new Error('Notifications are not permitted.');
if (!Notif.permitted) {
const permissionGranted = await Notif.askPermission();
if (!permissionGranted) throw new Error('Notifications permission denied.');
}
const notification = new Notification(title, { ...options, body });
// Add event listeners
['show', 'click', 'close', 'error'].forEach(eventName => {
const handler = options[`on${eventName.charAt(0).toUpperCase() + eventName.slice(1)}`];
if (typeof handler === 'function') {
notification.addEventListener(eventName, handler);
}
});
// Auto-close after specified duration
if (options.autoCloseSec) {
setTimeout(() => {
notification.close();
}, options.autoCloseSec * 1000);
}
return true;
}
});
}
}
/* Notif.askPermissionOnInteract()
Notif.notify({
title: "عنوان!!", body: "هيئة الجسم!!", dir: "rtl", lang: 'ar', tag: "olla senior", data: [1, 2],
image: "https://exabytellc.com/_assets/media/logo.png", icon: "https://exabytellc.com/_assets/media/tab-icon.jpg", badge: "https://exabytellc.com/_assets/media/tab-icon.jpg",
renotify: true, requireInteraction: true,
onShow: (evt) => console.trace("onShow", evt),
onClick: (evt) => console.trace("onClick", evt),
onClose: (evt) => console.trace("onClose", evt),
onError: (evt) => console.trace("onError", evt)
})
*/