From 827fcbbae6ca6a8585ae5611aecfb294f1c13288 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Fri, 5 Jun 2026 17:06:33 -0400 Subject: [PATCH] clean up login page --- lib/pages/login_page.dart | 104 ++++++++++---------------------------- 1 file changed, 28 insertions(+), 76 deletions(-) diff --git a/lib/pages/login_page.dart b/lib/pages/login_page.dart index 38941e2..4f57549 100644 --- a/lib/pages/login_page.dart +++ b/lib/pages/login_page.dart @@ -2,58 +2,43 @@ import "package:flutter/material.dart"; import "package:flutter_hooks/flutter_hooks.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:nexus/controllers/client_controller.dart"; -import "package:nexus/models/requests/login_request.dart"; import "package:nexus/widgets/appbar.dart"; class LoginPage extends HookConsumerWidget { final Uri homeserver; - const LoginPage({super.key, required this.homeserver}); @override Widget build(BuildContext context, WidgetRef ref) { final client = ref.watch(ClientController.provider.notifier); - final isLoggingIn = useState(false); - final hasError = useState(false); - final passwordFocusNode = useFocusNode(); - - final theme = Theme.of(context); + final isLoading = useState(false); final username = useTextEditingController(); final password = useTextEditingController(); + final inputError = useState(null); + Future tryLogin() async { - if (isLoggingIn.value) return; - isLoggingIn.value = true; - hasError.value = false; + isLoading.value = true; - final error = await client.login( - LoginRequest( - username: username.text, - password: password.text, - homeserverUrl: homeserver.origin, - ), - ); - - if (!context.mounted) return; - - if (error != null) { - hasError.value = true; - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text( - "Login failed. Is your password right?\nError: $error", - style: TextStyle(color: theme.colorScheme.onErrorContainer), - ), - backgroundColor: theme.colorScheme.errorContainer, + try { + final error = await client.login( + .new( + username: username.text, + password: password.text, + homeserverUrl: homeserver.origin, ), ); - isLoggingIn.value = false; - } else { - Navigator.of(context).pop(); + + if (error != null) { + inputError.value = error; + isLoading.value = false; + } else { + if (context.mounted) Navigator.of(context).pop(); + } + } finally { + isLoading.value = false; } - passwordFocusNode.requestFocus(); - isLoggingIn.value = false; } return Scaffold( @@ -66,57 +51,24 @@ class LoginPage extends HookConsumerWidget { body: AlertDialog( title: Text("Login to ${homeserver.host}"), content: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: .min, + crossAxisAlignment: .start, children: [ - Text("Enter your login credentials:"), - SizedBox(height: 12), TextField( autofocus: true, - textInputAction: TextInputAction.next, - onChanged: (newVal) { - if (hasError.value) { - hasError.value = false; - } - }, - decoration: InputDecoration( - label: Text("Username"), - focusedBorder: hasError.value - ? OutlineInputBorder( - borderSide: BorderSide(color: theme.colorScheme.error), - ) - : null, - enabledBorder: hasError.value - ? OutlineInputBorder( - borderSide: BorderSide(color: theme.colorScheme.error), - ) - : null, - ), + textInputAction: .next, + decoration: .new(label: Text("Username")), controller: username, ), SizedBox(height: 12), TextField( - focusNode: passwordFocusNode, - textInputAction: TextInputAction.done, + textInputAction: .done, onSubmitted: (_) => tryLogin(), - onChanged: (newVal) { - if (hasError.value) { - hasError.value = false; - } - }, selectAllOnFocus: true, - decoration: InputDecoration( + decoration: .new( label: Text("Password"), - focusedBorder: hasError.value - ? OutlineInputBorder( - borderSide: BorderSide(color: theme.colorScheme.error), - ) - : null, - enabledBorder: hasError.value - ? OutlineInputBorder( - borderSide: BorderSide(color: theme.colorScheme.error), - ) - : null, + errorText: inputError.value, + errorMaxLines: 5, ), controller: password, obscureText: true, @@ -125,7 +77,7 @@ class LoginPage extends HookConsumerWidget { ), actions: [ TextButton( - onPressed: hasError.value ? null : tryLogin, + onPressed: isLoading.value ? null : tryLogin, child: Text("Sign In"), ), ],