import 'dart:async'; import 'package:flutter/material.dart'; import 'package:matrix/matrix.dart'; import 'package:vrouter/vrouter.dart'; import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/pages/homeserver_picker/homeserver_picker_view.dart'; import 'package:fluffychat/widgets/matrix.dart'; import '../../utils/localized_exception_extension.dart'; class HomeserverPicker extends StatefulWidget { const HomeserverPicker({Key? key}) : super(key: key); @override HomeserverPickerController createState() => HomeserverPickerController(); } class HomeserverPickerController extends State { bool isLoading = false; final TextEditingController homeserverController = TextEditingController(text: AppConfig.defaultHomeserver); String? error; /// Starts an analysis of the given homeserver. It uses the current domain and /// makes sure that it is prefixed with https. Then it searches for the /// well-known information and forwards to the login page depending on the /// login type. Future checkHomeserverAction() async { setState(() { error = null; isLoading = true; }); try { homeserverController.text = homeserverController.text.trim().toLowerCase().replaceAll(' ', '-'); var homeserver = Uri.parse(homeserverController.text); if (homeserver.scheme.isEmpty) { homeserver = Uri.https(homeserverController.text, ''); } final matrix = Matrix.of(context); matrix.loginHomeserverSummary = await matrix.getLoginClient().checkHomeserver(homeserver); final ssoSupported = matrix.loginHomeserverSummary!.loginFlows .any((flow) => flow.type == 'm.login.sso'); try { await Matrix.of(context).getLoginClient().register(); matrix.loginRegistrationSupported = true; } on MatrixException catch (e) { matrix.loginRegistrationSupported = e.requireAdditionalAuthentication; } if (!ssoSupported && matrix.loginRegistrationSupported == false) { // Server does not support SSO or registration. We can skip to login page: VRouter.of(context).to('login'); } else { VRouter.of(context).to('connect'); } } catch (e) { setState(() => error = (e).toLocalizedString(context)); } finally { if (mounted) { setState(() => isLoading = false); } } } @override Widget build(BuildContext context) { Matrix.of(context).navigatorContext = context; return HomeserverPickerView(this); } }