diff --git a/lib/pages/chat/events/message_download_content.dart b/lib/pages/chat/events/message_download_content.dart index e3288f1523..ecc6a1a9fa 100644 --- a/lib/pages/chat/events/message_download_content.dart +++ b/lib/pages/chat/events/message_download_content.dart @@ -6,6 +6,7 @@ import 'package:fluffychat/app_state/failure.dart'; import 'package:fluffychat/app_state/success.dart'; import 'package:fluffychat/di/global/get_it_initializer.dart'; import 'package:fluffychat/presentation/model/chat/downloading_state_presentation_model.dart'; +import 'package:fluffychat/utils/exception/downloading_exception.dart'; import 'package:fluffychat/utils/manager/download_manager/download_file_state.dart'; import 'package:fluffychat/utils/manager/download_manager/download_manager.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/download_file_extension.dart'; @@ -95,7 +96,14 @@ class _MessageDownloadContentState extends State event.fold( (failure) { Logs().e('MessageDownloadContent::onDownloadingProcess(): $failure'); - downloadFileStateNotifier.value = const NotDownloadPresentationState(); + if (failure is DownloadFileFailureState && + failure.exception is CancelDownloadingException) { + downloadFileStateNotifier.value = + const NotDownloadPresentationState(); + } else { + downloadFileStateNotifier.value = + DownloadErrorPresentationState(error: failure); + } streamSubscription?.cancel(); }, (success) { @@ -159,7 +167,8 @@ class _MessageDownloadContentState extends State style: const MessageFileTileStyle(), ), ); - } else if (state is DownloadingPresentationState) { + } else if (state is DownloadingPresentationState || + state is DownloadErrorPresentationState) { return DownloadFileTileWidget( mimeType: widget.event.mimeType, fileType: filetype, @@ -173,6 +182,7 @@ class _MessageDownloadContentState extends State const NotDownloadPresentationState(); downloadManager.cancelDownload(widget.event.eventId); }, + hasError: state is DownloadErrorPresentationState, ); } diff --git a/lib/pages/chat/events/message_download_content_web.dart b/lib/pages/chat/events/message_download_content_web.dart index fcfd4e8101..6b1fecda7b 100644 --- a/lib/pages/chat/events/message_download_content_web.dart +++ b/lib/pages/chat/events/message_download_content_web.dart @@ -5,6 +5,7 @@ import 'package:fluffychat/app_state/failure.dart'; import 'package:fluffychat/app_state/success.dart'; import 'package:fluffychat/di/global/get_it_initializer.dart'; import 'package:fluffychat/presentation/model/chat/downloading_state_presentation_model.dart'; +import 'package:fluffychat/utils/exception/downloading_exception.dart'; import 'package:fluffychat/utils/manager/download_manager/download_file_state.dart'; import 'package:fluffychat/utils/manager/download_manager/download_manager.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/event_extension.dart'; @@ -59,8 +60,15 @@ class _MessageDownloadContentWebState extends State void setupDownloadingProcess(Either event) { event.fold( (failure) { - Logs().e('MessageDownloadContent::onDownloadingProcess(): $failure'); - downloadFileStateNotifier.value = const NotDownloadPresentationState(); + Logs().e('MessageDownloadContentWeb::onDownloadingProcess(): $failure'); + if (failure is DownloadFileFailureState && + failure.exception is CancelDownloadingException) { + downloadFileStateNotifier.value = + const NotDownloadPresentationState(); + } else { + downloadFileStateNotifier.value = + DownloadErrorPresentationState(error: failure); + } }, (success) { if (success is DownloadingFileState) { @@ -111,7 +119,8 @@ class _MessageDownloadContentWebState extends State return ValueListenableBuilder( valueListenable: downloadFileStateNotifier, builder: (context, DownloadPresentationState state, child) { - if (state is DownloadingPresentationState) { + if (state is DownloadingPresentationState || + state is DownloadErrorPresentationState) { return DownloadFileTileWidget( mimeType: widget.event.mimeType, fileType: filetype, @@ -125,6 +134,7 @@ class _MessageDownloadContentWebState extends State const NotDownloadPresentationState(); downloadManager.cancelDownload(widget.event.eventId); }, + hasError: state is DownloadErrorPresentationState, ); } else if (state is FileWebDownloadedPresentationState) { return InkWell( diff --git a/lib/presentation/model/chat/downloading_state_presentation_model.dart b/lib/presentation/model/chat/downloading_state_presentation_model.dart index 4086a76175..ca48a125a8 100644 --- a/lib/presentation/model/chat/downloading_state_presentation_model.dart +++ b/lib/presentation/model/chat/downloading_state_presentation_model.dart @@ -44,3 +44,12 @@ class DownloadingPresentationState extends DownloadPresentationState { @override List get props => [receive, total]; } + +class DownloadErrorPresentationState extends DownloadPresentationState { + final dynamic error; + + const DownloadErrorPresentationState({required this.error}); + + @override + List get props => [error]; +} diff --git a/lib/utils/matrix_sdk_extensions/download_file_extension.dart b/lib/utils/matrix_sdk_extensions/download_file_extension.dart index 0521192c01..2ebde64094 100644 --- a/lib/utils/matrix_sdk_extensions/download_file_extension.dart +++ b/lib/utils/matrix_sdk_extensions/download_file_extension.dart @@ -109,6 +109,11 @@ extension DownloadFileExtension on Event { Logs().i("downloadOrRetrieveAttachment: duplicate request"); } else { Logs().e("downloadOrRetrieveAttachment: $e"); + downloadStreamController?.add( + Left( + DownloadFileFailureState(exception: e), + ), + ); } } return null; diff --git a/lib/utils/matrix_sdk_extensions/download_file_web_extension.dart b/lib/utils/matrix_sdk_extensions/download_file_web_extension.dart index 88a31f72d3..242d6aafcf 100644 --- a/lib/utils/matrix_sdk_extensions/download_file_web_extension.dart +++ b/lib/utils/matrix_sdk_extensions/download_file_web_extension.dart @@ -115,6 +115,11 @@ extension DownloadFileWebExtension on Event { Logs().i("_handleDownloadFileWeb: user cancel the download"); } Logs().e("_handleDownloadFileWeb: $e"); + downloadStreamController.add( + Left( + DownloadFileFailureState(exception: e), + ), + ); } return null; } diff --git a/lib/widgets/file_widget/download_file_tile_widget.dart b/lib/widgets/file_widget/download_file_tile_widget.dart index c74469fb6f..8d24575b95 100644 --- a/lib/widgets/file_widget/download_file_tile_widget.dart +++ b/lib/widgets/file_widget/download_file_tile_widget.dart @@ -16,6 +16,7 @@ class DownloadFileTileWidget extends StatelessWidget { this.sizeString, required this.downloadFileStateNotifier, this.onCancelDownload, + this.hasError = false, }); final TwakeMimeType mimeType; @@ -26,6 +27,7 @@ class DownloadFileTileWidget extends StatelessWidget { final String? fileType; final ValueNotifier downloadFileStateNotifier; final VoidCallback? onCancelDownload; + final bool hasError; @override Widget build(BuildContext context) { @@ -63,11 +65,14 @@ class DownloadFileTileWidget extends StatelessWidget { width: style.iconSize, height: style.iconSize, decoration: BoxDecoration( - color: Theme.of(context).colorScheme.primary, + color: style.iconBackgroundColor( + hasError: hasError, + context: context, + ), shape: BoxShape.circle, ), ), - if (downloadProgress != 0) + if (downloadProgress != 0 && !hasError) SizedBox( width: style.circularProgressLoadingSize, height: style.circularProgressLoadingSize, @@ -81,13 +86,18 @@ class DownloadFileTileWidget extends StatelessWidget { child: Container( width: style.downloadIconSize, decoration: BoxDecoration( - color: Theme.of(context).colorScheme.primary, + color: style.iconBackgroundColor( + hasError: hasError, + context: context, + ), shape: BoxShape.circle, ), child: Icon( - downloadProgress == 0 - ? Icons.arrow_downward - : Icons.close, + hasError + ? Icons.error_outline + : downloadProgress == 0 + ? Icons.arrow_downward + : Icons.close, key: ValueKey(downloadProgress), color: Theme.of(context).colorScheme.surface, size: style.downloadIconSize, diff --git a/lib/widgets/file_widget/message_file_tile_style.dart b/lib/widgets/file_widget/message_file_tile_style.dart index 65f261af33..64b4c68149 100644 --- a/lib/widgets/file_widget/message_file_tile_style.dart +++ b/lib/widgets/file_widget/message_file_tile_style.dart @@ -47,4 +47,12 @@ class MessageFileTileStyle extends FileTileWidgetStyle { double get downloadIconSize => 28; EdgeInsets get marginDownloadIcon => const EdgeInsets.all(4); + + Color iconBackgroundColor({ + required bool hasError, + required BuildContext context, + }) => + hasError + ? Theme.of(context).colorScheme.error + : Theme.of(context).colorScheme.primary; }