Add notification support with enable/disable functionality and sound effects for new messages.
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
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');
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import {ChatMessage} from '@pages/altitude/chat/objects/chat-message.object';
|
||||
import {RawChatMessage} from '@pages/altitude/chat/objects/raw-chat-message.object';
|
||||
import {normalizeComponent} from '@pages/altitude/chat/mini-message/normalize.util';
|
||||
import {ChatServer} from '@pages/altitude/chat/objects/chat-server.object';
|
||||
import {NotificationService} from '@pages/altitude/chat/service/chat-notification.service';
|
||||
|
||||
export interface ChatEvent {
|
||||
type: string;
|
||||
@@ -18,6 +19,7 @@ interface SsePayloadEvent {
|
||||
@Injectable({providedIn: 'root'})
|
||||
export class ChatService implements OnDestroy {
|
||||
private eventSource?: EventSourcePolyfill;
|
||||
private readonly notificationService: NotificationService = inject(NotificationService);
|
||||
private readonly authService: AuthService = inject(AuthService)
|
||||
private readonly _messages = signal<ChatMessage[]>([])
|
||||
public readonly messages = computed(() => this._messages().filter((message) => message.server === this._selectedServer()).sort((a, b) => b.timestamp - a.timestamp));
|
||||
@@ -58,6 +60,7 @@ export class ChatService implements OnDestroy {
|
||||
find.unreadMessages++;
|
||||
}
|
||||
})
|
||||
this.notificationService.notify(`(${chatMessages.length}) new messages`, null);
|
||||
});
|
||||
|
||||
source.onerror = (err) => {
|
||||
|
||||
Reference in New Issue
Block a user