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 = `
`;
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;
}