feat(ui): Prepare for selectively removing media files

This commit is contained in:
PapaTutuWawa 2023-07-08 20:57:02 +02:00
parent d6416c77b8
commit 53e3b3c561
10 changed files with 95 additions and 50 deletions

View File

@ -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<ProfilePage> {
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) {},
),
],
),

View File

@ -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<StorageSharedMediaPage> {
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) {},
);
}
}

View File

@ -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!),
);
}

View File

@ -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,
);
}

View File

@ -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,
);
}
}

View File

@ -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,
),
),
),
),
);
}

View File

@ -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,
);
}
}

View File

@ -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,
);
}
}

View File

@ -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,
);
}
}

View File

@ -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(