168 lines
6.7 KiB
TypeScript
168 lines
6.7 KiB
TypeScript
import InfoUtils from "../utils/InfoUtils";
|
||
import MathUtils from "../utils/MathUtils";
|
||
import NOTIFY_HTML from "../../../static/html/buyBeer/notify.html";
|
||
import CommonUtils from "../utils/CommonUtils";
|
||
import Popup from "../utils/Popup";
|
||
import ResponseInject from "../../interface/ResponseInject";
|
||
import LocalConfigWrapper from "../LocalConfigWrapper";
|
||
import ClassName from "../../container/ClassName";
|
||
import { Injectable } from "../../container/Injectable";
|
||
import Logger from "../Logger";
|
||
import MsgWrapper from "../utils/MsgWrapper";
|
||
|
||
@ClassName('BuyBeerHelper')
|
||
@Injectable()
|
||
export default class BuyBeerHelper implements BeerMonitorLoop, ResponseInject {
|
||
|
||
private isNotifying = false;
|
||
private loopId: number = null;
|
||
private time: number;
|
||
private readonly notifyHtml: string = NOTIFY_HTML.replace('{{}}', this.mathUtils.getRandomInt(0, 99).toString());
|
||
|
||
public constructor(
|
||
private readonly localConfigWrapper: LocalConfigWrapper,
|
||
private readonly commonUtils: CommonUtils,
|
||
private readonly infoUtils: InfoUtils,
|
||
private readonly mathUtils: MathUtils,
|
||
private readonly logger: Logger,
|
||
private readonly msgWrapper: MsgWrapper,
|
||
) {
|
||
this.time = this.localConfigWrapper.config._15AlarmTime || 30;
|
||
}
|
||
|
||
public start(): void {
|
||
if (this.loopId) {
|
||
this.logger.info('啤酒助手已在运行');
|
||
} else {
|
||
this.logger.info('啤酒助手启动');
|
||
this.loopId = window.setInterval(async () => {
|
||
// 海外取消提醒
|
||
let { isTravelling, isAbroad } = await this.infoUtils.getUserState();
|
||
if (isTravelling || isAbroad) {
|
||
this.stop();
|
||
return;
|
||
}
|
||
let dt = new Date();
|
||
// 已选当天不提醒
|
||
const now = [dt.getUTCFullYear(), dt.getUTCMonth(), dt.getUTCDate()];
|
||
const ignore_date = this.localConfigWrapper.config._15_alarm_ignore || '{}';
|
||
if (JSON.stringify(now) === JSON.stringify(ignore_date)) return;
|
||
// 正常提醒
|
||
let m = 14 - (dt.getMinutes() % 15);
|
||
let s = 60 - dt.getSeconds();
|
||
if (m === 0 && s < this.time) {
|
||
// 如从通知点开,则本次通知跳过
|
||
if (location.href.includes('clickfromnotify')) {
|
||
this.isNotifying = true;
|
||
location.hash = '';
|
||
return;
|
||
}
|
||
// 本次已通知
|
||
if (this.isNotifying) return;
|
||
this.isNotifying = true;
|
||
// 发送通知
|
||
const rNum = this.mathUtils.getRandomInt(0, 99);
|
||
// const notify =
|
||
this.msgWrapper.create(NOTIFY_HTML.replace('{{}}', rNum.toString()), {
|
||
timeout: 30,
|
||
sysNotify: true,
|
||
});
|
||
document.querySelector('button#wh-rd-btn-' + rNum).addEventListener('click', () => this.skip_today());
|
||
// notify.getElement().addEventListener('click', ev => {
|
||
// if ((ev.target as HTMLElement).tagName.toLowerCase() === 'a') {
|
||
// notify.close();
|
||
// }
|
||
// });
|
||
// 声音提醒
|
||
{
|
||
let loop = 3;
|
||
let id = window.setInterval(async () => {
|
||
await this.commonUtils.audioPlay();
|
||
loop--;
|
||
if (!loop) window.clearInterval(id);
|
||
}, 800);
|
||
}
|
||
} else {
|
||
this.isNotifying = false;
|
||
}
|
||
}, 1000);
|
||
}
|
||
}
|
||
|
||
public stop(): void {
|
||
if (this.loopId) {
|
||
window.clearInterval(this.loopId);
|
||
this.loopId = null;
|
||
}
|
||
}
|
||
|
||
public set_time(t: number): void {
|
||
this.time = t;
|
||
}
|
||
|
||
public status(): '已启动' | '未启动' {
|
||
return this.loopId ? '已启动' : '未启动';
|
||
}
|
||
|
||
public is_running(): boolean {
|
||
return this.loopId !== null;
|
||
}
|
||
|
||
public skip_today(): void {
|
||
const date = new Date();
|
||
this.localConfigWrapper.config._15_alarm_ignore = [date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()];
|
||
// WuhuConfig.set('_15_alarm_ignore', [date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()], false);
|
||
// 通知
|
||
const rNumber = this.mathUtils.getRandomInt(0, 100);
|
||
const notify = this.msgWrapper.create(`明早8点前将不再提醒 <button id="wh-rd-btn-${ rNumber }">取消</button>`);
|
||
// 通知中的取消按钮
|
||
document.querySelector('#wh-rd-btn-' + rNumber)
|
||
.addEventListener(
|
||
'click',
|
||
() => this.localConfigWrapper.config._15_alarm_ignore.length = 0
|
||
);
|
||
}
|
||
|
||
public setTimeHandler(): void {
|
||
let popup = new Popup(`<label>提前提醒时间(秒):<input type="number" value="${ this.localConfigWrapper.config._15AlarmTime }" /></label><p>区间为 1 ~ 60,默认 50</p>`, '啤酒提醒时间设定');
|
||
let confirm = document.createElement('button');
|
||
confirm.innerHTML = '确定';
|
||
confirm.style.float = 'right';
|
||
confirm.addEventListener('click', () => {
|
||
let input: HTMLInputElement = popup.element.querySelector('input');
|
||
let num = (input.value as any) | 0;
|
||
if (num === this.localConfigWrapper.config._15AlarmTime) return;
|
||
if (num < 1 || num > 60) num = 50;
|
||
input.value = num.toString();
|
||
this.localConfigWrapper.config._15AlarmTime = num;
|
||
this.set_time(num);
|
||
// 之前的运行状态
|
||
if (this.is_running()) this.start();
|
||
popup.close();
|
||
});
|
||
popup.element.appendChild(confirm);
|
||
}
|
||
|
||
public responseHandler(url: string, body: { json: unknown; text: string; isModified: boolean }, opt: {
|
||
method: "GET" | "POST";
|
||
requestBody: string
|
||
}) {
|
||
if (url.includes('shops.php') && opt?.method === 'POST') {
|
||
let req = opt.requestBody;
|
||
if (req && req.includes('step=buyShopItem') && req.includes('ID=180') && body.json && body.json['success']) {
|
||
this.msgWrapper.create('检测到已成功购买啤酒');
|
||
this.skip_today();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
export interface BeerMonitorLoop {
|
||
start?: Function;
|
||
stop?: Function;
|
||
set_time?: Function;
|
||
status?: Function;
|
||
is_running?: Function;
|
||
skip_today?: Function;
|
||
}
|