diff --git a/lib/components/login_messages.dart b/lib/components/login_messages.dart new file mode 100644 index 0000000..1220e7e --- /dev/null +++ b/lib/components/login_messages.dart @@ -0,0 +1,87 @@ +import 'package:dio/dio.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; + +class LoginMessages { + static Future showErrorDialog( + BuildContext context, + Object e, + ) { + return showInfoDialog( + context, + Text( + AppLocalizations.of(context)!.errorConnectingToServer, + ), + content: Text(e.toString())); + } + + static Future showHttpErrorDialog( + BuildContext context, + DioException e, + ) { + return showInfoDialog( + context, + Text( + AppLocalizations.of(context)!.errorConnectingToServer, + ), + content: e.response?.statusCode == null + ? Text(e.toString()) + : Text(_formatHttpErrorCode(e.response)), + ); + } + + static Future showInfoDialog( + BuildContext context, + Widget title, { + Widget? content, + }) async { + await showDialog( + context: context, + builder: (context) => CallbackShortcuts( + bindings: { + const SingleActivator(LogicalKeyboardKey.enter): () { + Navigator.pop(context); + } + }, + child: FocusScope( + autofocus: true, + child: AlertDialog( + title: title, + content: content, + actions: [ + ElevatedButton( + onPressed: () { + Navigator.pop(context); + }, + child: const Text('Ok'), + ) + ], + ), + ), + ), + ); + } + + static String _formatHttpErrorCode(Response? resp) { + // todo PLACEHOLDER MESSAGES NOT FINAL + var message = ''; + switch (resp!.statusCode) { + case 400: + message = + 'The server could not understand the request, if you are using proxies check the configuration, if the issue still persists let us know'; + case 401: + message = 'Your username or password may be incorrect'; + case 403: + message = + 'The server is blocking request from this device, this probably means the device has been banned, please contact your admin to resolve this issue'; + default: + message = ''; + } + + return '$message\n\n' + 'Http Code: ${resp.statusCode ?? 'Unknown'}\n\n' + 'Http Response: ${resp.statusMessage ?? 'Unknown'}\n\n' + .trim(); + } +} diff --git a/lib/navigation/app_router.dart b/lib/navigation/app_router.dart index f9191cb..f113093 100644 --- a/lib/navigation/app_router.dart +++ b/lib/navigation/app_router.dart @@ -12,8 +12,8 @@ import 'package:jellyflix/screens/download_screen.dart'; import 'package:jellyflix/screens/home_screen.dart'; import 'package:jellyflix/screens/library_screen.dart'; import 'package:jellyflix/screens/loading_screen.dart'; -import 'package:jellyflix/screens/login_password.dart'; -import 'package:jellyflix/screens/login_quickconnect.dart'; +import 'package:jellyflix/screens/login_password_screen.dart'; +import 'package:jellyflix/screens/login_quickconnect_screen.dart'; import 'package:jellyflix/screens/login_wrapper_screen.dart'; import 'package:jellyflix/screens/offline_player_screen.dart'; import 'package:jellyflix/screens/profile_screen.dart'; @@ -147,7 +147,7 @@ class AppRouter { context: context, state: state, maintainState: false, - child: LoginWithPasswordScreen(serverAddress: state.pathParameters['server']!), + child: LoginPasswordScreen(serverAddress: state.pathParameters['server']!), ), ), GoRoute( @@ -157,7 +157,7 @@ class AppRouter { context: context, state: state, maintainState: false, - child: LoginWithQuickConnectScreen(serverAddress: state.pathParameters['server']!), + child: LoginQuickConnectScreen(serverAddress: state.pathParameters['server']!), ), ), ], diff --git a/lib/screens/login_messages.dart b/lib/screens/login_messages.dart deleted file mode 100644 index ab180a2..0000000 --- a/lib/screens/login_messages.dart +++ /dev/null @@ -1,86 +0,0 @@ -import 'package:dio/dio.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; - -Future showErrorDialog( - BuildContext context, - Object e, -) { - return showInfoDialog( - context, - Text( - AppLocalizations.of(context)!.errorConnectingToServer, - ), - content: Text(e.toString()) - ); -} - -Future showHttpErrorDialog( - BuildContext context, - DioException e, -) { - return showInfoDialog( - context, - Text( - AppLocalizations.of(context)!.errorConnectingToServer, - ), - content: e.response?.statusCode == null - ? Text(e.toString()) - : Text(_formatHttpErrorCode(e.response)), - ); -} - -Future showInfoDialog( - BuildContext context, - Widget title, { - Widget? content, -}) async { - await showDialog( - context: context, - builder: (context) => CallbackShortcuts( - bindings: { - const SingleActivator(LogicalKeyboardKey.enter): () { - Navigator.pop(context); - } - }, - child: FocusScope( - autofocus: true, - child: AlertDialog( - title: title, - content: content, - actions: [ - ElevatedButton( - onPressed: () { - Navigator.pop(context); - }, - child: const Text('Ok'), - ) - ], - ), - ), - ), - ); -} - -String _formatHttpErrorCode(Response? resp) { - // todo PLACEHOLDER MESSAGES NOT FINAL - var message = ''; - switch (resp!.statusCode) { - case 400: - message = - 'The server could not understand the request, if you are using proxies check the configuration, if the issue still persists let us know'; - case 401: - message = 'Your username or password may be incorrect'; - case 403: - message = - 'The server is blocking request from this device, this probably means the device has been banned, please contact your admin to resolve this issue'; - default: - message = ''; - } - - return '$message\n\n' - 'Http Code: ${resp.statusCode ?? 'Unknown'}\n\n' - 'Http Response: ${resp.statusMessage ?? 'Unknown'}\n\n' - .trim(); -} diff --git a/lib/screens/login_password.dart b/lib/screens/login_password_screen.dart similarity index 95% rename from lib/screens/login_password.dart rename to lib/screens/login_password_screen.dart index 45688d5..3d49182 100644 --- a/lib/screens/login_password.dart +++ b/lib/screens/login_password_screen.dart @@ -9,11 +9,11 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:jellyflix/models/screen_paths.dart'; import 'package:jellyflix/models/user.dart'; import 'package:jellyflix/providers/auth_provider.dart'; -import 'package:jellyflix/screens/login_messages.dart'; +import 'package:jellyflix/components/login_messages.dart'; -class LoginWithPasswordScreen extends HookConsumerWidget { +class LoginPasswordScreen extends HookConsumerWidget { final String serverAddress; - const LoginWithPasswordScreen({super.key, required this.serverAddress}); + const LoginPasswordScreen({super.key, required this.serverAddress}); @override Widget build(BuildContext context, WidgetRef ref) { @@ -145,7 +145,7 @@ class LoginWithPasswordScreen extends HookConsumerWidget { ); if (missingFields.isNotEmpty) { loadingListenable.value = false; - await showInfoDialog( + await LoginMessages.showInfoDialog( context, Text( AppLocalizations.of(context)!.emptyFields, @@ -169,12 +169,12 @@ class LoginWithPasswordScreen extends HookConsumerWidget { } on DioException catch (e) { if (!context.mounted) return; loadingListenable.value = false; - await showHttpErrorDialog(context, e); + await LoginMessages.showHttpErrorDialog(context, e); return; } catch (e) { if (!context.mounted) return; loadingListenable.value = false; - await showErrorDialog(context, e); + await LoginMessages.showErrorDialog(context, e); return; } loadingListenable.value = false; diff --git a/lib/screens/login_quickconnect.dart b/lib/screens/login_quickconnect_screen.dart similarity index 93% rename from lib/screens/login_quickconnect.dart rename to lib/screens/login_quickconnect_screen.dart index 6f88047..73593b6 100644 --- a/lib/screens/login_quickconnect.dart +++ b/lib/screens/login_quickconnect_screen.dart @@ -8,11 +8,11 @@ import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:jellyflix/models/screen_paths.dart'; import 'package:jellyflix/providers/auth_provider.dart'; -import 'package:jellyflix/screens/login_messages.dart'; +import 'package:jellyflix/components/login_messages.dart'; -class LoginWithQuickConnectScreen extends HookConsumerWidget { +class LoginQuickConnectScreen extends HookConsumerWidget { final String serverAddress; - const LoginWithQuickConnectScreen({super.key, required this.serverAddress}); + const LoginQuickConnectScreen({super.key, required this.serverAddress}); @override Widget build(BuildContext context, WidgetRef ref) { @@ -28,11 +28,11 @@ class LoginWithQuickConnectScreen extends HookConsumerWidget { .loginByQuickConnect(serverAddress, (c) => code.value = c, token); } on DioException catch (e) { if (!token.isCancelled && context.mounted) { - await showHttpErrorDialog(context, e); + await LoginMessages.showHttpErrorDialog(context, e); } } on Exception catch (e) { if (!token.isCancelled && context.mounted) { - await showErrorDialog(context, e); + await LoginMessages.showErrorDialog(context, e); } } diff --git a/lib/services/auth_service.dart b/lib/services/auth_service.dart index d04616e..208630b 100644 --- a/lib/services/auth_service.dart +++ b/lib/services/auth_service.dart @@ -44,15 +44,19 @@ class AuthService { try { if (user != null) { - await _apiService.registerAccessToken(user); + if (user.password != null) { + await login(user); + } else { + await _apiService.registerAccessToken(user); + } + _authStateStream.add(true); return true; } - } catch (_) { - } + } catch (_) {} - _authStateStream.add(false); - return false; + _authStateStream.add(false); + return false; } } @@ -75,8 +79,8 @@ class AuthService { return null; } - _databaseService.put(user.id! + serverAddress, user); - _databaseService.put("currentProfileId", user.id! + serverAddress); + _databaseService.put(user.id! + user.serverAdress!, user); + _databaseService.put("currentProfileId", user.id! + user.serverAdress!); _authStateStream.add(true); return user; @@ -140,7 +144,12 @@ class AuthService { Future switchProfile(String profileId) async { User? user = _databaseService.get(profileId); if (user != null && user.serverAdress != null && user.token != null) { - await _apiService.registerAccessToken(user); + if (user.password != null) { + await _apiService.login(user.serverAdress!, user.name!, user.password!); + } else { + await _apiService.registerAccessToken(user); + } + _authStateStream.add(true); } else { throw Exception("Profile not found");