Files
pyramid/docs/feature-checklist.md
Bernd Steckmeister 25ed765a03 wip: Sicherungs-Commit aller Änderungen seit April + Arbeitsstruktur (CLAUDE.md, ROADMAP.md, PROGRESS.md, Autopilot)
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
2026-07-03 05:47:18 +02:00

18 KiB
Raw Permalink Blame History

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

  • Textnachrichten senden
  • Nachrichten empfangen & anzeigen
  • Zeitstempel (formatiert, relativ)
  • Nachrichtengruppierung (gleicher Sender, <5 Min.)
  • Datumstrennlinien zwischen Gruppen
  • Verschlüsselte Nachrichten anzeigen (Entschlüsselungsstatus)
  • Nachrichtenverlauf paginieren (ältere Nachrichten beim Scrollen laden)
  • Ungelesene-Nachrichten-Tracking
  • [~] Nachrichtenbearbeitung (Edit-Event erkannt, getDisplayEvent wird nicht gerendert) 🟠 P1
  • [~] Nachrichtenvorschau bei Reply (Zitat-Preview vorhanden, kein Jump-to-original) 🟡 P2

Nachrichtenaktionen

  • Nachrichtentext kopieren
  • Eigene Nachrichten löschen (redact)
  • Nachrichten anpinnen / Pinboard anzeigen
  • 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

  • Dateianhänge senden (mit MIME-Erkennung)
  • Bilder senden & inline anzeigen
  • Videos senden & inline abspielen
  • Audio senden & inline abspielen
  • Sticker anzeigen (m.sticker)
  • Dateianhang mit Untertitel
  • Dateigröße berechnen & anzeigen
  • Verschlüsselte Medien entschlüsseln & herunterladen
  • Thumbnail-Generierung für Bilder/Videos
  • [~] Sprachnachrichten (Struktur vorhanden, Wiedergabe-UI fehlt)
  • Animierte GIFs
  • Link-Vorschau (URL-Unfurling)
  • Dokument-Vorschau (PDF, Office)

Reaktionen

  • Emoji-Reaktionen senden
  • Reaktionszähler anzeigen
  • 6 häufigste Reaktionen als Schnellauswahl
  • Vollständiger Emoji-Picker mit Suche
  • Eigene Reaktion entfernen
  • Anzeigen wer reagiert hat
  • Mehrere Reaktionen pro Nachricht
  • 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)

  • Senden von m.read-Receipts via room.setReadMarker()
  • Privacy-Toggle (kein Senden wenn deaktiviert)
  • ✓-Icon (Nachricht gesendet/zugestellt) auf eigenen Nachrichten
  • ✓✓-Icon (gelesen) in DMs
  • 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

  • _UnreadDivider-Widget korrekt gestylt
  • _sessionFullyReadId einmalig beim Öffnen erfasst (stabil für die Session)
  • 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

  • _PresenceLine im DM-Header mit Live-Updates
  • 4s-Debounce gegen Sync-Spike-Fehlmeldungen
  • Relative Zeitanzeige (gerade eben / vor Xmin / vor Xh)
  • Guard: eigene Presence wird nie angezeigt
  • Presence-Dot im Rooms-Panel und Members-Panel
  • setPresence(online/offline) in den Settings
  • [~] Kein Auto-HeartbeatsetPresence 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)

  • Android Local Notifications (flutter_local_notifications)
  • Windows Toast-Notifications (local_notifier)
  • Windows Taskbar-Badge (Progress-Error-Mode)
  • Tap-Handler navigiert zum richtigen Raum (Android)
  • Guards: nur fremde Nachrichten, nur aktive Rooms, nur Membership.join
  • notificationsBlockedProvider + Banner in app_shell.dart
  • [~] Alle 4 Notification-Prefs werden ignoriertnotifDesktopProvider, 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

  • Vodozemac (Rust-Olm) via Flutter-Isolate — modern, performant
  • Bootstrap: SSSS, Cross-Signing, Online-Key-Backup
  • _decryptLegacyEvents — entschlüsselt ältere Events in-place
  • Device-Key-Preload vor erstem Senden
  • Key-Verification UI (SAS Emoji, QR-Code, alle States)
  • Megolm Session Export/Import (Element-kompatibles Format)
  • Encrypted-Attachment-Handling
  • m.fully_read-Marker beim Timeline-Open
  • 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-Handlerclient.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

  • Suchdialog öffnen (UI vorhanden)
  • Server-seitige Volltextsuche via Matrix /search API
  • Filter: Alle / Medien / Personen
  • Ergebnisse: Raum + Absender + Body + Zeitstempel
  • Keyboard-Navigation in Ergebnissen
  • 400ms Debounce
  • Jump-to-Message bei Klick auf Suchergebnis
  • Suche nach Absender filtern
  • Filter nach Datum
  • Suchergebnisse im Chat hervorheben
  • Suchverlauf

Raumverwaltung

Grundfunktionen

  • Raumliste anzeigen (sortiert nach letzter Aktivität)
  • Räume beitreten
  • Räume verlassen
  • Raumname & Avatar anzeigen
  • Verschlüsselungsstatus (Schloss-Icon)
  • 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)

  • 1:1 DM-Räume anzeigen & öffnen
  • Presence-Status des Gegenübers anzeigen
  • Echtzeit-Presence-Updates
  • Sprachanruf aus DM starten
  • Videoanruf aus DM starten
  • DM starten (neuen Chat beginnen)

Mitglieder & Rollen

  • Mitgliederliste anzeigen
  • Mitgliederanzahl anzeigen
  • Avatar & Anzeigename der Mitglieder
  • Nutzer in Raum einladen
  • Nutzer aus Raum entfernen (Kick)
  • Nutzer sperren (Ban)
  • Power Levels bearbeiten

Spaces & Gemeinschaften

  • Spaces in der Seitenleiste anzeigen
  • Zwischen Spaces navigieren
  • Space-Avatar & Banner anzeigen
  • Räume nach Space filtern
  • Unterkategorien (Sub-Spaces)
  • Drag-and-drop Kanalreihenfolge für Admins
  • Space-Verwaltungsdialog
  • Neuen Space erstellen
  • Räume zum Space hinzufügen / entfernen
  • Space-Entdeckung (öffentliche Spaces)

Sprach- & Videoanrufe (LiveKit)

  • Sprachkanal betreten / verlassen
  • Mikrofon stummschalten / Deafen
  • Teilnehmerliste im Sprachkanal
  • Anruf-UI (Vollansicht + Mini-Widget)
  • Videoanruf mit Kamera-Toggle
  • Klingelton bei eingehenden Anrufen
  • Anruf annehmen / ablehnen (UI)
  • Anrufdauer-Timer
  • Bildschirmfreigabe

Nutzereinstellungen & Profil

  • Hell / Dunkel-Theme, Akzentfarbe, Eckradius, Dichte
  • Eigene User-ID, Avatar (Initialen-Fallback), Anzeigename anzeigen
  • Anzeigenamen & Avatar bearbeiten
  • Passwort ändern
  • Sitzungsverwaltung
  • Konto deaktivieren

Auto-Update

  • GitHub-Releases als Update-Quelle
  • Versions-Vergleich (SemVer), Rate-Limiting, Update-Banner
  • "Diese Version überspringen"-Option
  • Automatischer Download & Installation

Plattform-spezifisch

Desktop

  • Native Desktop-App, Tastenkürzel, Drag-and-Drop
  • System-Tray-Integration
  • Fenster-State speichern (Größe, Position)

Mobile

  • 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 145168 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 ~408421 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.dartWidgetsBindingObserver)
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