diff --git a/CHANGELOG.md b/CHANGELOG.md index bd1cf72..94fb527 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ ### New features - Voice messages - New message bubble design +### Changes: +- Use SnackBars instead of Toasts +### Fixes: +- Minor fixes in the SDK +- Loading dialog when sending files is displayed too long +- Fixed device settings list # Version 0.9.0 - 2020-03-13 ### New features diff --git a/lib/components/encryption_button.dart b/lib/components/encryption_button.dart index 28b410d..e056e81 100644 --- a/lib/components/encryption_button.dart +++ b/lib/components/encryption_button.dart @@ -5,7 +5,6 @@ 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:toast/toast.dart'; import 'dialogs/simple_dialogs.dart'; import 'matrix.dart'; @@ -22,8 +21,11 @@ class _EncryptionButtonState extends State { void _enableEncryptionAction() async { if (widget.room.encrypted) { - Toast.show(I18n.of(context).warningEncryptionInBeta, context, - duration: 5); + Scaffold.of(context).showSnackBar( + SnackBar( + content: Text(I18n.of(context).warningEncryptionInBeta), + ), + ); await Navigator.of(context).push( AppRoute.defaultRoute( context, @@ -33,7 +35,13 @@ class _EncryptionButtonState extends State { return; } if (!widget.room.client.encryptionEnabled) { - Toast.show(I18n.of(context).needPantalaimonWarning, context, duration: 8); + Scaffold.of(context).showSnackBar( + SnackBar( + content: Text( + 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 cea4b74..6cb9e0d 100644 --- a/lib/components/list_items/chat_list_item.dart +++ b/lib/components/list_items/chat_list_item.dart @@ -3,7 +3,6 @@ import 'package:fluffychat/views/chat.dart'; import 'package:flutter/material.dart'; import 'package:flutter_slidable/flutter_slidable.dart'; import 'package:pedantic/pedantic.dart'; -import 'package:toast/toast.dart'; import '../../i18n/i18n.dart'; import '../../utils/app_route.dart'; @@ -32,8 +31,13 @@ class ChatListItem extends StatelessWidget { } if (room.membership == Membership.ban) { - Toast.show(I18n.of(context).youHaveBeenBannedFromThisChat, context, - duration: 5); + Scaffold.of(context).showSnackBar( + SnackBar( + content: Text( + I18n.of(context).youHaveBeenBannedFromThisChat, + ), + ), + ); return; } @@ -139,19 +143,26 @@ class ChatListItem extends StatelessWidget { leading: Avatar(room.avatar, room.displayname), title: Row( children: [ - Text( - room.getLocalizedDisplayname(context), - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - SizedBox(width: 4), - room.pushRuleState == PushRuleState.notify - ? Container() - : Icon( - Icons.notifications_off, - color: Colors.grey[400], - size: 16, + Expanded( + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + room.getLocalizedDisplayname(context), + maxLines: 1, + overflow: TextOverflow.ellipsis, ), + SizedBox(width: 4), + room.pushRuleState == PushRuleState.notify + ? Container() + : Icon( + Icons.notifications_off, + color: Colors.grey[400], + size: 16, + ), + ], + ), + ), Spacer(), Text( room.timeCreated.localizedTimeShort(context), diff --git a/lib/components/matrix.dart b/lib/components/matrix.dart index f519187..410b0a3 100644 --- a/lib/components/matrix.dart +++ b/lib/components/matrix.dart @@ -10,7 +10,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:localstorage/localstorage.dart'; import 'package:path_provider/path_provider.dart'; -import 'package:toast/toast.dart'; import '../i18n/i18n.dart'; import '../utils/app_route.dart'; @@ -80,17 +79,21 @@ class MatrixState extends State { onAdditionalAuth != null) { return await tryRequestWithErrorToast(onAdditionalAuth(exception)); } else { - Toast.show( - exception.errorMessage, - context, - duration: Toast.LENGTH_LONG, + Scaffold.of(context).showSnackBar( + SnackBar( + content: Text( + exception.errorMessage, + ), + ), ); } } catch (exception) { - Toast.show( - exception.toString(), - context, - duration: Toast.LENGTH_LONG, + Scaffold.of(context).showSnackBar( + SnackBar( + content: Text( + exception.toString(), + ), + ), ); return false; } @@ -141,10 +144,12 @@ class MatrixState extends State { final String token = await _firebaseMessaging.getToken(); if (token?.isEmpty ?? true) { - return Toast.show( - I18n.of(context).noGoogleServicesWarning, - context, - duration: 10, + return Scaffold.of(context).showSnackBar( + SnackBar( + content: Text( + I18n.of(context).noGoogleServicesWarning, + ), + ), ); } await client.setPushers( @@ -175,7 +180,13 @@ class MatrixState extends State { ), (r) => r.isFirst); } catch (_) { - Toast.show("Failed to open chat...", context); + Scaffold.of(context).showSnackBar( + SnackBar( + content: Text( + "Failed to open chat...", + ), + ), + ); debugPrint(_); } }; diff --git a/lib/components/message_content.dart b/lib/components/message_content.dart index 90cf7e0..18f735c 100644 --- a/lib/components/message_content.dart +++ b/lib/components/message_content.dart @@ -1,3 +1,5 @@ +import 'dart:io'; + import 'package:bubble/bubble.dart'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:famedlysdk/famedlysdk.dart'; @@ -8,7 +10,9 @@ import 'package:fluffychat/views/image_viewer.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:link_text/link_text.dart'; +import 'package:path_provider/path_provider.dart'; import 'package:url_launcher/url_launcher.dart'; +import 'package:open_file/open_file.dart'; import 'matrix.dart'; @@ -20,11 +24,21 @@ class MessageContent extends StatelessWidget { @override Widget build(BuildContext context) { + var messageType = event.messageType; + if (event.room.encrypted && + [ + MessageTypes.Image, + MessageTypes.Sticker, + MessageTypes.Audio, + MessageTypes.Video, + ].contains(messageType)) { + messageType = MessageTypes.File; + } switch (event.type) { case EventTypes.Message: case EventTypes.Encrypted: case EventTypes.Sticker: - switch (event.messageType) { + switch (messageType) { case MessageTypes.Image: case MessageTypes.Sticker: final int size = 400; @@ -72,19 +86,41 @@ class MessageContent extends StatelessWidget { mainAxisSize: MainAxisSize.min, children: [ RaisedButton( - color: Colors.blueGrey, - child: Text( - I18n.of(context).downloadFile, - overflow: TextOverflow.fade, - softWrap: false, - maxLines: 1, - style: TextStyle(color: Colors.white), - ), - onPressed: () => launch( - MxContent(event.content["url"]) - .getDownloadLink(event.room.client), - ), - ), + color: Colors.blueGrey, + child: Text( + I18n.of(context).downloadFile, + overflow: TextOverflow.fade, + softWrap: false, + maxLines: 1, + style: TextStyle(color: Colors.white), + ), + onPressed: () async { + if (kIsWeb) { + if (event.room.encrypted) { + Scaffold.of(context).showSnackBar( + SnackBar( + content: + Text(I18n.of(context).notSupportedInWeb), + ), + ); + } + await launch( + MxContent(event.content["url"]) + .getDownloadLink(event.room.client), + ); + return; + } + final matrixFile = await Matrix.of(context) + .tryRequestWithLoadingDialog( + event.downloadAndDecryptAttachment(), + ); + Directory tempDir = await getTemporaryDirectory(); + final file = File(tempDir.path + + "/" + + matrixFile.path.split("/").last); + file.writeAsBytesSync(matrixFile.bytes); + await OpenFile.open(file.path); + }), Text( "- " + (event.content.containsKey("filename") diff --git a/lib/components/theme_switcher.dart b/lib/components/theme_switcher.dart index 6f87518..1f31799 100644 --- a/lib/components/theme_switcher.dart +++ b/lib/components/theme_switcher.dart @@ -16,6 +16,9 @@ final ThemeData lightTheme = ThemeData( backgroundColor: Colors.white, secondaryHeaderColor: Color(0xFFECECF2), scaffoldBackgroundColor: Colors.white, + snackBarTheme: SnackBarThemeData( + behavior: kIsWeb ? SnackBarBehavior.floating : SnackBarBehavior.fixed, + ), dialogTheme: DialogTheme( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8.0), @@ -47,6 +50,9 @@ final ThemeData darkTheme = ThemeData.dark().copyWith( scaffoldBackgroundColor: Color(0xff121212), accentColor: Color(0xFFF5B4D2), secondaryHeaderColor: Color(0xff1D1D1D), + snackBarTheme: SnackBarThemeData( + behavior: kIsWeb ? SnackBarBehavior.floating : SnackBarBehavior.fixed, + ), dialogTheme: DialogTheme( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8.0), @@ -78,6 +84,9 @@ final ThemeData amoledTheme = ThemeData.dark().copyWith( scaffoldBackgroundColor: Colors.black, accentColor: Color(0xFFF5B4D2), secondaryHeaderColor: Color(0xff1D1D1D), + snackBarTheme: SnackBarThemeData( + behavior: kIsWeb ? SnackBarBehavior.floating : SnackBarBehavior.fixed, + ), dialogTheme: DialogTheme( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8.0), diff --git a/lib/utils/famedlysdk_store.dart b/lib/utils/famedlysdk_store.dart index e59352c..1176690 100644 --- a/lib/utils/famedlysdk_store.dart +++ b/lib/utils/famedlysdk_store.dart @@ -1,4 +1,5 @@ import 'dart:convert'; +import 'dart:typed_data'; import 'package:famedlysdk/famedlysdk.dart'; import 'package:flutter/foundation.dart'; @@ -29,7 +30,11 @@ class Store extends StoreAPI { return null; } } - return await secureStorage.read(key: key); + try { + return await secureStorage.read(key: key); + } catch (_) { + return null; + } } Future setItem(String key, String value) async { @@ -71,12 +76,18 @@ class Store extends StoreAPI { } debugPrint("[Matrix] Restoring account credentials"); final Map credentials = json.decode(credentialsStr); + if (credentials["homeserver"] == null || + credentials["token"] == null || + credentials["userID"] == null) { + client.onLoginStateChanged.add(LoginState.loggedOut); + return; + } client.connect( newDeviceID: credentials["deviceID"], newDeviceName: credentials["deviceName"], newHomeserver: credentials["homeserver"], newLazyLoadMembers: credentials["lazyLoadMembers"], - newMatrixVersions: List.from(credentials["matrixVersions"]), + newMatrixVersions: List.from(credentials["matrixVersions"] ?? []), newToken: credentials["token"], newUserID: credentials["userID"], newPrevBatch: kIsWeb @@ -109,6 +120,10 @@ class Store extends StoreAPI { /// Responsible to store all data persistent and to query objects from the /// database. class ExtendedStore extends Store implements ExtendedStoreAPI { + /// The maximum time that files are allowed to stay in the + /// store. By default this is are 30 days. + static const int MAX_FILE_STORING_TIME = 1 * 30 * 24 * 60 * 60 * 1000; + @override final bool extended = true; @@ -126,21 +141,29 @@ class ExtendedStore extends Store implements ExtendedStoreAPI { // Open the database and migrate if necessary. var databasePath = await getDatabasesPath(); String path = p.join(databasePath, "FluffyMatrix.db"); - _db = await openDatabase(path, version: 16, + _db = await openDatabase(path, version: 20, onCreate: (Database db, int version) async { await createTables(db); }, onUpgrade: (Database db, int oldVersion, int newVersion) async { debugPrint( "[Store] Migrate database from version $oldVersion to $newVersion"); - if (oldVersion != newVersion) { + if (oldVersion >= 18 && newVersion <= 20) { + await createTables(db); + } else if (oldVersion != newVersion) { // Look for an old entry in an old clients library List list = []; try { list = await db.rawQuery( "SELECT * FROM Clients WHERE client=?", [client.clientName]); - } on DatabaseException catch (_) {} catch (_) { - rethrow; + } catch (_) { + list = []; } + client.prevBatch = null; + await this.storePrevBatch(null); + schemes.forEach((String name, String scheme) async { + await db.execute("DROP TABLE IF EXISTS $name"); + }); + await createTables(db); if (list.length == 1) { debugPrint("[Store] Found old client from deprecated store"); @@ -158,22 +181,26 @@ class ExtendedStore extends Store implements ExtendedStoreAPI { newPrevBatch: null, ); await db.execute("DROP TABLE IF EXISTS Clients"); - if (client.debug) { - debugPrint( - "[Store] Restore client credentials from deprecated database of ${client.userID}"); - } - schemes.forEach((String name, String scheme) async { - await db.execute("DROP TABLE IF EXISTS $name"); - }); - await createTables(db); + debugPrint( + "[Store] Restore client credentials from deprecated database of ${client.userID}"); } } else { client.onLoginStateChanged.add(LoginState.loggedOut); } + return; }); // Mark all pending events as failed. await _db.rawUpdate("UPDATE Events SET status=-1 WHERE status=0"); + + // Delete all stored files which are older than [MAX_FILE_STORING_TIME] + final int currentDeadline = DateTime.now().millisecondsSinceEpoch - + ExtendedStore.MAX_FILE_STORING_TIME; + await _db.rawDelete( + "DELETE From Files WHERE saved_at storeFile(Uint8List bytes, String mxcUri) async { + await _db.rawInsert( + "INSERT OR REPLACE INTO Files VALUES(?, ?, ?)", + [mxcUri, bytes, DateTime.now().millisecondsSinceEpoch], + ); + return; + } + + Future getFile(String mxcUri) async { + List> res = await _db.rawQuery( + "SELECT * FROM Files WHERE mxc_uri=?", + [mxcUri], + ); + if (res.isEmpty) return null; + return res.first["bytes"]; + } + static final Map schemes = { /// The database scheme for the Room class. 'Rooms': 'CREATE TABLE IF NOT EXISTS Rooms(' + @@ -574,5 +618,12 @@ class ExtendedStore extends Store implements ExtendedStoreAPI { 'sender TEXT, ' + 'content TEXT, ' + 'UNIQUE(sender))', + + /// The database scheme for room states. + 'Files': 'CREATE TABLE IF NOT EXISTS Files(' + + 'mxc_uri TEXT PRIMARY KEY, ' + + 'bytes BLOB, ' + + 'saved_at INTEGER, ' + + 'UNIQUE(mxc_uri))', }; } diff --git a/lib/views/chat.dart b/lib/views/chat.dart index 4894b9c..133ba5f 100644 --- a/lib/views/chat.dart +++ b/lib/views/chat.dart @@ -19,7 +19,6 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:image_picker/image_picker.dart'; -import 'package:toast/toast.dart'; import 'package:pedantic/pedantic.dart'; import 'chat_list.dart'; @@ -178,7 +177,14 @@ class _ChatState extends State<_Chat> { void sendFileAction(BuildContext context) async { if (kIsWeb) { - return Toast.show(I18n.of(context).notSupportedInWeb, context); + Scaffold.of(context).showSnackBar( + SnackBar( + content: Text( + I18n.of(context).notSupportedInWeb, + ), + ), + ); + return; } File file = await FilePicker.getFile(); if (file == null) return; @@ -191,7 +197,14 @@ class _ChatState extends State<_Chat> { void sendImageAction(BuildContext context) async { if (kIsWeb) { - return Toast.show(I18n.of(context).notSupportedInWeb, context); + Scaffold.of(context).showSnackBar( + SnackBar( + content: Text( + I18n.of(context).notSupportedInWeb, + ), + ), + ); + return; } File file = await ImagePicker.pickImage( source: ImageSource.gallery, @@ -208,7 +221,14 @@ class _ChatState extends State<_Chat> { void openCameraAction(BuildContext context) async { if (kIsWeb) { - return Toast.show(I18n.of(context).notSupportedInWeb, context); + Scaffold.of(context).showSnackBar( + SnackBar( + content: Text( + I18n.of(context).notSupportedInWeb, + ), + ), + ); + return; } File file = await ImagePicker.pickImage( source: ImageSource.camera, diff --git a/lib/views/chat_details.dart b/lib/views/chat_details.dart index c7f332a..a94cba6 100644 --- a/lib/views/chat_details.dart +++ b/lib/views/chat_details.dart @@ -19,7 +19,6 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:image_picker/image_picker.dart'; import 'package:link_text/link_text.dart'; -import 'package:toast/toast.dart'; class ChatDetails extends StatefulWidget { final Room room; @@ -44,10 +43,12 @@ class _ChatDetailsState extends State { widget.room.setName(displayname), ); if (success != false) { - Toast.show( - I18n.of(context).displaynameHasBeenChanged, - context, - duration: Toast.LENGTH_LONG, + Scaffold.of(context).showSnackBar( + SnackBar( + content: Text( + I18n.of(context).displaynameHasBeenChanged, + ), + ), ); } } @@ -109,10 +110,12 @@ class _ChatDetailsState extends State { widget.room.setDescription(displayname), ); if (success != false) { - Toast.show( - I18n.of(context).groupDescriptionHasBeenChanged, - context, - duration: Toast.LENGTH_LONG, + Scaffold.of(context).showSnackBar( + SnackBar( + content: Text( + I18n.of(context).groupDescriptionHasBeenChanged, + ), + ), ); } } @@ -134,10 +137,12 @@ class _ChatDetailsState extends State { ), ); if (success != false) { - Toast.show( - I18n.of(context).avatarHasBeenChanged, - context, - duration: Toast.LENGTH_LONG, + Scaffold.of(context).showSnackBar( + SnackBar( + content: Text( + I18n.of(context).avatarHasBeenChanged, + ), + ), ); } } @@ -195,8 +200,13 @@ class _ChatDetailsState extends State { Clipboard.setData( ClipboardData(text: widget.room.canonicalAlias), ); - Toast.show(I18n.of(context).copiedToClipboard, context, - duration: 5); + Scaffold.of(context).showSnackBar( + SnackBar( + content: Text( + I18n.of(context).copiedToClipboard, + ), + ), + ); }, ), ChatSettingsPopupMenu(widget.room, false) diff --git a/lib/views/chat_list.dart b/lib/views/chat_list.dart index 0e74a10..50a3276 100644 --- a/lib/views/chat_list.dart +++ b/lib/views/chat_list.dart @@ -6,7 +6,6 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_speed_dial/flutter_speed_dial.dart'; -import 'package:toast/toast.dart'; import 'package:uni_links/uni_links.dart'; import '../components/dialogs/simple_dialogs.dart'; @@ -125,10 +124,13 @@ class _ChatListState extends State { debugPrint("initUniLinks failed during platform exception"); } }, - onError: (error) => Toast.show( - I18n.of(context).oopsSomethingWentWrong + " " + error.toString(), - context, - duration: 5), + onError: (error) => Scaffold.of(context).showSnackBar( + SnackBar( + content: Text( + I18n.of(context).oopsSomethingWentWrong + " " + error.toString(), + ), + ), + ), ); } diff --git a/lib/views/invitation_selection.dart b/lib/views/invitation_selection.dart index aaef397..1fda12d 100644 --- a/lib/views/invitation_selection.dart +++ b/lib/views/invitation_selection.dart @@ -6,7 +6,6 @@ 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:toast/toast.dart'; import 'chat_list.dart'; @@ -52,10 +51,12 @@ class _InvitationSelectionState extends State { widget.room.invite(id), ); if (success != false) { - Toast.show( - I18n.of(context).contactHasBeenInvitedToTheGroup, - context, - duration: Toast.LENGTH_LONG, + Scaffold.of(context).showSnackBar( + SnackBar( + content: Text( + I18n.of(context).contactHasBeenInvitedToTheGroup, + ), + ), ); } } diff --git a/lib/views/settings.dart b/lib/views/settings.dart index a2ac8e4..2c76f37 100644 --- a/lib/views/settings.dart +++ b/lib/views/settings.dart @@ -5,7 +5,6 @@ import 'package:fluffychat/components/settings_themes.dart'; import 'package:fluffychat/views/settings_devices.dart'; import 'package:flutter/material.dart'; import 'package:image_picker/image_picker.dart'; -import 'package:toast/toast.dart'; import 'package:url_launcher/url_launcher.dart'; import 'app_info.dart'; @@ -86,11 +85,6 @@ class _SettingsState extends State { ), ); if (success != false) { - Toast.show( - I18n.of(context).avatarHasBeenChanged, - context, - duration: Toast.LENGTH_LONG, - ); setState(() { profileFuture = null; profile = null; @@ -194,25 +188,19 @@ class _SettingsState extends State { ), ), ListTile( - leading: Icon(Icons.help), + trailing: Icon(Icons.help), title: Text(I18n.of(context).help), onTap: () => launch( "https://gitlab.com/ChristianPauly/fluffychat-flutter/issues"), ), ListTile( - leading: Icon(Icons.list), - title: Text(I18n.of(context).changelog), - onTap: () => launch( - "https://gitlab.com/ChristianPauly/fluffychat-flutter/blob/master/CHANGELOG.md"), - ), - ListTile( - leading: Icon(Icons.link), + trailing: Icon(Icons.link), title: Text(I18n.of(context).license), onTap: () => launch( "https://gitlab.com/ChristianPauly/fluffychat-flutter/raw/master/LICENSE"), ), ListTile( - leading: Icon(Icons.code), + trailing: Icon(Icons.code), title: Text(I18n.of(context).sourceCode), onTap: () => launch( "https://gitlab.com/ChristianPauly/fluffychat-flutter"), diff --git a/lib/views/settings_devices.dart b/lib/views/settings_devices.dart index 9254c62..5b55711 100644 --- a/lib/views/settings_devices.dart +++ b/lib/views/settings_devices.dart @@ -87,6 +87,7 @@ class DevicesSettingsState extends State { UserDevice thisDevice = devices.firstWhere(isOwnDevice, orElse: () => null); devices.removeWhere(isOwnDevice); + devices.sort((a, b) => b.lastSeenTs.compareTo(a.lastSeenTs)); return Column( children: [ if (thisDevice != null) @@ -159,9 +160,15 @@ class UserDeviceListItem extends StatelessWidget { contentPadding: EdgeInsets.all(16.0), title: Row( children: [ - Text((userDevice.displayName?.isNotEmpty ?? false) - ? userDevice.displayName - : I18n.of(context).unknownDevice), + Expanded( + child: Text( + (userDevice.displayName?.isNotEmpty ?? false) + ? userDevice.displayName + : I18n.of(context).unknownDevice, + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ), Spacer(), Text(userDevice.lastSeenTs.localizedTimeShort(context)), ], diff --git a/lib/views/sign_up_password.dart b/lib/views/sign_up_password.dart index 0a53ccb..5a83182 100644 --- a/lib/views/sign_up_password.dart +++ b/lib/views/sign_up_password.dart @@ -7,7 +7,6 @@ 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:toast/toast.dart'; import 'chat_list.dart'; @@ -96,7 +95,13 @@ class _SignUpPasswordState extends State { try { await matrix.client.setDisplayname(widget.displayname); } catch (exception) { - Toast.show(I18n.of(context).couldNotSetDisplayname, context, duration: 5); + Scaffold.of(context).showSnackBar( + SnackBar( + content: Text( + I18n.of(context).couldNotSetDisplayname, + ), + ), + ); } if (widget.avatar != null) { try { @@ -107,7 +112,13 @@ class _SignUpPasswordState extends State { ), ); } catch (exception) { - Toast.show(I18n.of(context).couldNotSetAvatar, context, duration: 5); + Scaffold.of(context).showSnackBar( + SnackBar( + content: Text( + I18n.of(context).couldNotSetAvatar, + ), + ), + ); } } await Navigator.of(context).pushAndRemoveUntil( diff --git a/pubspec.lock b/pubspec.lock index 8bacb5d..7576511 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -124,8 +124,8 @@ packages: dependency: "direct main" description: path: "." - ref: eb84c2a0856af99527f00697cbed4eb67a47887d - resolved-ref: eb84c2a0856af99527f00697cbed4eb67a47887d + ref: eb66ec79d431c73d5d752cb237b94da56b92f10f + resolved-ref: eb66ec79d431c73d5d752cb237b94da56b92f10f url: "https://gitlab.com/famedly/famedlysdk.git" source: git version: "0.0.1" @@ -331,6 +331,15 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.12.6" + matrix_file_e2ee: + dependency: transitive + description: + path: "." + ref: HEAD + resolved-ref: b043fcc29031979dc65e5b08e10ebb9b8d2fae30 + url: "https://gitlab.com/famedly/libraries/matrix_file_e2ee.git" + source: git + version: "1.0.2" meta: dependency: transitive description: @@ -384,11 +393,18 @@ packages: dependency: transitive description: path: "." - ref: bbc7ce10a52be5d5c10d2eb6c3591aade71356e2 - resolved-ref: bbc7ce10a52be5d5c10d2eb6c3591aade71356e2 + ref: "1.x.y" + resolved-ref: "79868b06b3ea156f90b73abafb3bbf3ac4114cc6" url: "https://gitlab.com/famedly/libraries/dart-olm.git" source: git - version: "0.0.0" + version: "1.0.0" + open_file: + dependency: "direct main" + description: + name: open_file + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1" package_config: dependency: transitive description: @@ -466,6 +482,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.1" + pointycastle: + dependency: transitive + description: + name: pointycastle + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" pool: dependency: transitive description: @@ -611,13 +634,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.2.15" - toast: - dependency: "direct main" - description: - name: toast - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.5" typed_data: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 6fb531c..4fb5a01 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.9.0+28 +version: 0.10.0+29 environment: sdk: ">=2.6.0 <3.0.0" @@ -27,11 +27,10 @@ dependencies: famedlysdk: git: url: https://gitlab.com/famedly/famedlysdk.git - ref: eb84c2a0856af99527f00697cbed4eb67a47887d + ref: eb66ec79d431c73d5d752cb237b94da56b92f10f localstorage: ^3.0.1+4 bubble: ^1.1.9+1 - toast: ^0.1.5 file_picker: ^1.4.3+2 image_picker: ^0.6.2+3 flutter_speed_dial: ^1.2.5 @@ -53,6 +52,7 @@ dependencies: flutter_slidable: ^0.5.4 photo_view: ^0.9.2 flutter_sound: ^2.1.1 + open_file: ^3.0.1 intl: ^0.16.0 intl_translation: ^0.17.9