Skip to content

Commit

Permalink
More fixes to SSE code (#374)
Browse files Browse the repository at this point in the history
* Enhance notification handling in settingsBase.html

- Refactored notification management to utilize a unique ID for each notification.
- Updated the subscription to the SSEManager to use a class property for better context handling.
- Cleaned up event listeners on component destruction to prevent memory leaks.

* Enhance SSE initialization and notification handling in settingsBase.html

- Added logging for SSE connection initialization and re-initialization checks.
- Introduced an 'initialized' flag to prevent multiple SSE connections.
- Improved notification handling by ensuring unique IDs and managing notification removal with animations.
- Cleaned up event listeners on component destruction to prevent memory leaks.
  • Loading branch information
tphakala authored Jan 9, 2025
1 parent 3251595 commit 111e591
Showing 1 changed file with 58 additions and 35 deletions.
93 changes: 58 additions & 35 deletions views/settings/settingsBase.html
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,11 @@
return; // Already initialized
}

console.log('SSE: Initializing new connection');
this.eventSource = new EventSource('/sse');
this.eventSource.onmessage = (event) => {
const notification = JSON.parse(event.data);

this.notificationCallbacks.forEach(callback => callback(notification));
};

Expand Down Expand Up @@ -105,28 +107,43 @@
notifications: [],
hasChanges: false,
saving: false,
handleNotification: null,
initialized: false,
init() {
// Subscribe to notifications using the singleton SSE manager
const handleNotification = (notification) => {
this.addNotification(notification.message, notification.type);
if (this.initialized) {
console.log('SSE: Already initialized for this component');
return;
}
this.handleNotification = (notification) => {
const id = Date.now() + Math.random();
this.notifications.push({
id: id,
message: notification.message,
type: notification.type,
removing: false
});
setTimeout(() => {
const index = this.notifications.findIndex(n => n.id === id);
if (index !== -1) {
this.notifications[index].removing = true;
setTimeout(() => {
this.notifications = this.notifications.filter(n => n.id !== id);
}, 300);
}
}, 5000);
};
window.SSEManager.subscribe(handleNotification);
window.SSEManager.init(); // Initialize if not already done
window.SSEManager.subscribe(this.handleNotification);
window.SSEManager.init();
// Cleanup on component destroy
this.$cleanup(() => {
window.SSEManager.unsubscribe(handleNotification);
this.$el.addEventListener('alpine:destroyed', () => {
window.SSEManager.unsubscribe(this.handleNotification);
});
},
addNotification(message, type) {
const id = Date.now();
this.notifications.push({ id, message, type });
setTimeout(() => {
this.notifications = this.notifications.filter(n => n.id !== id);
}, 5000);
this.initialized = true;
},
isFormValid(form) {
const inputSelector = 'input[type=\'password\'][required], input[type=\'text\'][required]';
Expand Down Expand Up @@ -168,8 +185,6 @@
const security = Alpine.store('security');
if (security?.hasChanges) {
setTimeout(() => {
this.notifications = []; // Clear existing notifications
this.addNotification('Settings saved, reloading page...', 'success');
setTimeout(() => window.location.reload(), 1500);
}, 50);
} else {
Expand Down Expand Up @@ -203,27 +218,35 @@

<div class="fixed bottom-5 right-5 z-50 flex flex-col space-y-2">
<template x-for="notification in notifications" :key="notification.id">
<div x-show="!notification.removing" :class="{
<div x-show="!notification.removing"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 transform translate-x-8"
x-transition:enter-end="opacity-100 transform translate-x-0"
x-transition:leave="transition ease-in duration-300"
x-transition:leave-start="opacity-100 transform translate-x-0"
x-transition:leave-end="opacity-0 transform translate-x-8"
:class="{
'alert-success': notification.type === 'success',
'alert-error': notification.type === 'error',
'alert-info': notification.type === 'info'
}" class="alert">
}"
class="alert shadow-lg">
<div class="flex items-start">
<svg x-show="notification.type === 'success'" xmlns="http://www.w3.org/2000/svg"
class="stroke-current flex-shrink-0 h-6 w-6 mr-2" fill="none" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<svg x-show="notification.type === 'error'" xmlns="http://www.w3.org/2000/svg"
class="stroke-current flex-shrink-0 h-6 w-6 mr-2" fill="none" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<svg x-show="notification.type === 'info'" xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 24 24" class="stroke-current flex-shrink-0 w-6 h-6 mr-2">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
<template x-if="notification.type === 'success'">
<svg xmlns="http://www.w3.org/2000/svg" class="stroke-current flex-shrink-0 h-6 w-6 mr-2" fill="none" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
</template>
<template x-if="notification.type === 'error'">
<svg xmlns="http://www.w3.org/2000/svg" class="stroke-current flex-shrink-0 h-6 w-6 mr-2" fill="none" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
</template>
<template x-if="notification.type === 'info'">
<svg xmlns="http://www.w3.org/2000/svg" class="stroke-current flex-shrink-0 h-6 w-6 mr-2" fill="none" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
</template>
<span x-text="notification.message"></span>
</div>
</div>
Expand Down

0 comments on commit 111e591

Please sign in to comment.