From 6b4189a93b64e56d5b02505ca543b1349b22828c Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Mon, 26 May 2025 01:52:08 +0800 Subject: [PATCH] :drunk: Add call overlay --- lib/pods/call.dart | 1 + lib/screens/chat/call.dart | 29 ++++++++++++++++++++++++++--- lib/widgets/app_scaffold.dart | 16 ++++++++-------- lib/widgets/chat/call_overlay.dart | 19 ++++++++++++++----- 4 files changed, 49 insertions(+), 16 deletions(-) diff --git a/lib/pods/call.dart b/lib/pods/call.dart index 7b0b364..88d0a50 100644 --- a/lib/pods/call.dart +++ b/lib/pods/call.dart @@ -215,6 +215,7 @@ class CallNotifier extends _$CallNotifier { } String? _roomId; + String? get roomId => _roomId; Future joinRoom(String roomId) async { _roomId = roomId; diff --git a/lib/screens/chat/call.dart b/lib/screens/chat/call.dart index 86c62e0..bfc567e 100644 --- a/lib/screens/chat/call.dart +++ b/lib/screens/chat/call.dart @@ -42,9 +42,32 @@ class CallScreen extends HookConsumerWidget { appBar: AppBar( leading: PageBackButton( onWillPop: () { - callNotifier.disconnect().then((_) { - callNotifier.dispose(); - }); + showDialog( + context: context, + builder: (context) { + return AlertDialog( + content: const Text( + 'Do you want to leave the call or leave it in background?', + ), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: const Text('In Background'), + ), + TextButton( + onPressed: () async { + Navigator.of(context).pop(); + await callNotifier.disconnect(); + callNotifier.dispose(); + }, + child: const Text('Leave'), + ), + ], + ); + }, + ); }, ), title: Column( diff --git a/lib/widgets/app_scaffold.dart b/lib/widgets/app_scaffold.dart index 3965e9b..0c89b25 100644 --- a/lib/widgets/app_scaffold.dart +++ b/lib/widgets/app_scaffold.dart @@ -160,7 +160,12 @@ class AppScaffold extends StatelessWidget { ? content : AppBackground(isRoot: true, child: content), ), - const _GlobalCallOverlay(), + Positioned( + left: 16, + right: 16, + bottom: 8, + child: const _GlobalCallOverlay(), + ), ], ), appBar: appBar, @@ -211,13 +216,8 @@ class _GlobalCallOverlay extends HookConsumerWidget { final modalRoute = ModalRoute.of(context); final isOnCallScreen = modalRoute?.settings.name?.contains('call') ?? false; // You may want to store roomId in callState for more robust navigation - final roomId = - (modalRoute?.settings.arguments is Map && - (modalRoute!.settings.arguments as Map).containsKey('roomId')) - ? (modalRoute.settings.arguments as Map)['roomId'] as String - : null; - if (callState.isConnected && !isOnCallScreen && roomId != null) { - return CallOverlayBar(roomId: roomId); + if (callState.isConnected && !isOnCallScreen) { + return CallOverlayBar(); } return const SizedBox.shrink(); } diff --git a/lib/widgets/chat/call_overlay.dart b/lib/widgets/chat/call_overlay.dart index 7addb25..73319fd 100644 --- a/lib/widgets/chat/call_overlay.dart +++ b/lib/widgets/chat/call_overlay.dart @@ -6,12 +6,12 @@ import 'package:island/route.gr.dart'; /// A floating bar that appears when user is in a call but not on the call screen. class CallOverlayBar extends HookConsumerWidget { - final String roomId; - const CallOverlayBar({super.key, required this.roomId}); + const CallOverlayBar({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final callState = ref.watch(callNotifierProvider); + final callNotifier = ref.read(callNotifierProvider.notifier); // Only show if connected and not on the call screen if (!callState.isConnected) return const SizedBox.shrink(); @@ -21,7 +21,8 @@ class CallOverlayBar extends HookConsumerWidget { bottom: 32, child: GestureDetector( onTap: () { - context.router.push(CallRoute(roomId: roomId)); + if (callNotifier.roomId == null) return; + context.router.push(CallRoute(roomId: callNotifier.roomId!)); }, child: Material( elevation: 8, @@ -38,11 +39,19 @@ class CallOverlayBar extends HookConsumerWidget { const SizedBox(width: 12), const Text( 'In call', - style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 16), + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 16, + ), ), ], ), - const Icon(Icons.arrow_forward_ios, color: Colors.white, size: 18), + const Icon( + Icons.arrow_forward_ios, + color: Colors.white, + size: 18, + ), ], ), ),