Repository navigation
notifications
Zeigt die Liste der Benachrichtigungen (Likes, Follows, etc.) mit automatischer Aktualisierung.
Notifications werden im Tab "Meldungen" angezeigt und in der BottomNavigation mit einem Badge versehen, wenn ungelesene vorhanden sind.
app/src/main/kotlin/de/traewelling/app/ui/screens/NotificationScreen.ktapp/src/main/kotlin/de/traewelling/app/viewmodel/NotificationViewModel.ktapp/src/main/kotlin/de/traewelling/app/viewmodel/NotificationController.kt
-
loadNotifications(refresh)lädt eine Seite -
loadMore()lädt weitere Seiten (Pagination vialinks.next) -
refresh()lädt die erste Seite mit Pull-to-Refresh
Refresh beendet den alten Ladeauftrag und erhöht die Generation; eine ältere Seite darf die neue Liste nicht überschreiben. Pagination wartet auf laufenden Refresh und dedupliziert nach Meldungs-ID. Einträge ohne brauchbare ID werden nicht als ausführbare Meldung übernommen. Sessionwechsel beendet das gesamte Feature-ViewModel über den Auth-Store.
NotificationViewModel bleibt der Android-Lifecycle-Adapter mit unverändertem Anwendungskonstruktor und öffentlicher Aktions-API. NotificationController hält die accountbezogenen Zustände und erhält einen CoroutineScope sowie ein API-Gateway. Dadurch lassen sich echte verzögerte Listen-, Lese- und Zählerantworten ohne Android-Instanz überprüfen.
- Im
initwird ein Coroutine gestartet, der alle 60 SekundenrefreshUnreadCount()aufruft - Der Badge in der NavigationBar zeigt die Anzahl
Ein Mutex serialisiert Zähleranfragen. Zusätzlich tragen sie eine eigene Requestgeneration und den Stand der Leseänderungsrevision. Beginnt inzwischen ein neuer Zählerauftrag oder eine Leseaktion, darf die alte Antwort den Badge nicht überschreiben. Das gilt auch für parallele normale Anfragen aus Polling und Listenladen ohne zwischenzeitliches Lesen. HTTP-Fehler erzeugen keine erfolgreiche Nullantwort.
-
markAsRead(notificationId): Optimistic Update + API-Aufruf -
markAllAsRead(): Setzt alle auf gelesen - Tippen auf eine Meldung ruft nur für ungelesene Einträge
markAsRead()auf. Es gibt dabei keine Zielnavigation zum Profil oder zur Fahrt.
Unbekannte oder bereits gelesene IDs verringern den Badge nicht. Pro Meldung ist höchstens ein Leseauftrag offen; markAllAsRead und einzelne Leseaufträge überschneiden sich nicht. Neue Listenantworten erhalten noch offene optimistische Lesemarkierungen. Nach erfolgreichem Leseauftrag bleibt die konkrete ID zusätzlich bestätigt überlagert, auch nachdem pendingReads entfernt wurde. Erst ein danach gestarteter GET mit serverseitigem readAt beendet diese zusätzliche Überlagerung. Ein früher begonnener GET kann eine erfolgreich gelesene Meldung damit nicht erneut als ungelesen anzeigen.
markAllAsRead überlagert und bestätigt ausschließlich die beim Start bekannten IDs. Ein während des offenen PUT geladener neuer Eintrag kann nach dem Servercommit entstanden sein und bleibt entsprechend der Serverantwort ungelesen. Der Startzeitpunkt eines GET belegt nicht den Zeitpunkt seines Serversnapshots. Nach erfolgreichem PUT startet genau eine aktuelle erste Seite und beendet beziehungsweise sperrt ältere Listenaufträge; zuvor nicht geladene Einträge werden aus diesem neuen Serverstand übernommen, ohne globale Gelesen-Markierung.
Bei API-Fehler werden nur die eigenen vorläufigen Markierungen zurückgenommen. Der Badge erhält den bisherigen Zähler und mindestens die jetzt sichtbaren ungelesenen Einträge, einschließlich neuer Meldungen während des PUT, auch wenn der anschließende Count-GET fehlschlägt.
NotificationControllerTest prüft mit virtueller Coroutine-Zeit und gezielt zurückgehaltenen API-Antworten verspätete GETs nach erfolgreichem Lesen, neue Meldungen nach markAllAsRead, Rollback neben einem anderen laufenden Leseauftrag, Zählerserialisierung und abgebrochene Refreshs. NotificationReadStateTest ergänzt die lokalen Mapping-/Rollbackregeln. Es werden keine Zeit-Sleeps verwendet; siehe Tests.
- "Liked": Herz-Icon (Error-Farbe)
- "Follow": PersonAdd-Icon (Primary-Farbe)
- "Connection": Zug-Icon (Secondary-Farbe)
- "Mention": AlternateEmail-Icon
- Sonst: Notifications-Icon
- Lade-, Fehler- und Empty-States via
StateMessage - Benachrichtigungen werden als abgerundete Cards dargestellt
- Ungelesene Einträge erhalten einen farbigen linken Akzent, stärkere Elevation und ein
Neu-Badge
| Feld | Typ | Beschreibung |
|---|---|---|
notifications |
List | Liste aller Benachrichtigungen |
unreadCount |
Int | Anzahl ungelesener |
hasMore |
Boolean | Weitere Seiten verfügbar |
currentPage |
Int | Aktuelle Seiten-Nummer |
- TraewellingRepository: getNotifications, markNotificationRead, markAllNotificationsRead, getUnreadNotificationCount
- StateMessage: Einheitliche UI für Lade-, Fehler- und Empty-States
- TODO: Meldungen mit auflösbaren Zielinformationen zum zugehörigen Profil oder Status navigieren lassen.