diff --git a/dogfooding/lib/core/repos/user_auth_repository.dart b/dogfooding/lib/core/repos/user_auth_repository.dart index 39c586780..d232396f5 100644 --- a/dogfooding/lib/core/repos/user_auth_repository.dart +++ b/dogfooding/lib/core/repos/user_auth_repository.dart @@ -16,15 +16,15 @@ class UserAuthRepository { Future login() async { final response = await videoClient.connect(); - final userToken = response.getDataOrNull(); - if (userToken == null) { - throw Exception('Failed to connect user'); - } - - return UserCredentials( - token: userToken, - userInfo: currentUser, - ); + + return response.fold(success: (success) { + return UserCredentials( + token: success.data, + userInfo: currentUser, + ); + }, failure: (failure) { + throw failure.error; + }); } UserInfo get currentUser => videoClient.currentUser; diff --git a/dogfooding/lib/screens/home_screen.dart b/dogfooding/lib/screens/home_screen.dart index 3e531b86c..20df7a192 100644 --- a/dogfooding/lib/screens/home_screen.dart +++ b/dogfooding/lib/screens/home_screen.dart @@ -69,26 +69,40 @@ class _HomeScreenState extends State { bool isRinging = memberIds.isNotEmpty; try { - await _call!.getOrCreate( + final result = await _call!.getOrCreate( memberIds: memberIds, ringing: isRinging, video: true, ); + + result.fold( + success: (success) { + if (mounted) { + if (isRinging) { + CallRoute($extra: ( + call: _call!, + connectOptions: null, + )).push(context); + } else { + LobbyRoute($extra: _call!).push(context); + } + } + }, + failure: (failure) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + duration: const Duration(seconds: 20), + content: Text('Error: ${failure.error.message}'), + ), + ); + }, + ); } catch (e, stk) { debugPrint('Error joining or creating call: $e'); debugPrint(stk.toString()); - } - - if (mounted) { - hideLoadingIndicator(context); - - if (isRinging) { - CallRoute($extra: ( - call: _call!, - connectOptions: null, - )).push(context); - } else { - LobbyRoute($extra: _call!).push(context); + } finally { + if (mounted) { + hideLoadingIndicator(context); } } } diff --git a/dogfooding/lib/screens/login_screen.dart b/dogfooding/lib/screens/login_screen.dart index e454c0575..3f97f66d4 100644 --- a/dogfooding/lib/screens/login_screen.dart +++ b/dogfooding/lib/screens/login_screen.dart @@ -42,7 +42,7 @@ class _LoginScreenState extends State { final userInfo = UserInfo( role: 'admin', - id: googleUser.email, + id: createValidId(googleUser.email), name: googleUser.displayName ?? '', image: googleUser.photoUrl, ); @@ -56,7 +56,7 @@ class _LoginScreenState extends State { final userInfo = UserInfo( role: 'admin', - id: email.replaceAll('@', '_').replaceAll('.', '_'), + id: createValidId(email), name: email, ); @@ -82,9 +82,20 @@ class _LoginScreenState extends State { // Register StreamVideo client with the user. final authController = locator.get(); - await authController.login(user, environment); - if (mounted) hideLoadingIndicator(context); + try { + await authController.login(user, environment); + } catch (e, _) { + if (mounted) { + hideLoadingIndicator(context); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + duration: const Duration(seconds: 20), + content: Text('Error: $e'), + ), + ); + } + } } @override @@ -268,3 +279,7 @@ String randomId({int size = 21}) { } return id; } + +String createValidId(String id) { + return id.replaceAll(RegExp(r'[^\w]'), '_'); +} diff --git a/packages/stream_video/lib/src/errors/video_error_composer.dart b/packages/stream_video/lib/src/errors/video_error_composer.dart index 90bbd3bca..fcc511f01 100644 --- a/packages/stream_video/lib/src/errors/video_error_composer.dart +++ b/packages/stream_video/lib/src/errors/video_error_composer.dart @@ -1,6 +1,7 @@ import 'package:tart/tart.dart'; import 'package:web_socket_channel/web_socket_channel.dart'; +import '../../stream_video.dart'; import 'video_error.dart'; /// TODO @@ -24,6 +25,12 @@ mixin VideoErrors { cause: exception, stackTrace: stackTrace, ); + } else if (exception is ApiException) { + return VideoErrorWithCause( + message: exception.message ?? exception.toString(), + cause: exception, + stackTrace: stackTrace, + ); } else if (exception is Exception) { return VideoErrorWithCause( message: exception.toString(), diff --git a/packages/stream_video/lib/src/push_notification/push_notification_manager.dart b/packages/stream_video/lib/src/push_notification/push_notification_manager.dart index 1d1a7404e..10daf03da 100644 --- a/packages/stream_video/lib/src/push_notification/push_notification_manager.dart +++ b/packages/stream_video/lib/src/push_notification/push_notification_manager.dart @@ -26,7 +26,7 @@ abstract class PushNotificationManager { /// Unregisters the device for push notifications. Internal use only. @internal - void unregisterDevice(); + Future unregisterDevice(); /// Displays an incoming call notification. /// diff --git a/packages/stream_video/lib/src/stream_video.dart b/packages/stream_video/lib/src/stream_video.dart index 04d4f2643..8bbb6af9b 100644 --- a/packages/stream_video/lib/src/stream_video.dart +++ b/packages/stream_video/lib/src/stream_video.dart @@ -368,11 +368,12 @@ class StreamVideo extends Disposable { } try { await _connectOperation?.cancel(); - await _client.disconnectUser(); - _subscriptions.cancelAll(); // Unregister device from push notification manager. - pushNotificationManager?.unregisterDevice(); + await pushNotificationManager?.unregisterDevice(); + + await _client.disconnectUser(); + _subscriptions.cancelAll(); // Resetting the state. await _state.clear(); diff --git a/packages/stream_video_push_notification/lib/src/stream_video_push_notification.dart b/packages/stream_video_push_notification/lib/src/stream_video_push_notification.dart index a17b5f034..66127a33d 100644 --- a/packages/stream_video_push_notification/lib/src/stream_video_push_notification.dart +++ b/packages/stream_video_push_notification/lib/src/stream_video_push_notification.dart @@ -260,7 +260,7 @@ class StreamVideoPushNotificationManager implements PushNotificationManager { } @override - void unregisterDevice() async { + Future unregisterDevice() async { final token = await getDevicePushTokenVoIP(); if (token != null) { _client.deleteDevice(id: token); @@ -272,7 +272,7 @@ class StreamVideoPushNotificationManager implements PushNotificationManager { _client.deleteDevice(id: apnToken); } - removedStoredTokens(); + await removedStoredTokens(); } @override