103 lines
3.7 KiB
TypeScript
103 lines
3.7 KiB
TypeScript
import IWHNotify from "../../interface/IWHNotify";
|
|
import NotificationUtils from "./NotificationUtils";
|
|
import MathUtils from "./MathUtils";
|
|
import NOTIFY_HTML from "../../../static/html/notify.html";
|
|
import WindowActiveState from "../action/WindowActiveState";
|
|
import { Container } from "../../container/Container";
|
|
import Logger from "../Logger";
|
|
import ClassName from "../../container/ClassName";
|
|
|
|
@ClassName('Alert')
|
|
export default class Alert {
|
|
private static container: HTMLElement = null;
|
|
private static totalCounter: number = 0;
|
|
|
|
private notify: MyHTMLElement = null;
|
|
private intervalID = -1;
|
|
private readonly callback: Function;
|
|
|
|
public constructor(
|
|
msg: string,
|
|
options: IWHNotify = {},
|
|
private readonly mathUtils: MathUtils = Container.factory(MathUtils),
|
|
private readonly windowActiveState: WindowActiveState = Container.factory(WindowActiveState),
|
|
private readonly notificationUtils: NotificationUtils = Container.factory(NotificationUtils),
|
|
private readonly logger: Logger = Container.factory(Logger),
|
|
) {
|
|
|
|
let { timeout, callback, sysNotify, force } = options;
|
|
|
|
// 后台窗口、iframe内判断
|
|
if (!this.windowActiveState.get() || (self !== top)) {
|
|
if (!force) {
|
|
this.logger.warn('后台通知已被屏蔽');
|
|
return null;
|
|
} else {
|
|
this.logger.info('强制后台通知');
|
|
}
|
|
}
|
|
|
|
// 通知的容器
|
|
this.logger.info('通知的容器', Alert.container);
|
|
if (!Alert.container || !document.contains(Alert.container)) Alert.initContainer();
|
|
|
|
this.callback = callback || (() => null);
|
|
Alert.create(this, msg, timeout || 3);
|
|
Alert.totalCounter++;
|
|
this.logger.info('创建新通知:', this, msg);
|
|
if (sysNotify) this.notificationUtils.push(msg, options);
|
|
}
|
|
|
|
private static create(that: Alert, msg, timeout): void {
|
|
// 通知的唯一id
|
|
const uid = '' + that.mathUtils.getRandomInt(1000, 9999);
|
|
// 每条通知
|
|
const element: MyHTMLElement = document.createElement('div');
|
|
element.id = `wh-notify-${ uid }`;
|
|
element.classList.add('wh-notify-item');
|
|
element.innerHTML = NOTIFY_HTML.replace('{{}}', msg);
|
|
this.container.append(element);
|
|
// 进度条node
|
|
const progressBar: HTMLElement = element.querySelector('.wh-notify-bar');
|
|
// 是否hover
|
|
let mouse_enter = false;
|
|
element.addEventListener('mouseenter', () => mouse_enter = true, true);
|
|
element.addEventListener('mouseleave', () => mouse_enter = false);
|
|
// 通知进度条 TODO 改进
|
|
let progressCount = 101;
|
|
// 计时器
|
|
that.intervalID = window.setInterval(() => {
|
|
if (mouse_enter) {
|
|
progressCount = 101;
|
|
progressBar.style.width = '100%';
|
|
return;
|
|
}
|
|
progressCount--;
|
|
progressBar.style.width = `${ progressCount }%`;
|
|
if (progressCount === 0) {
|
|
that.close();
|
|
}
|
|
}, timeout * 1000 / 100) as unknown as number;
|
|
element.querySelector('.wh-notify-close').addEventListener('click', () => that.close());
|
|
that.notify = element;
|
|
}
|
|
|
|
private static initContainer() {
|
|
this.container = document.createElement('div');
|
|
this.container.id = 'wh-notify';
|
|
document.body.append(this.container);
|
|
}
|
|
|
|
public close() {
|
|
this.notify.remove();
|
|
this.notify = null;
|
|
this.callback();
|
|
window.clearInterval(this.intervalID);
|
|
Alert.totalCounter--;
|
|
}
|
|
|
|
public getElement() {
|
|
return this.notify;
|
|
}
|
|
}
|