diff --git a/lib/config/routes.dart b/lib/config/routes.dart index de4176268..37e3b853c 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -3,7 +3,6 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; -import 'package:matrix/matrix.dart'; import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/pages/archive/archive.dart'; @@ -107,7 +106,10 @@ abstract class AppRoutes { pageBuilder: (context, state) => defaultPageBuilder( context, state, - Login(client: state.extra as Client), + // #Pangea + // Login(client: state.extra as Client), + const Login(), + // Pangea# ), redirect: loggedInRedirect, ), diff --git a/lib/pages/login/login.dart b/lib/pages/login/login.dart index c3fd38808..86ab02fc8 100644 --- a/lib/pages/login/login.dart +++ b/lib/pages/login/login.dart @@ -1,5 +1,3 @@ -import 'dart:async'; - import 'package:flutter/material.dart'; import 'package:matrix/matrix.dart'; @@ -16,8 +14,12 @@ import 'package:fluffychat/widgets/future_loading_dialog.dart'; import 'package:fluffychat/widgets/matrix.dart'; class Login extends StatefulWidget { - final Client client; - const Login({required this.client, super.key}); + // #Pangea + // final Client client; + // const Login({required this.client, super.key}); + + const Login({super.key}); + // Pangea# @override LoginController createState() => LoginController(); @@ -42,6 +44,8 @@ class LoginController extends State { final PangeaController pangeaController = MatrixState.pangeaController; final GlobalKey formKey = GlobalKey(); + Client? client; + bool get enabledSignIn => !loadingSignIn && usernameController.text.isNotEmpty && @@ -66,6 +70,10 @@ class LoginController extends State { usernameController.addListener(() => setState(() {})); passwordController.addListener(() => setState(() {})); + + Matrix.of(context).getLoginClient().then((client) { + if (mounted) setState(() => this.client = client); + }); } @override @@ -155,74 +163,77 @@ class LoginController extends State { // if (mounted) setState(() => loading = false); // } - // Pangea# - Timer? _coolDown; + // Timer? _coolDown; - void checkWellKnownWithCoolDown(String userId) async { - _coolDown?.cancel(); - _coolDown = Timer( - const Duration(seconds: 1), - () => _checkWellKnown(userId), - ); - } + // void checkWellKnownWithCoolDown(String userId) async { + // _coolDown?.cancel(); + // _coolDown = Timer( + // const Duration(seconds: 1), + // () => _checkWellKnown(userId), + // ); + // } - void _checkWellKnown(String userId) async { - if (mounted) setState(() => usernameError = null); - if (!userId.isValidMatrixId) return; - final oldHomeserver = widget.client.homeserver; - try { - var newDomain = Uri.https(userId.domain!, ''); - widget.client.homeserver = newDomain; - DiscoveryInformation? wellKnownInformation; - try { - wellKnownInformation = await widget.client.getWellknown(); - if (wellKnownInformation.mHomeserver.baseUrl.toString().isNotEmpty) { - newDomain = wellKnownInformation.mHomeserver.baseUrl; - } - } catch (_) { - // do nothing, newDomain is already set to a reasonable fallback - } - if (newDomain != oldHomeserver) { - await widget.client.checkHomeserver(newDomain); - - if (widget.client.homeserver == null) { - widget.client.homeserver = oldHomeserver; - // okay, the server we checked does not appear to be a matrix server - Logs().v( - '$newDomain is not running a homeserver, asking to use $oldHomeserver', - ); - final dialogResult = await showOkCancelAlertDialog( - context: context, - useRootNavigator: false, - title: L10n.of(context) - .noMatrixServer(newDomain.toString(), oldHomeserver.toString()), - okLabel: L10n.of(context).ok, - cancelLabel: L10n.of(context).cancel, - ); - if (dialogResult == OkCancelResult.ok) { - if (mounted) setState(() => usernameError = null); - } else { - Navigator.of(context, rootNavigator: false).pop(); - return; - } - } - usernameError = null; - if (mounted) setState(() {}); - } else { - widget.client.homeserver = oldHomeserver; - if (mounted) { - setState(() {}); - } - } - } catch (e) { - widget.client.homeserver = oldHomeserver; - usernameError = e.toLocalizedString(context); - if (mounted) setState(() {}); - } - } + // void _checkWellKnown(String userId) async { + // if (mounted) setState(() => usernameError = null); + // if (!userId.isValidMatrixId) return; + // final oldHomeserver = widget.client.homeserver; + // try { + // var newDomain = Uri.https(userId.domain!, ''); + // widget.client.homeserver = newDomain; + // DiscoveryInformation? wellKnownInformation; + // try { + // wellKnownInformation = await widget.client.getWellknown(); + // if (wellKnownInformation.mHomeserver.baseUrl.toString().isNotEmpty) { + // newDomain = wellKnownInformation.mHomeserver.baseUrl; + // } + // } catch (_) { + // // do nothing, newDomain is already set to a reasonable fallback + // } + // if (newDomain != oldHomeserver) { + // await widget.client.checkHomeserver(newDomain); + + // if (widget.client.homeserver == null) { + // widget.client.homeserver = oldHomeserver; + // // okay, the server we checked does not appear to be a matrix server + // Logs().v( + // '$newDomain is not running a homeserver, asking to use $oldHomeserver', + // ); + // final dialogResult = await showOkCancelAlertDialog( + // context: context, + // useRootNavigator: false, + // title: L10n.of(context) + // .noMatrixServer(newDomain.toString(), oldHomeserver.toString()), + // okLabel: L10n.of(context).ok, + // cancelLabel: L10n.of(context).cancel, + // ); + // if (dialogResult == OkCancelResult.ok) { + // if (mounted) setState(() => usernameError = null); + // } else { + // Navigator.of(context, rootNavigator: false).pop(); + // return; + // } + // } + // usernameError = null; + // if (mounted) setState(() {}); + // } else { + // widget.client.homeserver = oldHomeserver; + // if (mounted) { + // setState(() {}); + // } + // } + // } catch (e) { + // widget.client.homeserver = oldHomeserver; + // usernameError = e.toLocalizedString(context); + // if (mounted) setState(() {}); + // } + // } + // Pangea# void passwordForgotten() async { + // #Pangea + if (client == null) return; + // Pangea# final input = await showTextInputDialog( useRootNavigator: false, context: context, @@ -239,11 +250,18 @@ class LoginController extends State { final clientSecret = DateTime.now().millisecondsSinceEpoch.toString(); final response = await showFutureLoadingDialog( context: context, - future: () => widget.client.requestTokenToResetPasswordEmail( + // #Pangea + // future: () => widget.client.requestTokenToResetPasswordEmail( + // clientSecret, + // input, + // sendAttempt++, + // ), + future: () => client!.requestTokenToResetPasswordEmail( clientSecret, input, sendAttempt++, ), + // Pangea# ); if (response.error != null) return; final password = await showTextInputDialog( @@ -283,11 +301,18 @@ class LoginController extends State { }; final success = await showFutureLoadingDialog( context: context, - future: () => widget.client.request( + // #Pangea + // future: () => widget.client.request( + // RequestType.POST, + // '/client/v3/account/password', + // data: data, + // ), + future: () => client!.request( RequestType.POST, '/client/v3/account/password', data: data, ), + // Pangea# ); if (success.error == null) { ScaffoldMessenger.of(context).showSnackBar( diff --git a/lib/pages/login/login_view.dart b/lib/pages/login/login_view.dart index 15b42018e..7904e545f 100644 --- a/lib/pages/login/login_view.dart +++ b/lib/pages/login/login_view.dart @@ -1,145 +1,145 @@ -import 'package:flutter/material.dart'; +// import 'package:flutter/material.dart'; -import 'package:fluffychat/l10n/l10n.dart'; -import 'package:fluffychat/widgets/layouts/login_scaffold.dart'; -import 'package:fluffychat/widgets/matrix.dart'; -import 'login.dart'; +// import 'package:fluffychat/l10n/l10n.dart'; +// import 'package:fluffychat/widgets/layouts/login_scaffold.dart'; +// import 'package:fluffychat/widgets/matrix.dart'; +// import 'login.dart'; -class LoginView extends StatelessWidget { - final LoginController controller; +// class LoginView extends StatelessWidget { +// final LoginController controller; - const LoginView(this.controller, {super.key}); +// const LoginView(this.controller, {super.key}); - @override - Widget build(BuildContext context) { - final theme = Theme.of(context); +// @override +// Widget build(BuildContext context) { +// final theme = Theme.of(context); - final homeserver = controller.widget.client.homeserver - .toString() - .replaceFirst('https://', ''); - final title = L10n.of(context).logInTo(homeserver); - final titleParts = title.split(homeserver); +// final homeserver = controller.widget.client.homeserver +// .toString() +// .replaceFirst('https://', ''); +// final title = L10n.of(context).logInTo(homeserver); +// final titleParts = title.split(homeserver); - return LoginScaffold( - enforceMobileMode: - Matrix.of(context).widget.clients.any((client) => client.isLogged()), - appBar: AppBar( - leading: - controller.loadingSignIn ? null : const Center(child: BackButton()), - automaticallyImplyLeading: !controller.loadingSignIn, - titleSpacing: !controller.loadingSignIn ? 0 : null, - title: Text.rich( - TextSpan( - children: [ - TextSpan(text: titleParts.first), - TextSpan( - text: homeserver, - style: const TextStyle(fontWeight: FontWeight.bold), - ), - TextSpan(text: titleParts.last), - ], - ), - style: const TextStyle(fontSize: 18), - ), - ), - body: Builder( - builder: (context) { - return AutofillGroup( - child: ListView( - padding: const EdgeInsets.symmetric(horizontal: 8), - children: [ - Hero( - tag: 'info-logo', - child: Image.asset('assets/banner_transparent.png'), - ), - const SizedBox(height: 16), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 24.0), - child: TextField( - readOnly: controller.loadingSignIn, - autocorrect: false, - autofocus: true, - onChanged: controller.checkWellKnownWithCoolDown, - controller: controller.usernameController, - textInputAction: TextInputAction.next, - keyboardType: TextInputType.emailAddress, - autofillHints: controller.loadingSignIn - ? null - : [AutofillHints.username], - decoration: InputDecoration( - prefixIcon: const Icon(Icons.account_box_outlined), - errorText: controller.usernameError, - errorStyle: const TextStyle(color: Colors.orange), - hintText: '@username:domain', - labelText: L10n.of(context).emailOrUsername, - ), - ), - ), - const SizedBox(height: 16), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 24.0), - child: TextField( - readOnly: controller.loadingSignIn, - autocorrect: false, - autofillHints: controller.loadingSignIn - ? null - : [AutofillHints.password], - controller: controller.passwordController, - textInputAction: TextInputAction.go, - obscureText: !controller.showPassword, - onSubmitted: (_) => controller.login(), - decoration: InputDecoration( - prefixIcon: const Icon(Icons.lock_outlined), - errorText: controller.passwordError, - errorStyle: const TextStyle(color: Colors.orange), - suffixIcon: IconButton( - onPressed: controller.toggleShowPassword, - icon: Icon( - controller.showPassword - ? Icons.visibility_off_outlined - : Icons.visibility_outlined, - color: Colors.black, - ), - ), - hintText: '******', - labelText: L10n.of(context).password, - ), - ), - ), - const SizedBox(height: 16), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 24.0), - child: ElevatedButton( - style: ElevatedButton.styleFrom( - backgroundColor: theme.colorScheme.primary, - foregroundColor: theme.colorScheme.onPrimary, - ), - onPressed: - controller.loadingSignIn ? null : controller.login, - child: controller.loadingSignIn - ? const LinearProgressIndicator() - : Text(L10n.of(context).login), - ), - ), - const SizedBox(height: 16), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 24.0), - child: TextButton( - onPressed: controller.loadingSignIn - ? () {} - : controller.passwordForgotten, - style: TextButton.styleFrom( - foregroundColor: theme.colorScheme.error, - ), - child: Text(L10n.of(context).passwordForgotten), - ), - ), - const SizedBox(height: 16), - ], - ), - ); - }, - ), - ); - } -} +// return LoginScaffold( +// enforceMobileMode: +// Matrix.of(context).widget.clients.any((client) => client.isLogged()), +// appBar: AppBar( +// leading: +// controller.loadingSignIn ? null : const Center(child: BackButton()), +// automaticallyImplyLeading: !controller.loadingSignIn, +// titleSpacing: !controller.loadingSignIn ? 0 : null, +// title: Text.rich( +// TextSpan( +// children: [ +// TextSpan(text: titleParts.first), +// TextSpan( +// text: homeserver, +// style: const TextStyle(fontWeight: FontWeight.bold), +// ), +// TextSpan(text: titleParts.last), +// ], +// ), +// style: const TextStyle(fontSize: 18), +// ), +// ), +// body: Builder( +// builder: (context) { +// return AutofillGroup( +// child: ListView( +// padding: const EdgeInsets.symmetric(horizontal: 8), +// children: [ +// Hero( +// tag: 'info-logo', +// child: Image.asset('assets/banner_transparent.png'), +// ), +// const SizedBox(height: 16), +// Padding( +// padding: const EdgeInsets.symmetric(horizontal: 24.0), +// child: TextField( +// readOnly: controller.loadingSignIn, +// autocorrect: false, +// autofocus: true, +// onChanged: controller.checkWellKnownWithCoolDown, +// controller: controller.usernameController, +// textInputAction: TextInputAction.next, +// keyboardType: TextInputType.emailAddress, +// autofillHints: controller.loadingSignIn +// ? null +// : [AutofillHints.username], +// decoration: InputDecoration( +// prefixIcon: const Icon(Icons.account_box_outlined), +// errorText: controller.usernameError, +// errorStyle: const TextStyle(color: Colors.orange), +// hintText: '@username:domain', +// labelText: L10n.of(context).emailOrUsername, +// ), +// ), +// ), +// const SizedBox(height: 16), +// Padding( +// padding: const EdgeInsets.symmetric(horizontal: 24.0), +// child: TextField( +// readOnly: controller.loadingSignIn, +// autocorrect: false, +// autofillHints: controller.loadingSignIn +// ? null +// : [AutofillHints.password], +// controller: controller.passwordController, +// textInputAction: TextInputAction.go, +// obscureText: !controller.showPassword, +// onSubmitted: (_) => controller.login(), +// decoration: InputDecoration( +// prefixIcon: const Icon(Icons.lock_outlined), +// errorText: controller.passwordError, +// errorStyle: const TextStyle(color: Colors.orange), +// suffixIcon: IconButton( +// onPressed: controller.toggleShowPassword, +// icon: Icon( +// controller.showPassword +// ? Icons.visibility_off_outlined +// : Icons.visibility_outlined, +// color: Colors.black, +// ), +// ), +// hintText: '******', +// labelText: L10n.of(context).password, +// ), +// ), +// ), +// const SizedBox(height: 16), +// Padding( +// padding: const EdgeInsets.symmetric(horizontal: 24.0), +// child: ElevatedButton( +// style: ElevatedButton.styleFrom( +// backgroundColor: theme.colorScheme.primary, +// foregroundColor: theme.colorScheme.onPrimary, +// ), +// onPressed: +// controller.loadingSignIn ? null : controller.login, +// child: controller.loadingSignIn +// ? const LinearProgressIndicator() +// : Text(L10n.of(context).login), +// ), +// ), +// const SizedBox(height: 16), +// Padding( +// padding: const EdgeInsets.symmetric(horizontal: 24.0), +// child: TextButton( +// onPressed: controller.loadingSignIn +// ? () {} +// : controller.passwordForgotten, +// style: TextButton.styleFrom( +// foregroundColor: theme.colorScheme.error, +// ), +// child: Text(L10n.of(context).passwordForgotten), +// ), +// ), +// const SizedBox(height: 16), +// ], +// ), +// ); +// }, +// ), +// ); +// } +// } diff --git a/lib/pangea/login/pages/pangea_login_view.dart b/lib/pangea/login/pages/pangea_login_view.dart index e55551186..1fd205a3d 100644 --- a/lib/pangea/login/pages/pangea_login_view.dart +++ b/lib/pangea/login/pages/pangea_login_view.dart @@ -69,7 +69,7 @@ class PangeaLoginView extends StatelessWidget { Padding( padding: const EdgeInsets.all(4.0), child: TextButton( - onPressed: controller.loadingSignIn + onPressed: controller.loadingSignIn || controller.client == null ? () {} : controller.passwordForgotten, style: TextButton.styleFrom(