149 lines
5.3 KiB
TypeScript
149 lines
5.3 KiB
TypeScript
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 = `<div class="wh-notify-bar"></div>
|
|
<div class="wh-notify-cont">
|
|
<div class="wh-notify-close"></div>
|
|
<div class="wh-notify-msg"><p>${ msg }</p></div>
|
|
</div>`;
|
|
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;
|
|
} |