25ed765a03
6 Wochen uncommittete Arbeit (Voice-Channels, LiveKit-Manager, Settings-Modal u.v.m.) als ein WIP-Commit gesichert, damit nichts verloren geht und der Pi den aktuellen Stand klonen kann. Thematische Aufarbeitung: siehe ROADMAP M0. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CPrAGBxBT6GfPXzeWQ4AXb
425 lines
18 KiB
Markdown
425 lines
18 KiB
Markdown
# Matrix / Element Feature Checklist für Pyramid
|
||
|
||
*Stand: April 2026 — Pyramid v0.1.x (Early Development)*
|
||
*Letzte Tiefenanalyse: 2026-04-29 (Vergleich mit FluffyChat / Element Web)*
|
||
|
||
---
|
||
|
||
## Legende
|
||
|
||
- ✅ `[x]` — Implementiert und funktioniert korrekt
|
||
- ⚠️ `[~]` — Teilweise / fehlerhaft implementiert (Details in Technische Analyse)
|
||
- ❌ `[ ]` — Fehlt komplett
|
||
- 🔴 P0 — Kritisch (Kernfunktionalität kaputt)
|
||
- 🟠 P1 — Hoch (wichtige Funktion defekt oder nicht vorhanden)
|
||
- 🟡 P2 — Mittel
|
||
- 🔵 P3 — Niedrig / Nice-to-have
|
||
|
||
---
|
||
|
||
## Nachrichten (Messaging)
|
||
|
||
### Kern-Funktionen
|
||
- [x] Textnachrichten senden
|
||
- [x] Nachrichten empfangen & anzeigen
|
||
- [x] Zeitstempel (formatiert, relativ)
|
||
- [x] Nachrichtengruppierung (gleicher Sender, <5 Min.)
|
||
- [x] Datumstrennlinien zwischen Gruppen
|
||
- [x] Verschlüsselte Nachrichten anzeigen (Entschlüsselungsstatus)
|
||
- [x] Nachrichtenverlauf paginieren (ältere Nachrichten beim Scrollen laden)
|
||
- [x] Ungelesene-Nachrichten-Tracking
|
||
- [~] Nachrichtenbearbeitung (Edit-Event erkannt, `getDisplayEvent` wird nicht gerendert) 🟠 P1
|
||
- [~] Nachrichtenvorschau bei Reply (Zitat-Preview vorhanden, kein Jump-to-original) 🟡 P2
|
||
|
||
### Nachrichtenaktionen
|
||
- [x] Nachrichtentext kopieren
|
||
- [x] Eigene Nachrichten löschen (redact)
|
||
- [x] Nachrichten anpinnen / Pinboard anzeigen
|
||
- [x] Auf Nachrichten antworten (in-reply-to)
|
||
- [ ] Nachrichten weiterleiten
|
||
- [ ] Zitat-Styling (visuelle Blockquote-Anzeige)
|
||
|
||
### Textformatierung (formatted_body)
|
||
- [~] Markdown-Rendering — `formatted_body` / `org.matrix.custom.html` wird nicht gesendet und nicht gerendert 🔵 P3
|
||
- [ ] Fett (**text**)
|
||
- [ ] Kursiv (*text*)
|
||
- [ ] Durchgestrichen (~~text~~)
|
||
- [ ] Inline-Code (`code`)
|
||
- [ ] Code-Block (```code```)
|
||
- [ ] Aufzählungslisten
|
||
- [ ] Klickbare Links
|
||
- [~] @Erwähnungen — Button vorhanden, `onTap: null` 🟡 P2
|
||
- [ ] #Kanal-Erwähnungen
|
||
- [ ] Spoiler-Tags (||text||)
|
||
|
||
### Medien & Anhänge
|
||
- [x] Dateianhänge senden (mit MIME-Erkennung)
|
||
- [x] Bilder senden & inline anzeigen
|
||
- [x] Videos senden & inline abspielen
|
||
- [x] Audio senden & inline abspielen
|
||
- [x] Sticker anzeigen (m.sticker)
|
||
- [x] Dateianhang mit Untertitel
|
||
- [x] Dateigröße berechnen & anzeigen
|
||
- [x] Verschlüsselte Medien entschlüsseln & herunterladen
|
||
- [x] Thumbnail-Generierung für Bilder/Videos
|
||
- [~] Sprachnachrichten (Struktur vorhanden, Wiedergabe-UI fehlt)
|
||
- [ ] Animierte GIFs
|
||
- [ ] Link-Vorschau (URL-Unfurling)
|
||
- [ ] Dokument-Vorschau (PDF, Office)
|
||
|
||
### Reaktionen
|
||
- [x] Emoji-Reaktionen senden
|
||
- [x] Reaktionszähler anzeigen
|
||
- [x] 6 häufigste Reaktionen als Schnellauswahl
|
||
- [x] Vollständiger Emoji-Picker mit Suche
|
||
- [x] Eigene Reaktion entfernen
|
||
- [x] Anzeigen wer reagiert hat
|
||
- [x] Mehrere Reaktionen pro Nachricht
|
||
- [x] Kategoriebasierte Emoji-Organisation
|
||
|
||
### Tipp-Indikatoren (Typing)
|
||
- [~] `room.setTyping()` wird **nirgendwo aufgerufen** — Einstellung existiert, aber Composer sendet nie "tippt…" 🟡 P2
|
||
- [ ] "X tippt gerade"-Anzeige empfangen (kein Widget)
|
||
- [ ] Timeout nach Tipp-Ende
|
||
|
||
### Threads
|
||
- [~] Thread-Button vorhanden (`onPressed: () {}` — leer) 🔵 P3
|
||
- [ ] Thread aufklappen / eigene Ansicht
|
||
- [ ] Thread-Benachrichtigungen
|
||
- [ ] Thread als gelöst markieren
|
||
|
||
---
|
||
|
||
## Lesebestätigungen (Read Receipts)
|
||
|
||
- [x] Senden von `m.read`-Receipts via `room.setReadMarker()`
|
||
- [x] Privacy-Toggle (kein Senden wenn deaktiviert)
|
||
- [x] ✓-Icon (Nachricht gesendet/zugestellt) auf eigenen Nachrichten
|
||
- [x] ✓✓-Icon (gelesen) in DMs
|
||
- [x] Sende-Status (Uhr/Fehler/gesendet/gelesen)
|
||
- [~] ✓✓-Logik nur für DMs — in Gruppenräumen wird `receiptState.global.otherUsers` nicht ausgewertet 🟡 P2
|
||
- [~] **Off-by-one**: Divider erscheint *über* der Gruppe die das `fullyRead`-Event enthält, nicht darunter 🟡 P2
|
||
- [ ] Gruppen-Read-Receipt-Display (Seen-by-Avatare wie in FluffyChat) 🟡 P2
|
||
- [ ] Hover-Tooltip "Gelesen von: ..." auf ✓✓
|
||
- [ ] **Notification-Cancellation**: `cancelNotification(roomId)` beim Setzen des Read-Markers 🟡 P2
|
||
|
||
---
|
||
|
||
## „Neue Nachrichten" Trennlinie
|
||
|
||
- [x] `_UnreadDivider`-Widget korrekt gestylt
|
||
- [x] `_sessionFullyReadId` einmalig beim Öffnen erfasst (stabil für die Session)
|
||
- [x] Keine Anzeige wenn Raum bereits gelesen
|
||
- [~] **Position falsch** — Divider über der Gruppe mit `fullyRead`-Event statt darunter 🟡 P2
|
||
- [ ] **Auto-Scroll zum Divider** beim Öffnen eines Raums mit ungelesenen Nachrichten 🟡 P2
|
||
|
||
---
|
||
|
||
## Presence / Zuletzt Online
|
||
|
||
- [x] `_PresenceLine` im DM-Header mit Live-Updates
|
||
- [x] 4s-Debounce gegen Sync-Spike-Fehlmeldungen
|
||
- [x] Relative Zeitanzeige (gerade eben / vor Xmin / vor Xh)
|
||
- [x] Guard: eigene Presence wird nie angezeigt
|
||
- [x] Presence-Dot im Rooms-Panel und Members-Panel
|
||
- [x] `setPresence(online/offline)` in den Settings
|
||
- [~] **Kein Auto-Heartbeat** — `setPresence` nur in Settings, nie periodisch während Nutzung 🔵 P3
|
||
- [~] **Kein `WidgetsBindingObserver`** — App-Lifecycle (Hintergrund/Vordergrund) löst kein Presence-Event aus 🔵 P3
|
||
- [ ] Presence-Dot in DM-Listen-Items (`room_list_item.dart`) 🔵 P3
|
||
|
||
---
|
||
|
||
## Benachrichtigungen
|
||
|
||
### Local Notifications (App im Vordergrund)
|
||
- [x] Android Local Notifications (`flutter_local_notifications`)
|
||
- [x] Windows Toast-Notifications (`local_notifier`)
|
||
- [x] Windows Taskbar-Badge (Progress-Error-Mode)
|
||
- [x] Tap-Handler navigiert zum richtigen Raum (Android)
|
||
- [x] Guards: nur fremde Nachrichten, nur aktive Rooms, nur `Membership.join`
|
||
- [x] `notificationsBlockedProvider` + Banner in `app_shell.dart`
|
||
- [~] **Alle 4 Notification-Prefs werden ignoriert** — `notifDesktopProvider`, `notifSoundProvider`, `notifPreviewProvider`, `notifMentionOnlyDmProvider` haben keinen Effekt 🟠 P1
|
||
- [~] Android-Grouping ohne Summary-Notification 🔵 P3
|
||
|
||
### Remote Push (App im Hintergrund / geschlossen)
|
||
- [ ] 🔴 **Keine Remote-Push-Integration** — FCM/UnifiedPush fehlt komplett, App muss laufen
|
||
- [ ] iOS APNs-Setup
|
||
- [ ] macOS-Notifications
|
||
- [ ] Android Icon-Badge (Zahlenbadge)
|
||
|
||
---
|
||
|
||
## E2EE Verschlüsselungs-Pipeline
|
||
|
||
### Implementiert
|
||
- [x] Vodozemac (Rust-Olm) via Flutter-Isolate — modern, performant
|
||
- [x] Bootstrap: SSSS, Cross-Signing, Online-Key-Backup
|
||
- [x] `_decryptLegacyEvents` — entschlüsselt ältere Events in-place
|
||
- [x] Device-Key-Preload vor erstem Senden
|
||
- [x] Key-Verification UI (SAS Emoji, QR-Code, alle States)
|
||
- [x] Megolm Session Export/Import (Element-kompatibles Format)
|
||
- [x] Encrypted-Attachment-Handling
|
||
- [x] `m.fully_read`-Marker beim Timeline-Open
|
||
- [x] `timeline.requestKeys(onlineKeyBackupOnly: false)`
|
||
|
||
### Fehlerhaft / Fehlend
|
||
- [~] **"Entschlüsselt…"-Placeholder bleibt dauerhaft** wenn Key fehlt — kein Recovery-Button 🟠 P1
|
||
- [~] `loadAllKeysFromRoom` Fehler werden silent geschluckt (`catch (_) {}`) 🟡 P2
|
||
- [~] **Kein Incoming-Verification-Request-Handler** — `client.onKeyVerificationRequest` wird nicht abonniert 🔴 P0
|
||
- [~] **Doppelte Bootstrap-Implementierung** (page vs. dialog) mit leicht inkonsistenter Logik 🔵 P3
|
||
- [ ] Device-Trust-Indicator in der Timeline 🔵 P3
|
||
- [ ] Unverified-Device-Warning beim Senden 🔵 P3
|
||
- [ ] "Schlüssel anfordern"-Button bei dauerhaft verschlüsselten Events 🟠 P1
|
||
|
||
---
|
||
|
||
## Suche
|
||
|
||
- [x] Suchdialog öffnen (UI vorhanden)
|
||
- [x] Server-seitige Volltextsuche via Matrix `/search` API
|
||
- [x] Filter: Alle / Medien / Personen
|
||
- [x] Ergebnisse: Raum + Absender + Body + Zeitstempel
|
||
- [x] Keyboard-Navigation in Ergebnissen
|
||
- [x] 400ms Debounce
|
||
- [ ] Jump-to-Message bei Klick auf Suchergebnis
|
||
- [ ] Suche nach Absender filtern
|
||
- [ ] Filter nach Datum
|
||
- [ ] Suchergebnisse im Chat hervorheben
|
||
- [ ] Suchverlauf
|
||
|
||
---
|
||
|
||
## Raumverwaltung
|
||
|
||
### Grundfunktionen
|
||
- [x] Raumliste anzeigen (sortiert nach letzter Aktivität)
|
||
- [x] Räume beitreten
|
||
- [x] Räume verlassen
|
||
- [x] Raumname & Avatar anzeigen
|
||
- [x] Verschlüsselungsstatus (Schloss-Icon)
|
||
- [x] Einladungen annehmen / ablehnen
|
||
- [ ] Neuen Raum erstellen (UI-Einstiegspunkt)
|
||
- [ ] Raumname bearbeiten
|
||
- [ ] Raumthema/Beschreibung bearbeiten
|
||
- [ ] Raum-Avatar ändern
|
||
- [ ] Raumvisibilität (öffentlich / privat)
|
||
- [ ] Verlaufsvisibilität konfigurieren
|
||
|
||
### Direktnachrichten (DMs)
|
||
- [x] 1:1 DM-Räume anzeigen & öffnen
|
||
- [x] Presence-Status des Gegenübers anzeigen
|
||
- [x] Echtzeit-Presence-Updates
|
||
- [x] Sprachanruf aus DM starten
|
||
- [x] Videoanruf aus DM starten
|
||
- [ ] DM starten (neuen Chat beginnen)
|
||
|
||
### Mitglieder & Rollen
|
||
- [x] Mitgliederliste anzeigen
|
||
- [x] Mitgliederanzahl anzeigen
|
||
- [x] Avatar & Anzeigename der Mitglieder
|
||
- [x] Nutzer in Raum einladen
|
||
- [ ] Nutzer aus Raum entfernen (Kick)
|
||
- [ ] Nutzer sperren (Ban)
|
||
- [ ] Power Levels bearbeiten
|
||
|
||
---
|
||
|
||
## Spaces & Gemeinschaften
|
||
|
||
- [x] Spaces in der Seitenleiste anzeigen
|
||
- [x] Zwischen Spaces navigieren
|
||
- [x] Space-Avatar & Banner anzeigen
|
||
- [x] Räume nach Space filtern
|
||
- [x] Unterkategorien (Sub-Spaces)
|
||
- [x] Drag-and-drop Kanalreihenfolge für Admins
|
||
- [x] Space-Verwaltungsdialog
|
||
- [ ] Neuen Space erstellen
|
||
- [ ] Räume zum Space hinzufügen / entfernen
|
||
- [ ] Space-Entdeckung (öffentliche Spaces)
|
||
|
||
---
|
||
|
||
## Sprach- & Videoanrufe (LiveKit)
|
||
|
||
- [x] Sprachkanal betreten / verlassen
|
||
- [x] Mikrofon stummschalten / Deafen
|
||
- [x] Teilnehmerliste im Sprachkanal
|
||
- [x] Anruf-UI (Vollansicht + Mini-Widget)
|
||
- [x] Videoanruf mit Kamera-Toggle
|
||
- [ ] Klingelton bei eingehenden Anrufen
|
||
- [ ] Anruf annehmen / ablehnen (UI)
|
||
- [ ] Anrufdauer-Timer
|
||
- [ ] Bildschirmfreigabe
|
||
|
||
---
|
||
|
||
## Nutzereinstellungen & Profil
|
||
|
||
- [x] Hell / Dunkel-Theme, Akzentfarbe, Eckradius, Dichte
|
||
- [x] Eigene User-ID, Avatar (Initialen-Fallback), Anzeigename anzeigen
|
||
- [ ] Anzeigenamen & Avatar bearbeiten
|
||
- [ ] Passwort ändern
|
||
- [ ] Sitzungsverwaltung
|
||
- [ ] Konto deaktivieren
|
||
|
||
---
|
||
|
||
## Auto-Update
|
||
|
||
- [x] GitHub-Releases als Update-Quelle
|
||
- [x] Versions-Vergleich (SemVer), Rate-Limiting, Update-Banner
|
||
- [x] "Diese Version überspringen"-Option
|
||
- [ ] Automatischer Download & Installation
|
||
|
||
---
|
||
|
||
## Plattform-spezifisch
|
||
|
||
### Desktop
|
||
- [x] Native Desktop-App, Tastenkürzel, Drag-and-Drop
|
||
- [ ] System-Tray-Integration
|
||
- [ ] Fenster-State speichern (Größe, Position)
|
||
|
||
### Mobile
|
||
- [x] Mobile App (Flutter), Drawer-Navigation
|
||
- [ ] Touch-optimiertes UI
|
||
- [ ] Mobile Push-Benachrichtigungen
|
||
|
||
---
|
||
|
||
---
|
||
|
||
# Technische Tiefenanalyse (2026-04-29)
|
||
|
||
*Vergleichsbasis: FluffyChat (krille-chan/fluffychat) und Element Web*
|
||
*Format: Befund → betroffene Datei:Zeile → Referenz-Implementierung*
|
||
|
||
---
|
||
|
||
## IMPLEMENTIERUNGS-BACKLOG (nach Priorität)
|
||
|
||
### 🔴 P0 — Kritisch
|
||
|
||
#### [P0-1] Incoming Key-Verification-Request-Handler fehlt
|
||
**Problem:** Wenn ein anderes Gerät eine Verifikations-Anfrage (`m.key.verification.request`) an Pyramid schickt, gibt es keinen Listener. Die Anfrage läuft ab, ohne dass der Nutzer sie sieht. Das bedeutet: andere Geräte können Pyramid de facto nicht verifizieren — nur Pyramid kann aktiv verifizieren.
|
||
**Betroffene Datei:** `lib/widgets/settings_modal.dart` (kein `onKeyVerificationRequest`-Listener)
|
||
**FluffyChat-Referenz:** `lib/pages/key_verification/key_verification_dialog.dart` + `client.onKeyVerificationRequest.stream.listen(...)` in `lib/pages/matrix.dart`
|
||
**Fix:** Stream auf `client.onKeyVerificationRequest` in `matrix_client.dart` oder `app_shell.dart` subscriben und `KeyVerificationDialog` öffnen.
|
||
|
||
---
|
||
|
||
### 🟠 P1 — Hoch
|
||
|
||
#### [P1-1] Notification-Prefs werden ignoriert
|
||
**Problem:** `notifDesktopProvider`, `notifSoundProvider`, `notifPreviewProvider`, `notifMentionOnlyDmProvider` sind in `settings_prefs.dart` gespeichert, werden in `notification_service.dart/_watchEvents()` aber nie ausgelesen. Notifications erscheinen immer, unabhängig von Nutzereinstellungen.
|
||
**Betroffene Datei:** `lib/core/notification_service.dart`, Zeile 145–168
|
||
**Fix:** In `_watchEvents()` die Prefs vor `showMessageNotification()` prüfen.
|
||
|
||
#### [P1-2] Edits werden nicht gerendert
|
||
**Problem:** `_isVisible()` filtert Edit-Events korrekt heraus, aber `event.getDisplayEvent(timeline)` wird nirgendwo aufgerufen. Nachrichten zeigen immer die Originalversion, auch wenn sie via `m.replace` bearbeitet wurden. Ein `(bearbeitet)`-Label fehlt ebenfalls.
|
||
**Betroffene Datei:** `lib/features/chat/message_group.dart` — Event-Rendering-Bereich
|
||
**FluffyChat-Referenz:** `event.getDisplayEvent(timeline)` vor dem Rendern jedes Events
|
||
**Fix:** Beim Rendern von Events `event.getDisplayEvent(timeline)` statt `event` verwenden; `(bearbeitet)`-Label wenn `event != displayEvent`.
|
||
|
||
#### [P1-3] Encrypted-Placeholder bleibt dauerhaft — kein Recovery-Button
|
||
**Problem:** `EventTypes.Encrypted` zeigt "Nachricht wird entschlüsselt…" dauerhaft wenn die Entschlüsselung scheitert. Es gibt keinen Button zum Anfordern fehlender Keys.
|
||
**Betroffene Datei:** `lib/features/chat/message_group.dart`, Zeilen ~408–421
|
||
**FluffyChat-Referenz:** `_requestMissingKey()` mit `room.client.sendToDeviceEncrypted(...)` / SDK-`requestKey()`
|
||
**Fix:** Wenn `event.status == EventStatus.error` oder nach Timeout immer noch `EventTypes.Encrypted`: "Schlüssel anfordern"-Button anzeigen, der `timeline.requestKeys()` aufruft.
|
||
|
||
---
|
||
|
||
### 🟡 P2 — Mittel
|
||
|
||
#### [P2-1] Typing-Indikator: `room.setTyping()` nie aufgerufen
|
||
**Problem:** `privacyTypingProvider` existiert, `chat_composer.dart` ruft aber nie `room.setTyping()` auf. Andere Nutzer sehen nie "X tippt gerade…".
|
||
**Betroffene Datei:** `lib/features/chat/chat_input.dart` (oder `chat_composer.dart`)
|
||
**FluffyChat-Referenz:** `onInputBarChanged` → 2s Debounce → `room.setTyping(true, timeout: 30000)`; bei Senden/Leerfeld: `room.setTyping(false)`
|
||
**Fix:** Im Composer-Input `onChanged`-Handler mit Debounce und `room.setTyping()` ergänzen.
|
||
|
||
#### [P2-2] Typing-Indikator: Kein Display-Widget
|
||
**Problem:** Kein Widget das `room.typingUsers` anzeigt.
|
||
**Fix:** `_TypingIndicator`-Widget in `chat_view.dart` unter der Nachrichtenliste einfügen, das `room.onUpdate`-Stream abonniert und `room.typingUsers` anzeigt.
|
||
|
||
#### [P2-3] Unread-Divider: Position off-by-one
|
||
**Problem:** Divider erscheint *über* der Gruppe die das `fullyRead`-Event *enthält*, nicht darunter. Das bereits-gelesene Event liegt unter dem "Neue Nachrichten"-Strich.
|
||
**Betroffene Datei:** `lib/features/chat/chat_view.dart`, Zeile ~715
|
||
**Fix:** Divider nach der Gruppe einsetzen, die das `fullyReadId`-Event enthält, nicht davor.
|
||
|
||
#### [P2-4] Unread-Divider: Kein Auto-Scroll beim Öffnen
|
||
**Problem:** Beim Öffnen eines Raums mit ungelesenen Nachrichten landet die View unten, nicht beim Divider.
|
||
**FluffyChat-Referenz:** Initialer `scrollController.jumpTo()` zum Index des `fullyRead`-Events nach dem ersten Frame.
|
||
**Fix:** In `initState`/`WidgetsBinding.addPostFrameCallback` zum Divider-Index springen wenn `_sessionHasUnread`.
|
||
|
||
#### [P2-5] Gruppen-Read-Receipts fehlen
|
||
**Problem:** ✓✓-Logik greift nur bei `room.isDirectChat`. In Gruppenräumen sehen eigene Nachrichten nie ✓✓.
|
||
**FluffyChat-Referenz:** `SeenByRow` zeigt Avatare aller Leser unter der letzten Nachricht.
|
||
**Fix:** Receipt-Prüfung auch in Gruppenräumen aktivieren; ggf. Avatar-Reihe unter letzter Nachricht.
|
||
|
||
#### [P2-6] Notification-Cancellation beim Lesen fehlt
|
||
**Problem:** Android-Notifications bleiben in der Benachrichtigungsleiste stehen, auch wenn der Chat geöffnet und die Nachrichten gelesen wurden.
|
||
**FluffyChat-Referenz:** `backgroundPush?.cancelNotification(roomId)` in `_markRead()`
|
||
**Fix:** In `_markRead()` in `chat_view.dart` die Android-Notification für `roomId` canceln.
|
||
|
||
---
|
||
|
||
### 🔵 P3 — Niedrig
|
||
|
||
#### [P3-1] Presence: Kein Auto-Heartbeat
|
||
**Problem:** `setPresence(online)` nur in Settings — Server setzt Client nach Timeout offline.
|
||
**Fix:** Periodischer Timer (alle 60s) der `setPresence(online)` sendet solange App im Vordergrund.
|
||
|
||
#### [P3-2] Presence: Kein App-Lifecycle-Hook
|
||
**Problem:** Kein `WidgetsBindingObserver` — kein `unavailable` bei App-Hintergrund.
|
||
**Fix:** `WidgetsBindingObserver.didChangeAppLifecycleState` in `matrix_client.dart` oder `app_shell.dart`.
|
||
|
||
#### [P3-3] Markdown/`formatted_body` nicht gerendert
|
||
**Problem:** `sendTextEvent` sendet nur plain text. Empfangene `formatted_body`-Felder werden nicht gerendert.
|
||
**Fix:** Empfang: `flutter_html` oder `flutter_markdown` für `formatted_body`; Senden: simple Markdown-Erkennung im Composer.
|
||
|
||
#### [P3-4] `requestFuture()` fehlt
|
||
**Problem:** Kein Forward-Pagination-Mechanismus. Nach Jump-to-Event in der Vergangenheit kein Weg zurück.
|
||
**Fix:** `timeline.requestFuture()` im Scroll-Listener für die Vorwärts-Richtung.
|
||
|
||
#### [P3-5] `message_bubble.dart` — ungenutzter Code
|
||
**Problem:** Veraltete WhatsApp-Style-Implementation koexistiert neben aktiver Discord-Style-Implementierung.
|
||
**Fix:** Datei löschen oder auskommentieren.
|
||
|
||
---
|
||
|
||
## Statistik
|
||
|
||
| Bereich | Implementiert | Fehlerhaft | Fehlend |
|
||
|---|---|---|---|
|
||
| Chat-Mechanik | Solide Basis | Edits, Typing, `requestFuture` | Jump-to-quote, Threads, Edited-Badge |
|
||
| Read Receipts | DM-Logik ✓ | Gruppen, Off-by-one, Notif-Cancel | Seen-by-Avatare, Tooltip |
|
||
| Presence | Anzeige ✓ | Broadcasting, Lifecycle | Heartbeat, Dot in Raumliste |
|
||
| Benachrichtigungen | Local ✓ | Prefs ignoriert, Grouping | Remote Push, iOS, macOS |
|
||
| Unread-Divider | Konzept ✓ | Position, Auto-Scroll | — |
|
||
| E2EE | Stärkster Bereich | Incoming-Verif., Placeholder | Device-Trust-Indicator, Warn beim Senden |
|
||
| Suche | API-Basis ✓ | — | Jump-to-message, Filter |
|
||
|
||
**Implementierungsgrad gesamt: ~42 %** (inkl. Teilimplementierungen)
|
||
|
||
---
|
||
|
||
## Implementierungs-Fortschritt
|
||
|
||
| ID | Beschreibung | Status |
|
||
|---|---|---|
|
||
| P0-1 | Incoming Key-Verification-Request-Handler | ✅ War bereits implementiert (`app_shell.dart`) |
|
||
| P1-1 | Notification-Prefs auswerten | ✅ Implementiert (`notification_service.dart`) |
|
||
| P1-2 | Edits rendern (`getDisplayEvent`) | ✅ Implementiert (`message_group.dart`) |
|
||
| P1-3 | Encrypted-Placeholder + Recovery-Button | ✅ Implementiert (`message_group.dart`) |
|
||
| P2-1 | Typing: `room.setTyping()` senden | ✅ Implementiert (`chat_composer.dart`) |
|
||
| P2-2 | Typing: Display-Widget | ✅ Implementiert (`chat_view.dart` — `_TypingIndicator`) |
|
||
| P2-3 | Unread-Divider: Position + leere fullyRead-Guard | ✅ Neu implementiert (`chat_view.dart`) |
|
||
| P2-4 | Unread-Divider: Auto-Scroll (Schätzung) | ✅ Implementiert (`_scrollToUnread`) |
|
||
| P2-5 | Gruppen-Read-Receipts (DM-Guard entfernt) | ✅ Implementiert (`chat_view.dart`) |
|
||
| P2-6 | Notification-Cancellation beim Lesen | ✅ Implementiert (`chat_view.dart/_markRead`) |
|
||
| P3-1 | Presence: Auto-Heartbeat (10s) | ✅ Implementiert (`app_shell.dart`) |
|
||
| P3-2 | Presence: App-Lifecycle-Hook | ✅ Implementiert (`app_shell.dart` — `WidgetsBindingObserver`) |
|
||
| P3-3 | HTML/Markdown (`_MatrixHtmlText`, `_PlainLinkText`) | ✅ Implementiert (`message_group.dart`) |
|
||
| P3-4 | `requestFuture()` | ✅ Implementiert (`chat_view.dart/_onScroll`) |
|
||
| P3-5 | `message_bubble.dart` entfernen | ⏳ Offen |
|