AltitudeWeb/frontend/src/app/pages/altitude/chat/service/chat-notification.service.ts

111 lines
3.0 KiB
TypeScript
Raw Normal View History

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<Record<string, boolean>>(
this.getStoredNotificationSettings()
);
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(server: string, title: string, body: string | null) {
if (!this.isNotificationEnabled(server)) {
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);
});
}
public isNotificationEnabled(server: string): boolean {
return this._notificationEnabled()[server];
}
enableNotifications(server: string) {
this.setNotificationEnabled(server, true);
}
disableNotifications(server: string) {
this.setNotificationEnabled(server, false);
}
private setNotificationEnabled(server: string, enabled: boolean) {
const notificationSettings = {
...this._notificationEnabled(),
[server]: enabled
};
this._notificationEnabled.set(notificationSettings);
localStorage.setItem(this.notificationStorageKey, JSON.stringify(notificationSettings));
}
private getStoredNotificationSettings(): Record<string, boolean> {
const storedSettings = localStorage.getItem(this.notificationStorageKey);
if (storedSettings === null) {
return {};
}
if (storedSettings === 'true' || storedSettings === 'false') {
return {};
}
try {
return JSON.parse(storedSettings) as Record<string, boolean>;
} catch {
return {};
}
}
}