:drunk: Add call overlay

This commit is contained in:
LittleSheep 2025-05-26 01:52:08 +08:00
parent fed8171b36
commit 6b4189a93b
4 changed files with 49 additions and 16 deletions

View File

@ -215,6 +215,7 @@ class CallNotifier extends _$CallNotifier {
} }
String? _roomId; String? _roomId;
String? get roomId => _roomId;
Future<void> joinRoom(String roomId) async { Future<void> joinRoom(String roomId) async {
_roomId = roomId; _roomId = roomId;

View File

@ -42,9 +42,32 @@ class CallScreen extends HookConsumerWidget {
appBar: AppBar( appBar: AppBar(
leading: PageBackButton( leading: PageBackButton(
onWillPop: () { onWillPop: () {
callNotifier.disconnect().then((_) { showDialog<void>(
callNotifier.dispose(); 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( title: Column(

View File

@ -160,7 +160,12 @@ class AppScaffold extends StatelessWidget {
? content ? content
: AppBackground(isRoot: true, child: content), : AppBackground(isRoot: true, child: content),
), ),
const _GlobalCallOverlay(), Positioned(
left: 16,
right: 16,
bottom: 8,
child: const _GlobalCallOverlay(),
),
], ],
), ),
appBar: appBar, appBar: appBar,
@ -211,13 +216,8 @@ class _GlobalCallOverlay extends HookConsumerWidget {
final modalRoute = ModalRoute.of(context); final modalRoute = ModalRoute.of(context);
final isOnCallScreen = modalRoute?.settings.name?.contains('call') ?? false; final isOnCallScreen = modalRoute?.settings.name?.contains('call') ?? false;
// You may want to store roomId in callState for more robust navigation // You may want to store roomId in callState for more robust navigation
final roomId = if (callState.isConnected && !isOnCallScreen) {
(modalRoute?.settings.arguments is Map && return CallOverlayBar();
(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);
} }
return const SizedBox.shrink(); return const SizedBox.shrink();
} }

View File

@ -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. /// A floating bar that appears when user is in a call but not on the call screen.
class CallOverlayBar extends HookConsumerWidget { class CallOverlayBar extends HookConsumerWidget {
final String roomId; const CallOverlayBar({super.key});
const CallOverlayBar({super.key, required this.roomId});
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final callState = ref.watch(callNotifierProvider); final callState = ref.watch(callNotifierProvider);
final callNotifier = ref.read(callNotifierProvider.notifier);
// Only show if connected and not on the call screen // Only show if connected and not on the call screen
if (!callState.isConnected) return const SizedBox.shrink(); if (!callState.isConnected) return const SizedBox.shrink();
@ -21,7 +21,8 @@ class CallOverlayBar extends HookConsumerWidget {
bottom: 32, bottom: 32,
child: GestureDetector( child: GestureDetector(
onTap: () { onTap: () {
context.router.push(CallRoute(roomId: roomId)); if (callNotifier.roomId == null) return;
context.router.push(CallRoute(roomId: callNotifier.roomId!));
}, },
child: Material( child: Material(
elevation: 8, elevation: 8,
@ -38,11 +39,19 @@ class CallOverlayBar extends HookConsumerWidget {
const SizedBox(width: 12), const SizedBox(width: 12),
const Text( const Text(
'In call', '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,
),
], ],
), ),
), ),