UNPKG

@fto-consult/common

Version:

Un ensemble de bibliothèques et d'utilistaires communs pour le développement d'applications javascript

158 lines (148 loc) 5.97 kB
// Copyright 2022 @fto-consult/Boris Fouomene. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. /*** * @namespace notify * permet de gérer les différentes notifications de l'application */ import React from "react"; import {isNonNullString,defaultNumber,defaultObj,defaultVal,isObj,defaultStr} from "$cutils"; import getTextContent from "../utils/react/getTextContent"; export const TYPES = { info : "info", error : "error", success : "success", warning : 'warn', } const notificationRef = React.createRef(null); export {notificationRef}; export const notifyRef = React.createRef(); const messageRefs = {}; const messageTimeouts = {}; const getMessageId = (text)=>{ text = typeof text =="string" && text || ""; return text.replaceAll(" ","."); } export const notify = function(message,type,title,settings){ if(typeof notifyRef.current !=='function') return; type = defaultStr(type).toLowerCase(); if(isObj(message)){ settings = message; type = type || settings.type; title = title || settings.title || undefined; message = settings.message || settings.msg; } if(isObj(title)){ settings = isObj(settings)? settings : title; type = type || settings.type; title = settings.title; } settings = defaultObj(settings); type = defaultStr(type,settings.type); if(!type || !(type in TYPES)){ type = TYPES.info; } if(type =="warning"){ type = TYPES.warning; } else if(!TYPES[type]){ type = TYPES.info; } if(!(message)) message = '' if(!(title)) title = '' const m = defaultVal(message,settings.message,settings.msg); message = defaultVal(m,typeof message !== 'boolean'? (message?.message || message?.msg || message?.toString()):undefined); if(isNonNullString(message)){ message = message.trim(); } if(!message) { return; } settings.title = defaultVal(title,settings.title); if(isNonNullString(title)){ title = title.trim(); } let _t = defaultStr(settings.type,type); let defInterval = 5000; switch(_t.toLowerCase().trim()){ case TYPES.error: message = defaultVal(message,settings.error,settings.errorText) defInterval = 12000; break; case TYPES.warning: defInterval = 10000; break; } if(!title){ if(type ===TYPES.error){ title = "Erreur"; }else if(type ==TYPES.warning){ title = "Alerte"; } else title = defaultStr(TYPES[type]).toUpperCase(); } let interval = defaultNumber(settings.interval,settings.timeout,defInterval); if(Math.abs(interval,defInterval)<=200){ //on définit l'intervalle par défaut en fonction de la longueur du message const ccc = getTextContent(message); if(ccc){ interval = Math.max(defInterval,(ccc.length*100)); } } const messageText = getTextContent(message); /***used to avoid duplication on messages */ const mId = getMessageId(type+getTextContent(title)+messageText.substring(0,Math.min(messageText.length,15))); if(!mId || messageRefs[mId] == messageText) return null;//this notification already sent messageRefs[mId] = messageText; clearTimeout(messageTimeouts[mId]); const payload = isObj(settings.payload)? settings.payload : undefined; const options = {...settings,type, title, message, payload, interval}; const {onClose} = options; options.onClose = (...args)=>{ messageTimeouts[mId] = setTimeout(()=>{ delete messageRefs[mId]; clearTimeout(messageTimeouts[mId]); },2000); if(typeof onClose =="function") return onClose(...args); return true; } return notifyRef.current(options); } export const error = (message,title,set)=>{ return notify(message,TYPES.error,title,set) } export const success = (message,title,set)=>{ return notify(message,TYPES.success,title,set) } export const info = (message,title,set)=>{ return notify(message,TYPES.info,title,set) } export const warning = (message,title,set)=>{ return notify(message,"warning",title,set) } export const canSendDesktop = x=> typeof window ==='undefined' || !window || !window?.Notification || !window?.Notification?.requestPermission ? false: true; /*** @see : https://developer.mozilla.org/en-US/docs/Web/API/Notification @param {string} message, le message de la notification @param {string|object} options, si chaine de caractère, alors il s'agit du titre de la notification, sinon, alors il s'agit des options supplémentaires */ export const sendDesktop = (message,options)=>{ if(typeof options ==='string'){ options = {body:options}; } if (!canSendDesktop()) { return Promise.resolve(notify(message,null,null,options)); } options = Object.assign({},options); return Promise.resolve((Notification.permission === 'granted'?Notification.permission:Notification.requestPermission())).then(function(p) { if(p === 'granted') { return new Notification(message,options) } else { throw {message:"Notifications Bloqués par l'utilisateur, veuillez autoriser l'affichage des notifications à partir du navigateur."}; } }).catch((e)=>{ if(options.showError !== false){ notify(e,TYPES.error); } throw e; }); } export const toast = info; export default {error,success,warning,info,toast,notify,canSendDesktop,sendDesktop,desktop:sendDesktop};