import 'package:flutter/widgets.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc; import 'package:matrix/matrix.dart'; import 'package:pyramid/features/call_signaling/voip_manager.dart'; /// Öffentliche Schnittstelle des Moduls `call_signaling` – natives /// Matrix-1:1-VoIP (`m.call.*`-Events, direkte WebRTC-Peer-Connection, /// kein SFU). Schnitt nach `docs/M2_MODULE_SCHNITT.md`. /// /// Andere Module (UI, Settings, Shell) konsumieren AUSSCHLIESSLICH diese /// Schnittstelle über [callSignalingProvider] – nie `voip_manager.dart` /// direkt. Einzige Ausnahme ist der Kompositions-Punkt in /// `matrix_client.dart`, der die Implementierung konstruiert. /// /// Bewusste Abweichungen vom Entwurf im Doc (Verhaltensgleichheit vor /// Schönheit, heiliger Call-Pfad): /// * ChangeNotifier statt Streams – die gesamte UI hängt heute an /// `ref.watch(...)` mit notifyListeners; ein Stream-Umbau wäre eine /// Verhaltensänderung ohne Not. /// * [currentCall] bleibt als matrix-SDK-`CallSession` sichtbar (die UI /// braucht state/room/answer/reject), ebenso die WebRTC-Renderer – /// das Doc sieht Letzteres ausdrücklich vor. abstract class CallSignalingService extends ChangeNotifier { /// Der laufende 1:1-Call (null = keiner). UI liest state/room und /// beantwortet eingehende Calls über [safeAction] + answer()/reject(). CallSession? get currentCall; rtc.RTCVideoRenderer get localRenderer; rtc.RTCVideoRenderer get remoteRenderer; bool get isMicMuted; bool get isCameraMuted; bool get isScreensharing; bool get isRemoteScreensharing; bool get isDeafened; /// Sende-Qualität ('sd' | 'hd' | 'fhd' | '4k'). String get currentQualityKey; Future startCall(String roomId, {bool video}); Future hangup(); Future toggleMic(); Future toggleCamera(); Future toggleDeafen(); /// Auf Windows öffnet ein [context] den Quellen-Picker fürs Screensharing. Future toggleScreenSharing([BuildContext? context]); Future changeQuality(String key); /// Wendet die in den Einstellungen gewählte Ausgabelautstärke auf den /// Remote-Stream an. Ohne [value] wird der Pref-Wert gelesen. Future applyOutputVolume([double? value]); /// Führt eine Call-Aktion (answer/reject/…) fehlertolerant aus und stößt /// danach die interne Zustands-/Renderer-Aktualisierung an. Future safeAction(Future Function() action); } /// Einziger Zugriffsweg der UI auf das 1:1-VoIP-Modul. Die Instanz wird beim /// Client-Aufbau in `matrix_client.dart` erzeugt (existiert also, sobald die /// eingeloggte Shell steht). final callSignalingProvider = ChangeNotifierProvider((ref) { return PyramidVoipManager.instance; });