Files
pyramid/docs/M2_STATE_MANAGEMENT.md
T
Bernd Steckmeister 3300a44c4a docs: State-Management-Doc korrigiert - MediaCache-Umstellung ist NICHT risikoarm (Chat-Timeline haengt dran), zurueckgestellt
Der erste Befund beruhte auf einem durch head-limit abgeschnittenen grep;
message_media.dart (am wenigsten geprueft laut PC_TESTPLAN 3) nutzt den
Cache ebenfalls, inkl. statischem Wrapper ohne ref-Zugang.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 17:52:09 +02:00

5.4 KiB
Raw Blame History

M2 Einheitliches State-Management: Ist-Analyse + Umbauplan

STATUS 2026-07-06: reine Analyse, noch KEIN Umbau. Grundlage für den ROADMAP-M2-Punkt „Einheitliches State-Management (Riverpod konsequent, keine Misch-Patterns)". Die Schritte 12 unten betreffen den heiligen Call-Pfad und sind GESPERRT, bis Bernds Klick-Test des Call-Piloten (docs/PC_TESTPLAN.md Abschnitt 8) grün ist vorher nur Schritt 3.

Ist-Stand (repo-weit erhoben, 2026-07-06)

Riverpod ist bereits das dominante Muster: rund 50 Provider StateProvider für UI-Zustand, StreamProvider auf client.onSync, FutureProvider (Client, Update-Info), StateNotifierProvider für die Prefs-Notifier (BoolPref/StringSetPref in core/settings_prefs.dart). ValueNotifier/eigene StreamController gibt es NICHT. Lokales setState in Widgets für rein ephemeren Zustand (Hover, Dialog-Schritte, Textfelder) ist normales Flutter und zählt hier bewusst NICHT als Misch-Pattern.

Gefundene Misch-Patterns, nach Gewicht:

  1. Call-Schicht: Singletons + ChangeNotifier hinter den Fassaden. LiveKitCallManager.instance (static final Singleton, features/voice_channel/livekit_call_manager.dart:17) und PyramidVoipManager._instance (nullable static, features/call_signaling/voip_manager.dart:17; konstruiert im Kompositions-Punkt core/matrix_client.dart:6671). Die Modul-Provider (voiceChannelProvider/callSignalingProvider) geben nur die Singletons zurück. Das ist die im Pilot BEWUSST gewählte Zwischenform (Verhaltensgleichheit vor Schönheit). Eigentliches Problem: UI-Zustand (Mute-Flags, Teilnehmer, Renderer, Qualitätswahl) lebt mutierbar IN den Managern und wird per notifyListeners() grob-granular publiziert.
  2. Voice-UI-Zustand außerhalb des Moduls: activeVoiceRoomIdProvider und voiceParticipantsProvider liegen in core/app_state.dart (Kopplungspunkt laut Ist-Analyse), werden aber von Rooms-Panel und Mini-Call-Widget gesetzt/gelesen und gehören fachlich ins voice_channel-Modul (Join-Zustand + Presence sind Modulsache).
  3. MediaCache.instance (core/media_cache.dart:19): reines Singleton, kein UI-Zustand, nur Cache. Nutzer sind widgets/mxc_image.dart (7 Stellen, Widgets leicht umstellbar) UND features/chat/message/message_media.dart (7 Stellen, darunter der statische Wrapper _DocBytesCache für Dokument-Vorschauen, dessen Aufrufer keinen ref-Zugang haben). Eine Umstellung müsste ref/die Cache-Instanz durch die statischen Helfer der Chat-Timeline fädeln und genau dieser Code (Download-/Entschlüsselungs-Fehlerpfade) ist laut PC_TESTPLAN Abschnitt 3 der am wenigsten geprüfte Teil der App.
  4. Push/Notifications: modul-globale Mutable-Zustände in core/notification_service.dart (_windowsNotifs-Map, Plugin-Globals) und direkte SharedPreferences-Zugriffe in background_push.dart/ fcm_push_service.dart. Das ist dem Background-Isolate-Zwang geschuldet (siehe Schnitt-Doc Punkt 8 + Memory „Pyramid Push") bewusst KEIN Umbau-Kandidat, nur hier dokumentiert.

Bereits erledigt im Zuge dieser Analyse: der seit dem Call-Piloten tote incomingCallProvider ist aus app_state.dart entfernt (41bcaf2).

Zielbild

  • core/app_state.dart enthält nur noch ECHTEN App-weiten UI-Zustand (Theme, Layout/Panels, Navigation, Toast, Space-Auswahl) kein Feature-Fachzustand.
  • Feature-Zustand lebt im jeweiligen Modul hinter dessen Provider; andere Module lesen ihn NUR über die öffentliche Schnittstelle.
  • Kein .instance-Zugriff über Modulgrenzen; Konstruktion ausschließlich im Kompositions-Punkt bzw. im Provider des Moduls.
  • ChangeNotifier ist als Übergangsform ok; Endzustand der Call-Module ist ein immutables Zustandsobjekt (z. B. VoiceChannelState) pro Modul, das der Provider publiziert, plus Kommando-Methoden auf dem Service (entspricht dem Schnitt-Doc-Entwurf, dort als Stream skizziert).

Schrittfolge (Reihenfolge = Priorität)

  1. [GESPERRT bis Klick-Test] UI-State aus den Managern herauslösen: je Call-Modul ein immutables Zustandsobjekt + Notifier/ StateNotifier, Manager wird interne Implementierung ohne UI-Zustand. Das ist der bereits in PROGRESS.md zurückgestellte Logik-Umbau NICHT vorher anfangen (heiliger Call-Pfad, ein ungetesteter Umbau liegt schon auf dem Stapel).
  2. [GESPERRT bis Klick-Test] activeVoiceRoomIdProvider + voiceParticipantsProvider ins voice_channel-Modul umziehen (zusammen mit kVoicePresenceType). Mechanisch klein, aber Call-Pfad-nah sinnvoll im selben Zug wie Schritt 1.
  3. [ZURÜCKGESTELLT] MediaCache hinter Provider<MediaCache>: Erst als „risikoarm, jederzeit" eingestuft das stimmte NICHT (Korrektur 2026-07-06, siehe Ist-Stand Punkt 3: auch die Chat-Timeline hängt dran, inkl. statischer Helfer ohne ref). Gehört in den Zug des chat_timeline-Moduls (Schnitt-Doc Punkt 9) bzw. frühestens nach dem Klick-Test von PC_TESTPLAN Abschnitt 3 nicht als Lückenfüller.
  4. [kein Umbau] Push/Notifications: bleibt wie es ist (Isolate-Zwang); nur bei ohnehin anstehenden Push-Arbeiten die Prefs-Zugriffe auf die Prefs-Fassade ziehen (Schnitt-Doc Punkt 6).

Abhak-Kriterium für den ROADMAP-Punkt: Schritte 13 umgesetzt und die Kernflows (Login, Raum, Nachricht, Voice-Join) nach jedem Schritt praktisch geprüft; Punkt 4 braucht nur den Doku-Vermerk (steht hiermit).