feat(calendar): add event notifications with alert evaluation
Add client-side calendar event notification system that evaluates JMAP CalendarEventAlert triggers and displays toast notifications when alert times are reached. Includes configurable notification sound, acknowledged alert persistence, and proactive event fetching for background alerts. Also mounts ToastContainer globally to fix silent toast failures.
This commit is contained in:
@@ -1097,7 +1097,11 @@
|
||||
"default_calendar": "Standardkalender",
|
||||
"default_reminder": "Standarderinnerung",
|
||||
"time_format_12h": "12-Stunden",
|
||||
"time_format_24h": "24-Stunden"
|
||||
"time_format_24h": "24-Stunden",
|
||||
"notifications_enabled": "Ereignisbenachrichtigungen",
|
||||
"notifications_enabled_desc": "Benachrichtigungen für bevorstehende Termine anzeigen",
|
||||
"notification_sound": "Benachrichtigungston",
|
||||
"notification_sound_desc": "Ton für Kalenderbenachrichtigungen abspielen"
|
||||
},
|
||||
"days": {
|
||||
"monday": "Montag",
|
||||
@@ -1121,7 +1125,10 @@
|
||||
"event_deleted": "Termin gelöscht",
|
||||
"calendar_created": "Kalender erstellt",
|
||||
"calendar_deleted": "Kalender gelöscht",
|
||||
"event_move_error": "Termin konnte nicht verschoben werden"
|
||||
"event_move_error": "Termin konnte nicht verschoben werden",
|
||||
"alert_title": "Bevorstehender Termin",
|
||||
"alert_now": "Beginnt jetzt",
|
||||
"alert_in_minutes": "In {count} Min."
|
||||
},
|
||||
"status": {
|
||||
"loading_calendars": "Kalender werden geladen...",
|
||||
|
||||
@@ -1097,7 +1097,11 @@
|
||||
"default_calendar": "Default calendar",
|
||||
"default_reminder": "Default reminder",
|
||||
"time_format_12h": "12-hour",
|
||||
"time_format_24h": "24-hour"
|
||||
"time_format_24h": "24-hour",
|
||||
"notifications_enabled": "Event notifications",
|
||||
"notifications_enabled_desc": "Show alerts for upcoming calendar events",
|
||||
"notification_sound": "Notification sound",
|
||||
"notification_sound_desc": "Play a sound for calendar alerts"
|
||||
},
|
||||
"days": {
|
||||
"monday": "Monday",
|
||||
@@ -1121,7 +1125,10 @@
|
||||
"event_deleted": "Event deleted",
|
||||
"calendar_created": "Calendar created",
|
||||
"calendar_deleted": "Calendar deleted",
|
||||
"event_move_error": "Failed to move event"
|
||||
"event_move_error": "Failed to move event",
|
||||
"alert_title": "Upcoming event",
|
||||
"alert_now": "Starting now",
|
||||
"alert_in_minutes": "In {count} min"
|
||||
},
|
||||
"status": {
|
||||
"loading_calendars": "Loading calendars...",
|
||||
|
||||
@@ -1097,7 +1097,11 @@
|
||||
"default_calendar": "Calendario predeterminado",
|
||||
"default_reminder": "Recordatorio predeterminado",
|
||||
"time_format_12h": "12 horas",
|
||||
"time_format_24h": "24 horas"
|
||||
"time_format_24h": "24 horas",
|
||||
"notifications_enabled": "Notificaciones de eventos",
|
||||
"notifications_enabled_desc": "Mostrar alertas para eventos próximos",
|
||||
"notification_sound": "Sonido de notificación",
|
||||
"notification_sound_desc": "Reproducir un sonido para las alertas del calendario"
|
||||
},
|
||||
"days": {
|
||||
"monday": "Lunes",
|
||||
@@ -1121,7 +1125,10 @@
|
||||
"event_deleted": "Evento eliminado",
|
||||
"calendar_created": "Calendario creado",
|
||||
"calendar_deleted": "Calendario eliminado",
|
||||
"event_move_error": "Error al mover el evento"
|
||||
"event_move_error": "Error al mover el evento",
|
||||
"alert_title": "Evento próximo",
|
||||
"alert_now": "Comienza ahora",
|
||||
"alert_in_minutes": "En {count} min"
|
||||
},
|
||||
"status": {
|
||||
"loading_calendars": "Cargando calendarios...",
|
||||
|
||||
@@ -1097,7 +1097,11 @@
|
||||
"default_calendar": "Calendrier par défaut",
|
||||
"default_reminder": "Rappel par défaut",
|
||||
"time_format_12h": "12 heures",
|
||||
"time_format_24h": "24 heures"
|
||||
"time_format_24h": "24 heures",
|
||||
"notifications_enabled": "Notifications d'événements",
|
||||
"notifications_enabled_desc": "Afficher les alertes pour les événements à venir",
|
||||
"notification_sound": "Son de notification",
|
||||
"notification_sound_desc": "Jouer un son pour les alertes de calendrier"
|
||||
},
|
||||
"days": {
|
||||
"monday": "Lundi",
|
||||
@@ -1121,7 +1125,10 @@
|
||||
"event_deleted": "Événement supprimé",
|
||||
"calendar_created": "Calendrier créé",
|
||||
"calendar_deleted": "Calendrier supprimé",
|
||||
"event_move_error": "Échec du déplacement de l'événement"
|
||||
"event_move_error": "Échec du déplacement de l'événement",
|
||||
"alert_title": "Événement à venir",
|
||||
"alert_now": "Commence maintenant",
|
||||
"alert_in_minutes": "Dans {count} min"
|
||||
},
|
||||
"status": {
|
||||
"loading_calendars": "Chargement des calendriers...",
|
||||
|
||||
@@ -1097,7 +1097,11 @@
|
||||
"default_calendar": "Calendario predefinito",
|
||||
"default_reminder": "Promemoria predefinito",
|
||||
"time_format_12h": "12 ore",
|
||||
"time_format_24h": "24 ore"
|
||||
"time_format_24h": "24 ore",
|
||||
"notifications_enabled": "Notifiche eventi",
|
||||
"notifications_enabled_desc": "Mostra avvisi per gli eventi in arrivo",
|
||||
"notification_sound": "Suono di notifica",
|
||||
"notification_sound_desc": "Riproduci un suono per gli avvisi del calendario"
|
||||
},
|
||||
"days": {
|
||||
"monday": "Lunedì",
|
||||
@@ -1121,7 +1125,10 @@
|
||||
"event_deleted": "Evento eliminato",
|
||||
"calendar_created": "Calendario creato",
|
||||
"calendar_deleted": "Calendario eliminato",
|
||||
"event_move_error": "Spostamento dell'evento non riuscito"
|
||||
"event_move_error": "Spostamento dell'evento non riuscito",
|
||||
"alert_title": "Evento in arrivo",
|
||||
"alert_now": "Inizia ora",
|
||||
"alert_in_minutes": "Tra {count} min"
|
||||
},
|
||||
"status": {
|
||||
"loading_calendars": "Caricamento calendari...",
|
||||
|
||||
@@ -1097,7 +1097,11 @@
|
||||
"default_calendar": "デフォルトのカレンダー",
|
||||
"default_reminder": "デフォルトのリマインダー",
|
||||
"time_format_12h": "12時間制",
|
||||
"time_format_24h": "24時間制"
|
||||
"time_format_24h": "24時間制",
|
||||
"notifications_enabled": "イベント通知",
|
||||
"notifications_enabled_desc": "予定のイベントのアラートを表示する",
|
||||
"notification_sound": "通知音",
|
||||
"notification_sound_desc": "カレンダーアラートの音を鳴らす"
|
||||
},
|
||||
"days": {
|
||||
"monday": "月曜日",
|
||||
@@ -1121,7 +1125,10 @@
|
||||
"event_deleted": "予定を削除しました",
|
||||
"calendar_created": "カレンダーを作成しました",
|
||||
"calendar_deleted": "カレンダーを削除しました",
|
||||
"event_move_error": "イベントの移動に失敗しました"
|
||||
"event_move_error": "イベントの移動に失敗しました",
|
||||
"alert_title": "予定のイベント",
|
||||
"alert_now": "まもなく開始",
|
||||
"alert_in_minutes": "{count}分後"
|
||||
},
|
||||
"status": {
|
||||
"loading_calendars": "カレンダーを読み込み中...",
|
||||
|
||||
@@ -1097,7 +1097,11 @@
|
||||
"default_calendar": "Standaardagenda",
|
||||
"default_reminder": "Standaardherinnering",
|
||||
"time_format_12h": "12-uurs",
|
||||
"time_format_24h": "24-uurs"
|
||||
"time_format_24h": "24-uurs",
|
||||
"notifications_enabled": "Evenementmeldingen",
|
||||
"notifications_enabled_desc": "Meldingen weergeven voor aankomende evenementen",
|
||||
"notification_sound": "Meldingsgeluid",
|
||||
"notification_sound_desc": "Geluid afspelen voor agendameldingen"
|
||||
},
|
||||
"days": {
|
||||
"monday": "Maandag",
|
||||
@@ -1121,7 +1125,10 @@
|
||||
"event_deleted": "Evenement verwijderd",
|
||||
"calendar_created": "Agenda aangemaakt",
|
||||
"calendar_deleted": "Agenda verwijderd",
|
||||
"event_move_error": "Evenement verplaatsen mislukt"
|
||||
"event_move_error": "Evenement verplaatsen mislukt",
|
||||
"alert_title": "Aankomend evenement",
|
||||
"alert_now": "Begint nu",
|
||||
"alert_in_minutes": "Over {count} min"
|
||||
},
|
||||
"status": {
|
||||
"loading_calendars": "Agenda's laden...",
|
||||
|
||||
@@ -1097,7 +1097,11 @@
|
||||
"default_calendar": "Calendário padrão",
|
||||
"default_reminder": "Lembrete padrão",
|
||||
"time_format_12h": "12 horas",
|
||||
"time_format_24h": "24 horas"
|
||||
"time_format_24h": "24 horas",
|
||||
"notifications_enabled": "Notificações de eventos",
|
||||
"notifications_enabled_desc": "Mostrar alertas para eventos próximos",
|
||||
"notification_sound": "Som de notificação",
|
||||
"notification_sound_desc": "Reproduzir um som para alertas do calendário"
|
||||
},
|
||||
"days": {
|
||||
"monday": "Segunda-feira",
|
||||
@@ -1121,7 +1125,10 @@
|
||||
"event_deleted": "Evento excluído",
|
||||
"calendar_created": "Calendário criado",
|
||||
"calendar_deleted": "Calendário excluído",
|
||||
"event_move_error": "Falha ao mover o evento"
|
||||
"event_move_error": "Falha ao mover o evento",
|
||||
"alert_title": "Evento próximo",
|
||||
"alert_now": "Começa agora",
|
||||
"alert_in_minutes": "Em {count} min"
|
||||
},
|
||||
"status": {
|
||||
"loading_calendars": "Carregando calendários...",
|
||||
|
||||
Reference in New Issue
Block a user