diff --git a/lib/pages/chat/events/audio_player.dart b/lib/pages/chat/events/audio_player.dart index 5609c62d0..b4730649f 100644 --- a/lib/pages/chat/events/audio_player.dart +++ b/lib/pages/chat/events/audio_player.dart @@ -47,6 +47,7 @@ class AudioPlayerState extends State { static const double buttonSize = 36; AudioPlayerStatus status = AudioPlayerStatus.notDownloaded; + double? _downloadProgress; late final MatrixState matrix; List? _waveform; @@ -149,7 +150,20 @@ class AudioPlayerState extends State { setState(() => status = AudioPlayerStatus.downloading); try { - matrixFile = await widget.event.downloadAndDecryptAttachment(); + final fileSize = widget.event.content + .tryGetMap('info') + ?.tryGet('size'); + matrixFile = await widget.event.downloadAndDecryptAttachment( + onDownloadProgress: fileSize != null && fileSize > 0 + ? (progress) { + final progressPercentage = progress / fileSize; + setState(() { + _downloadProgress = + progressPercentage < 1 ? progressPercentage : null; + }); + } + : null, + ); if (!kIsWeb) { final tempDir = await getTemporaryDirectory(); @@ -320,6 +334,7 @@ class AudioPlayerState extends State { ? CircularProgressIndicator( strokeWidth: 2, color: widget.color, + value: _downloadProgress, ) : InkWell( borderRadius: BorderRadius.circular(64), diff --git a/lib/pages/image_viewer/video_player.dart b/lib/pages/image_viewer/video_player.dart index a362b94c3..3f3ac9e19 100644 --- a/lib/pages/image_viewer/video_player.dart +++ b/lib/pages/image_viewer/video_player.dart @@ -32,6 +32,8 @@ class EventVideoPlayerState extends State { ChewieController? _chewieController; VideoPlayerController? _videoPlayerController; + double? _downloadProgress; + // The video_player package only doesn't support Windows and Linux. final _supportsVideoPlayer = !PlatformInfos.isWindows && !PlatformInfos.isLinux; @@ -43,7 +45,20 @@ class EventVideoPlayerState extends State { } try { - final videoFile = await widget.event.downloadAndDecryptAttachment(); + final fileSize = widget.event.content + .tryGetMap('info') + ?.tryGet('size'); + final videoFile = await widget.event.downloadAndDecryptAttachment( + onDownloadProgress: fileSize == null + ? null + : (progress) { + final progressPercentage = progress / fileSize; + setState(() { + _downloadProgress = + progressPercentage < 1 ? progressPercentage : null; + }); + }, + ); // Dispose the controllers if we already have them. _disposeControllers(); @@ -165,7 +180,11 @@ class EventVideoPlayerState extends State { ), ), ), - const Center(child: CircularProgressIndicator.adaptive()), + Center( + child: CircularProgressIndicator.adaptive( + value: _downloadProgress, + ), + ), ], ); } diff --git a/lib/utils/matrix_sdk_extensions/event_extension.dart b/lib/utils/matrix_sdk_extensions/event_extension.dart index b28ea258e..046df2598 100644 --- a/lib/utils/matrix_sdk_extensions/event_extension.dart +++ b/lib/utils/matrix_sdk_extensions/event_extension.dart @@ -14,7 +14,15 @@ extension LocalizedBody on Event { Future> _getFile(BuildContext context) => showFutureLoadingDialog( context: context, - future: downloadAndDecryptAttachment, + futureWithProgress: (onProgress) { + final fileSize = + infoMap['size'] is int ? infoMap['size'] as int : null; + return downloadAndDecryptAttachment( + onDownloadProgress: fileSize == null + ? null + : (bytes) => onProgress(bytes / fileSize), + ); + }, ); void saveFile(BuildContext context) async {