81 lines
2.2 KiB
TypeScript
81 lines
2.2 KiB
TypeScript
|
|
import {Injectable, signal} from '@angular/core';
|
||
|
|
|
||
|
|
@Injectable({providedIn: 'root'})
|
||
|
|
export class NotificationService {
|
||
|
|
|
||
|
|
private readonly notificationSound = new Audio('/public/sounds/notification.mp3');
|
||
|
|
private readonly notificationStorageKey = 'chat-notifications-enabled';
|
||
|
|
private readonly _notificationEnabled = signal<boolean>(
|
||
|
|
localStorage.getItem(this.notificationStorageKey) === 'true'
|
||
|
|
);
|
||
|
|
public readonly notificationEnabled = this._notificationEnabled.asReadonly();
|
||
|
|
|
||
|
|
async requestPermission(): Promise<boolean> {
|
||
|
|
if (!('Notification' in window)) {
|
||
|
|
console.log('This browser does not support notifications');
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (Notification.permission === 'granted') {
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (Notification.permission === 'denied') {
|
||
|
|
console.log('Notification permission was denied');
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
const permission = await Notification.requestPermission();
|
||
|
|
if (permission === 'granted') {
|
||
|
|
this.enableSound()
|
||
|
|
return true
|
||
|
|
}
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
notify(title: string, body: string | null) {
|
||
|
|
if (!this.notificationEnabled()) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
if (Notification.permission === 'granted') {
|
||
|
|
if (body === null) {
|
||
|
|
new Notification(title);
|
||
|
|
} else {
|
||
|
|
new Notification(title, {body});
|
||
|
|
}
|
||
|
|
this.playSound();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private enableSound() {
|
||
|
|
this.notificationSound.muted = true;
|
||
|
|
this.notificationSound.play()
|
||
|
|
.then(() => {
|
||
|
|
this.notificationSound.pause();
|
||
|
|
this.notificationSound.currentTime = 0;
|
||
|
|
this.notificationSound.muted = false;
|
||
|
|
})
|
||
|
|
.catch((error) => {
|
||
|
|
console.log('Could not unlock notification sound:', error);
|
||
|
|
this.notificationSound.muted = false;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
private playSound() {
|
||
|
|
this.notificationSound.currentTime = 0;
|
||
|
|
this.notificationSound.play().catch((error) => {
|
||
|
|
console.log('Could not play notification sound:', error);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
enableNotifications() {
|
||
|
|
this._notificationEnabled.set(true);
|
||
|
|
localStorage.setItem(this.notificationStorageKey, 'true');
|
||
|
|
}
|
||
|
|
|
||
|
|
disableNotifications() {
|
||
|
|
this._notificationEnabled.set(false);
|
||
|
|
localStorage.setItem(this.notificationStorageKey, 'false');
|
||
|
|
}
|
||
|
|
}
|