chore: load client within login page instead of passing to route (#3434)
This commit is contained in:
parent
7e07289ae7
commit
0b577270a5
4 changed files with 240 additions and 213 deletions
|
|
@ -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,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -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<Login> {
|
|||
final PangeaController pangeaController = MatrixState.pangeaController;
|
||||
final GlobalKey<FormState> formKey = GlobalKey<FormState>();
|
||||
|
||||
Client? client;
|
||||
|
||||
bool get enabledSignIn =>
|
||||
!loadingSignIn &&
|
||||
usernameController.text.isNotEmpty &&
|
||||
|
|
@ -66,6 +70,10 @@ class LoginController extends State<Login> {
|
|||
|
||||
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<Login> {
|
|||
|
||||
// if (mounted) setState(() => loading = false);
|
||||
// }
|
||||
|
||||
// Timer? _coolDown;
|
||||
|
||||
// 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(() {});
|
||||
// }
|
||||
// }
|
||||
// Pangea#
|
||||
|
||||
Timer? _coolDown;
|
||||
|
||||
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 passwordForgotten() async {
|
||||
// #Pangea
|
||||
if (client == null) return;
|
||||
// Pangea#
|
||||
final input = await showTextInputDialog(
|
||||
useRootNavigator: false,
|
||||
context: context,
|
||||
|
|
@ -239,11 +250,18 @@ class LoginController extends State<Login> {
|
|||
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<Login> {
|
|||
};
|
||||
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(
|
||||
|
|
|
|||
|
|
@ -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: <Widget>[
|
||||
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: <Widget>[
|
||||
// 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),
|
||||
// ],
|
||||
// ),
|
||||
// );
|
||||
// },
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue