- NotificationInterface: add sendInfo() and sendWarning() levels - SymfonyNotification: implement new levels (publishes to 'notifications' topic) - ChapterScrapingStarted: carry mangaTitle + chapterNumber, now dispatched - ScrapeChapterHandler: dispatch ChapterScrapingStarted before scraping loop - ScrapingEventSubscriber: wire NotificationInterface for started/scraped/failed events - useMercureNotifications: new global Vue composable subscribing to 'notifications' topic - App.vue: mount useMercureNotifications() at app root - SendTestNotificationCommand: `app:notify:test --type --message` for dev/prod testing Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
46 lines
1.4 KiB
JavaScript
46 lines
1.4 KiB
JavaScript
import { onMounted, onBeforeUnmount } from 'vue';
|
|
import { useNotifications } from './useNotifications';
|
|
|
|
export function useMercureNotifications() {
|
|
const { showSuccess, showError, showInfo, showWarning } = useNotifications();
|
|
let eventSource = null;
|
|
|
|
const handleNotification = data => {
|
|
const message = data.message ?? 'Notification';
|
|
switch (data.status) {
|
|
case 'success': showSuccess(message); break;
|
|
case 'error': showError(message); break;
|
|
case 'warning': showWarning(message); break;
|
|
default: showInfo(message);
|
|
}
|
|
};
|
|
|
|
const setup = () => {
|
|
const url = new URL('/.well-known/mercure', window.location.origin);
|
|
url.searchParams.append('topic', 'notifications');
|
|
|
|
eventSource = new EventSource(url, { withCredentials: true });
|
|
|
|
eventSource.onmessage = event => {
|
|
try {
|
|
const data = JSON.parse(event.data);
|
|
handleNotification(data);
|
|
} catch (e) {
|
|
console.error('useMercureNotifications: erreur de parsing', e);
|
|
}
|
|
};
|
|
|
|
eventSource.onerror = () => {
|
|
eventSource?.close();
|
|
setTimeout(setup, 5000);
|
|
};
|
|
};
|
|
|
|
onMounted(setup);
|
|
|
|
onBeforeUnmount(() => {
|
|
eventSource?.close();
|
|
eventSource = null;
|
|
});
|
|
}
|