custom-notification-bell
Version:
A customizable notification bell component
120 lines (103 loc) • 3.32 kB
text/typescript
class NotificationService {
url: string;
socket: any;
subscribers: Array<(notifications: any[]) => void>;
notificationCache: any[];
isConnected: boolean;
reconnectAttempts: number;
maxReconnectAttempts: number;
constructor(url: string) {
this.url = url;
this.socket = null;
this.subscribers = [];
this.notificationCache = [];
this.isConnected = false;
this.reconnectAttempts = 0;
this.maxReconnectAttempts = 5;
}
connect() {
this.socket = new WebSocket(this.url);
this.socket.onopen = () => {
this.isConnected = true;
this.reconnectAttempts = 0;
console.log('WebSocket connected');
this.socket.send(JSON.stringify({
event: 'handshake',
userId: this.url.split('?')[1].split('=')[1]
}));
};
this.socket.onmessage = (event: any) => {
console.log('event', event);
const notification = JSON.parse(event.data);
switch (notification.event) {
case 'notification':
this.notificationCache = [{ data: notification.data }];
this.notifySubscribers();
break;
case 'newnotification':
const currentCount = this.notificationCache[0]?.count ?? 0;
const increment = typeof notification.data === "number" ? notification.data : 1;
this.notificationCache = [{ data: currentCount + increment }];
this.notifySubscribers();
break;
default:
break;
}
// if (notification.event === 'notification') {
// // this.notificationCache.unshift(notification);
// this.notificationCache = [{ data: notification.data }];
// this.notifySubscribers();
// }
};
this.socket.onclose = () => {
this.isConnected = false;
console.log('WebSocket disconnected');
this.attemptReconnect();
};
this.socket.onerror = (error: any) => {
console.error('WebSocket error:', error);
};
}
attemptReconnect() {
if (this.reconnectAttempts < this.maxReconnectAttempts) {
this.reconnectAttempts++;
const delay = Math.min(1000 * this.reconnectAttempts, 5000);
setTimeout(() => {
console.log(`Reconnection attempt ${this.reconnectAttempts}`);
this.connect();
}, delay);
}
}
subscribe(callback: any) {
this.subscribers.push(callback);
return () => {
this.subscribers = this.subscribers.filter(sub => sub !== callback);
};
}
notifySubscribers() {
this.subscribers.forEach(callback => callback([...this.notificationCache]));
}
dismissNotification(id: string | string[]) {
console.log('dismissnotification', id);
if (this.isConnected) {
this.socket.send(JSON.stringify({
event: 'markRead',
data: {
userId: this.url.split('?')[1].split('=')[1],
NotificationId: id
}
}));
}
this.notificationCache = this.notificationCache.filter(n => n.id !== id);
this.notifySubscribers();
}
getNotificationCount() {
return this.notificationCache.length;
}
disconnect() {
if (this.socket) {
this.socket.close();
}
}
}
export default NotificationService;