docs: State-Management-Ist-Analyse + Umbauplan (M2), ROADMAP-Punkt annotiert
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
# 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 1–2 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:66–71`). 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, direkt von `widgets/mxc_image.dart` benutzt. Kein
|
||||
UI-Zustand, nur Cache – geringer Schaden, leicht hinter einen
|
||||
`Provider<MediaCache>` zu legen.
|
||||
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. **[frei] `MediaCache` hinter `Provider<MediaCache>`** und die
|
||||
`.instance`-Zugriffe in `mxc_image.dart` auf `ref` umstellen –
|
||||
risikoarm, jederzeit möglich, guter 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 1–3 umgesetzt und die
|
||||
Kernflows (Login, Raum, Nachricht, Voice-Join) nach jedem Schritt
|
||||
praktisch geprüft; Punkt 4 braucht nur den Doku-Vermerk (steht hiermit).
|
||||
Reference in New Issue
Block a user