diff --git a/lib/config/routes.dart b/lib/config/routes.dart index 9c0710a8..4e0b4747 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -1,5 +1,6 @@ import 'package:adaptive_page_layout/adaptive_page_layout.dart'; import 'package:famedlysdk/famedlysdk.dart'; +import 'package:fluffychat/controllers/homeserver_picker_controller.dart'; import 'package:fluffychat/views/widgets/matrix.dart'; import 'package:fluffychat/views/archive.dart'; import 'package:fluffychat/views/chat.dart'; @@ -8,7 +9,6 @@ import 'package:fluffychat/views/chat_encryption_settings.dart'; import 'package:fluffychat/views/chat_list.dart'; import 'package:fluffychat/views/chat_permissions_settings.dart'; import 'package:fluffychat/views/empty_page.dart'; -import 'package:fluffychat/views/homeserver_picker.dart'; import 'package:fluffychat/views/invitation_selection.dart'; import 'package:fluffychat/views/loading_view.dart'; import 'package:fluffychat/views/log_view.dart'; diff --git a/lib/views/homeserver_picker.dart b/lib/controllers/homeserver_picker_controller.dart similarity index 51% rename from lib/views/homeserver_picker.dart rename to lib/controllers/homeserver_picker_controller.dart index d81f1996..ad103d5d 100644 --- a/lib/views/homeserver_picker.dart +++ b/lib/controllers/homeserver_picker_controller.dart @@ -2,11 +2,9 @@ import 'dart:async'; import 'package:adaptive_page_layout/adaptive_page_layout.dart'; import 'package:famedlysdk/famedlysdk.dart'; -import 'package:fluffychat/views/widgets/default_app_bar_search_field.dart'; -import 'package:fluffychat/views/widgets/fluffy_banner.dart'; +import 'package:fluffychat/views/homeserver_picker_view.dart'; import 'package:fluffychat/views/widgets/matrix.dart'; import 'package:fluffychat/app_config.dart'; -import 'package:fluffychat/views/widgets/one_page_card.dart'; import 'package:fluffychat/config/setting_keys.dart'; import 'package:fluffychat/utils/platform_infos.dart'; @@ -21,13 +19,13 @@ import 'package:universal_html/prefer_universal/html.dart' as html; class HomeserverPicker extends StatefulWidget { @override - _HomeserverPickerState createState() => _HomeserverPickerState(); + HomeserverPickerController createState() => HomeserverPickerController(); } -class _HomeserverPickerState extends State { - bool _isLoading = false; - String _domain = AppConfig.defaultHomeserver; - final TextEditingController _controller = +class HomeserverPickerController extends State { + bool isLoading = false; + String domain = AppConfig.defaultHomeserver; + final TextEditingController homeserverController = TextEditingController(text: AppConfig.defaultHomeserver); StreamSubscription _intentDataStreamSubscription; @@ -61,6 +59,13 @@ class _HomeserverPickerState extends State { void initState() { super.initState(); _initReceiveSharingContent(); + if (kIsWeb) { + WidgetsBinding.instance.addPostFrameCallback((_) { + final token = + Uri.parse(html.window.location.href).queryParameters['loginToken']; + _loginWithToken(token); + }); + } } @override @@ -69,16 +74,21 @@ class _HomeserverPickerState extends State { _intentDataStreamSubscription?.cancel(); } - void _checkHomeserverAction(BuildContext context) async { + /// 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. For SSO login only the app opens the page and otherwise it + /// forwards to the route `/signup`. + void checkHomeserverAction() async { try { - if (_domain.isEmpty) throw L10n.of(context).changeTheHomeserver; - var homeserver = _domain; + if (domain.isEmpty) throw L10n.of(context).changeTheHomeserver; + var homeserver = domain; if (!homeserver.startsWith('https://')) { homeserver = 'https://$homeserver'; } - setState(() => _isLoading = true); + setState(() => isLoading = true); final wellKnown = await Matrix.of(context).client.checkHomeserver(homeserver); @@ -114,105 +124,11 @@ class _HomeserverPickerState extends State { SnackBar(content: Text((e as Object).toLocalizedString(context)))); } finally { if (mounted) { - setState(() => _isLoading = false); + setState(() => isLoading = false); } } } @override - Widget build(BuildContext context) { - if (kIsWeb) { - WidgetsBinding.instance.addPostFrameCallback((_) { - final token = - Uri.parse(html.window.location.href).queryParameters['loginToken']; - _loginWithToken(token); - }); - } - return OnePageCard( - child: Scaffold( - appBar: AppBar( - titleSpacing: 8, - title: DefaultAppBarSearchField( - prefixText: 'https://', - hintText: L10n.of(context).enterYourHomeserver, - searchController: _controller, - suffix: Icon(Icons.edit_outlined), - padding: EdgeInsets.zero, - onChanged: (s) => _domain = s, - readOnly: !AppConfig.allowOtherHomeservers, - onSubmit: (_) => _checkHomeserverAction(context), - ), - elevation: 0, - ), - body: SafeArea( - child: ListView( - children: [ - Hero( - tag: 'loginBanner', - child: FluffyBanner(), - ), - Padding( - padding: const EdgeInsets.all(16.0), - child: Text( - AppConfig.applicationWelcomeMessage ?? - L10n.of(context).welcomeText, - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 22, - ), - ), - ), - ], - ), - ), - bottomNavigationBar: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Hero( - tag: 'loginButton', - child: Container( - width: double.infinity, - padding: EdgeInsets.symmetric(horizontal: 12), - child: ElevatedButton( - onPressed: - _isLoading ? null : () => _checkHomeserverAction(context), - child: _isLoading - ? LinearProgressIndicator() - : Text( - L10n.of(context).connect.toUpperCase(), - style: TextStyle(color: Colors.white, fontSize: 16), - ), - ), - ), - ), - Wrap( - alignment: WrapAlignment.center, - children: [ - TextButton( - onPressed: () => launch(AppConfig.privacyUrl), - child: Text( - L10n.of(context).privacy, - style: TextStyle( - decoration: TextDecoration.underline, - color: Colors.blueGrey, - ), - ), - ), - TextButton( - onPressed: () => PlatformInfos.showDialog(context), - child: Text( - L10n.of(context).about, - style: TextStyle( - decoration: TextDecoration.underline, - color: Colors.blueGrey, - ), - ), - ), - ], - ), - ], - ), - ), - ); - } + Widget build(BuildContext context) => HomeserverPickerView(this); } diff --git a/lib/views/homeserver_picker_view.dart b/lib/views/homeserver_picker_view.dart new file mode 100644 index 00000000..ff128279 --- /dev/null +++ b/lib/views/homeserver_picker_view.dart @@ -0,0 +1,111 @@ +import 'package:fluffychat/controllers/homeserver_picker_controller.dart'; +import 'package:fluffychat/views/widgets/default_app_bar_search_field.dart'; +import 'package:fluffychat/views/widgets/fluffy_banner.dart'; +import 'package:fluffychat/app_config.dart'; +import 'package:fluffychat/views/widgets/one_page_card.dart'; +import 'package:fluffychat/utils/platform_infos.dart'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:flutter/material.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class HomeserverPickerView extends StatelessWidget { + final HomeserverPickerController controller; + + const HomeserverPickerView( + this.controller, { + Key key, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return OnePageCard( + child: Scaffold( + appBar: AppBar( + titleSpacing: 8, + title: DefaultAppBarSearchField( + prefixText: 'https://', + hintText: L10n.of(context).enterYourHomeserver, + searchController: controller.homeserverController, + suffix: Icon(Icons.edit_outlined), + padding: EdgeInsets.zero, + onChanged: (s) => controller.domain = s, + readOnly: !AppConfig.allowOtherHomeservers, + onSubmit: (_) => controller.checkHomeserverAction, + ), + elevation: 0, + ), + body: SafeArea( + child: ListView( + children: [ + Hero( + tag: 'loginBanner', + child: FluffyBanner(), + ), + Padding( + padding: const EdgeInsets.all(16.0), + child: Text( + AppConfig.applicationWelcomeMessage ?? + L10n.of(context).welcomeText, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 22, + ), + ), + ), + ], + ), + ), + bottomNavigationBar: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Hero( + tag: 'loginButton', + child: Container( + width: double.infinity, + padding: EdgeInsets.symmetric(horizontal: 12), + child: ElevatedButton( + onPressed: controller.isLoading + ? null + : controller.checkHomeserverAction, + child: controller.isLoading + ? LinearProgressIndicator() + : Text( + L10n.of(context).connect.toUpperCase(), + style: TextStyle(color: Colors.white, fontSize: 16), + ), + ), + ), + ), + Wrap( + alignment: WrapAlignment.center, + children: [ + TextButton( + onPressed: () => launch(AppConfig.privacyUrl), + child: Text( + L10n.of(context).privacy, + style: TextStyle( + decoration: TextDecoration.underline, + color: Colors.blueGrey, + ), + ), + ), + TextButton( + onPressed: () => PlatformInfos.showDialog(context), + child: Text( + L10n.of(context).about, + style: TextStyle( + decoration: TextDecoration.underline, + color: Colors.blueGrey, + ), + ), + ), + ], + ), + ], + ), + ), + ); + } +}