import getRandomInt from "./getRandomInt"; import addStyle from "./addStyle"; import WuhuBase from "../../class/WuhuBase"; /** * 通知方法 * @param {string} msg - 通知内容 * @param {Object} [options] - 通知选项 * @param {number} [options.timeout] - 通知超时时间 * @param {function} [options.callback] - 通知回调 * @param {boolean} [options.sysNotify] - 是否开启系统通知 * @param {string} [options.sysNotifyTag] - 系统通知标记 * @param {function} [options.sysNotifyClick] - 系统通知点击事件 * @return {HTMLElement} */ export default function WHNotify(msg: string, options: WHNotifyOpt = {}): MyHTMLElement { let { isWindowActive, notifies } = WuhuBase.glob; let { timeout = 3, callback = function () { }, sysNotify = false, sysNotifyTag = '芜湖助手', sysNotifyClick = () => window.focus() } = options; if (!isWindowActive() || (self !== top)) return null; const date = new Date(); // 通知的唯一id const uid = `${ date.getHours() }${ date.getSeconds() }${ date.getMilliseconds() }${ getRandomInt(1000, 9999) }`; // 通知容器id const node_id = 'wh-notify'; // 通知的容器 let notify_contain: MyHTMLElement = document.querySelector(`#${ node_id }`); // 添加通知到容器 const add_notify = () => { // 每条通知 const new_node: MyHTMLElement = document.createElement('div'); new_node.id = `wh-notify-${ uid }`; new_node.classList.add('wh-notify-item'); new_node.innerHTML = `

${ msg }

`; notify_contain.append(new_node); notify_contain['msgInnerText'] = new_node.querySelector('.wh-notify-msg').innerText; // 进度条node const progressBar: HTMLElement = new_node.querySelector('.wh-notify-bar'); // 是否hover let mouse_enter = false; new_node.addEventListener('mouseenter', () => mouse_enter = true, true); new_node.addEventListener('mouseleave', () => mouse_enter = false); // 通知进度条 let progressCount = 101; // 删除通知 new_node.close = () => { clearInterval(intervalID); new_node.remove(); callback(); }; // 计时器 let intervalID = window.setInterval(() => { if (mouse_enter) { progressCount = 101; progressBar.style.width = '100%'; return; } progressCount--; progressBar.style.width = `${ progressCount }%`; if (progressCount === 0) new_node.remove(); }, timeout * 1000 / 100); new_node.querySelector('.wh-notify-close').addEventListener('click', new_node.close); return new_node; }; // 不存在容器 创建 if (!notify_contain) { notify_contain = document.createElement('div'); notify_contain.id = node_id; addStyle(` #${ node_id } { display: inline-block; position: fixed; top: 0; left: calc(50% - 180px); width: 360px; z-index: 9999990; color:#333; } #${ node_id } a{ color:red; text-decoration:none; } #${ node_id } .wh-notify-item { /*height: 50px;*/ background: rgb(239 249 255 / 90%); border-radius: 2px; margin: 0.5em 0 0 0; box-shadow: 0 0 5px 0px #959595; } #${ node_id } .wh-notify-item:hover { background: rgb(239 249 255 / 98%); } #${ node_id } .wh-notify-item .wh-notify-bar { height:2px; background:#2196f3; } #${ node_id } .wh-notify-item .wh-notify-close { float:right; padding:0; width:16px;height:16px; background:url('data:image/svg+xml,%3Csvg%20viewBox%3D%220%200%201024%201024%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M923%20571H130.7c-27.6%200-50-22.4-50-50s22.4-50%2050-50H923c27.6%200%2050%2022.4%2050%2050s-22.4%2050-50%2050z%22%20fill%3D%22%232196f3%22%3E%3C%2Fpath%3E%3C%2Fsvg%3E') no-repeat center; background-size:100%; margin: 6px 6px 0 0; cursor: pointer; } #${ node_id } .wh-notify-item .wh-notify-msg { padding:12px; } `); document.body.append(notify_contain); } const notify_obj = add_notify(); // 浏览器通知 if (window.Notification && Notification.permission === 'granted' && sysNotify) { const date_local_string = `[${ date.getHours() }:${ date.getMinutes() }:${ date.getSeconds() }]\r`; notify_obj.sys_notify = new Notification('芜湖助手', { body: date_local_string + notify_contain.msgInnerText, requireInteraction: true, renotify: true, tag: sysNotifyTag + getRandomInt(0, 99), }); notify_obj.sys_notify.addEventListener('close', () => sysNotifyClick()); notify_obj.sys_notify.onshow = () => setTimeout(() => notify_obj.sys_notify.close(), timeout * 1000); notify_obj.sys_notify.id = notifies.count++; notifies[notify_obj.sys_notify.id] = notify_obj.sys_notify; notify_obj.sys_notify.addEventListener('close', () => notifies[notify_obj.sys_notify.id] = null); } return notify_obj; } interface WHNotifyOpt { timeout?: number; callback?: Function; sysNotify?: boolean; sysNotifyTag?: string; sysNotifyClick?: Function; }