refactor: M2-Call-Pilot – Module call_signaling + voice_channel mit Fassaden (Entscheidung 2)

- 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)
This commit is contained in:
Bernd Steckmeister
2026-07-06 12:42:59 +02:00
parent f64398d3c6
commit 3c7eb9ddca
20 changed files with 383 additions and 53 deletions
+8 -8
View File
@@ -3,14 +3,14 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:pyramid/core/app_state.dart';
import 'package:pyramid/core/theme.dart';
import 'package:pyramid/core/livekit_call_manager.dart';
import 'package:pyramid/core/voip_manager.dart';
import 'package:pyramid/features/call_signaling/call_signaling_service.dart';
import 'package:pyramid/features/voice_channel/voice_channel_service.dart';
import 'package:pyramid/widgets/screen_share_picker.dart';
import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc;
import 'package:livekit_client/livekit_client.dart';
class MiniCallWidget extends ConsumerStatefulWidget {
final dynamic call; // Can be LiveKitCallManager or PyramidVoipManager
final dynamic call; // CallSignalingService (1:1) oder VoiceChannelService
const MiniCallWidget({super.key, required this.call});
@override
@@ -45,7 +45,7 @@ class _MiniCallWidgetState extends ConsumerState<MiniCallWidget> {
@override
Widget build(BuildContext context) {
final pt = PyramidTheme.of(context);
final isVoip = widget.call is PyramidVoipManager;
final isVoip = widget.call is CallSignalingService;
final call = widget.call;
final String displayName = isVoip
@@ -95,7 +95,7 @@ class _MiniCallWidgetState extends ConsumerState<MiniCallWidget> {
isStreaming ? call.localRenderer : call.remoteRenderer,
objectFit: rtc.RTCVideoViewObjectFit.RTCVideoViewObjectFitCover,
)
: _LiveKitPreview(manager: call as LiveKitCallManager),
: _LiveKitPreview(manager: call as VoiceChannelService),
),
// Top bar of preview
@@ -259,9 +259,9 @@ class _MiniCallWidgetState extends ConsumerState<MiniCallWidget> {
pt: pt,
onTap: () async {
if (isVoip) {
(call as PyramidVoipManager).toggleScreenSharing(context);
(call as CallSignalingService).toggleScreenSharing(context);
} else {
final lk = call as LiveKitCallManager;
final lk = call as VoiceChannelService;
if (lk.isScreenSharing) {
await lk.stopScreenShare();
} else {
@@ -351,7 +351,7 @@ class _ControlBtnState extends State<_ControlBtn> {
}
class _LiveKitPreview extends StatelessWidget {
final LiveKitCallManager manager;
final VoiceChannelService manager;
const _LiveKitPreview({required this.manager});
@override
+9 -9
View File
@@ -6,8 +6,8 @@ import 'package:collection/collection.dart';
import 'package:pyramid/core/app_state.dart';
import 'package:pyramid/widgets/screen_share_picker.dart';
import 'package:pyramid/core/theme.dart';
import 'package:pyramid/core/livekit_call_manager.dart';
import 'package:pyramid/core/voip_manager.dart';
import 'package:pyramid/features/call_signaling/call_signaling_service.dart';
import 'package:pyramid/features/voice_channel/voice_channel_service.dart';
import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc;
import 'package:pyramid/widgets/hover_region.dart';
import 'package:pyramid/widgets/pyramid_loader.dart';
@@ -45,8 +45,8 @@ class VoiceChannelView extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final pt = PyramidTheme.of(context);
final call = ref.watch(callStateProvider);
final voip = ref.watch(voipStateProvider);
final call = ref.watch(voiceChannelProvider);
final voip = ref.watch(callSignalingProvider);
if (voip.currentCall != null && voip.currentCall!.state != CallState.kEnded) {
return _UnifiedCallView(
@@ -101,7 +101,7 @@ class VoiceChannelView extends ConsumerWidget {
);
}
List<_ParticipantData> _getLiveKitParticipants(LiveKitCallManager call) {
List<_ParticipantData> _getLiveKitParticipants(VoiceChannelService call) {
final room = call.room;
if (room == null) return [];
final all = <Participant>[
@@ -142,7 +142,7 @@ class VoiceChannelView extends ConsumerWidget {
}).toList();
}
List<_ParticipantData> _getVoipParticipants(PyramidVoipManager voip) {
List<_ParticipantData> _getVoipParticipants(CallSignalingService voip) {
final participants = <_ParticipantData>[];
double ar(rtc.RTCVideoRenderer r) {
@@ -997,7 +997,7 @@ class _FullscreenVideoPage extends StatelessWidget {
}
}
void _handleLiveKitScreenShare(BuildContext context, LiveKitCallManager call) async {
void _handleLiveKitScreenShare(BuildContext context, VoiceChannelService call) async {
if (call.isScreenSharing) {
await call.stopScreenShare();
} else {
@@ -1006,7 +1006,7 @@ void _handleLiveKitScreenShare(BuildContext context, LiveKitCallManager call) as
}
}
void _showLiveKitQualityMenu(BuildContext context, LiveKitCallManager call, Offset pos) {
void _showLiveKitQualityMenu(BuildContext context, VoiceChannelService call, Offset pos) {
final pt = PyramidTheme.of(context);
showMenu(
context: context,
@@ -1025,7 +1025,7 @@ void _showLiveKitQualityMenu(BuildContext context, LiveKitCallManager call, Offs
);
}
void _showVoipQualityMenu(BuildContext context, PyramidVoipManager voip, Offset pos) {
void _showVoipQualityMenu(BuildContext context, CallSignalingService voip, Offset pos) {
final pt = PyramidTheme.of(context);
showMenu(
context: context,