From 53e3b3c561b4ae61ba657db8f55dd9fc569550c3 Mon Sep 17 00:00:00 2001 From: "Alexander \"PapaTutuWawa" Date: Sat, 8 Jul 2023 20:57:02 +0200 Subject: [PATCH] feat(ui): Prepare for selectively removing media files --- lib/ui/pages/profile/profile.dart | 4 ++ .../pages/settings/storage/shared_media.dart | 4 ++ lib/ui/widgets/chat/message.dart | 34 ------------- lib/ui/widgets/chat/shared.dart | 50 +++++++++++++++++++ lib/ui/widgets/chat/shared/audio.dart | 3 ++ lib/ui/widgets/chat/shared/base.dart | 29 ++++++----- lib/ui/widgets/chat/shared/file.dart | 3 ++ lib/ui/widgets/chat/shared/image.dart | 3 ++ lib/ui/widgets/chat/shared/video.dart | 3 ++ lib/ui/widgets/shared_media_view.dart | 12 ++++- 10 files changed, 95 insertions(+), 50 deletions(-) create mode 100644 lib/ui/widgets/chat/shared.dart diff --git a/lib/ui/pages/profile/profile.dart b/lib/ui/pages/profile/profile.dart index e8a8b195..bc61dc5c 100644 --- a/lib/ui/pages/profile/profile.dart +++ b/lib/ui/pages/profile/profile.dart @@ -4,6 +4,7 @@ import 'package:moxxyv2/i18n/strings.g.dart'; import 'package:moxxyv2/ui/bloc/navigation_bloc.dart'; import 'package:moxxyv2/ui/constants.dart'; import 'package:moxxyv2/ui/controller/shared_media_controller.dart'; +import 'package:moxxyv2/ui/helpers.dart'; import 'package:moxxyv2/ui/pages/profile/profile_view.dart'; import 'package:moxxyv2/ui/widgets/shared_media_view.dart'; @@ -117,6 +118,9 @@ class ProfilePageState extends State { emptyText: t.pages.sharedMedia.empty.chat, showBackButton: false, key: const PageStorageKey('shared_media_view'), + onTap: (fm) => openFile(fm.path!), + // TODO(Unknown): Allow deleting singular items + //onLongPress: (fm) {}, ), ], ), diff --git a/lib/ui/pages/settings/storage/shared_media.dart b/lib/ui/pages/settings/storage/shared_media.dart index a2bf5adb..8de89a1c 100644 --- a/lib/ui/pages/settings/storage/shared_media.dart +++ b/lib/ui/pages/settings/storage/shared_media.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:moxxyv2/i18n/strings.g.dart'; import 'package:moxxyv2/ui/constants.dart'; import 'package:moxxyv2/ui/controller/shared_media_controller.dart'; +import 'package:moxxyv2/ui/helpers.dart'; import 'package:moxxyv2/ui/widgets/shared_media_view.dart'; class StorageSharedMediaPage extends StatefulWidget { @@ -43,6 +44,9 @@ class StorageSharedMediaPageState extends State { emptyText: t.pages.sharedMedia.empty.general, showBackButton: true, title: t.pages.settings.storage.mediaFiles, + onTap: (fm) => openFile(fm.path!), + // TODO(Unknown): Allow deleting singular items + //onLongPress: (fm) {}, ); } } diff --git a/lib/ui/widgets/chat/message.dart b/lib/ui/widgets/chat/message.dart index 70f2aab2..9e18914e 100644 --- a/lib/ui/widgets/chat/message.dart +++ b/lib/ui/widgets/chat/message.dart @@ -1,25 +1,18 @@ import 'package:flutter/material.dart'; -import 'package:moxxyv2/shared/models/file_metadata.dart'; import 'package:moxxyv2/shared/models/message.dart'; import 'package:moxxyv2/ui/constants.dart'; -import 'package:moxxyv2/ui/helpers.dart'; import 'package:moxxyv2/ui/widgets/chat/message/audio.dart'; import 'package:moxxyv2/ui/widgets/chat/message/file.dart'; import 'package:moxxyv2/ui/widgets/chat/message/image.dart'; import 'package:moxxyv2/ui/widgets/chat/message/sticker.dart'; import 'package:moxxyv2/ui/widgets/chat/message/text.dart'; import 'package:moxxyv2/ui/widgets/chat/message/video.dart'; -import 'package:moxxyv2/ui/widgets/chat/playbutton.dart'; import 'package:moxxyv2/ui/widgets/chat/quote/audio.dart'; import 'package:moxxyv2/ui/widgets/chat/quote/file.dart'; import 'package:moxxyv2/ui/widgets/chat/quote/image.dart'; import 'package:moxxyv2/ui/widgets/chat/quote/sticker.dart'; import 'package:moxxyv2/ui/widgets/chat/quote/text.dart'; import 'package:moxxyv2/ui/widgets/chat/quote/video.dart'; -import 'package:moxxyv2/ui/widgets/chat/shared/audio.dart'; -import 'package:moxxyv2/ui/widgets/chat/shared/file.dart'; -import 'package:moxxyv2/ui/widgets/chat/shared/image.dart'; -import 'package:moxxyv2/ui/widgets/chat/shared/video.dart'; enum MessageType { text, @@ -180,30 +173,3 @@ Widget buildQuoteMessageWidget( ); } } - -Widget buildSharedMediaWidget(FileMetadata metadata, String conversationJid) { - if (metadata.mimeType!.startsWith('image/')) { - return SharedImageWidget( - metadata.path!, - onTap: () => openFile(metadata.path!), - ); - } else if (metadata.mimeType!.startsWith('video/')) { - return SharedVideoWidget( - metadata.path!, - conversationJid, - metadata.mimeType!, - onTap: () => openFile(metadata.path!), - child: const PlayButton(size: 32), - ); - } else if (metadata.mimeType!.startsWith('audio/')) { - return SharedAudioWidget( - metadata.path!, - onTap: () => openFile(metadata.path!), - ); - } - - return SharedFileWidget( - metadata.path!, - onTap: () => openFile(metadata.path!), - ); -} diff --git a/lib/ui/widgets/chat/shared.dart b/lib/ui/widgets/chat/shared.dart new file mode 100644 index 00000000..8c0c8ad0 --- /dev/null +++ b/lib/ui/widgets/chat/shared.dart @@ -0,0 +1,50 @@ +import 'package:flutter/material.dart'; +import 'package:moxxyv2/shared/models/file_metadata.dart'; +import 'package:moxxyv2/ui/widgets/chat/playbutton.dart'; +import 'package:moxxyv2/ui/widgets/chat/shared/audio.dart'; +import 'package:moxxyv2/ui/widgets/chat/shared/file.dart'; +import 'package:moxxyv2/ui/widgets/chat/shared/image.dart'; +import 'package:moxxyv2/ui/widgets/chat/shared/video.dart'; + +typedef SharedMediaWidgetCallback = void Function(FileMetadata); + +/// Build a widget to represent a shared media file. +Widget buildSharedMediaWidget( + FileMetadata metadata, + String conversationJid, + SharedMediaWidgetCallback onTap, { + SharedMediaWidgetCallback? onLongPress, +}) { + // Prevent having the phone vibrate if no onLongPress is passed + final longPressCallback = + onLongPress != null ? () => onLongPress(metadata) : null; + + if (metadata.mimeType!.startsWith('image/')) { + return SharedImageWidget( + metadata.path!, + onTap: () => onTap(metadata), + onLongPress: longPressCallback, + ); + } else if (metadata.mimeType!.startsWith('video/')) { + return SharedVideoWidget( + metadata.path!, + conversationJid, + metadata.mimeType!, + onTap: () => onTap(metadata), + onLongPress: () => onLongPress?.call(metadata), + child: const PlayButton(size: 32), + ); + } else if (metadata.mimeType!.startsWith('audio/')) { + return SharedAudioWidget( + metadata.path!, + onTap: () => onTap(metadata), + onLongPress: longPressCallback, + ); + } + + return SharedFileWidget( + metadata.path!, + onTap: () => onTap(metadata), + onLongPress: longPressCallback, + ); +} diff --git a/lib/ui/widgets/chat/shared/audio.dart b/lib/ui/widgets/chat/shared/audio.dart index 1f119464..cbe8c443 100644 --- a/lib/ui/widgets/chat/shared/audio.dart +++ b/lib/ui/widgets/chat/shared/audio.dart @@ -6,6 +6,7 @@ class SharedAudioWidget extends StatelessWidget { const SharedAudioWidget( this.path, { this.onTap, + this.onLongPress, this.borderColor, this.borderRadius = 3, this.size = sharedMediaContainerDimension, @@ -14,6 +15,7 @@ class SharedAudioWidget extends StatelessWidget { final String path; final Color? borderColor; final void Function()? onTap; + final void Function()? onLongPress; final double borderRadius; final double size; @@ -39,6 +41,7 @@ class SharedAudioWidget extends StatelessWidget { color: sharedMediaItemBackgroundColor, size: size, onTap: onTap, + onLongPress: onLongPress, ); } } diff --git a/lib/ui/widgets/chat/shared/base.dart b/lib/ui/widgets/chat/shared/base.dart index b5a58f5e..d5b74a14 100644 --- a/lib/ui/widgets/chat/shared/base.dart +++ b/lib/ui/widgets/chat/shared/base.dart @@ -27,6 +27,7 @@ class SharedMediaContainer extends StatelessWidget { this.child, { required this.color, this.onTap, + this.onLongPress, this.size = sharedMediaContainerDimension, this.borderRadius = 10, super.key, @@ -34,30 +35,28 @@ class SharedMediaContainer extends StatelessWidget { final double borderRadius; final Widget? child; final void Function()? onTap; + final void Function()? onLongPress; final double size; final Color color; @override Widget build(BuildContext context) { - final childWidget = SizedBox( - height: size, - width: size, - child: AspectRatio( - aspectRatio: 1, - child: child, - ), - ); - return ClipRRect( borderRadius: BorderRadius.circular(borderRadius), child: Material( color: color, - child: onTap != null - ? InkWell( - onTap: onTap, - child: childWidget, - ) - : childWidget, + child: InkWell( + onTap: onTap, + onLongPress: onLongPress, + child: SizedBox( + height: size, + width: size, + child: AspectRatio( + aspectRatio: 1, + child: child, + ), + ), + ), ), ); } diff --git a/lib/ui/widgets/chat/shared/file.dart b/lib/ui/widgets/chat/shared/file.dart index 10b55576..af7c355d 100644 --- a/lib/ui/widgets/chat/shared/file.dart +++ b/lib/ui/widgets/chat/shared/file.dart @@ -6,12 +6,14 @@ class SharedFileWidget extends StatelessWidget { const SharedFileWidget( this.path, { this.onTap, + this.onLongPress, this.borderRadius = 3, this.size = sharedMediaContainerDimension, super.key, }); final String path; final void Function()? onTap; + final void Function()? onLongPress; final double borderRadius; final double size; @@ -26,6 +28,7 @@ class SharedFileWidget extends StatelessWidget { borderRadius: borderRadius, size: size, onTap: onTap, + onLongPress: onLongPress, ); } } diff --git a/lib/ui/widgets/chat/shared/image.dart b/lib/ui/widgets/chat/shared/image.dart index 2550f234..2a560d93 100644 --- a/lib/ui/widgets/chat/shared/image.dart +++ b/lib/ui/widgets/chat/shared/image.dart @@ -6,6 +6,7 @@ class SharedImageWidget extends StatelessWidget { const SharedImageWidget( this.path, { this.onTap, + this.onLongPress, this.borderColor, this.child, this.borderRadius = 3, @@ -15,6 +16,7 @@ class SharedImageWidget extends StatelessWidget { final String path; final Color? borderColor; final void Function()? onTap; + final void Function()? onLongPress; final Widget? child; final double borderRadius; final double size; @@ -50,6 +52,7 @@ class SharedImageWidget extends StatelessWidget { color: Colors.transparent, size: size, onTap: onTap, + onLongPress: onLongPress, ); } } diff --git a/lib/ui/widgets/chat/shared/video.dart b/lib/ui/widgets/chat/shared/video.dart index 471102e3..75a638ff 100644 --- a/lib/ui/widgets/chat/shared/video.dart +++ b/lib/ui/widgets/chat/shared/video.dart @@ -8,6 +8,7 @@ class SharedVideoWidget extends StatelessWidget { this.conversationJid, this.mime, { this.onTap, + this.onLongPress, this.borderColor, this.child, this.size = sharedMediaContainerDimension, @@ -19,6 +20,7 @@ class SharedVideoWidget extends StatelessWidget { final String mime; final Color? borderColor; final void Function()? onTap; + final void Function()? onLongPress; final Widget? child; final double size; final double borderRadius; @@ -40,6 +42,7 @@ class SharedVideoWidget extends StatelessWidget { color: Colors.transparent, size: size, onTap: onTap, + onLongPress: onLongPress, ); } } diff --git a/lib/ui/widgets/shared_media_view.dart b/lib/ui/widgets/shared_media_view.dart index e6869424..7c9ffcec 100644 --- a/lib/ui/widgets/shared_media_view.dart +++ b/lib/ui/widgets/shared_media_view.dart @@ -4,7 +4,7 @@ import 'package:moxxyv2/shared/models/message.dart'; import 'package:moxxyv2/ui/constants.dart'; import 'package:moxxyv2/ui/controller/shared_media_controller.dart'; import 'package:moxxyv2/ui/widgets/chat/bubbles/date.dart'; -import 'package:moxxyv2/ui/widgets/chat/message.dart'; +import 'package:moxxyv2/ui/widgets/chat/shared.dart'; import 'package:moxxyv2/ui/widgets/grouped_grid_view.dart'; import 'package:moxxyv2/ui/widgets/topbar.dart'; @@ -15,7 +15,9 @@ class SharedMediaView extends StatelessWidget { this.mediaController, { required this.emptyText, required this.showBackButton, + required this.onTap, this.title, + this.onLongPress, super.key, }); @@ -33,6 +35,12 @@ class SharedMediaView extends StatelessWidget { /// sent/received in the chat. final String emptyText; + /// Callback for when a widget has been tapped. + final SharedMediaWidgetCallback onTap; + + /// Callback for when a widget has been long pressed. + final SharedMediaWidgetCallback? onLongPress; + @override Widget build(BuildContext context) { final now = DateTime.now(); @@ -124,6 +132,8 @@ class SharedMediaView extends StatelessWidget { itemBuilder: (_, message) => buildSharedMediaWidget( message.fileMetadata!, message.conversationJid, + onTap, + onLongPress: onLongPress, ), separatorBuilder: (_, timestamp) => Padding( padding: const EdgeInsets.only(