fchat-rising/chat/notifications.ts

81 lines
3.3 KiB
TypeScript
Raw Permalink Normal View History

2020-06-29 22:01:06 +00:00
// import path from 'path';
2017-09-02 01:50:31 +00:00
import core from './core';
import {Conversation, Notifications as Interface} from './interfaces';
const codecs: {[key: string]: string} = {mpeg: 'mp3', wav: 'wav', ogg: 'ogg'};
export default class Notifications implements Interface {
isInBackground = false;
2018-04-11 19:17:58 +00:00
protected shouldNotify(conversation: Conversation): boolean {
return core.characters.ownCharacter.status !== 'dnd' && (this.isInBackground ||
conversation !== core.conversations.selectedConversation || core.state.settings.alwaysNotify);
}
2018-07-20 01:12:26 +00:00
async notify(conversation: Conversation, title: string, body: string, icon: string, sound: string): Promise<void> {
2018-04-11 19:17:58 +00:00
if(!this.shouldNotify(conversation)) return;
2018-08-10 16:59:37 +00:00
this.playSound(sound);
2018-09-28 00:08:10 +00:00
if(core.state.settings.notifications && (<{Notification?: object}>window).Notification !== undefined
&& Notification.permission === 'granted') {
2018-07-20 01:12:26 +00:00
const notification = new Notification(title, this.getOptions(conversation, body, icon));
2017-09-02 01:50:31 +00:00
notification.onclick = () => {
conversation.show();
window.focus();
2018-08-10 16:59:37 +00:00
if('close' in notification) notification.close();
2017-09-02 01:50:31 +00:00
};
2018-08-10 16:59:37 +00:00
if('close' in notification) window.setTimeout(() => notification.close(), 5000);
2017-09-02 01:50:31 +00:00
}
}
2018-07-20 01:12:26 +00:00
getOptions(conversation: Conversation, body: string, icon: string):
NotificationOptions & {badge: string, silent: boolean, renotify: boolean} {
2020-06-29 22:01:06 +00:00
2020-10-24 20:47:50 +00:00
//tslint:disable-next-line:no-require-imports no-unsafe-any
const badge = <string>require(`./assets/ic_notification.png`).default;
2020-06-29 22:01:06 +00:00
2018-07-20 01:12:26 +00:00
return {
body, icon: core.state.settings.showAvatars ? icon : undefined, badge, silent: true, data: {key: conversation.key},
tag: conversation.key, renotify: true
};
}
2018-08-10 16:59:37 +00:00
playSound(sound: string): void {
2017-09-02 01:50:31 +00:00
if(!core.state.settings.playSound) return;
2018-07-20 01:12:26 +00:00
const audio = <HTMLAudioElement>document.getElementById(`soundplayer-${sound}`);
audio.volume = 1;
audio.muted = false;
2018-08-10 16:59:37 +00:00
const promise = audio.play();
if(promise instanceof Promise) promise.catch((e) => console.error(e));
2018-07-20 01:12:26 +00:00
}
2018-08-10 16:59:37 +00:00
async initSounds(sounds: ReadonlyArray<string>): Promise<void> {
2018-07-20 01:12:26 +00:00
const promises = [];
for(const sound of sounds) {
const id = `soundplayer-${sound}`;
if(document.getElementById(id) !== null) continue;
const audio = document.createElement('audio');
2018-08-10 16:59:37 +00:00
audio.preload = 'auto';
2017-09-02 01:50:31 +00:00
audio.id = id;
for(const name in codecs) {
const src = document.createElement('source');
src.type = `audio/${name}`;
2020-06-29 22:01:06 +00:00
src.src = <string>require(`./assets/${sound}.${codecs[name]}`).default; // tslint:disable-line: no-unsafe-any
2017-09-02 01:50:31 +00:00
audio.appendChild(src);
}
2018-07-20 01:12:26 +00:00
document.body.appendChild(audio);
audio.volume = 0;
audio.muted = true;
2020-06-29 22:01:06 +00:00
2018-07-20 01:12:26 +00:00
const promise = audio.play();
if(promise instanceof Promise)
2018-08-10 16:59:37 +00:00
promises.push(promise.catch((e) => console.error(e)));
2017-09-02 01:50:31 +00:00
}
2018-07-20 01:12:26 +00:00
return <any>Promise.all(promises); //tslint:disable-line:no-any
2017-09-02 01:50:31 +00:00
}
2018-01-06 16:14:21 +00:00
async requestPermission(): Promise<void> {
2018-09-28 00:08:10 +00:00
if((<{Notification?: object}>window).Notification !== undefined) await Notification.requestPermission();
2018-01-06 16:14:21 +00:00
}
2020-06-29 22:01:06 +00:00
}