From 0b570b86f004fd10a1a286e45b47fb1de423a938 Mon Sep 17 00:00:00 2001 From: Christian Pauly Date: Sun, 12 Apr 2020 09:19:22 +0200 Subject: [PATCH] Fix login and toasts --- lib/components/encryption_button.dart | 15 +- lib/components/list_items/chat_list_item.dart | 9 +- lib/components/matrix.dart | 42 ++--- lib/components/message_content.dart | 8 +- lib/main.dart | 70 +++++---- lib/views/chat.dart | 25 +-- lib/views/chat_details.dart | 33 +--- lib/views/invitation_selection.dart | 9 +- lib/views/login.dart | 146 +++++++++--------- lib/views/sign_up_password.dart | 17 +- pubspec.lock | 29 ++-- pubspec.yaml | 3 +- 12 files changed, 166 insertions(+), 240 deletions(-) diff --git a/lib/components/encryption_button.dart b/lib/components/encryption_button.dart index 9340fcf..37b5cc2 100644 --- a/lib/components/encryption_button.dart +++ b/lib/components/encryption_button.dart @@ -5,6 +5,7 @@ import 'package:fluffychat/i18n/i18n.dart'; import 'package:fluffychat/utils/app_route.dart'; import 'package:fluffychat/views/chat_encryption_settings.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_styled_toast/flutter_styled_toast.dart'; import 'dialogs/simple_dialogs.dart'; import 'matrix.dart'; @@ -21,11 +22,7 @@ class _EncryptionButtonState extends State { void _enableEncryptionAction() async { if (widget.room.encrypted) { - Scaffold.of(context).showSnackBar( - SnackBar( - content: Text(I18n.of(context).warningEncryptionInBeta), - ), - ); + showToast(I18n.of(context).warningEncryptionInBeta); await Navigator.of(context).push( AppRoute.defaultRoute( context, @@ -35,13 +32,7 @@ class _EncryptionButtonState extends State { return; } if (!widget.room.client.encryptionEnabled) { - Scaffold.of(context).showSnackBar( - SnackBar( - content: Text( - I18n.of(context).needPantalaimonWarning, - ), - ), - ); + showToast(I18n.of(context).needPantalaimonWarning); return; } if (await SimpleDialogs(context).askConfirmation( diff --git a/lib/components/list_items/chat_list_item.dart b/lib/components/list_items/chat_list_item.dart index 2a63b5e..d9f57f3 100644 --- a/lib/components/list_items/chat_list_item.dart +++ b/lib/components/list_items/chat_list_item.dart @@ -2,6 +2,7 @@ import 'package:famedlysdk/famedlysdk.dart'; import 'package:fluffychat/views/chat.dart'; import 'package:flutter/material.dart'; import 'package:flutter_slidable/flutter_slidable.dart'; +import 'package:flutter_styled_toast/flutter_styled_toast.dart'; import 'package:pedantic/pedantic.dart'; import '../../i18n/i18n.dart'; @@ -31,13 +32,7 @@ class ChatListItem extends StatelessWidget { } if (room.membership == Membership.ban) { - Scaffold.of(context).showSnackBar( - SnackBar( - content: Text( - I18n.of(context).youHaveBeenBannedFromThisChat, - ), - ), - ); + showToast(I18n.of(context).youHaveBeenBannedFromThisChat); return; } diff --git a/lib/components/matrix.dart b/lib/components/matrix.dart index 1e1b543..bf346ed 100644 --- a/lib/components/matrix.dart +++ b/lib/components/matrix.dart @@ -8,6 +8,7 @@ import 'package:fluffychat/components/dialogs/simple_dialogs.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; +import 'package:flutter_styled_toast/flutter_styled_toast.dart'; import 'package:localstorage/localstorage.dart'; import 'package:path_provider/path_provider.dart'; import 'package:url_launcher/url_launcher.dart'; @@ -95,22 +96,10 @@ class MatrixState extends State { onAdditionalAuth != null) { return await tryRequestWithErrorToast(onAdditionalAuth(exception)); } else { - Scaffold.of(context).showSnackBar( - SnackBar( - content: Text( - exception.errorMessage, - ), - ), - ); + showToast(exception.errorMessage); } } catch (exception) { - Scaffold.of(context).showSnackBar( - SnackBar( - content: Text( - exception.toString(), - ), - ), - ); + showToast(exception.toString()); return false; } } @@ -158,15 +147,14 @@ class MatrixState extends State { Future setupFirebase() async { if (Platform.isIOS) iOS_Permission(); - final String token = await _firebaseMessaging.getToken(); + String token; + try { + token = await _firebaseMessaging.getToken(); + } catch (_) { + token = null; + } if (token?.isEmpty ?? true) { - return Scaffold.of(context).showSnackBar( - SnackBar( - content: Text( - I18n.of(context).noGoogleServicesWarning, - ), - ), - ); + showToast(I18n.of(context).noGoogleServicesWarning); } await client.setPushers( token, @@ -196,13 +184,7 @@ class MatrixState extends State { ), (r) => r.isFirst); } catch (_) { - Scaffold.of(context).showSnackBar( - SnackBar( - content: Text( - "Failed to open chat...", - ), - ), - ); + showToast("Failed to open chat..."); debugPrint(_); } }; @@ -419,7 +401,7 @@ class MatrixState extends State { void initState() { if (widget.client == null) { debugPrint("[Matrix] Init matrix client"); - client = Client(widget.clientName, debug: false); + client = Client(widget.clientName, debug: true); onJitsiCallSub ??= client.onEvent.stream .where((e) => e.type == 'timeline' && diff --git a/lib/components/message_content.dart b/lib/components/message_content.dart index b17206c..7b41d8d 100644 --- a/lib/components/message_content.dart +++ b/lib/components/message_content.dart @@ -5,6 +5,7 @@ import 'package:fluffychat/i18n/i18n.dart'; import 'package:fluffychat/utils/event_extension.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_styled_toast/flutter_styled_toast.dart'; import 'package:link_text/link_text.dart'; import 'package:url_launcher/url_launcher.dart'; import 'package:fluffychat/utils/matrix_file_extension.dart'; @@ -51,12 +52,7 @@ class MessageContent extends StatelessWidget { onPressed: () async { if (kIsWeb) { if (event.room.encrypted) { - Scaffold.of(context).showSnackBar( - SnackBar( - content: - Text(I18n.of(context).notSupportedInWeb), - ), - ); + showToast(I18n.of(context).notSupportedInWeb); } await launch( MxContent(event.content["url"]) diff --git a/lib/main.dart b/lib/main.dart index 114cbde..db9bf5f 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -5,6 +5,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:flutter_styled_toast/flutter_styled_toast.dart'; import 'i18n/i18n.dart'; import 'views/sign_up.dart'; @@ -28,38 +29,43 @@ class App extends StatelessWidget { child: Builder( builder: (BuildContext context) => ThemeSwitcherWidget( child: Builder( - builder: (BuildContext context) => MaterialApp( - title: 'FluffyChat', - theme: ThemeSwitcherWidget.of(context).themeData, - localizationsDelegates: [ - AppLocalizationsDelegate(), - GlobalMaterialLocalizations.delegate, - GlobalWidgetsLocalizations.delegate, - GlobalCupertinoLocalizations.delegate, - ], - supportedLocales: [ - const Locale('en'), // English - const Locale('de'), // German - ], - locale: kIsWeb - ? Locale(html.window.navigator.language.split("-").first) - : null, - home: FutureBuilder( - future: - Matrix.of(context).client.onLoginStateChanged.stream.first, - builder: (context, snapshot) { - if (!snapshot.hasData) { - return Scaffold( - body: Center( - child: CircularProgressIndicator(), - ), - ); - } - if (Matrix.of(context).client.isLogged()) { - return ChatListView(); - } - return SignUp(); - }, + builder: (BuildContext context) => StyledToast( + child: MaterialApp( + title: 'FluffyChat', + theme: ThemeSwitcherWidget.of(context).themeData, + localizationsDelegates: [ + AppLocalizationsDelegate(), + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + ], + supportedLocales: [ + const Locale('en'), // English + const Locale('de'), // German + ], + locale: kIsWeb + ? Locale(html.window.navigator.language.split("-").first) + : null, + home: FutureBuilder( + future: Matrix.of(context) + .client + .onLoginStateChanged + .stream + .first, + builder: (context, snapshot) { + if (!snapshot.hasData) { + return Scaffold( + body: Center( + child: CircularProgressIndicator(), + ), + ); + } + if (Matrix.of(context).client.isLogged()) { + return ChatListView(); + } + return SignUp(); + }, + ), ), ), ), diff --git a/lib/views/chat.dart b/lib/views/chat.dart index ae7decc..04dbda4 100644 --- a/lib/views/chat.dart +++ b/lib/views/chat.dart @@ -17,6 +17,7 @@ import 'package:fluffychat/utils/room_extension.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:flutter_styled_toast/flutter_styled_toast.dart'; import 'package:image_picker/image_picker.dart'; import 'package:pedantic/pedantic.dart'; @@ -176,13 +177,7 @@ class _ChatState extends State<_Chat> { void sendFileAction(BuildContext context) async { if (kIsWeb) { - Scaffold.of(context).showSnackBar( - SnackBar( - content: Text( - I18n.of(context).notSupportedInWeb, - ), - ), - ); + showToast(I18n.of(context).notSupportedInWeb); return; } File file = await FilePicker.getFile(); @@ -196,13 +191,7 @@ class _ChatState extends State<_Chat> { void sendImageAction(BuildContext context) async { if (kIsWeb) { - Scaffold.of(context).showSnackBar( - SnackBar( - content: Text( - I18n.of(context).notSupportedInWeb, - ), - ), - ); + showToast(I18n.of(context).notSupportedInWeb); return; } File file = await ImagePicker.pickImage( @@ -220,13 +209,7 @@ class _ChatState extends State<_Chat> { void openCameraAction(BuildContext context) async { if (kIsWeb) { - Scaffold.of(context).showSnackBar( - SnackBar( - content: Text( - I18n.of(context).notSupportedInWeb, - ), - ), - ); + showToast(I18n.of(context).notSupportedInWeb); return; } File file = await ImagePicker.pickImage( diff --git a/lib/views/chat_details.dart b/lib/views/chat_details.dart index dda7ec9..1705692 100644 --- a/lib/views/chat_details.dart +++ b/lib/views/chat_details.dart @@ -17,6 +17,7 @@ import 'package:fluffychat/views/invitation_selection.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:flutter_styled_toast/flutter_styled_toast.dart'; import 'package:image_picker/image_picker.dart'; import 'package:link_text/link_text.dart'; @@ -43,13 +44,7 @@ class _ChatDetailsState extends State { widget.room.setName(displayname), ); if (success != false) { - Scaffold.of(context).showSnackBar( - SnackBar( - content: Text( - I18n.of(context).displaynameHasBeenChanged, - ), - ), - ); + showToast(I18n.of(context).displaynameHasBeenChanged); } } @@ -110,13 +105,7 @@ class _ChatDetailsState extends State { widget.room.setDescription(displayname), ); if (success != false) { - Scaffold.of(context).showSnackBar( - SnackBar( - content: Text( - I18n.of(context).groupDescriptionHasBeenChanged, - ), - ), - ); + showToast(I18n.of(context).groupDescriptionHasBeenChanged); } } @@ -137,13 +126,7 @@ class _ChatDetailsState extends State { ), ); if (success != false) { - Scaffold.of(context).showSnackBar( - SnackBar( - content: Text( - I18n.of(context).avatarHasBeenChanged, - ), - ), - ); + showToast(I18n.of(context).avatarHasBeenChanged); } } @@ -201,13 +184,7 @@ class _ChatDetailsState extends State { Clipboard.setData( ClipboardData(text: widget.room.canonicalAlias), ); - Scaffold.of(context).showSnackBar( - SnackBar( - content: Text( - I18n.of(context).copiedToClipboard, - ), - ), - ); + showToast(I18n.of(context).copiedToClipboard); }, ), ChatSettingsPopupMenu(widget.room, false) diff --git a/lib/views/invitation_selection.dart b/lib/views/invitation_selection.dart index d697eba..3925f66 100644 --- a/lib/views/invitation_selection.dart +++ b/lib/views/invitation_selection.dart @@ -6,6 +6,7 @@ import 'package:fluffychat/components/avatar.dart'; import 'package:fluffychat/components/matrix.dart'; import 'package:fluffychat/i18n/i18n.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_styled_toast/flutter_styled_toast.dart'; import 'chat_list.dart'; @@ -56,13 +57,7 @@ class _InvitationSelectionState extends State { widget.room.invite(id), ); if (success != false) { - Scaffold.of(context).showSnackBar( - SnackBar( - content: Text( - I18n.of(context).contactHasBeenInvitedToTheGroup, - ), - ), - ); + showToast(I18n.of(context).contactHasBeenInvitedToTheGroup); } } diff --git a/lib/views/login.dart b/lib/views/login.dart index 19bf3cc..dd1ee95 100644 --- a/lib/views/login.dart +++ b/lib/views/login.dart @@ -104,82 +104,86 @@ class _LoginState extends State { labelText: serverError == null ? "Homeserver" : serverError), ), ), - body: ListView( - padding: EdgeInsets.symmetric( - horizontal: max((MediaQuery.of(context).size.width - 600) / 2, 0)), - children: [ - Container( - height: 150, - color: Theme.of(context).secondaryHeaderColor, - child: Center( - child: Icon( - Icons.vpn_key, - size: 60, + body: Builder(builder: (context) { + return ListView( + padding: EdgeInsets.symmetric( + horizontal: + max((MediaQuery.of(context).size.width - 600) / 2, 0)), + children: [ + Container( + height: 150, + color: Theme.of(context).secondaryHeaderColor, + child: Center( + child: Icon( + Icons.vpn_key, + size: 60, + ), ), ), - ), - ListTile( - leading: CircleAvatar( - child: Icon(Icons.account_box, - color: Theme.of(context).primaryColor), - ), - title: TextField( - readOnly: loading, - autocorrect: false, - controller: usernameController, - decoration: InputDecoration( - hintText: - "@${I18n.of(context).username.toLowerCase()}:domain", - errorText: usernameError, - labelText: I18n.of(context).username), - ), - ), - ListTile( - leading: CircleAvatar( - backgroundColor: Theme.of(context).brightness == Brightness.dark - ? Color(0xff121212) - : Colors.white, - child: Icon(Icons.lock, color: Theme.of(context).primaryColor), - ), - title: TextField( - readOnly: loading, - autocorrect: false, - controller: passwordController, - obscureText: !showPassword, - onSubmitted: (t) => login(context), - decoration: InputDecoration( - hintText: "****", - errorText: passwordError, - suffixIcon: IconButton( - icon: Icon( - showPassword ? Icons.visibility_off : Icons.visibility), - onPressed: () => - setState(() => showPassword = !showPassword), - ), - labelText: I18n.of(context).password), - ), - ), - SizedBox(height: 20), - Container( - height: 50, - padding: EdgeInsets.symmetric(horizontal: 12), - child: RaisedButton( - elevation: 7, - color: Theme.of(context).primaryColor, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(6), + ListTile( + leading: CircleAvatar( + child: Icon(Icons.account_box, + color: Theme.of(context).primaryColor), ), - child: loading - ? CircularProgressIndicator() - : Text( - I18n.of(context).login.toUpperCase(), - style: TextStyle(color: Colors.white, fontSize: 16), + title: TextField( + readOnly: loading, + autocorrect: false, + controller: usernameController, + decoration: InputDecoration( + hintText: + "@${I18n.of(context).username.toLowerCase()}:domain", + errorText: usernameError, + labelText: I18n.of(context).username), + ), + ), + ListTile( + leading: CircleAvatar( + backgroundColor: Theme.of(context).brightness == Brightness.dark + ? Color(0xff121212) + : Colors.white, + child: Icon(Icons.lock, color: Theme.of(context).primaryColor), + ), + title: TextField( + readOnly: loading, + autocorrect: false, + controller: passwordController, + obscureText: !showPassword, + onSubmitted: (t) => login(context), + decoration: InputDecoration( + hintText: "****", + errorText: passwordError, + suffixIcon: IconButton( + icon: Icon(showPassword + ? Icons.visibility_off + : Icons.visibility), + onPressed: () => + setState(() => showPassword = !showPassword), ), - onPressed: () => loading ? null : login(context), + labelText: I18n.of(context).password), + ), ), - ), - ], - ), + SizedBox(height: 20), + Container( + height: 50, + padding: EdgeInsets.symmetric(horizontal: 12), + child: RaisedButton( + elevation: 7, + color: Theme.of(context).primaryColor, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(6), + ), + child: loading + ? CircularProgressIndicator() + : Text( + I18n.of(context).login.toUpperCase(), + style: TextStyle(color: Colors.white, fontSize: 16), + ), + onPressed: () => loading ? null : login(context), + ), + ), + ], + ); + }), ); } } diff --git a/lib/views/sign_up_password.dart b/lib/views/sign_up_password.dart index 5a83182..1c12c23 100644 --- a/lib/views/sign_up_password.dart +++ b/lib/views/sign_up_password.dart @@ -7,6 +7,7 @@ import 'package:fluffychat/i18n/i18n.dart'; import 'package:fluffychat/utils/app_route.dart'; import 'package:fluffychat/views/auth_web_view.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_styled_toast/flutter_styled_toast.dart'; import 'chat_list.dart'; @@ -95,13 +96,7 @@ class _SignUpPasswordState extends State { try { await matrix.client.setDisplayname(widget.displayname); } catch (exception) { - Scaffold.of(context).showSnackBar( - SnackBar( - content: Text( - I18n.of(context).couldNotSetDisplayname, - ), - ), - ); + showToast(I18n.of(context).couldNotSetDisplayname); } if (widget.avatar != null) { try { @@ -112,13 +107,7 @@ class _SignUpPasswordState extends State { ), ); } catch (exception) { - Scaffold.of(context).showSnackBar( - SnackBar( - content: Text( - I18n.of(context).couldNotSetAvatar, - ), - ), - ); + showToast(I18n.of(context).couldNotSetAvatar); } } await Navigator.of(context).pushAndRemoveUntil( diff --git a/pubspec.lock b/pubspec.lock index ddaa982..f8204f5 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -21,28 +21,28 @@ packages: name: archive url: "https://pub.dartlang.org" source: hosted - version: "2.0.11" + version: "2.0.13" args: dependency: transitive description: name: args url: "https://pub.dartlang.org" source: hosted - version: "1.5.2" + version: "1.6.0" async: dependency: transitive description: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.0" + version: "2.4.1" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "2.0.0" bubble: dependency: "direct main" description: @@ -63,14 +63,14 @@ packages: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.2" + version: "1.1.3" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.11" + version: "1.14.12" convert: dependency: transitive description: @@ -91,7 +91,7 @@ packages: name: crypto url: "https://pub.dartlang.org" source: hosted - version: "2.1.3" + version: "2.1.4" csslib: dependency: transitive description: @@ -202,6 +202,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.5" + flutter_styled_toast: + dependency: "direct main" + description: + name: flutter_styled_toast + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.1" flutter_svg: dependency: transitive description: @@ -260,7 +267,7 @@ packages: name: image url: "https://pub.dartlang.org" source: hosted - version: "2.1.4" + version: "2.1.12" image_picker: dependency: "direct main" description: @@ -502,7 +509,7 @@ packages: name: quiver url: "https://pub.dartlang.org" source: hosted - version: "2.0.5" + version: "2.1.3" receive_sharing_intent: dependency: "direct main" description: @@ -570,7 +577,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.5.5" + version: "1.7.0" sqflite: dependency: "direct main" description: @@ -738,7 +745,7 @@ packages: name: xml url: "https://pub.dartlang.org" source: hosted - version: "3.5.0" + version: "3.6.1" yaml: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index fd85e38..9d16103 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -11,7 +11,7 @@ description: Chat with your friends. # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 0.12.0+32 +version: 0.12.2+34 environment: sdk: ">=2.6.0 <3.0.0" @@ -53,6 +53,7 @@ dependencies: flutter_sound: ^2.1.1 open_file: ^3.0.1 mime_type: ^0.2.7 + flutter_styled_toast: ^1.2.1 intl: ^0.16.0 intl_translation: ^0.17.9