From e84bc256022fc6fd6428fd41a63a7e105fb33435 Mon Sep 17 00:00:00 2001 From: Christian Pauly Date: Fri, 25 Dec 2020 09:58:34 +0100 Subject: [PATCH] refactor: Switch to loading dialog --- lib/components/audio_player.dart | 22 ++-- lib/components/chat_settings_popup_menu.dart | 33 +++--- lib/components/default_drawer.dart | 7 +- lib/components/dialogs/bootstrap_dialog.dart | 20 ++-- .../dialogs/key_verification_dialog.dart | 41 +++---- lib/components/dialogs/send_file_dialog.dart | 6 +- lib/components/dialogs/simple_dialogs.dart | 50 --------- lib/components/encryption_button.dart | 7 +- lib/components/list_items/chat_list_item.dart | 26 +++-- .../list_items/public_room_list_item.dart | 12 +- lib/components/message_content.dart | 9 +- lib/components/message_reactions.dart | 14 ++- lib/components/user_bottom_sheet.dart | 24 ++-- lib/l10n/intl_en.arb | 10 ++ lib/main.dart | 7 ++ lib/utils/event_extension.dart | 10 +- lib/utils/localized_exception_extension.dart | 23 ++++ lib/utils/url_launcher.dart | 37 +++--- lib/views/chat.dart | 26 +++-- lib/views/chat_details.dart | 74 ++++++------ lib/views/chat_list.dart | 28 +++-- lib/views/chat_permissions_settings.dart | 8 +- lib/views/discover_view.dart | 11 +- lib/views/homeserver_picker.dart | 9 +- lib/views/invitation_selection.dart | 25 +++-- lib/views/login.dart | 22 ++-- lib/views/new_group.dart | 12 +- lib/views/new_private_chat.dart | 21 ++-- lib/views/settings.dart | 105 ++++++++++-------- lib/views/settings_3pid.dart | 23 ++-- lib/views/settings_devices.dart | 16 +-- lib/views/settings_emotes.dart | 36 +++--- lib/views/settings_ignore_list.dart | 14 ++- lib/views/settings_notifications.dart | 15 ++- pubspec.lock | 7 ++ pubspec.yaml | 1 + 36 files changed, 461 insertions(+), 350 deletions(-) delete mode 100644 lib/components/dialogs/simple_dialogs.dart create mode 100644 lib/utils/localized_exception_extension.dart diff --git a/lib/components/audio_player.dart b/lib/components/audio_player.dart index 2abf37f5..a9a6ddcc 100644 --- a/lib/components/audio_player.dart +++ b/lib/components/audio_player.dart @@ -3,12 +3,12 @@ import 'dart:typed_data'; import 'package:famedlysdk/famedlysdk.dart'; import 'package:fluffychat/components/message_download_content.dart'; +import 'package:flushbar/flushbar_helper.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_sound/flutter_sound.dart'; import 'package:intl/intl.dart'; import 'package:universal_html/prefer_universal/html.dart' as html; -import 'dialogs/simple_dialogs.dart'; import '../utils/ui_fake.dart' if (dart.library.html) 'dart:ui' as ui; import 'matrix.dart'; import '../utils/event_extension.dart'; @@ -68,13 +68,19 @@ class _AudioPlayerState extends State { Future _downloadAction() async { if (status != AudioPlayerStatus.NOT_DOWNLOADED) return; setState(() => status = AudioPlayerStatus.DOWNLOADING); - final matrixFile = await SimpleDialogs(context).tryRequestWithErrorToast( - widget.event.downloadAndDecryptAttachmentCached()); - setState(() { - audioFile = matrixFile.bytes; - status = AudioPlayerStatus.DOWNLOADED; - }); - _playAction(); + try { + final matrixFile = + await widget.event.downloadAndDecryptAttachmentCached(); + setState(() { + audioFile = matrixFile.bytes; + status = AudioPlayerStatus.DOWNLOADED; + }); + _playAction(); + } catch (e, s) { + Logs().v('Could not download audio file', e, s); + await FlushbarHelper.createError(message: e.toLocalizedString(context)) + .show(context); + } } void _playAction() async { diff --git a/lib/components/chat_settings_popup_menu.dart b/lib/components/chat_settings_popup_menu.dart index 8b22fc77..80e75f48 100644 --- a/lib/components/chat_settings_popup_menu.dart +++ b/lib/components/chat_settings_popup_menu.dart @@ -10,7 +10,7 @@ import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:url_launcher/url_launcher.dart'; import '../app_config.dart'; -import 'dialogs/simple_dialogs.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'matrix.dart'; class ChatSettingsPopupMenu extends StatefulWidget { @@ -35,12 +35,13 @@ class _ChatSettingsPopupMenuState extends State { void startCallAction(BuildContext context) async { final url = '${AppConfig.jitsiInstance}${Uri.encodeComponent(widget.room.id.localpart)}'; - final success = await SimpleDialogs(context) - .tryRequestWithLoadingDialog(widget.room.sendEvent({ - 'msgtype': Matrix.callNamespace, - 'body': url, - })); - if (success == false) return; + final success = await showFutureLoadingDialog( + context: context, + future: () => widget.room.sendEvent({ + 'msgtype': Matrix.callNamespace, + 'body': url, + })); + if (success.error != null) return; await launch(url); } @@ -91,9 +92,9 @@ class _ChatSettingsPopupMenuState extends State { title: L10n.of(context).areYouSure, ); if (confirmed == OkCancelResult.ok) { - final success = await SimpleDialogs(context) - .tryRequestWithLoadingDialog(widget.room.leave()); - if (success != false) { + final success = await showFutureLoadingDialog( + context: context, future: () => widget.room.leave()); + if (success.error == null) { await Navigator.of(context).pushAndRemoveUntil( AppRoute.defaultRoute(context, ChatListView()), (Route r) => false); @@ -101,12 +102,16 @@ class _ChatSettingsPopupMenuState extends State { } break; case 'mute': - await SimpleDialogs(context).tryRequestWithLoadingDialog( - widget.room.setPushRuleState(PushRuleState.mentions_only)); + await showFutureLoadingDialog( + context: context, + future: () => + widget.room.setPushRuleState(PushRuleState.mentions_only)); break; case 'unmute': - await SimpleDialogs(context).tryRequestWithLoadingDialog( - widget.room.setPushRuleState(PushRuleState.notify)); + await showFutureLoadingDialog( + context: context, + future: () => + widget.room.setPushRuleState(PushRuleState.notify)); break; case 'call': startCallAction(context); diff --git a/lib/components/default_drawer.dart b/lib/components/default_drawer.dart index 7741474b..78e764ea 100644 --- a/lib/components/default_drawer.dart +++ b/lib/components/default_drawer.dart @@ -9,7 +9,7 @@ import 'package:fluffychat/views/settings.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; -import 'dialogs/simple_dialogs.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'matrix.dart'; class DefaultDrawer extends StatelessWidget { @@ -37,8 +37,9 @@ class DefaultDrawer extends StatelessWidget { ); if (input == null || input.single.isEmpty) return; final client = Matrix.of(context).client; - await SimpleDialogs(context).tryRequestWithLoadingDialog( - client.sendPresence( + await showFutureLoadingDialog( + context: context, + future: () => client.sendPresence( client.userID, PresenceType.online, statusMsg: input.single, diff --git a/lib/components/dialogs/bootstrap_dialog.dart b/lib/components/dialogs/bootstrap_dialog.dart index f7018705..ebd3f92a 100644 --- a/lib/components/dialogs/bootstrap_dialog.dart +++ b/lib/components/dialogs/bootstrap_dialog.dart @@ -2,7 +2,7 @@ import 'package:adaptive_dialog/adaptive_dialog.dart'; import 'package:famedlysdk/encryption.dart'; import 'package:famedlysdk/encryption/utils/bootstrap.dart'; import 'package:fluffychat/components/dialogs/adaptive_flat_button.dart'; -import 'package:fluffychat/components/dialogs/simple_dialogs.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:fluffychat/utils/platform_infos.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -119,11 +119,12 @@ class _BootstrapDialogState extends State { ) ]); if (input?.isEmpty ?? true) return; - final valid = - await SimpleDialogs(context).tryRequestWithLoadingDialog( - bootstrap.newSsssKey.unlock(keyOrPassphrase: input.single), + final valid = await showFutureLoadingDialog( + context: context, + future: () => + bootstrap.newSsssKey.unlock(keyOrPassphrase: input.single), ); - if (valid != false) bootstrap.openExistingSsss(); + if (valid.error == null) bootstrap.openExistingSsss(); })); break; case BootstrapState.askWipeCrossSigning: @@ -237,9 +238,12 @@ class _AskUnlockOldSsssState extends State<_AskUnlockOldSsss> { return; } - valid = await SimpleDialogs(context).tryRequestWithLoadingDialog( - widget.ssssKey.unlock(keyOrPassphrase: input), - ); + valid = (await showFutureLoadingDialog( + context: context, + future: () => widget.ssssKey.unlock(keyOrPassphrase: input), + )) + .error == + null; setState(() => null); } diff --git a/lib/components/dialogs/key_verification_dialog.dart b/lib/components/dialogs/key_verification_dialog.dart index 4a602551..b7eca9ed 100644 --- a/lib/components/dialogs/key_verification_dialog.dart +++ b/lib/components/dialogs/key_verification_dialog.dart @@ -7,7 +7,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import '../avatar.dart'; import 'adaptive_flat_button.dart'; -import 'simple_dialogs.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; import '../../utils/string_color.dart'; class KeyVerificationDialog extends StatefulWidget { @@ -70,25 +70,26 @@ class _KeyVerificationPageState extends State { if (input == null) { return; } - final valid = await SimpleDialogs(context) - .tryRequestWithLoadingDialog(Future.microtask(() async { - // make sure the loading spinner shows before we test the keys - await Future.delayed(Duration(milliseconds: 100)); - var valid = false; - try { - await widget.request.openSSSS(recoveryKey: input); - valid = true; - } catch (_) { - try { - await widget.request.openSSSS(passphrase: input); - valid = true; - } catch (_) { - valid = false; - } - } - return valid; - })); - if (valid == false) { + final valid = await showFutureLoadingDialog( + context: context, + future: () async { + // make sure the loading spinner shows before we test the keys + await Future.delayed(Duration(milliseconds: 100)); + var valid = false; + try { + await widget.request.openSSSS(recoveryKey: input); + valid = true; + } catch (_) { + try { + await widget.request.openSSSS(passphrase: input); + valid = true; + } catch (_) { + valid = false; + } + } + return valid; + }); + if (valid.error != null) { await showOkAlertDialog( context: context, message: L10n.of(context).incorrectPassphraseOrKey, diff --git a/lib/components/dialogs/send_file_dialog.dart b/lib/components/dialogs/send_file_dialog.dart index 061c0b75..6b26225f 100644 --- a/lib/components/dialogs/send_file_dialog.dart +++ b/lib/components/dialogs/send_file_dialog.dart @@ -2,7 +2,7 @@ import 'package:famedlysdk/famedlysdk.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; -import '../../components/dialogs/simple_dialogs.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; import '../../utils/matrix_file_extension.dart'; import '../../utils/room_send_file_extension.dart'; import '../../utils/resize_image.dart'; @@ -88,8 +88,8 @@ class _SendFileDialogState extends State { setState(() { _isSending = true; }); - await SimpleDialogs(context) - .tryRequestWithLoadingDialog(_send()); + await showFutureLoadingDialog( + context: context, future: () => _send()); await Navigator.of(context).pop(); }, ), diff --git a/lib/components/dialogs/simple_dialogs.dart b/lib/components/dialogs/simple_dialogs.dart deleted file mode 100644 index 640c9381..00000000 --- a/lib/components/dialogs/simple_dialogs.dart +++ /dev/null @@ -1,50 +0,0 @@ -import 'package:flushbar/flushbar_helper.dart'; -import 'package:famedlysdk/famedlysdk.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_gen/gen_l10n/l10n.dart'; - -class SimpleDialogs { - final BuildContext context; - - const SimpleDialogs(this.context); - - Future tryRequestWithLoadingDialog(Future request, - {Function(MatrixException) onAdditionalAuth}) async { - final futureResult = tryRequestWithErrorToast( - request, - onAdditionalAuth: onAdditionalAuth, - ); - return showDialog( - context: context, - barrierDismissible: false, - builder: (BuildContext context) { - futureResult.then( - (result) => Navigator.of(context).pop(result), - ); - return AlertDialog( - title: Text(L10n.of(context).loadingPleaseWait), - content: LinearProgressIndicator(), - ); - }, - ); - } - - Future tryRequestWithErrorToast(Future request, - {Function(MatrixException) onAdditionalAuth}) async { - try { - return await request; - } on MatrixException catch (exception) { - if (exception.requireAdditionalAuthentication && - onAdditionalAuth != null) { - return await tryRequestWithErrorToast(onAdditionalAuth(exception)); - } else { - await FlushbarHelper.createError(message: exception.errorMessage) - .show(context); - } - } catch (exception) { - await FlushbarHelper.createError(message: exception.toString()) - .show(context); - } - return false; - } -} diff --git a/lib/components/encryption_button.dart b/lib/components/encryption_button.dart index b337a7dc..a2611a93 100644 --- a/lib/components/encryption_button.dart +++ b/lib/components/encryption_button.dart @@ -8,7 +8,7 @@ import 'package:fluffychat/views/chat_encryption_settings.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; -import 'dialogs/simple_dialogs.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'matrix.dart'; class EncryptionButton extends StatefulWidget { @@ -46,8 +46,9 @@ class _EncryptionButtonState extends State { okLabel: L10n.of(context).yes, ) == OkCancelResult.ok) { - await SimpleDialogs(context).tryRequestWithLoadingDialog( - widget.room.enableEncryption(), + await showFutureLoadingDialog( + context: context, + future: () => widget.room.enableEncryption(), ); // we want to enable the lock icon setState(() => null); diff --git a/lib/components/list_items/chat_list_item.dart b/lib/components/list_items/chat_list_item.dart index a13de37b..0559e294 100644 --- a/lib/components/list_items/chat_list_item.dart +++ b/lib/components/list_items/chat_list_item.dart @@ -15,7 +15,7 @@ import '../../utils/date_time_extension.dart'; import '../../views/chat.dart'; import '../avatar.dart'; import '../dialogs/send_file_dialog.dart'; -import '../dialogs/simple_dialogs.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; import '../matrix.dart'; import '../mouse_over_builder.dart'; import '../theme_switcher.dart'; @@ -41,9 +41,10 @@ class ChatListItem extends StatelessWidget { if (onTap != null) return onTap(); if (!activeChat) { if (room.membership == Membership.invite && - await SimpleDialogs(context) - .tryRequestWithLoadingDialog(room.join()) == - false) { + (await showFutureLoadingDialog( + context: context, future: () => room.join())) + .error != + null) { return; } @@ -77,8 +78,10 @@ class ChatListItem extends StatelessWidget { await archiveAction(context); break; case ArchivedRoomAction.rejoin: - await SimpleDialogs(context) - .tryRequestWithLoadingDialog(room.join()); + await showFutureLoadingDialog( + context: context, + future: () => room.join(), + ); break; } } @@ -111,9 +114,11 @@ class ChatListItem extends StatelessWidget { Future archiveAction(BuildContext context) async { { if ([Membership.leave, Membership.ban].contains(room.membership)) { - final success = await SimpleDialogs(context) - .tryRequestWithLoadingDialog(room.forget()); - if (success != false) { + final success = await showFutureLoadingDialog( + context: context, + future: () => room.forget(), + ); + if (success.error == null) { if (onForget != null) onForget(); } return success; @@ -123,7 +128,8 @@ class ChatListItem extends StatelessWidget { title: L10n.of(context).areYouSure, ); if (confirmed == OkCancelResult.cancel) return; - await SimpleDialogs(context).tryRequestWithLoadingDialog(room.leave()); + await showFutureLoadingDialog( + context: context, future: () => room.leave()); return; } } diff --git a/lib/components/list_items/public_room_list_item.dart b/lib/components/list_items/public_room_list_item.dart index 82f44959..429cd770 100644 --- a/lib/components/list_items/public_room_list_item.dart +++ b/lib/components/list_items/public_room_list_item.dart @@ -1,6 +1,6 @@ import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/matrix_api.dart'; -import 'package:fluffychat/components/dialogs/simple_dialogs.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; @@ -15,13 +15,15 @@ class PublicRoomListItem extends StatelessWidget { const PublicRoomListItem(this.publicRoomEntry, {Key key}) : super(key: key); void joinAction(BuildContext context) async { - final success = await SimpleDialogs(context) - .tryRequestWithLoadingDialog(_joinRoomAndWait(context)); - if (success != false) { + final success = await showFutureLoadingDialog( + context: context, + future: () => _joinRoomAndWait(context), + ); + if (success.error == null) { await Navigator.of(context).push( AppRoute.defaultRoute( context, - ChatView(success), + ChatView(success.result), ), ); } diff --git a/lib/components/message_content.dart b/lib/components/message_content.dart index 59e35df6..0e11e043 100644 --- a/lib/components/message_content.dart +++ b/lib/components/message_content.dart @@ -1,7 +1,7 @@ import 'package:famedlysdk/encryption/utils/key_verification.dart'; import 'package:famedlysdk/famedlysdk.dart'; import 'package:fluffychat/components/audio_player.dart'; -import 'package:fluffychat/components/dialogs/simple_dialogs.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:fluffychat/components/image_bubble.dart'; import 'package:fluffychat/utils/event_extension.dart'; import 'package:fluffychat/utils/matrix_locals.dart'; @@ -54,10 +54,11 @@ class MessageContent extends StatelessWidget { }; await KeyVerificationDialog(request: req).show(context); } else { - final success = await SimpleDialogs(context).tryRequestWithLoadingDialog( - event.requestKey(), + final success = await showFutureLoadingDialog( + context: context, + future: () => event.requestKey(), ); - if (success != false) { + if (success.error == null) { await FlushbarHelper.createLoading( title: L10n.of(context).loadingPleaseWait, message: L10n.of(context).requestToReadOlderMessages, diff --git a/lib/components/message_reactions.dart b/lib/components/message_reactions.dart index 26198914..d7f757ec 100644 --- a/lib/components/message_reactions.dart +++ b/lib/components/message_reactions.dart @@ -2,7 +2,7 @@ import 'package:famedlysdk/famedlysdk.dart'; import 'package:flutter/material.dart'; import 'package:cached_network_image/cached_network_image.dart'; -import 'dialogs/simple_dialogs.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'matrix.dart'; class MessageReactions extends StatelessWidget { @@ -48,12 +48,16 @@ class MessageReactions extends StatelessWidget { e.content['m.relates_to']['key'] == r.key, orElse: () => null); if (evt != null) { - SimpleDialogs(context) - .tryRequestWithLoadingDialog(evt.redact()); + showFutureLoadingDialog( + context: context, + future: () => evt.redact(), + ); } } else { - SimpleDialogs(context).tryRequestWithLoadingDialog( - event.room.sendReaction(event.eventId, r.key)); + showFutureLoadingDialog( + context: context, + future: () => + event.room.sendReaction(event.eventId, r.key)); } }, )) diff --git a/lib/components/user_bottom_sheet.dart b/lib/components/user_bottom_sheet.dart index 1b51e714..7ea9de04 100644 --- a/lib/components/user_bottom_sheet.dart +++ b/lib/components/user_bottom_sheet.dart @@ -12,7 +12,7 @@ import 'content_banner.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import '../utils/presence_extension.dart'; -import 'dialogs/simple_dialogs.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'matrix.dart'; import 'dialogs/key_verification_dialog.dart'; import '../utils/app_route.dart'; @@ -36,20 +36,28 @@ class UserBottomSheet extends StatelessWidget { break; case 'ban': if (await _askConfirmation()) { - await SimpleDialogs(context).tryRequestWithLoadingDialog(user.ban()); + await showFutureLoadingDialog( + context: context, + future: () => user.ban(), + ); Navigator.of(context).pop(); } break; case 'unban': if (await _askConfirmation()) { - await SimpleDialogs(context) - .tryRequestWithLoadingDialog(user.unban()); + await showFutureLoadingDialog( + context: context, + future: () => user.unban(), + ); Navigator.of(context).pop(); } break; case 'kick': if (await _askConfirmation()) { - await SimpleDialogs(context).tryRequestWithLoadingDialog(user.kick()); + await showFutureLoadingDialog( + context: context, + future: () => user.kick(), + ); Navigator.of(context).pop(); } break; @@ -59,8 +67,10 @@ class UserBottomSheet extends StatelessWidget { .show(context); if (newPermission != null) { if (newPermission == 100 && await _askConfirmation() == false) break; - await SimpleDialogs(context) - .tryRequestWithLoadingDialog(user.setPower(newPermission)); + await showFutureLoadingDialog( + context: context, + future: () => user.setPower(newPermission), + ); Navigator.of(context).pop(); } break; diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index ba9732f5..6edca275 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -1735,6 +1735,16 @@ "type": {} } }, + "noConnectionToTheServer": "No connection to the server", + "@noConnectionToTheServer": { + "type": "text", + "placeholders": {} + }, + "tooManyRequestsWarning": "Too many requests. Please try again later!", + "@tooManyRequestsWarning": { + "type": "text", + "placeholders": {} + }, "unpin": "Unpin", "@unpin": { "type": "text", diff --git a/lib/main.dart b/lib/main.dart index c4cb8f60..e4e382ba 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -9,10 +9,12 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:universal_html/prefer_universal/html.dart' as html; import 'components/matrix.dart'; import 'components/theme_switcher.dart'; +import 'utils/localized_exception_extension.dart'; import 'app_config.dart'; import 'views/chat_list.dart'; @@ -50,6 +52,11 @@ class App extends StatelessWidget { .stream .first, builder: (context, snapshot) { + LoadingDialog.defaultTitle = + L10n.of(context).loadingPleaseWait; + LoadingDialog.defaultBackLabel = L10n.of(context).close; + LoadingDialog.defaultOnError = + (Object e) => e.toLocalizedString(context); if (snapshot.hasError) { WidgetsBinding.instance.addPostFrameCallback((_) => FlushbarHelper.createError( diff --git a/lib/utils/event_extension.dart b/lib/utils/event_extension.dart index 6bd4ec6c..c22e67cc 100644 --- a/lib/utils/event_extension.dart +++ b/lib/utils/event_extension.dart @@ -1,5 +1,5 @@ import 'package:famedlysdk/famedlysdk.dart'; -import 'package:fluffychat/components/dialogs/simple_dialogs.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_cache_manager/flutter_cache_manager.dart'; @@ -18,11 +18,11 @@ extension LocalizedBody on Event { ); return; } - final MatrixFile matrixFile = - await SimpleDialogs(context).tryRequestWithLoadingDialog( - downloadAndDecryptAttachmentCached(), + final matrixFile = await showFutureLoadingDialog( + context: context, + future: () => downloadAndDecryptAttachmentCached(), ); - matrixFile.open(); + matrixFile.result?.open(); } IconData get statusIcon { diff --git a/lib/utils/localized_exception_extension.dart b/lib/utils/localized_exception_extension.dart new file mode 100644 index 00000000..31002802 --- /dev/null +++ b/lib/utils/localized_exception_extension.dart @@ -0,0 +1,23 @@ +import 'package:famedlysdk/famedlysdk.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +extension LocalizedExceptionExtension on Object { + String toLocalizedString(BuildContext context) { + if (this is MatrixException) { + switch ((this as MatrixException).error) { + case MatrixError.M_FORBIDDEN: + return L10n.of(context).noPermission; + case MatrixError.M_LIMIT_EXCEEDED: + return L10n.of(context).tooManyRequestsWarning; + default: + return (this as MatrixException).errorMessage; + } + } + if (this is MatrixConnectionException) { + L10n.of(context).noConnectionToTheServer; + } + Logs().d('Something went wrong: ', this); + return L10n.of(context).oopsSomethingWentWrong; + } +} diff --git a/lib/utils/url_launcher.dart b/lib/utils/url_launcher.dart index 999610de..898a8fab 100644 --- a/lib/utils/url_launcher.dart +++ b/lib/utils/url_launcher.dart @@ -1,6 +1,6 @@ import 'package:adaptive_dialog/adaptive_dialog.dart'; import 'package:famedlysdk/famedlysdk.dart'; -import 'package:fluffychat/components/dialogs/simple_dialogs.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/utils/app_route.dart'; @@ -44,13 +44,14 @@ class UrlLauncher { var servers = {}; if (room == null && roomIdOrAlias.startsWith('#')) { // we were unable to find the room locally...so resolve it - final response = - await SimpleDialogs(context).tryRequestWithLoadingDialog( - matrix.client.requestRoomAliasInformations(roomIdOrAlias), + final response = await showFutureLoadingDialog( + context: context, + future: () => + matrix.client.requestRoomAliasInformations(roomIdOrAlias), ); - if (response != false) { - roomId = response.roomId; - servers.addAll(response.servers); + if (response.error == null) { + roomId = response.result.roomId; + servers.addAll(response.result.servers); room = matrix.client.getRoomById(roomId); } } @@ -81,21 +82,22 @@ class UrlLauncher { } if (roomIdOrAlias.sigil == '!') { roomId = roomIdOrAlias; - final response = - await SimpleDialogs(context).tryRequestWithLoadingDialog( - matrix.client.joinRoomOrAlias( + final response = await showFutureLoadingDialog( + context: context, + future: () => matrix.client.joinRoomOrAlias( roomIdOrAlias, servers: servers.isNotEmpty ? servers.toList() : null, ), ); - if (response == false) return; + if (response.error != null) return; // wait for two seconds so that it probably came down /sync - await SimpleDialogs(context).tryRequestWithLoadingDialog( - Future.delayed(const Duration(seconds: 2))); + await showFutureLoadingDialog( + context: context, + future: () => Future.delayed(const Duration(seconds: 2))); await Navigator.pushAndRemoveUntil( context, AppRoute.defaultRoute( - context, ChatView(response, scrollToEventId: event)), + context, ChatView(response.result, scrollToEventId: event)), (r) => r.isFirst, ); } else if (identifier.sigil == '#') { @@ -126,8 +128,11 @@ class UrlLauncher { title: 'Message user $identifier', ) == OkCancelResult.ok) { - roomId = await SimpleDialogs(context) - .tryRequestWithLoadingDialog(user.startDirectChat()); + roomId = (await showFutureLoadingDialog( + context: context, + future: () => user.startDirectChat(), + )) + .result; Navigator.of(context).pop(); if (roomId != null) { diff --git a/lib/views/chat.dart b/lib/views/chat.dart index 665781a5..8a0fed7a 100644 --- a/lib/views/chat.dart +++ b/lib/views/chat.dart @@ -11,7 +11,7 @@ import 'package:fluffychat/components/avatar.dart'; import 'package:fluffychat/components/chat_settings_popup_menu.dart'; import 'package:fluffychat/components/connection_status_header.dart'; import 'package:fluffychat/components/dialogs/recording_dialog.dart'; -import 'package:fluffychat/components/dialogs/simple_dialogs.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:fluffychat/components/encryption_button.dart'; import 'package:fluffychat/components/list_items/message.dart'; import 'package:fluffychat/components/matrix.dart'; @@ -114,8 +114,9 @@ class _ChatState extends State<_Chat> { if (_canLoadMore) { setState(() => _loadingHistory = true); - await SimpleDialogs(context).tryRequestWithErrorToast( - timeline.requestHistory(historyCount: _loadHistoryCount), + await showFutureLoadingDialog( + context: context, + future: () => timeline.requestHistory(historyCount: _loadHistoryCount), ); // we do NOT setState() here as then the event order will be wrong. @@ -275,8 +276,9 @@ class _ChatState extends State<_Chat> { final audioFile = File(result); // as we already explicitly say send in the recording dialog, // we do not need the send file dialog anymore. We can just send this straight away. - await SimpleDialogs(context).tryRequestWithLoadingDialog( - room.sendFileEvent( + await showFutureLoadingDialog( + context: context, + future: () => room.sendFileEvent( MatrixAudioFile( bytes: audioFile.readAsBytesSync(), name: audioFile.path), ), @@ -313,8 +315,9 @@ class _ChatState extends State<_Chat> { OkCancelResult.ok; if (!confirmed) return; for (var event in selectedEvents) { - await SimpleDialogs(context).tryRequestWithLoadingDialog( - event.status > 0 ? event.redact() : event.remove()); + await showFutureLoadingDialog( + context: context, + future: () => event.status > 0 ? event.redact() : event.remove()); } setState(() => selectedEvents.clear()); } @@ -400,7 +403,7 @@ class _ChatState extends State<_Chat> { } }); if (context != null) { - await SimpleDialogs(context).tryRequestWithLoadingDialog(task); + await showFutureLoadingDialog(context: context, future: () => task); } else { await task; } @@ -445,8 +448,9 @@ class _ChatState extends State<_Chat> { } void _sendEmojiAction(BuildContext context, String emoji) { - SimpleDialogs(context).tryRequestWithLoadingDialog( - room.sendReaction( + showFutureLoadingDialog( + context: context, + future: () => room.sendReaction( selectedEvents.first.eventId, emoji, ), @@ -472,7 +476,7 @@ class _ChatState extends State<_Chat> { matrix.activeRoomId = widget.id; if (room.membership == Membership.invite) { - SimpleDialogs(context).tryRequestWithLoadingDialog(room.join()); + showFutureLoadingDialog(context: context, future: () => room.join()); } final typingText = room.getLocalizedTypingText(context); diff --git a/lib/views/chat_details.dart b/lib/views/chat_details.dart index e21ac9d0..c4ada971 100644 --- a/lib/views/chat_details.dart +++ b/lib/views/chat_details.dart @@ -10,7 +10,7 @@ import 'package:file_picker_cross/file_picker_cross.dart'; import 'package:fluffychat/components/adaptive_page_layout.dart'; import 'package:fluffychat/components/chat_settings_popup_menu.dart'; import 'package:fluffychat/components/content_banner.dart'; -import 'package:fluffychat/components/dialogs/simple_dialogs.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:fluffychat/components/list_items/participant_list_item.dart'; import 'package:fluffychat/utils/app_route.dart'; import 'package:fluffychat/utils/matrix_locals.dart'; @@ -52,10 +52,11 @@ class _ChatDetailsState extends State { ], ); if (input == null) return; - final success = await SimpleDialogs(context).tryRequestWithLoadingDialog( - widget.room.setName(input.single), + final success = await showFutureLoadingDialog( + context: context, + future: () => widget.room.setName(input.single), ); - if (success != false) { + if (success.error == null) { await FlushbarHelper.createSuccess( message: L10n.of(context).displaynameHasBeenChanged) .show(context); @@ -82,19 +83,24 @@ class _ChatDetailsState extends State { if (aliases.indexWhere((s) => s == canonicalAlias) == -1) { var newAliases = List.from(aliases); newAliases.add(canonicalAlias); - final response = await SimpleDialogs(context).tryRequestWithLoadingDialog( - widget.room.client.requestRoomAliasInformations(canonicalAlias), + final response = await showFutureLoadingDialog( + context: context, + future: () => + widget.room.client.requestRoomAliasInformations(canonicalAlias), ); - if (response == false) { - final success = - await SimpleDialogs(context).tryRequestWithLoadingDialog( - widget.room.client.createRoomAlias(canonicalAlias, widget.room.id), + if (response.error != null) { + final success = await showFutureLoadingDialog( + context: context, + future: () => widget.room.client + .createRoomAlias(canonicalAlias, widget.room.id), ); - if (success == false) return; + if (success.error != null) return; } } - await SimpleDialogs(context).tryRequestWithLoadingDialog( - widget.room.client.sendState(widget.room.id, 'm.room.canonical_alias', { + await showFutureLoadingDialog( + context: context, + future: () => widget.room.client + .sendState(widget.room.id, 'm.room.canonical_alias', { 'alias': input.single, }), ); @@ -114,10 +120,11 @@ class _ChatDetailsState extends State { ], ); if (input == null) return; - final success = await SimpleDialogs(context).tryRequestWithLoadingDialog( - widget.room.setDescription(input.single), + final success = await showFutureLoadingDialog( + context: context, + future: () => widget.room.setDescription(input.single), ); - if (success != false) { + if (success.error == null) { await FlushbarHelper.createSuccess( message: L10n.of(context).groupDescriptionHasBeenChanged) .show(context); @@ -148,10 +155,11 @@ class _ChatDetailsState extends State { ); } - final success = await SimpleDialogs(context).tryRequestWithLoadingDialog( - widget.room.setAvatar(file), + final success = await showFutureLoadingDialog( + context: context, + future: () => widget.room.setAvatar(file), ); - if (success != false) { + if (success.error == null) { await FlushbarHelper.createSuccess( message: L10n.of(context).avatarHasBeenChanged) .show(context); @@ -159,9 +167,11 @@ class _ChatDetailsState extends State { } void requestMoreMembersAction(BuildContext context) async { - final List participants = await SimpleDialogs(context) - .tryRequestWithLoadingDialog(widget.room.requestParticipants()); - if (participants != null) setState(() => members = participants); + final participants = await showFutureLoadingDialog( + context: context, future: () => widget.room.requestParticipants()); + if (participants.error == null) { + setState(() => members = participants.result); + } } @override @@ -359,9 +369,10 @@ class _ChatDetailsState extends State { ), ), onSelected: (JoinRules joinRule) => - SimpleDialogs(context) - .tryRequestWithLoadingDialog( - widget.room.setJoinRules(joinRule), + showFutureLoadingDialog( + context: context, + future: () => + widget.room.setJoinRules(joinRule), ), itemBuilder: (BuildContext context) => >[ @@ -399,9 +410,9 @@ class _ChatDetailsState extends State { ), onSelected: (HistoryVisibility historyVisibility) => - SimpleDialogs(context) - .tryRequestWithLoadingDialog( - widget.room + showFutureLoadingDialog( + context: context, + future: () => widget.room .setHistoryVisibility(historyVisibility), ), itemBuilder: (BuildContext context) => @@ -453,9 +464,10 @@ class _ChatDetailsState extends State { ), ), onSelected: (GuestAccess guestAccess) => - SimpleDialogs(context) - .tryRequestWithLoadingDialog( - widget.room.setGuestAccess(guestAccess), + showFutureLoadingDialog( + context: context, + future: () => + widget.room.setGuestAccess(guestAccess), ), itemBuilder: (BuildContext context) => >[ diff --git a/lib/views/chat_list.dart b/lib/views/chat_list.dart index c827e4a3..5ae3eff4 100644 --- a/lib/views/chat_list.dart +++ b/lib/views/chat_list.dart @@ -6,7 +6,7 @@ import 'package:famedlysdk/famedlysdk.dart'; import 'package:fluffychat/components/connection_status_header.dart'; import 'package:fluffychat/components/default_app_bar_search_field.dart'; import 'package:fluffychat/components/default_drawer.dart'; -import 'package:fluffychat/components/dialogs/simple_dialogs.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:fluffychat/app_config.dart'; import 'package:fluffychat/utils/platform_infos.dart'; import 'package:flutter/foundation.dart'; @@ -142,24 +142,28 @@ class _ChatListState extends State { Future _toggleUnread(BuildContext context) { final room = Matrix.of(context).client.getRoomById(_selectedRoomIds.single); - return SimpleDialogs(context).tryRequestWithLoadingDialog( - room.setUnread(!room.isUnread), + return showFutureLoadingDialog( + context: context, + future: () => room.setUnread(!room.isUnread), ); } Future _toggleFavouriteRoom(BuildContext context) { final room = Matrix.of(context).client.getRoomById(_selectedRoomIds.single); - return SimpleDialogs(context).tryRequestWithLoadingDialog( - room.setFavourite(!room.isFavourite), + return showFutureLoadingDialog( + context: context, + future: () => room.setFavourite(!room.isFavourite), ); } Future _toggleMuted(BuildContext context) { final room = Matrix.of(context).client.getRoomById(_selectedRoomIds.single); - return SimpleDialogs(context).tryRequestWithLoadingDialog( - room.setPushRuleState(room.pushRuleState == PushRuleState.notify - ? PushRuleState.mentions_only - : PushRuleState.notify), + return showFutureLoadingDialog( + context: context, + future: () => room.setPushRuleState( + room.pushRuleState == PushRuleState.notify + ? PushRuleState.mentions_only + : PushRuleState.notify), ); } @@ -170,8 +174,10 @@ class _ChatListState extends State { ) == OkCancelResult.ok; if (!confirmed) return; - await SimpleDialogs(context) - .tryRequestWithLoadingDialog(_archiveSelectedRooms(context)); + await showFutureLoadingDialog( + context: context, + future: () => _archiveSelectedRooms(context), + ); setState(() => null); } diff --git a/lib/views/chat_permissions_settings.dart b/lib/views/chat_permissions_settings.dart index 7a3616e6..21fd7351 100644 --- a/lib/views/chat_permissions_settings.dart +++ b/lib/views/chat_permissions_settings.dart @@ -2,7 +2,7 @@ import 'dart:developer'; import 'package:fluffychat/components/adaptive_page_layout.dart'; import 'package:fluffychat/components/dialogs/permission_slider_dialog.dart'; -import 'package:fluffychat/components/dialogs/simple_dialogs.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:fluffychat/components/matrix.dart'; import 'package:flushbar/flushbar_helper.dart'; import 'package:flutter/material.dart'; @@ -55,8 +55,10 @@ class ChatPermissionsSettings extends StatelessWidget { content[key] = newLevel; } inspect(content); - await SimpleDialogs(context).tryRequestWithLoadingDialog( - room.client.sendState(room.id, EventTypes.RoomPowerLevels, content), + await showFutureLoadingDialog( + context: context, + future: () => + room.client.sendState(room.id, EventTypes.RoomPowerLevels, content), ); } diff --git a/lib/views/discover_view.dart b/lib/views/discover_view.dart index 1f5d9313..6490adba 100644 --- a/lib/views/discover_view.dart +++ b/lib/views/discover_view.dart @@ -5,7 +5,7 @@ import 'package:famedlysdk/famedlysdk.dart'; import 'package:fluffychat/components/adaptive_page_layout.dart'; import 'package:fluffychat/components/avatar.dart'; import 'package:fluffychat/components/default_app_bar_search_field.dart'; -import 'package:fluffychat/components/dialogs/simple_dialogs.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:fluffychat/components/matrix.dart'; import 'package:fluffychat/utils/app_route.dart'; import 'package:fluffychat/views/chat.dart'; @@ -101,18 +101,19 @@ class _DiscoverPageState extends State { OkCancelResult.cancel) { return; } - final success = await SimpleDialogs(context).tryRequestWithLoadingDialog( - _joinRoomAndWait( + final success = await showFutureLoadingDialog( + context: context, + future: () => _joinRoomAndWait( context, room.roomId, room.canonicalAlias ?? room.aliases.first, ), ); - if (success != false) { + if (success.error == null) { await Navigator.of(context).push( AppRoute.defaultRoute( context, - ChatView(success), + ChatView(success.result), ), ); } diff --git a/lib/views/homeserver_picker.dart b/lib/views/homeserver_picker.dart index 876e1d48..67d4c935 100644 --- a/lib/views/homeserver_picker.dart +++ b/lib/views/homeserver_picker.dart @@ -2,7 +2,7 @@ import 'dart:math'; import 'package:adaptive_dialog/adaptive_dialog.dart'; import 'package:famedlysdk/famedlysdk.dart'; -import 'package:fluffychat/components/dialogs/simple_dialogs.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:fluffychat/components/matrix.dart'; import 'package:fluffychat/app_config.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; @@ -41,9 +41,10 @@ class HomeserverPicker extends StatelessWidget { homeserver = 'https://$homeserver'; } - final success = await SimpleDialogs(context).tryRequestWithLoadingDialog( - checkHomeserver(homeserver, Matrix.of(context).client)); - if (success == true) { + final success = await showFutureLoadingDialog( + context: context, + future: () => checkHomeserver(homeserver, Matrix.of(context).client)); + if (success.result == true) { await Navigator.of(context) .push(AppRoute(AppConfig.enableRegistration ? SignUp() : Login())); } diff --git a/lib/views/invitation_selection.dart b/lib/views/invitation_selection.dart index a920c9b3..f9804915 100644 --- a/lib/views/invitation_selection.dart +++ b/lib/views/invitation_selection.dart @@ -6,11 +6,12 @@ import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/matrix_api.dart'; import 'package:fluffychat/components/adaptive_page_layout.dart'; import 'package:fluffychat/components/avatar.dart'; -import 'package:fluffychat/components/dialogs/simple_dialogs.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:fluffychat/components/matrix.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; +import '../utils/localized_exception_extension.dart'; import 'chat_list.dart'; class InvitationSelection extends StatefulWidget { @@ -57,10 +58,11 @@ class _InvitationSelectionState extends State { } void inviteAction(BuildContext context, String id) async { - final success = await SimpleDialogs(context).tryRequestWithLoadingDialog( - widget.room.invite(id), + final success = await showFutureLoadingDialog( + context: context, + future: () => widget.room.invite(id), ); - if (success != false) { + if (success.error == null) { await FlushbarHelper.createSuccess( message: L10n.of(context).contactHasBeenInvitedToTheGroup) .show(context); @@ -87,11 +89,16 @@ class _InvitationSelectionState extends State { if (loading) return; setState(() => loading = true); final matrix = Matrix.of(context); - final response = await SimpleDialogs(context).tryRequestWithErrorToast( - matrix.client.searchUser(text, limit: 10), - ); - setState(() => loading = false); - if (response == false || (response?.results == null)) return; + UserSearchResult response; + try { + response = await matrix.client.searchUser(text, limit: 10); + } catch (e) { + FlushbarHelper.createError( + message: (e as Object).toLocalizedString(context)); + return; + } finally { + setState(() => loading = false); + } setState(() { foundProfiles = List.from(response.results); if ('@$text'.isValidMatrixId && diff --git a/lib/views/login.dart b/lib/views/login.dart index 1fd23ec5..5521d701 100644 --- a/lib/views/login.dart +++ b/lib/views/login.dart @@ -3,7 +3,7 @@ import 'dart:math'; import 'package:adaptive_dialog/adaptive_dialog.dart'; import 'package:famedlysdk/famedlysdk.dart'; -import 'package:fluffychat/components/dialogs/simple_dialogs.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:fluffychat/components/matrix.dart'; import 'package:fluffychat/utils/app_route.dart'; import 'package:fluffychat/utils/firebase_controller.dart'; @@ -87,8 +87,10 @@ class _LoginState extends State { final newDomain = wellKnownInformations.mHomeserver?.baseUrl; if ((newDomain?.isNotEmpty ?? false) && newDomain != Matrix.of(context).client.homeserver.toString()) { - await SimpleDialogs(context).tryRequestWithErrorToast( - Matrix.of(context).client.checkHomeserver(newDomain)); + await showFutureLoadingDialog( + context: context, + future: () => Matrix.of(context).client.checkHomeserver(newDomain), + ); setState(() => usernameError = null); } } catch (e) { @@ -109,14 +111,15 @@ class _LoginState extends State { ); if (input == null) return; final clientSecret = DateTime.now().millisecondsSinceEpoch.toString(); - final response = await SimpleDialogs(context).tryRequestWithLoadingDialog( - Matrix.of(context).client.resetPasswordUsingEmail( + final response = await showFutureLoadingDialog( + context: context, + future: () => Matrix.of(context).client.resetPasswordUsingEmail( input.single, clientSecret, sendAttempt++, ), ); - if (response == false) return; + if (response.error != null) return; final ok = await showOkAlertDialog( context: context, title: L10n.of(context).weSentYouAnEmail, @@ -137,8 +140,9 @@ class _LoginState extends State { ], ); if (password == null) return; - final success = await SimpleDialogs(context).tryRequestWithLoadingDialog( - Matrix.of(context).client.changePassword( + final success = await showFutureLoadingDialog( + context: context, + future: () => Matrix.of(context).client.changePassword( password.single, auth: AuthenticationThreePidCreds( type: AuthenticationTypes.emailIdentity, @@ -151,7 +155,7 @@ class _LoginState extends State { ), ), ); - if (success != false) { + if (success.error == null) { FlushbarHelper.createSuccess( message: L10n.of(context).passwordHasBeenChanged); } diff --git a/lib/views/new_group.dart b/lib/views/new_group.dart index 8f0154ee..1befce32 100644 --- a/lib/views/new_group.dart +++ b/lib/views/new_group.dart @@ -1,6 +1,6 @@ import 'package:famedlysdk/matrix_api.dart' as api; import 'package:fluffychat/components/adaptive_page_layout.dart'; -import 'package:fluffychat/components/dialogs/simple_dialogs.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:fluffychat/components/matrix.dart'; import 'package:fluffychat/utils/app_route.dart'; import 'package:flutter/material.dart'; @@ -33,9 +33,9 @@ class _NewGroupState extends State<_NewGroup> { void submitAction(BuildContext context) async { final matrix = Matrix.of(context); - final String roomID = - await SimpleDialogs(context).tryRequestWithLoadingDialog( - matrix.client.createRoom( + final roomID = await showFutureLoadingDialog( + context: context, + future: () => matrix.client.createRoom( preset: publicGroup ? api.CreateRoomPreset.public_chat : api.CreateRoomPreset.private_chat, @@ -51,7 +51,7 @@ class _NewGroupState extends State<_NewGroup> { Navigator.of(context).push( AppRoute.defaultRoute( context, - ChatView(roomID), + ChatView(roomID.result), ), ), ); @@ -59,7 +59,7 @@ class _NewGroupState extends State<_NewGroup> { context, MaterialPageRoute( builder: (context) => InvitationSelection( - matrix.client.getRoomById(roomID), + matrix.client.getRoomById(roomID.result), ), ), ); diff --git a/lib/views/new_private_chat.dart b/lib/views/new_private_chat.dart index 67f050a3..12a5bf33 100644 --- a/lib/views/new_private_chat.dart +++ b/lib/views/new_private_chat.dart @@ -4,7 +4,7 @@ import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/matrix_api.dart'; import 'package:fluffychat/components/adaptive_page_layout.dart'; import 'package:fluffychat/components/avatar.dart'; -import 'package:fluffychat/components/dialogs/simple_dialogs.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:fluffychat/components/matrix.dart'; import 'package:fluffychat/utils/app_route.dart'; import 'package:fluffychat/utils/fluffy_share.dart'; @@ -56,15 +56,17 @@ class _NewPrivateChatState extends State<_NewPrivateChat> { '@' + controller.text.trim(), room: Room(id: '', client: matrix.client), ); - final String roomID = await SimpleDialogs(context) - .tryRequestWithLoadingDialog(user.startDirectChat()); + final roomID = await showFutureLoadingDialog( + context: context, + future: () => user.startDirectChat(), + ); Navigator.of(context).pop(); - if (roomID != null) { + if (roomID.error == null) { await Navigator.of(context).push( AppRoute.defaultRoute( context, - ChatView(roomID), + ChatView(roomID.result), ), ); } @@ -89,13 +91,14 @@ class _NewPrivateChatState extends State<_NewPrivateChat> { if (loading) return; setState(() => loading = true); final matrix = Matrix.of(context); - final response = await SimpleDialogs(context).tryRequestWithErrorToast( - matrix.client.searchUser(text, limit: 10), + final response = await showFutureLoadingDialog( + context: context, + future: () => matrix.client.searchUser(text, limit: 10), ); setState(() => loading = false); - if (response == false || (response?.results?.isEmpty ?? true)) return; + if (response.result?.results?.isEmpty ?? true) return; setState(() { - foundProfiles = List.from(response.results); + foundProfiles = List.from(response.result.results); }); } diff --git a/lib/views/settings.dart b/lib/views/settings.dart index e832d848..07b6c5f6 100644 --- a/lib/views/settings.dart +++ b/lib/views/settings.dart @@ -21,7 +21,7 @@ import 'package:url_launcher/url_launcher.dart'; import '../components/adaptive_page_layout.dart'; import '../components/content_banner.dart'; -import '../components/dialogs/simple_dialogs.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; import '../components/matrix.dart'; import '../utils/app_route.dart'; import '../app_config.dart'; @@ -62,8 +62,10 @@ class _SettingsState extends State { return; } var matrix = Matrix.of(context); - await SimpleDialogs(context) - .tryRequestWithLoadingDialog(matrix.client.logout()); + await showFutureLoadingDialog( + context: context, + future: () => matrix.client.logout(), + ); } void _changePasswordAccountAction(BuildContext context) async { @@ -86,8 +88,9 @@ class _SettingsState extends State { ], ); if (input == null) return; - await SimpleDialogs(context).tryRequestWithLoadingDialog( - Matrix.of(context) + await showFutureLoadingDialog( + context: context, + future: () => Matrix.of(context) .client .changePassword(input.last, oldPassword: input.first), ); @@ -123,8 +126,9 @@ class _SettingsState extends State { ], ); if (input == null) return; - await SimpleDialogs(context).tryRequestWithLoadingDialog( - Matrix.of(context).client.deactivateAccount( + await showFutureLoadingDialog( + context: context, + future: () => Matrix.of(context).client.deactivateAccount( auth: AuthenticationPassword( password: input.single, user: Matrix.of(context).client.userID, @@ -170,10 +174,12 @@ class _SettingsState extends State { ); if (input == null) return; final matrix = Matrix.of(context); - final success = await SimpleDialogs(context).tryRequestWithLoadingDialog( - matrix.client.setDisplayname(matrix.client.userID, input.single), + final success = await showFutureLoadingDialog( + context: context, + future: () => + matrix.client.setDisplayname(matrix.client.userID, input.single), ); - if (success != false) { + if (success.error == null) { setState(() { profileFuture = null; profile = null; @@ -204,10 +210,11 @@ class _SettingsState extends State { ); } final matrix = Matrix.of(context); - final success = await SimpleDialogs(context).tryRequestWithLoadingDialog( - matrix.client.setAvatar(file), + final success = await showFutureLoadingDialog( + context: context, + future: () => matrix.client.setAvatar(file), ); - if (success != false) { + if (success.error == null) { setState(() { profileFuture = null; profile = null; @@ -230,21 +237,22 @@ class _SettingsState extends State { ], ); if (input != null) { - final valid = await SimpleDialogs(context) - .tryRequestWithLoadingDialog(Future.microtask(() async { - // make sure the loading spinner shows before we test the keys - await Future.delayed(Duration(milliseconds: 100)); - var valid = false; - try { - await handle.unlock(recoveryKey: input.single); - valid = true; - } catch (e, s) { - SentryController.captureException(e, s); - } - return valid; - })); + final valid = await showFutureLoadingDialog( + context: context, + future: () async { + // make sure the loading spinner shows before we test the keys + await Future.delayed(Duration(milliseconds: 100)); + var valid = false; + try { + await handle.unlock(recoveryKey: input.single); + valid = true; + } catch (e, s) { + SentryController.captureException(e, s); + } + return valid; + }); - if (valid == true) { + if (valid.result == true) { await handle.maybeCacheAll(); await showOkAlertDialog( context: context, @@ -514,28 +522,29 @@ class _SettingsState extends State { ], ); if (input != null) { - final valid = await SimpleDialogs(context) - .tryRequestWithLoadingDialog(Future.microtask(() async { - // make sure the loading spinner shows before we test the keys - await Future.delayed(Duration(milliseconds: 100)); - var valid = false; - try { - await client.encryption.crossSigning - .selfSign(recoveryKey: input.single); - valid = true; - } catch (_) { - try { - await client.encryption.crossSigning - .selfSign(passphrase: input.single); - valid = true; - } catch (_) { - valid = false; - } - } - return valid; - })); + final valid = await showFutureLoadingDialog( + context: context, + future: () async { + // make sure the loading spinner shows before we test the keys + await Future.delayed(Duration(milliseconds: 100)); + var valid = false; + try { + await client.encryption.crossSigning + .selfSign(recoveryKey: input.single); + valid = true; + } catch (_) { + try { + await client.encryption.crossSigning + .selfSign(passphrase: input.single); + valid = true; + } catch (_) { + valid = false; + } + } + return valid; + }); - if (valid == true) { + if (valid.result == true) { await showOkAlertDialog( context: context, message: L10n.of(context).verifiedSession, diff --git a/lib/views/settings_3pid.dart b/lib/views/settings_3pid.dart index b9a231ba..96c9040c 100644 --- a/lib/views/settings_3pid.dart +++ b/lib/views/settings_3pid.dart @@ -1,7 +1,7 @@ import 'package:adaptive_dialog/adaptive_dialog.dart'; import 'package:famedlysdk/famedlysdk.dart'; import 'package:fluffychat/components/adaptive_page_layout.dart'; -import 'package:fluffychat/components/dialogs/simple_dialogs.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:fluffychat/components/matrix.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; @@ -40,14 +40,15 @@ class _Settings3PidState extends State { ); if (input == null) return; final clientSecret = DateTime.now().millisecondsSinceEpoch.toString(); - final response = await SimpleDialogs(context).tryRequestWithLoadingDialog( - Matrix.of(context).client.requestEmailToken( + final response = await showFutureLoadingDialog( + context: context, + future: () => Matrix.of(context).client.requestEmailToken( input.single, clientSecret, Settings3Pid.sendAttempt++, ), ); - if (response == false) return; + if (response.error != null) return; final ok = await showOkAlertDialog( context: context, title: L10n.of(context).weSentYouAnEmail, @@ -68,8 +69,9 @@ class _Settings3PidState extends State { ], ); if (password == null) return; - final success = await SimpleDialogs(context).tryRequestWithLoadingDialog( - Matrix.of(context).client.uiaRequestBackground( + final success = await showFutureLoadingDialog( + context: context, + future: () => Matrix.of(context).client.uiaRequestBackground( (auth) => Matrix.of(context).client.addThirdPartyIdentifier( clientSecret, (response as RequestTokenResponse).sid, @@ -77,7 +79,7 @@ class _Settings3PidState extends State { ), ), ); - if (success == false) return; + if (success.error != null) return; setState(() => _request = null); } @@ -92,12 +94,13 @@ class _Settings3PidState extends State { OkCancelResult.ok) { return; } - final success = await SimpleDialogs(context).tryRequestWithLoadingDialog( - Matrix.of(context).client.deleteThirdPartyIdentifier( + final success = await showFutureLoadingDialog( + context: context, + future: () => Matrix.of(context).client.deleteThirdPartyIdentifier( identifier.address, identifier.medium, )); - if (success == false) return; + if (success.error != null) return; setState(() => _request = null); } diff --git a/lib/views/settings_devices.dart b/lib/views/settings_devices.dart index 4ab04554..b19e0681 100644 --- a/lib/views/settings_devices.dart +++ b/lib/views/settings_devices.dart @@ -1,6 +1,6 @@ import 'package:adaptive_dialog/adaptive_dialog.dart'; import 'package:famedlysdk/famedlysdk.dart'; -import 'package:fluffychat/components/dialogs/simple_dialogs.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; @@ -60,8 +60,9 @@ class DevicesSettingsState extends State { ); if (password == null) return; - final success = await SimpleDialogs(context).tryRequestWithLoadingDialog( - matrix.client.deleteDevices( + final success = await showFutureLoadingDialog( + context: context, + future: () => matrix.client.deleteDevices( deviceIds, auth: AuthenticationPassword( password: password.single, @@ -70,7 +71,7 @@ class DevicesSettingsState extends State { ), ), ); - if (success != false) { + if (success.error == null) { reload(); } } @@ -86,12 +87,13 @@ class DevicesSettingsState extends State { ], ); if (displayName == null) return; - final success = await SimpleDialogs(context).tryRequestWithLoadingDialog( - Matrix.of(context) + final success = await showFutureLoadingDialog( + context: context, + future: () => Matrix.of(context) .client .setDeviceMetadata(device.deviceId, displayName: displayName.single), ); - if (success != false) { + if (success.error == null) { reload(); } } diff --git a/lib/views/settings_emotes.dart b/lib/views/settings_emotes.dart index e7474eda..a5f1f4e3 100644 --- a/lib/views/settings_emotes.dart +++ b/lib/views/settings_emotes.dart @@ -11,7 +11,7 @@ import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:image_picker/image_picker.dart'; import '../components/adaptive_page_layout.dart'; -import '../components/dialogs/simple_dialogs.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; import '../components/matrix.dart'; import 'chat_list.dart'; @@ -94,13 +94,16 @@ class _EmotesSettingsState extends State { // remove the old "short" key content.remove('short'); if (widget.room != null) { - await SimpleDialogs(context).tryRequestWithLoadingDialog( - client.sendState(widget.room.id, 'im.ponies.room_emotes', content, - widget.stateKey ?? ''), + await showFutureLoadingDialog( + context: context, + future: () => client.sendState(widget.room.id, 'im.ponies.room_emotes', + content, widget.stateKey ?? ''), ); } else { - await SimpleDialogs(context).tryRequestWithLoadingDialog( - client.setAccountData(client.userID, 'im.ponies.user_emotes', content), + await showFutureLoadingDialog( + context: context, + future: () => client.setAccountData( + client.userID, 'im.ponies.user_emotes', content), ); } } @@ -128,8 +131,10 @@ class _EmotesSettingsState extends State { content['rooms'][widget.room.id].remove(widget.stateKey ?? ''); } // and save - await SimpleDialogs(context).tryRequestWithLoadingDialog( - client.setAccountData(client.userID, 'im.ponies.emote_rooms', content), + await showFutureLoadingDialog( + context: context, + future: () => client.setAccountData( + client.userID, 'im.ponies.emote_rooms', content), ); } @@ -477,13 +482,16 @@ class _EmoteImagePickerState extends State<_EmoteImagePicker> { name: result.fileName, ); } - final uploadResp = - await SimpleDialogs(context).tryRequestWithLoadingDialog( - Matrix.of(context).client.upload(file.bytes, file.name), + final uploadResp = await showFutureLoadingDialog( + context: context, + future: () => + Matrix.of(context).client.upload(file.bytes, file.name), ); - setState(() { - widget.controller.text = uploadResp; - }); + if (uploadResp.error == null) { + setState(() { + widget.controller.text = uploadResp.result; + }); + } }, ); } else { diff --git a/lib/views/settings_ignore_list.dart b/lib/views/settings_ignore_list.dart index 35326670..94b08360 100644 --- a/lib/views/settings_ignore_list.dart +++ b/lib/views/settings_ignore_list.dart @@ -1,7 +1,7 @@ import 'package:famedlysdk/famedlysdk.dart'; import 'package:fluffychat/components/adaptive_page_layout.dart'; import 'package:fluffychat/components/avatar.dart'; -import 'package:fluffychat/components/dialogs/simple_dialogs.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; @@ -24,8 +24,9 @@ class SettingsIgnoreList extends StatelessWidget { void _ignoreUser(BuildContext context) { if (controller.text.isEmpty) return; - SimpleDialogs(context).tryRequestWithLoadingDialog( - Matrix.of(context).client.ignoreUser('@${controller.text}'), + showFutureLoadingDialog( + context: context, + future: () => Matrix.of(context).client.ignoreUser('@${controller.text}'), ); controller.clear(); } @@ -86,9 +87,10 @@ class SettingsIgnoreList extends StatelessWidget { Text(s.data?.displayname ?? client.ignoredUsers[i]), trailing: IconButton( icon: Icon(Icons.delete_forever_outlined), - onPressed: () => SimpleDialogs(context) - .tryRequestWithLoadingDialog( - client.unignoreUser(client.ignoredUsers[i]), + onPressed: () => showFutureLoadingDialog( + context: context, + future: () => + client.unignoreUser(client.ignoredUsers[i]), ), ), ), diff --git a/lib/views/settings_notifications.dart b/lib/views/settings_notifications.dart index 0d936aae..64b11ce4 100644 --- a/lib/views/settings_notifications.dart +++ b/lib/views/settings_notifications.dart @@ -2,7 +2,7 @@ import 'dart:io'; import 'package:famedlysdk/famedlysdk.dart'; import 'package:fluffychat/components/adaptive_page_layout.dart'; -import 'package:fluffychat/components/dialogs/simple_dialogs.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:fluffychat/app_config.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; @@ -107,8 +107,9 @@ class SettingsNotifications extends StatelessWidget { void _setNotificationSetting( BuildContext context, NotificationSettingsItem item, bool enabled) { - SimpleDialogs(context).tryRequestWithLoadingDialog( - Matrix.of(context).client.enablePushRule( + showFutureLoadingDialog( + context: context, + future: () => Matrix.of(context).client.enablePushRule( 'global', item.type, item.key, @@ -136,9 +137,11 @@ class SettingsNotifications extends StatelessWidget { value: !Matrix.of(context).client.allPushNotificationsMuted, title: Text(L10n.of(context).notificationsEnabledForThisAccount), - onChanged: (_) => - SimpleDialogs(context).tryRequestWithLoadingDialog( - Matrix.of(context).client.setMuteAllPushNotifications( + onChanged: (_) => showFutureLoadingDialog( + context: context, + future: () => Matrix.of(context) + .client + .setMuteAllPushNotifications( !Matrix.of(context).client.allPushNotificationsMuted, ), ), diff --git a/pubspec.lock b/pubspec.lock index 34c9ea44..d9aea970 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -429,6 +429,13 @@ packages: description: flutter source: sdk version: "0.0.0" + future_loading_dialog: + dependency: "direct main" + description: + name: future_loading_dialog + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.2" glob: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index c8778caa..4e8ab373 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -64,6 +64,7 @@ dependencies: flutter_cache_manager: ^2.1.0 open_noti_settings: ^0.0.4 emoji_picker: ^0.1.0 + future_loading_dialog: ^0.1.2 dev_dependencies: flutter_test: