diff --git a/lib/helpers/ui.dart b/lib/helpers/ui.dart index 5219c000..be594ec8 100644 --- a/lib/helpers/ui.dart +++ b/lib/helpers/ui.dart @@ -56,7 +56,15 @@ void showHttpExceptionErrorDialog(WgerHttpException exception, BuildContext cont final List errorList = []; for (final key in exception.errors!.keys) { // Error headers - errorList.add(Text(key, style: const TextStyle(fontWeight: FontWeight.bold))); + // Ensure that the error heading first letter is capitalized. + final String errorHeaderMsg = key[0].toUpperCase() + key.substring(1, key.length); + + errorList.add( + Text( + errorHeaderMsg, + style: const TextStyle(fontWeight: FontWeight.bold), + ), + ); // Error messages if (exception.errors![key] is String) { @@ -74,6 +82,7 @@ void showHttpExceptionErrorDialog(WgerHttpException exception, BuildContext cont builder: (ctx) => AlertDialog( title: Text(AppLocalizations.of(ctx).anErrorOccurred), content: Column( + crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [...errorList], ), @@ -94,7 +103,7 @@ void showHttpExceptionErrorDialog(WgerHttpException exception, BuildContext cont } dynamic showDeleteDialog(BuildContext context, String confirmDeleteName, Log log, Exercise exercise, - Map> _exerciseData) async { + Map> exerciseData) async { final res = await showDialog( context: context, builder: (BuildContext contextDialog) { @@ -113,7 +122,7 @@ dynamic showDeleteDialog(BuildContext context, String confirmDeleteName, Log log style: TextStyle(color: Theme.of(context).errorColor), ), onPressed: () { - _exerciseData[exercise]!.removeWhere((el) => el.id == log.id); + exerciseData[exercise]!.removeWhere((el) => el.id == log.id); Provider.of(context, listen: false).deleteLog( log, ); diff --git a/lib/providers/auth.dart b/lib/providers/auth.dart index e1f1f6db..57d7bddc 100644 --- a/lib/providers/auth.dart +++ b/lib/providers/auth.dart @@ -98,7 +98,7 @@ class AuthProvider with ChangeNotifier { } /// Registers a new user - Future register( + Future> register( {required String username, required String password, required String email, @@ -124,14 +124,21 @@ class AuthProvider with ChangeNotifier { throw WgerHttpException(responseData); } + // If update is required don't log in user + final bool updateRequired = await applicationUpdateRequired(); + if (updateRequired) { + return {'action': 'update'}; + } + login(username, password, serverUrl); + return {'action': 'proceed'}; } catch (error) { rethrow; } } /// Authenticates a user - Future login(String username, String password, String serverUrl) async { + Future> login(String username, String password, String serverUrl) async { await logout(shouldNotify: false); try { @@ -149,6 +156,12 @@ class AuthProvider with ChangeNotifier { throw WgerHttpException(responseData); } + // If update is required don't log in user + final bool updateRequired = await applicationUpdateRequired(); + if (updateRequired) { + return {'action': 'update'}; + } + // Log user in this.serverUrl = serverUrl; token = responseData['token']; @@ -169,6 +182,7 @@ class AuthProvider with ChangeNotifier { await setApplicationVersion(); prefs.setString('userData', userData); prefs.setString('lastServer', serverData); + return {'action': 'proceed'}; } catch (error) { rethrow; } diff --git a/lib/screens/auth_screen.dart b/lib/screens/auth_screen.dart index 79b8e561..3d5fd578 100644 --- a/lib/screens/auth_screen.dart +++ b/lib/screens/auth_screen.dart @@ -24,6 +24,7 @@ import 'package:wger/exceptions/http_exception.dart'; import 'package:wger/helpers/consts.dart'; import 'package:wger/helpers/misc.dart'; import 'package:wger/helpers/ui.dart'; +import 'package:wger/screens/update_app_screen.dart'; import '../providers/auth.dart'; @@ -139,19 +140,30 @@ class _AuthCardState extends State { try { // Login existing user + late Map res; if (_authMode == AuthMode.Login) { - await Provider.of(context, listen: false) + res = await Provider.of(context, listen: false) .login(_authData['username']!, _authData['password']!, _authData['serverUrl']!); // Register new user } else { - await Provider.of(context, listen: false).register( + res = await Provider.of(context, listen: false).register( username: _authData['username']!, password: _authData['password']!, email: _authData['email']!, serverUrl: _authData['serverUrl']!); } + // Check if update is required else continue normally + if (res.containsKey('action')) { + if (res['action'] == 'update' && mounted) { + Navigator.of(context).push( + MaterialPageRoute(builder: (context) => UpdateAppScreen()), + ); + return; + } + } + setState(() { _isLoading = false; }); @@ -161,10 +173,12 @@ class _AuthCardState extends State { _isLoading = false; }); } catch (error) { - showErrorDialog(error, context); - setState(() { - _isLoading = false; - }); + if (mounted) { + showErrorDialog(error, context); + setState(() { + _isLoading = false; + }); + } } } @@ -221,7 +235,7 @@ class _AuthCardState extends State { } return null; }, - inputFormatters: [FilteringTextInputFormatter.deny(new RegExp(r"\s\b|\b\s"))], + inputFormatters: [FilteringTextInputFormatter.deny(RegExp(r'\s\b|\b\s'))], onSaved: (value) { _authData['username'] = value!; }, @@ -349,23 +363,23 @@ class _AuthCardState extends State { ), TextButton( key: const Key('toggleActionButton'), + onPressed: _switchAuthMode, child: Text( _authMode == AuthMode.Login ? AppLocalizations.of(context).registerInstead.toUpperCase() : AppLocalizations.of(context).loginInstead.toUpperCase(), ), - onPressed: _switchAuthMode, ), TextButton( - child: Text(_hideCustomServer - ? AppLocalizations.of(context).useCustomServer - : AppLocalizations.of(context).useDefaultServer), key: const Key('toggleCustomServerButton'), onPressed: () { setState(() { _hideCustomServer = !_hideCustomServer; }); }, + child: Text(_hideCustomServer + ? AppLocalizations.of(context).useCustomServer + : AppLocalizations.of(context).useDefaultServer), ), ], ),