diff --git a/lib/pages/chat/events/message_download_content.dart b/lib/pages/chat/events/message_download_content.dart index 7ceb864..11ad585 100644 --- a/lib/pages/chat/events/message_download_content.dart +++ b/lib/pages/chat/events/message_download_content.dart @@ -42,7 +42,12 @@ class MessageDownloadContent extends StatelessWidget { color: Colors.transparent, child: InkWell( borderRadius: BorderRadius.circular(AppConfig.borderRadius / 2), - onTap: () => event.saveFile(context), + onTap: () => { + if (event.canDownloadInBackground) + event.downloadInBackground(context) + else + event.saveFile(context) + }, child: Container( width: 400, padding: const EdgeInsets.all(16.0), diff --git a/lib/pages/chat_list/client_chooser_button.dart b/lib/pages/chat_list/client_chooser_button.dart index 555df6c..57335a8 100644 --- a/lib/pages/chat_list/client_chooser_button.dart +++ b/lib/pages/chat_list/client_chooser_button.dart @@ -1,3 +1,4 @@ +import 'package:extera_next/pages/download_manager/download_manager_view.dart'; import 'package:flutter/material.dart'; import 'package:extera_next/generated/l10n/l10n.dart'; @@ -56,6 +57,16 @@ class ClientChooserButton extends StatelessWidget { ], ), ), + PopupMenuItem( + value: SettingsAction.downloads, + child: Row( + children: [ + Icon(Icons.download_outlined), + const SizedBox(width: 18), + Text("Downloads"), + ], + ), + ), PopupMenuItem( value: SettingsAction.archive, child: Row( @@ -220,6 +231,9 @@ class ClientChooserButton extends StatelessWidget { case SettingsAction.setStatus: controller.setStatus(); break; + case SettingsAction.downloads: + DownloadManagerView.showDownloads(context); + break; } } } @@ -229,6 +243,7 @@ enum SettingsAction { addAccount, newGroup, setStatus, + downloads, invite, settings, archive, diff --git a/lib/pages/download_manager/download_manager_view.dart b/lib/pages/download_manager/download_manager_view.dart index c1eff9c..24fcbc6 100644 --- a/lib/pages/download_manager/download_manager_view.dart +++ b/lib/pages/download_manager/download_manager_view.dart @@ -1,32 +1,48 @@ import 'package:extera_next/pages/download_manager/download_manager.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; class DownloadManagerView extends StatelessWidget { final DownloadManagerController controller; const DownloadManagerView(this.controller, {super.key}); + static void showDownloads(BuildContext context) { + showAdaptiveDialog( + context: context, + builder: (context) => DownloadManagerView(Provider.of(context)), + barrierDismissible: true + ); + } + @override Widget build(BuildContext context) { - return Scaffold( - body: ListView.builder( - itemCount: controller.downloads.length, - itemBuilder: (context, index) { - final download = controller.downloads[index]; - return ListTile( - title: Text(download.name), - subtitle: LinearProgressIndicator( - value: download.progress, - backgroundColor: Colors.grey[200], - valueColor: AlwaysStoppedAnimation(Colors.blue), - ), - trailing: ElevatedButton( - onPressed: () { - // "Cancel" button action can be added here - }, - child: Text("Cancel"), - ), - ); - }, + return AlertDialog.adaptive( + content: ConstrainedBox( + constraints: const BoxConstraints(maxHeight: 256, maxWidth: 256), + child: ListView.builder( + itemCount: controller.downloads.length, + itemBuilder: (context, index) { + final download = controller.downloads[index]; + return ListTile( + title: Text(download.name), + subtitle: LinearProgressIndicator( + value: download.progress, + backgroundColor: Colors.grey[200], + valueColor: AlwaysStoppedAnimation(Colors.blue), + ), + trailing: ElevatedButton( + onPressed: () { + // "Cancel" button action can be added here + }, + child: Text("Cancel"), + ), + ); + }, + ), + ), + title: ConstrainedBox( + constraints: const BoxConstraints(maxWidth: 256), + child: const Center(child: Text("Downloads", textAlign: TextAlign.center)), ), ); } diff --git a/lib/utils/matrix_sdk_extensions/event_extension.dart b/lib/utils/matrix_sdk_extensions/event_extension.dart index 82e97dc..3966897 100644 --- a/lib/utils/matrix_sdk_extensions/event_extension.dart +++ b/lib/utils/matrix_sdk_extensions/event_extension.dart @@ -27,10 +27,12 @@ extension LocalizedBody on Event { } void downloadInBackground(BuildContext context) async { - if (this.hasAttachment && this.status.isSent && !room.encrypted) { + if (!canDownloadInBackground) { final dmc = Provider.of(context); final filename = content.tryGet('filename') ?? body; dmc.download(context, "$filename.${roomId!.substring(0, 4)}.${eventId.substring(0, 4)}.${extensionFromMime(attachmentMimetype)}", attachmentMxcUrl.toString()); + } else { + throw Exception("Cannot download in background"); } } @@ -41,6 +43,11 @@ extension LocalizedBody on Event { matrixFile.result?.share(context); } + bool get canDownloadInBackground => + hasAttachment && + status.isSent && + !room.encrypted; + bool get isAttachmentSmallEnough => infoMap['size'] is int && infoMap['size'] < room.client.database!.maxFileSize;