_ReplyPreview nutzt den Sprung-Mechanismus der Suche (pendingJumpEventProvider).
Der Sprung scrollt jetzt schrittweise Richtung aeltere Nachrichten, wenn das
Ziel zwar geladen, aber in der lazy ListView noch nicht gezeichnet ist (vorher
gab er dann nach 40 Versuchen auf); dasselbe Zitat darf erneut angetippt
werden. UI-Durchlauf prueft den Sprung per Screenshot.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Bernds Feedback 2026-10-07:
- Schrift-Standard Handy 110 % (statt 115 %).
- PyrIconBtn: im Handy-Layout Symbol 22 px (vorher fest 16), Flaeche 40,
Tippflaeche 44; Farben aus dem Farbmodus statt fest verdrahtet.
- Eingabeleiste: Anhaengen/GIF/Emoji/Senden auf dem Handy 22-23 px statt
12-13 px.
- Chat-Kopf (Handy): Anrufen + Videoanruf sichtbar, Suchen + Mitglieder im
Drei-Punkte-Menue.
- Aufklappbarer DM-Kopf als Ebenen: Zurueck + Symbole bleiben oben,
Profilbereich gleitet darunter und nutzt die volle Breite (vorher Name zu
"p..." gekuerzt, Symbole rutschten in die Mitte); Kuerzel im Avatar
mittig, skaliert mit.
- SpringPress (widgets/spring_press.dart): federnde Druck-Rueckmeldung,
aus bei "Animationen 0 %".
Co-Authored-By: Claude Opus 5.5 <[email protected]>
- rooms_mobile_tile.dart: auf dem Handy grosser Avatar, Name + Uhrzeit der
letzten Nachricht, Vorschau (gleiche Texte wie Push: Medien-Labels,
Antwort-Zitat entfernt; "Du:" bzw. Absender in Gruppen), Ungelesen-Zaehler.
PC behaelt die kompakte Liste, Voice-Kanaele ihre Darstellung.
- utils/date_labels.dart: chatListTime (heute Uhrzeit, Gestern, Wochentag,
Datum; sicher an Zeitumstellungs-Tagen) + 5 Tests.
- Sichtbare englische Texte eingedeutscht (Chats durchsuchen,
Direktnachrichten, Raeume, Nachricht..., Mitglieder, Suchen, ...).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Bernds Entscheidungen 2026-10-07:
- theme.dart: ThemeVariant (Dunkel = neues weiches Dunkelgrau als Standard,
Schwarz = bisheriges Fast-Schwarz, Hell) mit PyramidPalette; Nebentexte
kontrastreicher. Alte Einstellung theme_dark wird uebernommen
(dunkel -> weiches Dunkel). Fest verdrahtete Dunkelfarben im Profil-Popup
und GIF-Picker folgen jetzt dem Farbmodus.
- appearance.dart: Schriftgroesse = Pyramid-Regler x Systemeinstellung
(Handy-Standard 115 %, PC 100 %), MessageStyle Automatisch/Sprechblasen/
Liste, gemeinsame isMobileLayout-Regel.
- message_bubbles.dart: Sprechblasen-Darstellung (eigene rechts in
Akzentfarbe, Gruppen mit Name + Avatar, Bilder ohne Blase in voller Groesse);
Listen-Darstellung unveraendert, Weiche in MessageGroup.
- Formatierte Nachrichten (u. a. Antworten) nutzten RichText ohne
Schriftskalierung -> erschienen kleiner; jetzt Text.rich.
- Einstellungen auf dem Handy als ganze Seite, Schalter unter dem Text.
- UI-Durchlauf um Liste/Hell/Gruppe/Einstellungen erweitert; Tests fuer
Theme-Varianten, Uebernahme alter Werte, Schriftfaktor, Darstellung.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Mit zwei echten Test-Accounts (zwei GUI-Instanzen via PYRAMID_PROFILE_DIR)
durchgeklickt: Beitreten, Teilnehmerliste, bidirektionaler Screenshare,
Live-Qualitaetswechsel (Full HD 60fps), sauberes Verlassen.
- rooms_list.dart: Voice-Channel in der normalen Raumliste war per Klick
nicht beitretbar (oeffnete nur Chat) -> _toggleVoiceChannel wie Space-Liste.
- livekit_call_manager.dart: _callGeneration entwertet laufenden connect
bei Auflegen/Wechsel (keine Geisterverbindung mit offenem Mikro);
Fehlerpfade setzen error sichtbar statt still zu verschwinden.
- rooms_panel_core.dart: raeumt activeVoiceRoomIdProvider auf, wenn der
Voice-Service inaktiv wird, + Fehler-SnackBar.
- test/live_call_setup_test.dart: gegateter Setup-Helfer fuer den Testraum.
UNGETESTET: echtes 2-Peer-Audio, Netz-Abbruch mitten im Call.
Co-Authored-By: Claude Fable 5 <[email protected]>
Nach docs/STREAMING_60FPS.md: neue Presets 720p/1080p mit 60 FPS und
hoher Bitrate (5/8 Mbit/s), Preset-Aufloesung+FPS werden jetzt bis in
die Capture-Constraints durchgereicht (vorher blieb der LiveKit-Default
1080p/15 aktiv), 60-FPS-Presets publishen ohne Simulcast mit
DegradationPreference.maintainFramerate (unter Last Aufloesung statt
Frames opfern). contentHint 'motion' ist in flutter_webrtc 1.4.1 aus
Dart nicht setzbar (geprueft) - im Code dokumentiert.
4 neue Vertragstests fuer die Preset-Tabellen.
Co-Authored-By: Claude Fable 5 <[email protected]>
- CallSignalingService/callSignalingProvider und VoiceChannelService/
voiceChannelProvider als einzige oeffentliche Schnittstellen
- voip_manager.dart / livekit_call_manager.dart in ihre Module verschoben,
Logik unangetastet (nur Klassen-Koepfe, @override, Imports, Provider-Namen)
- Alle Konsumenten entkoppelt; Kompositions-Punkt matrix_client.dart als
dokumentierte Ausnahme. analyze sauber, 29 Tests gruen, Windows-Start ok.
Call-Klick-/Geraetetest steht aus (PROGRESS.md)
Qualitäts-Review-Befund (b): Der Refresh-Token-Fix (9dc83f7) war richtig
analysiert, aber unvollständig – drei Restlücken gegen das matrix-SDK
6.2.0 verifiziert und geschlossen:
1. Client._handleSoftLogout ruft bei JEDEM Refresh-Fehler logout() auf,
und logout() macht 'finally clear()' – die lokale Session inkl.
Krypto-Schlüssel wird selbst bei einem transienten Netzwerkfehler
zerstört. Mit refreshToken:true laufen Access-Tokens künftig ab,
Refreshes werden Routine – das Restrisiko wäre also GESTIEGEN.
Fix: eigener onSoftLogout-Handler (soft_logout_guard.dart) mit
3 Versuchen, der nie wirft → SDK ruft nie logout() auf; bei
Dauerfehler bleibt der Client soft-logged-out und der nächste
Sync versucht es erneut (CLAUDE.md: Fehlerpfade dürfen NIE in
einem stillen Logout enden).
2. Das Push-Hintergrund-Isolate (background_push.dart) teilt sich die
pyramid.sqlite mit der Haupt-App; getEventByPushNotification()
ruft ensureNotSoftLoggedOut() auf. Ohne Guard hätte ein
Refresh-Fehler im Isolate (inkl. Token-Rotations-Race mit der
Haupt-App) die Session der GESAMTEN App gelöscht. Guard auch dort
gesetzt; das Race heilt der Retry, weil refreshAccessToken() den
Token bei jedem Versuch frisch aus der DB liest.
3. isLoggedInProvider behandelte softLoggedOut wie ausgeloggt – die UI
wäre bei jedem Routine-Token-Refresh kurz auf den Login-Screen
gesprungen (für Nutzer nicht von einem 'Random Logout' zu
unterscheiden). Jetzt zählt nur echtes loggedOut.
UNGETESTET (Pi) – gehört zum selben ausstehenden PC-Praxistest wie
9dc83f7: Login → Nachrichten → Logout → Neu-Login → alte Nachrichten
lesbar; zusätzlich auth_log.txt auf die neuen Guard-Einträge prüfen.
Co-Authored-By: Claude Fable 5 <[email protected]>
Qualitäts-Review-Befund (a): Alle 6 part/part-of-Aufteilungen hatten Code
vollständig übernommen (Zeilen-Multiset-Vergleich Original vs. heutiger
Stand: keine Code-Zeile verloren, keine hinzugefügt), ABER erklärende
Kommentare über den Klassen gingen verloren (24 Blöcke, u. a. die
HTML-Subset-Doku über _MatrixHtmlText, die Selbst-Aussperr-Warnung über
updatePowerLevelsSafely, TURN-Verbrauchskarte, PDF-Cache/Viewer-Doku).
Alle an den richtigen Klassen wiederhergestellt; reine Trennlinien und
ALL-CAPS-Abschnittslabels bewusst nicht (Gott-Datei-Navigation, durch
die neuen Dateinamen ersetzt).
Co-Authored-By: Claude Fable 5 <[email protected]>
Sechster Durchgang derselben part/part-of-Technik wie bei den 5 vorigen
Umbauten - reine Verschiebung, keine Logikänderung. document_viewer.dart
schrumpft von 1773 auf 20 Zeilen (nur noch Bibliothekskopf), 34
Top-Level-Bloecke (31 Klassen/Enums + 3 lose Funktionen) auf 5 thematische
Dateien unter lib/features/chat/document/ verteilt. Verifiziert per
automatisiertem Blockvergleich gegen das Original und flutter analyze
(weiterhin nur 1 bekannter Hinweis).
voice_channel.dart und app_shell.dart bewusst nicht angefasst - haengen an
der noch unentschiedenen Call-Fassade bzw. dem Bootstrap/Login-Pfad.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Fünfter und letzter Durchgang der part/part-of-Aufteilung - reine
Verschiebung, keine Logikänderung. chat_view.dart schrumpft von 2116 auf
33 Zeilen (nur noch Bibliothekskopf). Verifiziert per automatisiertem
Blockvergleich gegen das Original und flutter analyze.
Damit sind alle 5 in der M2-Ist-Analyse gefundenen Gott-Dateien aufgeteilt;
ROADMAP-Punkt "Toten Code & Duplikate entfernen, Ordnerstruktur
vereinheitlichen" abgehakt.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Gleiche Technik wie bei den vorigen drei Umbauten: reine Verschiebung per
Dart part/part-of, keine Logikänderung. space_admin_dialog.dart schrumpft
von 2278 auf 19 Zeilen (nur noch Bibliothekskopf). Verifiziert per
automatisiertem Blockvergleich gegen das Original und flutter analyze.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Gleiche Technik wie bei settings_modal.dart/message_group.dart: reine
Verschiebung per Dart part/part-of, keine Logikänderung. rooms_panel.dart
schrumpft von 2555 auf 31 Zeilen (nur noch Bibliothekskopf). Verifiziert
per automatisiertem Blockvergleich gegen das Original und flutter analyze.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Gleiche Technik wie bei settings_modal.dart: reine Verschiebung per Dart
part/part-of, keine Logikänderung. message_group.dart schrumpft von 2775
auf 30 Zeilen (nur noch Bibliothekskopf). Verifiziert per automatisiertem
Blockvergleich gegen das Original und flutter analyze (Baseline unverändert).
Co-Authored-By: Claude Sonnet 5 <[email protected]>
message_bubble.dart war vollständig unbenutzt (durch message_group.dart
abgelöst). Die zwei identischen _formatTime-Methoden in message_group.dart
zu einer Top-Level-Funktion zusammengeführt - reine Extraktion, keine
Verhaltensänderung. flutter analyze bleibt sauber.
Beide Logout-Bestätigungsdialoge prüfen jetzt vorab per neuem
isKeyBackupMissing(client) (bootstrap_dialog.dart), ob Cross-Signing/
Key-Backup eingerichtet ist. Fehlt es, zeigt der Dialog eine
Klartext-Warnung: alte verschlüsselte Nachrichten wären nach dem
Logout auf keinem Gerät mehr lesbar. Ohne fehlendes Backup bleibt der
bisherige Text unverändert.
Ursache gefunden: Ohne Refresh-Token eskaliert das matrix-SDK jeden
Soft-Logout (z. B. abgelaufenes Access-Token, M_UNKNOWN_TOKEN mit
soft_logout=true) automatisch zu einem echten, destruktiven Logout —
_handleSoftLogout() versucht refreshAccessToken(), das ohne
gespeicherten Refresh-Token sofort mit "No refresh token available"
scheitert, und ruft danach client.logout() auf (client.dart:2374-2384
im matrix-Paket, Version 6.2.0).
Mit refreshToken: true beim Login bekommt der Client vom Server einen
Refresh-Token und kann einen Soft-Logout künftig durch stillen
Token-Refresh überstehen, statt die Sitzung zu zerstören. Falls der
Server keine Refresh-Tokens unterstützt, bleibt das Verhalten
unverändert (response.refreshToken ist dann null).
Wichtig: gilt nur für neue Logins. Bereits eingeloggte Geräte (z. B.
Uta) profitieren erst nach einmaligem Neu-Login. Zur Diagnose siehe
den mit 63e4919 eingeführten AuthLog.
UNGETESTET (Pi, kein GUI/Login hier möglich) – nächster PC-Lauf muss
den vollen Kreislauf prüfen: Login → Nachrichten → Logout → erneuter
Login → alte verschlüsselte Nachrichten noch lesbar?
- document_viewer: Matrix4.translate/scale durch translateByDouble/
scaleByDouble ersetzt (PDF-Zoom-Transformation, gleiches Verhalten)
- rooms_panel: onReorder durch onReorderItem ersetzt (Index-Korrektur
jetzt intern erledigt), implementation_imports-Hinweis kommentiert
(SpaceChild wird vom matrix-Paket nicht öffentlich exportiert)
- voip_manager: getSources()-Override kommentiert (erzwungen durch
abstrakte MediaDevices-Klasse, die die Methode selbst deprecated hat)
- settings_modal: BuildContext-Nutzung nach await mit context.mounted
abgesichert (Geräte umbenennen, Passwort-Abfrage bei Massenlogout)
Verbleibend: chat_provider.dart onUpdate (Timeline-Redecrypt-Pfad,
bewusst nicht angefasst ohne dedizierten E2EE-Test, siehe PROGRESS.md).
Ungenutzte Imports (dart:typed_data, flutter/services.dart), unnötige
String-Interpolations-Klammern, führender Unterstrich bei lokaler Funktion,
fehlende Blockklammern bei if-Statements und SCREAMING_CASE-Konstanten in
clipboard_image.dart auf lowerCamelCase umbenannt. Rein mechanisch, keine
Verhaltensänderung.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Dart 3 erlaubt mehrere Wildcard-Parameter mit demselben Namen "_" in
einem Scope, daher sind __ / ___ für ungenutzte Callback-Parameter
(pageBuilder, errorBuilder etc.) unnötig. Rein mechanische Änderung,
keine Verhaltensänderung.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Entfernt tatsächlich toten Code, den flutter analyze als Warning markiert
hatte: unbenutzte Felder/Parameter (_saved, _hovered wird jetzt für Hover-
Feedback genutzt, destructive-Flag ohne Aufrufer, size-Parameter ohne
Override), unerreichbaren dead_code (Room.topic/Space.topic sind laut SDK
nie null, client.database ist nie null) sowie Legacy-Funktionen aus der
alten Push-Architektur (_showNotif/_fetchTitle, ersetzt durch natives
PushService.kt) und einen leeren Noise-Suppression-Stub ohne Aufrufer.
Keine funktionale Verhaltensänderung an aktiven Code-Pfaden.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
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 <[email protected]>
Claude-Session: https://claude.ai/code/session_01CPrAGBxBT6GfPXzeWQ4AXb
open_file_plus 3.4.1 uses deprecated PluginRegistry.Registrar API incompatible
with current Flutter. Replaced with a MethodChannel in MainActivity.kt that calls
FileProvider.getUriForFile() and launches the system package installer directly.
Also rework chat_input: 4px border radius on desktop, vPad 18px, 56px send button.
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>