diff --git a/lib/components/sentry_switch_list_tile.dart b/lib/components/sentry_switch_list_tile.dart new file mode 100644 index 00000000..943213c4 --- /dev/null +++ b/lib/components/sentry_switch_list_tile.dart @@ -0,0 +1,29 @@ +import 'package:fluffychat/utils/sentry_controller.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +class SentrySwitchListTile extends StatefulWidget { + @override + _SentrySwitchListTileState createState() => _SentrySwitchListTileState(); +} + +class _SentrySwitchListTileState extends State { + bool _enabled = false; + + @override + Widget build(BuildContext context) { + return FutureBuilder( + future: SentryController.getSentryStatus(), + builder: (context, snapshot) { + _enabled = snapshot.data ?? false; + return SwitchListTile( + title: Text(L10n.of(context).sendBugReports), + value: _enabled, + onChanged: (b) => + SentryController.toggleSentryAction(context, b).then( + (_) => setState(() => null), + ), + ); + }); + } +} diff --git a/lib/main.dart b/lib/main.dart index 89b6c495..ed8398ee 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -3,6 +3,7 @@ import 'dart:async'; import 'package:adaptive_theme/adaptive_theme.dart'; import 'package:adaptive_page_layout/adaptive_page_layout.dart'; +import 'package:famedlysdk/famedlysdk.dart'; import 'package:fluffychat/config/routes.dart'; import 'package:fluffychat/utils/sentry_controller.dart'; import 'package:flutter/cupertino.dart'; @@ -56,9 +57,9 @@ class App extends StatelessWidget { dividerColor: Theme.of(context).dividerColor, columnWidth: FluffyThemes.columnWidth, routeBuilder: (builder, settings) => - _apl.currentState.columnMode(context) - ? FadeRoute(page: builder(context)) - : CupertinoPageRoute(builder: builder), + Matrix.of(context).loginState == LoginState.logged + ? CupertinoPageRoute(builder: builder) + : FadeRoute(page: builder(context)), ), ), ), diff --git a/lib/utils/sentry_controller.dart b/lib/utils/sentry_controller.dart index 28724444..61090ba1 100644 --- a/lib/utils/sentry_controller.dart +++ b/lib/utils/sentry_controller.dart @@ -1,31 +1,18 @@ -import 'package:adaptive_dialog/adaptive_dialog.dart'; import 'package:famedlysdk/famedlysdk.dart'; -import 'package:flushbar/flushbar_helper.dart'; import 'package:fluffychat/app_config.dart'; import 'package:flutter/material.dart'; import 'package:flutter/foundation.dart'; -import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:sentry/sentry.dart'; import 'famedlysdk_store.dart'; import '../config/setting_keys.dart'; abstract class SentryController { - static Future toggleSentryAction(BuildContext context) async { + static Future toggleSentryAction( + BuildContext context, bool enableSentry) async { if (!AppConfig.enableSentry) return; - final enableSentry = await showOkCancelAlertDialog( - context: context, - title: L10n.of(context).sendBugReports, - message: L10n.of(context).sentryInfo, - okLabel: L10n.of(context).ok, - cancelLabel: L10n.of(context).no, - ) == - OkCancelResult.ok; final storage = Store(); await storage.setItem(SettingKeys.sentry, enableSentry.toString()); - // ignore: unawaited_futures - FlushbarHelper.createSuccess(message: L10n.of(context).changesHaveBeenSaved) - .show(context); return; } diff --git a/lib/views/homeserver_picker.dart b/lib/views/homeserver_picker.dart index a3243d20..a27e3197 100644 --- a/lib/views/homeserver_picker.dart +++ b/lib/views/homeserver_picker.dart @@ -1,100 +1,101 @@ import 'dart:math'; -import 'package:adaptive_dialog/adaptive_dialog.dart'; import 'package:adaptive_page_layout/adaptive_page_layout.dart'; -import 'package:famedlysdk/famedlysdk.dart'; -import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:fluffychat/components/matrix.dart'; import 'package:fluffychat/app_config.dart'; +import 'package:fluffychat/components/sentry_switch_list_tile.dart'; +import 'package:flushbar/flushbar_helper.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; -import 'package:fluffychat/utils/sentry_controller.dart'; import 'package:flutter/material.dart'; import 'package:url_launcher/url_launcher.dart'; +import '../utils/localized_exception_extension.dart'; -class HomeserverPicker extends StatelessWidget { - Future _setHomeserverAction(BuildContext context) async { - const prefix = 'https://'; - final homeserver = await showTextInputDialog( - title: L10n.of(context).enterYourHomeserver, - context: context, - textFields: [ - DialogTextField( - hintText: AppConfig.defaultHomeserver, - prefixText: prefix, - keyboardType: TextInputType.url, - ) - ], - ); - if (homeserver?.single?.isEmpty ?? true) return; - _checkHomeserverAction(prefix + homeserver.single, context); - } +class HomeserverPicker extends StatefulWidget { + @override + _HomeserverPickerState createState() => _HomeserverPickerState(); +} - void _checkHomeserverAction(String homeserver, BuildContext context) async { - if (await SentryController.getSentryStatus() == null || true) { - await SentryController.toggleSentryAction(context); - } +class _HomeserverPickerState extends State { + final TextEditingController _controller = + TextEditingController(text: AppConfig.defaultHomeserver); + + bool _isLoading = false; + + void _checkHomeserverAction(BuildContext context) async { + var homeserver = _controller.text; if (!homeserver.startsWith('https://')) { homeserver = 'https://$homeserver'; } - final success = await showFutureLoadingDialog( - context: context, - future: () => checkHomeserver(homeserver, Matrix.of(context).client)); - if (success.result == true) { + setState(() => _isLoading = true); + try { + await Matrix.of(context).client.checkHomeserver(homeserver); await AdaptivePageLayout.of(context) .pushNamed(AppConfig.enableRegistration ? '/signup' : '/login'); + } catch (e) { + // ignore: unawaited_futures + FlushbarHelper.createError( + title: L10n.of(context).noConnectionToTheServer, + message: (e as Object).toLocalizedString(context)) + .show(context); + } finally { + if (mounted) { + setState(() => _isLoading = false); + } } } - Future checkHomeserver(dynamic homeserver, Client client) async { - await client.checkHomeserver(homeserver); - return true; - } - @override Widget build(BuildContext context) { return Scaffold( + appBar: AppBar( + title: Container( + height: 40, + child: Material( + color: Theme.of(context).secondaryHeaderColor, + borderRadius: BorderRadius.circular(32), + child: TextField( + controller: _controller, + autocorrect: false, + readOnly: !AppConfig.allowOtherHomeservers, + decoration: InputDecoration( + prefixText: 'https://', + suffix: Icon(Icons.domain_outlined), + contentPadding: EdgeInsets.only( + left: 24, + right: 16, + ), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(32), + ), + labelText: L10n.of(context).changeTheHomeserver, + hintText: AppConfig.defaultHomeserver, + ), + ), + ), + ), + ), body: SafeArea( child: Padding( padding: EdgeInsets.symmetric( horizontal: max((MediaQuery.of(context).size.width - 600) / 2, 0)), - child: Column( - children: [ - Expanded( - child: ListView( - children: [ - Hero( - tag: 'loginBanner', - child: InkWell( - onTap: () => showAboutDialog( - context: context, - children: [ - RaisedButton( - child: Text(L10n.of(context).privacy), - onPressed: () => launch(AppConfig.privacyUrl), - ) - ], - applicationIcon: Image.asset('assets/logo.png', - width: 100, height: 100), - applicationName: AppConfig.applicationName, - ), - child: Image.asset('assets/banner.png'), - ), - ), - Padding( - padding: const EdgeInsets.all(16.0), - child: Text( - AppConfig.applicationWelcomeMessage ?? - L10n.of(context).welcomeText, - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 22, - ), - ), - ), - ], + child: ListView( + children: [ + Hero( + tag: 'loginBanner', + child: Image.asset('assets/banner.png'), + ), + Padding( + padding: const EdgeInsets.all(16.0), + child: Text( + AppConfig.applicationWelcomeMessage ?? + L10n.of(context).welcomeText, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 22, + ), ), ), SizedBox(height: 16), @@ -110,42 +111,48 @@ class HomeserverPicker extends StatelessWidget { shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(6), ), - child: Text( - L10n.of(context).connect.toUpperCase(), - style: TextStyle(color: Colors.white, fontSize: 16), - ), - onPressed: () => _checkHomeserverAction( - AppConfig.defaultHomeserver, context), - ), - ), - ), - Padding( - padding: - const EdgeInsets.only(left: 16.0, right: 16.0, top: 16.0), - child: Text( - L10n.of(context).byDefaultYouWillBeConnectedTo( - AppConfig.defaultHomeserver), - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 16, + child: _isLoading + ? LinearProgressIndicator() + : Text( + L10n.of(context).connect.toUpperCase(), + style: TextStyle(color: Colors.white, fontSize: 16), + ), + onPressed: _isLoading + ? null + : () => _checkHomeserverAction(context), ), ), ), + SentrySwitchListTile(), Wrap( + alignment: WrapAlignment.center, children: [ - if (AppConfig.allowOtherHomeservers) - FlatButton( - padding: EdgeInsets.all(8), - child: Text( - L10n.of(context).changeTheHomeserver, - style: TextStyle( - decoration: TextDecoration.underline, - color: Theme.of(context).primaryColor, - fontSize: 16, - ), + FlatButton( + padding: EdgeInsets.all(8), + child: Text( + L10n.of(context).about, + style: TextStyle( + decoration: TextDecoration.underline, + fontSize: 16, ), - onPressed: () => _setHomeserverAction(context), ), + onPressed: () => showAboutDialog( + context: context, + children: [ + RaisedButton( + child: Text(L10n.of(context).sourceCode), + onPressed: () => launch(AppConfig.sourceCodeUrl), + ), + RaisedButton( + child: Text(L10n.of(context).help), + onPressed: () => launch(AppConfig.supportUrl), + ), + ], + applicationIcon: Image.asset('assets/logo.png', + width: 100, height: 100), + applicationName: AppConfig.applicationName, + ), + ), FlatButton( padding: EdgeInsets.all(8), child: Text( diff --git a/lib/views/settings.dart b/lib/views/settings.dart index 54d6530e..59fd9bab 100644 --- a/lib/views/settings.dart +++ b/lib/views/settings.dart @@ -1,6 +1,7 @@ import 'package:adaptive_dialog/adaptive_dialog.dart'; import 'package:adaptive_page_layout/adaptive_page_layout.dart'; import 'package:fluffychat/components/dialogs/bootstrap_dialog.dart'; +import 'package:fluffychat/components/sentry_switch_list_tile.dart'; import 'package:flushbar/flushbar_helper.dart'; import 'package:famedlysdk/famedlysdk.dart'; import 'package:file_picker_cross/file_picker_cross.dart'; @@ -406,11 +407,7 @@ class _SettingsState extends State { onTap: () => AdaptivePageLayout.of(context).pushNamed('/settings/ignore'), ), - ListTile( - trailing: Icon(Icons.bug_report_outlined), - title: Text(L10n.of(context).sendBugReports), - onTap: () => SentryController.toggleSentryAction(context), - ), + SentrySwitchListTile(), Divider(thickness: 1), ListTile( trailing: Icon(Icons.security_outlined),