diff --git a/lib/model/error/invalid_userid_error.dart b/lib/model/error/invalid_userid_error.dart new file mode 100644 index 0000000..4e582b1 --- /dev/null +++ b/lib/model/error/invalid_userid_error.dart @@ -0,0 +1 @@ +class InvalidUserIdError extends Error {} diff --git a/lib/model/error/invalid_username_error.dart b/lib/model/error/invalid_username_error.dart new file mode 100644 index 0000000..12c4e01 --- /dev/null +++ b/lib/model/error/invalid_username_error.dart @@ -0,0 +1 @@ +class InvalidUserNameError extends Error {} diff --git a/lib/model/error/not_loggedin_error.dart b/lib/model/error/not_loggedin_error.dart new file mode 100644 index 0000000..490d829 --- /dev/null +++ b/lib/model/error/not_loggedin_error.dart @@ -0,0 +1 @@ +class NotLoggedInError extends Error {} diff --git a/lib/navigation/main_navigator.dart b/lib/navigation/main_navigator.dart index 0f2a1df..53d4186 100644 --- a/lib/navigation/main_navigator.dart +++ b/lib/navigation/main_navigator.dart @@ -22,6 +22,8 @@ class MainNavigator with BaseNavigator { List get navigatorObservers => _navigatorObservers; void showError(String title, {Object? error, StackTrace? trace}) { + final context = navigatorKey.currentContext; + if (context == null) return; Flushbar( title: title, message: error.toString(), @@ -40,6 +42,8 @@ class MainNavigator with BaseNavigator { } void showMessage(String message) { + final context = navigatorKey.currentContext; + if (context == null) return; Flushbar( message: message.toString(), icon: const Icon( diff --git a/lib/navigation/main_navigator.navigator.dart b/lib/navigation/main_navigator.navigator.dart index 530a478..c1c8a0d 100644 --- a/lib/navigation/main_navigator.navigator.dart +++ b/lib/navigation/main_navigator.navigator.dart @@ -64,48 +64,39 @@ mixin BaseNavigator { return null; } - void goToLoginScreen({_i1.Key? key}) => - navigatorKey.currentState?.pushNamedAndRemoveUntil( + void goToLoginScreen({_i1.Key? key}) => navigatorKey.currentState?.pushNamedAndRemoveUntil( RouteNames.loginScreen, (_) => false, arguments: {'key': key}, ); - Future goToRaffleWinnerPickerScreen({_i1.Key? key}) async => - navigatorKey.currentState?.pushNamed( + Future goToRaffleWinnerPickerScreen({_i1.Key? key}) async => navigatorKey.currentState?.pushNamed( RouteNames.raffleWinnerPickerScreen, arguments: {'key': key}, ); - void goToQrScannerScreen({_i1.Key? key}) => - navigatorKey.currentState?.pushNamedAndRemoveUntil( + void goToQrScannerScreen({_i1.Key? key}) => navigatorKey.currentState?.pushNamedAndRemoveUntil( RouteNames.qrScannerScreen, (_) => false, arguments: {'key': key}, ); - void goToRaffleScreen({_i1.Key? key}) => - navigatorKey.currentState?.pushNamedAndRemoveUntil( + void goToRaffleScreen({_i1.Key? key}) => navigatorKey.currentState?.pushNamedAndRemoveUntil( RouteNames.raffleScreen, (_) => false, arguments: {'key': key}, ); - void goToSplashScreen({_i1.Key? key}) => - navigatorKey.currentState?.pushNamedAndRemoveUntil( + void goToSplashScreen({_i1.Key? key}) => navigatorKey.currentState?.pushNamedAndRemoveUntil( RouteNames.splashScreen, (_) => false, arguments: {'key': key}, ); void goBack() => navigatorKey.currentState?.pop(); - void goBackWithResult({T? result}) => - navigatorKey.currentState?.pop(result); - void popUntil(bool Function(Route) predicate) => - navigatorKey.currentState?.popUntil(predicate); - void goBackTo(String routeName) => - popUntil((route) => route.settings.name == routeName); + void goBackWithResult({T? result}) => navigatorKey.currentState?.pop(result); + void popUntil(bool Function(Route) predicate) => navigatorKey.currentState?.popUntil(predicate); + void goBackTo(String routeName) => popUntil((route) => route.settings.name == routeName); Future showCustomDialog({Widget? widget}) async => showDialog( context: navigatorKey.currentContext!, builder: (_) => widget ?? const SizedBox.shrink(), ); - Future showBottomSheet({Widget? widget}) async => - showModalBottomSheet( + Future showBottomSheet({Widget? widget}) async => showModalBottomSheet( context: navigatorKey.currentContext!, builder: (_) => widget ?? const SizedBox.shrink(), ); diff --git a/lib/repo/login_repo.dart b/lib/repo/login_repo.dart index bca606d..81ec235 100644 --- a/lib/repo/login_repo.dart +++ b/lib/repo/login_repo.dart @@ -57,7 +57,8 @@ class _LoginRepository implements LoginRepository { authProvider = GoogleAuthProvider(); break; } - await _firebaseAuth.signInWithPopup(authProvider); + final userCredentials = await _firebaseAuth.signInWithPopup(authProvider); + _user = userCredentials.user; } @override diff --git a/lib/viewmodel/login_viewmodel.dart b/lib/viewmodel/login_viewmodel.dart index ed27a62..5a61ad4 100644 --- a/lib/viewmodel/login_viewmodel.dart +++ b/lib/viewmodel/login_viewmodel.dart @@ -1,4 +1,4 @@ -import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; import 'package:flutter_belgium/model/data/login/login_type.dart'; import 'package:injectable/injectable.dart'; import 'package:flutter_belgium/navigation/main_navigator.dart'; @@ -18,7 +18,14 @@ class LoginViewModel with ChangeNotifier { this._mainNavigator, ); - void init() {} + void init() { + if (_loginRepository.isLoggedIn) { + WidgetsBinding.instance.addPostFrameCallback((timeStamp) { + _mainNavigator.goToRaffleScreen(); + }); + return; + } + } Future onLoginTapped(LoginType loginType) async { try { diff --git a/lib/viewmodel/raffle_viewmodel.dart b/lib/viewmodel/raffle_viewmodel.dart index 3cedb93..67b3cc2 100644 --- a/lib/viewmodel/raffle_viewmodel.dart +++ b/lib/viewmodel/raffle_viewmodel.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'package:confetti/confetti.dart'; -import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_belgium/model/data/raffle/raffle.dart'; import 'package:flutter_belgium/repo/raffle_repo.dart'; import 'package:flutter_belgium/style/theme_duration.dart'; @@ -48,7 +48,15 @@ class RaffleViewModel with ChangeNotifier { this._mainNavigator, ); - void init() => _getData(); + void init() { + if (!_loginRepository.isLoggedIn) { + WidgetsBinding.instance.addPostFrameCallback((timeStamp) { + _mainNavigator.goToLoginScreen(); + }); + return; + } + _getData(); + } @override void dispose() { @@ -101,12 +109,16 @@ class RaffleViewModel with ChangeNotifier { } Future onEnterRaffleTapped() async { - final raffle = _raffle; - if (raffle == null) { - _mainNavigator.showError('No raffle found'); - return; + try { + final raffle = _raffle; + if (raffle == null) { + _mainNavigator.showError('No raffle found'); + return; + } + await _raffleRepository.enterRaffle(raffle.id); + } catch (e) { + _mainNavigator.showError('Failed to enter raffle', error: e); } - await _raffleRepository.enterRaffle(raffle.id); } void onStartFortuneWheel() => _mainNavigator.goToRaffleWinnerPickerScreen(); diff --git a/lib/widget/general/button.dart b/lib/widget/general/button.dart index 37607cd..c1afd24 100644 --- a/lib/widget/general/button.dart +++ b/lib/widget/general/button.dart @@ -1,5 +1,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_belgium/di/injectable.dart'; +import 'package:flutter_belgium/navigation/main_navigator.dart'; import 'package:flutter_belgium/style/theme.dart'; import 'package:flutter_belgium/widget/general/loading.dart'; @@ -86,7 +88,11 @@ class _ButtonState extends State