diff --git a/lib/src/views/camera/camera_preview_components/video_recording_time.dart b/lib/src/views/camera/camera_preview_components/video_recording_time.dart new file mode 100644 index 0000000..27f9c37 --- /dev/null +++ b/lib/src/views/camera/camera_preview_components/video_recording_time.dart @@ -0,0 +1,64 @@ +import 'package:flutter/material.dart'; + +class VideoRecordingTimer extends StatelessWidget { + final DateTime? videoRecordingStarted; + final int maxVideoRecordingTime; + + const VideoRecordingTimer({ + super.key, + required this.videoRecordingStarted, + required this.maxVideoRecordingTime, + }); + + @override + Widget build(BuildContext context) { + if (videoRecordingStarted != null) { + final currentTime = DateTime.now(); + return Positioned( + top: 50, + left: 0, + right: 0, + child: Center( + child: SizedBox( + width: 50, + height: 50, + child: Stack( + children: [ + Center( + child: CircularProgressIndicator( + value: (currentTime.difference(videoRecordingStarted!)) + .inMilliseconds / + (maxVideoRecordingTime * 1000), + strokeWidth: 4, + valueColor: AlwaysStoppedAnimation(Colors.red), + backgroundColor: Colors.grey[300], + ), + ), + Center( + child: Text( + currentTime + .difference(videoRecordingStarted!) + .inSeconds + .toString(), + textAlign: TextAlign.center, + style: const TextStyle( + fontSize: 17, + shadows: [ + Shadow( + color: Color.fromARGB(122, 0, 0, 0), + blurRadius: 5.0, + ) + ], + ), + ), + ) + ], + ), + ), + ), + ); + } else { + return const SizedBox.shrink(); + } + } +} diff --git a/lib/src/views/camera/camera_preview_controller_view.dart b/lib/src/views/camera/camera_preview_controller_view.dart index 83506ec..aef04c8 100644 --- a/lib/src/views/camera/camera_preview_controller_view.dart +++ b/lib/src/views/camera/camera_preview_controller_view.dart @@ -10,6 +10,7 @@ import 'package:permission_handler/permission_handler.dart'; import 'package:screenshot/screenshot.dart'; import 'package:twonly/globals.dart'; import 'package:twonly/src/views/camera/camera_preview_components/send_to.dart'; +import 'package:twonly/src/views/camera/camera_preview_components/video_recording_time.dart'; import 'package:twonly/src/views/camera/camera_preview_components/zoom_selector.dart'; import 'package:twonly/src/database/daos/contacts_dao.dart'; import 'package:twonly/src/database/twonly_database.dart'; @@ -267,7 +268,7 @@ class _CameraPreviewViewState extends State { Future pushMediaEditor( Future? imageBytes, File? videoFilePath) async { - bool? shoudReturn = await Navigator.push( + bool? shouldReturn = await Navigator.push( context, PageRouteBuilder( opaque: false, @@ -285,9 +286,15 @@ class _CameraPreviewViewState extends State { reverseTransitionDuration: Duration.zero, ), ); + if (context.mounted) { + setState(() { + sharePreviewIsShown = false; + showSelfieFlash = false; + }); + } if (!context.mounted) return true; // shouldReturn is null when the user used the back button - if (shoudReturn != null && shoudReturn) { + if (shouldReturn != null && shouldReturn) { // ignore: use_build_context_synchronously if (widget.sendTo == null) { globalUpdateOfHomeViewPageIndex(0); @@ -297,12 +304,6 @@ class _CameraPreviewViewState extends State { return true; } widget.selectCamera(selectedCameraDetails.cameraId, false, false); - if (context.mounted) { - setState(() { - sharePreviewIsShown = false; - showSelfieFlash = false; - }); - } return false; } @@ -485,11 +486,6 @@ class _CameraPreviewViewState extends State { onPanUpdate: onPanUpdate, child: Stack( children: [ - // if (!galleryLoadedImageIsShown) - // CameraPreviewWidget( - // controller: cameraController, - // screenshotController: screenshotController, - // ), if (galleryLoadedImageIsShown) Center( child: SizedBox( @@ -499,9 +495,6 @@ class _CameraPreviewViewState extends State { strokeWidth: 1, color: context.color.primary), ), ), - // Positioned.fill( - // child: GestureDetector(), - // ), if (!sharePreviewIsShown && widget.sendTo != null && !isVideoRecording) @@ -667,52 +660,10 @@ class _CameraPreviewViewState extends State { ), ), ), - if (videoRecordingStarted != null) - Positioned( - top: 50, - left: 0, - right: 0, - child: Center( - child: SizedBox( - width: 50, - height: 50, - child: Stack( - children: [ - Center( - child: CircularProgressIndicator( - value: - (currentTime.difference(videoRecordingStarted!)) - .inMilliseconds / - (maxVideoRecordingTime * 1000), - strokeWidth: 4, - valueColor: - AlwaysStoppedAnimation(Colors.red), - backgroundColor: Colors.grey[300], - ), - ), - Center( - child: Text( - currentTime - .difference(videoRecordingStarted!) - .inSeconds - .toString(), - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 17, - shadows: [ - Shadow( - color: const Color.fromARGB(122, 0, 0, 0), - blurRadius: 5.0, - ) - ], - ), - ), - ) - ], - ), - ), - ), - ), + VideoRecordingTimer( + videoRecordingStarted: videoRecordingStarted, + maxVideoRecordingTime: maxVideoRecordingTime, + ), if (!sharePreviewIsShown && widget.sendTo != null) Positioned( left: 5, diff --git a/lib/src/views/chats/chat_messages_components/in_chat_media_viewer.dart b/lib/src/views/chats/chat_messages_components/in_chat_media_viewer.dart index a078ba6..8460a07 100644 --- a/lib/src/views/chats/chat_messages_components/in_chat_media_viewer.dart +++ b/lib/src/views/chats/chat_messages_components/in_chat_media_viewer.dart @@ -1,121 +1,16 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; -import 'package:drift/drift.dart' show Value; import 'package:flutter/material.dart'; -import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:twonly/globals.dart'; import 'package:twonly/src/providers/api/media_send.dart' as send; -import 'package:twonly/src/views/camera/camera_send_to_view.dart'; -import 'package:twonly/src/views/components/alert_dialog.dart'; -import 'package:twonly/src/views/components/media_view_sizing.dart'; import 'package:twonly/src/views/components/message_send_state_icon.dart'; import 'package:twonly/src/database/twonly_database.dart'; import 'package:twonly/src/database/tables/messages_table.dart'; import 'package:twonly/src/model/json/message.dart'; -import 'package:twonly/src/providers/api/media_received.dart' as received; import 'package:twonly/src/views/gallery/gallery_main_view.dart'; import 'package:video_player/video_player.dart'; -// class ChatMediaViewerFullScreen extends StatefulWidget { -// const ChatMediaViewerFullScreen({ -// super.key, -// required this.message, -// required this.contact, -// required this.color, -// }); -// final Message message; -// final Contact contact; -// final Color color; - -// @override -// State createState() => -// _ChatMediaViewerFullScreenState(); -// } - -// class _ChatMediaViewerFullScreenState extends State { -// bool hideMediaFile = false; - -// Future deleteFiles(context) async { -// bool confirmed = await showAlertDialog( -// context, "Are you sure?", "The image will be irrevocably deleted."); - -// if (!confirmed) return; - -// await twonlyDatabase.messagesDao.updateMessageByMessageId( -// widget.message.messageId, -// MessagesCompanion(mediaStored: Value(false)), -// ); -// await send.purgeSendMediaFiles(); -// await received.purgeReceivedMediaFiles(); -// if (context.mounted) { -// Navigator.pop(context, true); -// } -// } - -// @override -// Widget build(BuildContext context) { -// return Scaffold( -// body: MediaViewSizing( -// bottomNavigation: Positioned( -// bottom: 10, -// left: 0, -// right: 0, -// child: Row( -// mainAxisAlignment: MainAxisAlignment.spaceEvenly, -// children: [ -// IconButton.outlined( -// onPressed: () { -// deleteFiles(context); -// }, -// icon: FaIcon(FontAwesomeIcons.trashCan), -// style: ButtonStyle( -// padding: WidgetStateProperty.all( -// EdgeInsets.symmetric(vertical: 10, horizontal: 20), -// ), -// ), -// ), -// IconButton.filled( -// icon: FaIcon(FontAwesomeIcons.camera), -// onPressed: () async { -// setState(() { -// hideMediaFile = true; -// }); -// await Navigator.push(context, MaterialPageRoute( -// builder: (context) { -// return CameraSendToView(widget.contact); -// }, -// )); -// setState(() { -// hideMediaFile = false; -// }); -// }, -// style: ButtonStyle( -// padding: WidgetStateProperty.all( -// EdgeInsets.symmetric(vertical: 10, horizontal: 30), -// ), -// backgroundColor: WidgetStateProperty.all( -// Theme.of(context).colorScheme.primary, -// )), -// ), -// ], -// ), -// ), -// child: (hideMediaFile) -// ? Container() -// : Hero( -// tag: "chat_entry_${widget.message.messageId}", -// child: InChatMediaViewer( -// message: widget.message, -// contact: widget.contact, -// color: widget.color, -// isInFullscreen: true, -// ), -// )), -// ); -// } -// } - class InChatMediaViewer extends StatefulWidget { const InChatMediaViewer({ super.key, @@ -222,9 +117,6 @@ class _InChatMediaViewerState extends State { MaterialPageRoute( builder: (context) => GalleryPhotoViewWrapper( galleryItems: widget.galleryItems, - // backgroundDecoration: const BoxDecoration( - // color: Colors.black, - // ), initialIndex: widget.galleryItems.indexWhere((x) => x.id == (widget.message.mediaUploadId ?? widget.message.messageId) diff --git a/lib/src/views/chats/chat_messages_view.dart b/lib/src/views/chats/chat_messages_view.dart index 949fec9..c8502e3 100644 --- a/lib/src/views/chats/chat_messages_view.dart +++ b/lib/src/views/chats/chat_messages_view.dart @@ -138,22 +138,22 @@ class _ChatMessagesViewState extends State { notifyContactAboutOpeningMessage( widget.contact.userId, openedMessageOtherIds); } + twonlyDatabase.messagesDao .openedAllNonMediaMessages(widget.contact.userId); - // should be fixed with that - // if (!updated) { - // // The stream should be get an update, so only update the UI when all are opened + setState(() { textReactionsToMessageId = tmpTextReactionsToMessageId; emojiReactionsToMessageId = tmpEmojiReactionsToMessageId; messages = displayedMessages; }); - Map items = await GalleryItem.convertFromMessages( - displayedMessages - .where((x) => x.kind == MessageKind.media) - .toList() - .reversed - .toList()); + + final filteredMediaFiles = displayedMessages + .where((x) => x.kind == MessageKind.media) + .toList() + .reversed + .toList(); + final items = await GalleryItem.convertFromMessages(filteredMediaFiles); setState(() { galleryItems = items.values.toList(); });