From 11267248da4af81432b9e0d9325144ea2a5c5317 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Wed, 25 Nov 2020 15:03:22 +0100 Subject: [PATCH 1/6] wip --- example/ios/Podfile.lock | 20 +- example/ios/Runner.xcodeproj/project.pbxproj | 2 + example/pubspec.yaml | 2 +- lib/src/channel_list_view.dart | 217 ++++++++++--------- lib/src/message_input.dart | 193 ++++++++++++----- pubspec.yaml | 1 + 6 files changed, 269 insertions(+), 166 deletions(-) diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 131e8aec..b028e9b7 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -121,9 +121,9 @@ PODS: - Flutter - PromisesObjC (1.2.11) - Protobuf (3.13.0) - - SDWebImage (5.9.4): - - SDWebImage/Core (= 5.9.4) - - SDWebImage/Core (5.9.4) + - SDWebImage (5.10.0): + - SDWebImage/Core (= 5.10.0) + - SDWebImage/Core (5.10.0) - shared_preferences (0.0.1): - Flutter - sqflite (0.0.2): @@ -148,11 +148,13 @@ PODS: - sqlite3/perf-threadsafe - sqlite3/rtree - Starscream (4.0.4) - - StreamChatClient (2.4.1): + - StreamChatClient (2.4.2): - Starscream (~> 4.0) - SwiftyGif (5.3.0) - url_launcher (0.0.1): - Flutter + - video_compress (0.3.0): + - Flutter - video_player (0.0.1): - Flutter - wakelock (0.0.1): @@ -177,6 +179,7 @@ DEPENDENCIES: - sqlite3_flutter_libs (from `.symlinks/plugins/sqlite3_flutter_libs/ios`) - StreamChatClient - url_launcher (from `.symlinks/plugins/url_launcher/ios`) + - video_compress (from `.symlinks/plugins/video_compress/ios`) - video_player (from `.symlinks/plugins/video_player/ios`) - wakelock (from `.symlinks/plugins/wakelock/ios`) @@ -237,6 +240,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/sqlite3_flutter_libs/ios" url_launcher: :path: ".symlinks/plugins/url_launcher/ios" + video_compress: + :path: ".symlinks/plugins/video_compress/ios" video_player: :path: ".symlinks/plugins/video_player/ios" wakelock: @@ -270,18 +275,19 @@ SPEC CHECKSUMS: permission_handler: eac8e15b4a1a3fba55b761d19f3f4e6b005d15b6 PromisesObjC: 8c196f5a328c2cba3e74624585467a557dcb482f Protobuf: 3dac39b34a08151c6d949560efe3f86134a3f748 - SDWebImage: b69257f4ab14e9b6a2ef53e910fdf914d8f757c1 + SDWebImage: 9169792e9eec3e45bba2a0c02f74bf8bd922d1ee shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904 sqlite3: 8f7d2078ae27778699a622a94b853285793422a2 sqlite3_flutter_libs: 5651f8ff48e3b44d910863c4ea5916085b1b245f Starscream: 5178aed56b316f13fa3bc55694e583d35dd414d9 - StreamChatClient: d061cf52babcd9df930aee9cf864ab0379427eff + StreamChatClient: fc6419fa7ceda9c048188bb7c8e9f07755ced05f SwiftyGif: e466e86c660d343357ab944a819a101c4127cb40 url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef + video_compress: fce97e4fb1dfd88175aa07d2ffc8a2f297f87fbe video_player: 9cc823b1d9da7e8427ee591e8438bfbcde500e6e wakelock: bfc7955c418d0db797614075aabbc58a39ab5107 PODFILE CHECKSUM: eb001256612a59f8f9e4d083ad8b9671e69dd184 -COCOAPODS: 1.10.0.rc.1 +COCOAPODS: 1.10.0 diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index 709db931..bb101716 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -335,6 +335,7 @@ "${BUILT_PRODUCTS_DIR}/sqlite3/sqlite3.framework", "${BUILT_PRODUCTS_DIR}/sqlite3_flutter_libs/sqlite3_flutter_libs.framework", "${BUILT_PRODUCTS_DIR}/url_launcher/url_launcher.framework", + "${BUILT_PRODUCTS_DIR}/video_compress/video_compress.framework", "${BUILT_PRODUCTS_DIR}/video_player/video_player.framework", "${BUILT_PRODUCTS_DIR}/wakelock/wakelock.framework", ); @@ -366,6 +367,7 @@ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sqlite3.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sqlite3_flutter_libs.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/url_launcher.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/video_compress.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/video_player.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/wakelock.framework", ); diff --git a/example/pubspec.yaml b/example/pubspec.yaml index e5daa043..6e34335d 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -1,6 +1,6 @@ name: example description: A new Flutter project. -version: 1.0.66+68 +version: 1.0.70+72 environment: sdk: ">=2.2.2 <3.0.0" diff --git a/lib/src/channel_list_view.dart b/lib/src/channel_list_view.dart index 9dae4213..ab576b4f 100644 --- a/lib/src/channel_list_view.dart +++ b/lib/src/channel_list_view.dart @@ -166,123 +166,124 @@ class _ChannelListViewState extends State ChannelsBlocState channelsBlocState, ) { return StreamBuilder>( - stream: channelsBlocState.channelsStream, - builder: (context, snapshot) { - var child; - if (snapshot.hasError) { - child = _buildErrorWidget( - snapshot, - context, - channelsBlocState, - ); - } else if (!snapshot.hasData) { - child = _buildLoadingWidget(); - } else { - final channels = snapshot.data; + stream: channelsBlocState.channelsStream, + builder: (context, snapshot) { + var child; + if (snapshot.hasError) { + child = _buildErrorWidget( + snapshot, + context, + channelsBlocState, + ); + } else if (!snapshot.hasData) { + child = _buildLoadingWidget(); + } else { + final channels = snapshot.data; - if (channels.isEmpty && widget.emptyBuilder != null) { - child = widget.emptyBuilder(context); - } + if (channels.isEmpty && widget.emptyBuilder != null) { + child = widget.emptyBuilder(context); + } - if (channels.isEmpty && widget.emptyBuilder == null) { - child = LayoutBuilder( - builder: (context, viewportConstraints) { - return SingleChildScrollView( - physics: AlwaysScrollableScrollPhysics(), - child: Stack( - children: [ - ConstrainedBox( - constraints: BoxConstraints( - minHeight: viewportConstraints.maxHeight, - ), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: Icon( - StreamIcons.message, - size: 136, - color: Color(0xffDBDBDB), - ), - ), - Padding( - padding: const EdgeInsets.all(8.0), - child: Text( - 'Let’s start chatting!', - style: TextStyle( - fontSize: 16, - ), - ), - ), - Padding( - padding: const EdgeInsets.symmetric( - vertical: 8.0, - horizontal: 52, - ), - child: Text( - 'How about sending your first message to a friend?', - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 14, - color: Color(0xff7A7A7A), - ), - ), - ), - ], - ), + if (channels.isEmpty && widget.emptyBuilder == null) { + child = LayoutBuilder( + builder: (context, viewportConstraints) { + return SingleChildScrollView( + physics: AlwaysScrollableScrollPhysics(), + child: Stack( + children: [ + ConstrainedBox( + constraints: BoxConstraints( + minHeight: viewportConstraints.maxHeight, ), - if (widget.onStartChatPressed != null) - Positioned( - right: 0, - left: 0, - bottom: 32, - child: Center( - child: FlatButton( - onPressed: widget.onStartChatPressed, - child: Text( - 'Start a chat', - style: TextStyle( - color: - StreamChatTheme.of(context).accentColor, - fontWeight: FontWeight.bold, - ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Icon( + StreamIcons.message, + size: 136, + color: Color(0xffDBDBDB), + ), + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + 'Let’s start chatting!', + style: TextStyle( + fontSize: 16, + ), + ), + ), + Padding( + padding: const EdgeInsets.symmetric( + vertical: 8.0, + horizontal: 52, + ), + child: Text( + 'How about sending your first message to a friend?', + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 14, + color: Color(0xff7A7A7A), + ), + ), + ), + ], + ), + ), + if (widget.onStartChatPressed != null) + Positioned( + right: 0, + left: 0, + bottom: 32, + child: Center( + child: FlatButton( + onPressed: widget.onStartChatPressed, + child: Text( + 'Start a chat', + style: TextStyle( + color: + StreamChatTheme.of(context).accentColor, + fontWeight: FontWeight.bold, ), ), ), ), - ], - ), - ); - }, - ); - } - - if (channels.isNotEmpty) { - child = ListView.custom( - physics: AlwaysScrollableScrollPhysics(), - controller: _scrollController, - childrenDelegate: SliverChildBuilderDelegate( - (context, i) { - return _itemBuilder(context, i, channels); - }, - childCount: (channels.length * 2) + 1, - findChildIndexCallback: (key) { - final ValueKey valueKey = key; - final index = channels.indexWhere( - (channel) => 'CHANNEL-${channel.id}' == valueKey.value); - return index != -1 ? (index * 2) : null; - }, - ), - ); - } + ), + ], + ), + ); + }, + ); } - return AnimatedSwitcher( - child: child, - duration: Duration(milliseconds: 500), - ); - }); + if (channels.isNotEmpty) { + child = ListView.custom( + physics: AlwaysScrollableScrollPhysics(), + controller: _scrollController, + childrenDelegate: SliverChildBuilderDelegate( + (context, i) { + return _itemBuilder(context, i, channels); + }, + childCount: (channels.length * 2) + 1, + findChildIndexCallback: (key) { + final ValueKey valueKey = key; + final index = channels.indexWhere( + (channel) => 'CHANNEL-${channel.id}' == valueKey.value); + return index != -1 ? (index * 2) : null; + }, + ), + ); + } + } + + return AnimatedSwitcher( + child: child, + duration: Duration(milliseconds: 500), + ); + }, + ); } Widget _buildLoadingWidget() { diff --git a/lib/src/message_input.dart b/lib/src/message_input.dart index af4b8979..c9bba5f6 100644 --- a/lib/src/message_input.dart +++ b/lib/src/message_input.dart @@ -21,6 +21,7 @@ import 'package:stream_chat_flutter/src/stream_chat_theme.dart'; import 'package:stream_chat_flutter/src/user_avatar.dart'; import 'package:stream_chat_flutter/src/video_thumbnail.dart'; import 'package:substring_highlight/substring_highlight.dart'; +import 'package:video_compress/video_compress.dart'; import '../stream_chat_flutter.dart'; import 'stream_channel.dart'; @@ -44,6 +45,8 @@ enum DefaultAttachmentTypes { const _kMinMediaPickerSize = 360.0; +const _kMaxAttachmentSize = 20480; //20MB + /// Inactive state /// ![screenshot](https://raw.githubusercontent.com/GetStream/stream-chat-flutter/master/screenshots/message_input.png) /// ![screenshot](https://raw.githubusercontent.com/GetStream/stream-chat-flutter/master/screenshots/message_input_paint.png) @@ -797,7 +800,6 @@ class MessageInputState extends State { var status = await (Platform.isAndroid ? Permission.storage.status : Permission.photos.status); - print('status: ${status}'); if (status.isPermanentlyDenied || status.isDenied) { if (await openAppSettings()) { setState(() {}); @@ -844,55 +846,114 @@ class MessageInputState extends State { } void _addAttachment(Media medium) async { - final attachment = _SendingAttachment( - id: medium.id, - ); - - setState(() { - _attachments.add(attachment); - }); - - final mediaFile = await medium.getFile(); - - final file = PlatformFile( - path: mediaFile.path, - bytes: mediaFile.readAsBytesSync(), - ); - - final channel = StreamChannel.of(context).channel; - setState(() { - attachment - ..file = file - ..attachment = Attachment( - localUri: file.path != null ? Uri.parse(file.path) : null, - type: medium.mediaType == MediaType.image ? 'image' : 'video', - ); - }); - - final url = await _uploadAttachment( - file, - medium.mediaType == MediaType.image - ? DefaultAttachmentTypes.image - : DefaultAttachmentTypes.video, - channel); - - final fileType = medium.mediaType == MediaType.image - ? DefaultAttachmentTypes.image - : DefaultAttachmentTypes.video; - - if (fileType == DefaultAttachmentTypes.image) { - attachment.attachment = attachment.attachment.copyWith( - imageUrl: url, + try { + final attachment = _SendingAttachment( + id: medium.id, ); - } else { - attachment.attachment = attachment.attachment.copyWith( - assetUrl: url, + + setState(() { + _attachments.add(attachment); + }); + + final mediaFile = await medium.getFile(); + + var file = PlatformFile( + path: mediaFile.path, + size: (await mediaFile.length()) ~/ 1024, + bytes: mediaFile.readAsBytesSync(), + ); + + if (file.size > _kMaxAttachmentSize) { + if (medium.mediaType == MediaType.video) { + final mediaInfo = await _compressVideo(file); + file = PlatformFile( + name: file.name, + size: mediaInfo.filesize, + bytes: await mediaInfo.file.readAsBytes(), + path: mediaInfo.path, + ); + } else { + Scaffold.of(context).showSnackBar( + SnackBar( + content: Text( + 'The file is too large to upload. The file size limit is 20MB', + ), + ), + ); + } + } + + final channel = StreamChannel.of(context).channel; + setState(() { + attachment + ..file = file + ..attachment = Attachment( + localUri: file.path != null ? Uri.parse(file.path) : null, + type: medium.mediaType == MediaType.image ? 'image' : 'video', + ); + }); + + final url = await _uploadAttachment( + file, + medium.mediaType == MediaType.image + ? DefaultAttachmentTypes.image + : DefaultAttachmentTypes.video, + channel); + + final fileType = medium.mediaType == MediaType.image + ? DefaultAttachmentTypes.image + : DefaultAttachmentTypes.video; + + if (fileType == DefaultAttachmentTypes.image) { + attachment.attachment = attachment.attachment.copyWith( + imageUrl: url, + ); + } else { + attachment.attachment = attachment.attachment.copyWith( + assetUrl: url, + ); + } + + if (mounted) { + setState(() { + attachment.uploaded = true; + }); + } + } catch (e, s) { + print(s); + Scaffold.of(context).showSnackBar( + SnackBar( + content: Text('Error adding the attachment: $e'), + ), ); } + } - setState(() { - attachment.uploaded = true; - }); + Future _compressVideo(PlatformFile file) async { + print('file.size: ${file.size}'); + print('VideoCompress.isCompressing: ${VideoCompress.isCompressing}'); + if (VideoCompress.isCompressing) { + final compressCompleter = Completer(); + VideoCompress.compressProgress$.subscribe( + (event) { + print('event: ${event}'); + }, + onDone: () { + compressCompleter.complete(); + }, + onError: (e) { + compressCompleter.completeError(e); + }, + ); + await compressCompleter.future; + } + final mediaInfo = await VideoCompress.compressVideo( + file.path, + ); + + print('mediaInfo.filesize: ${mediaInfo.filesize / 1024}'); + + return mediaInfo; } CircleAvatar _buildGiphyIcon() { @@ -1270,9 +1331,10 @@ class MessageInputState extends State { Positioned.fill( child: Container( child: VideoThumbnail( - file: File( - attachment.file.path, - )), + file: File( + attachment.file.path, + ), + ), ), ), Positioned( @@ -1501,7 +1563,6 @@ class MessageInputState extends State { ); if (res?.files?.isNotEmpty == true) { file = res.files.single; - print('file.bytes?.length: ${file.bytes?.length}'); } } @@ -1513,6 +1574,26 @@ class MessageInputState extends State { return; } + if (file.size > _kMaxAttachmentSize) { + if (attachmentType == 'video') { + final mediaInfo = await _compressVideo(file); + file = PlatformFile( + name: mediaInfo.title, + size: mediaInfo.filesize, + bytes: await mediaInfo.file.readAsBytes(), + path: mediaInfo.path, + ); + } else { + Scaffold.of(context).showSnackBar( + SnackBar( + content: Text( + 'The file is too large to upload. The file size limit is 20MB', + ), + ), + ); + } + } + final channel = StreamChannel.of(context).channel; final attachment = _SendingAttachment( file: file, @@ -1740,11 +1821,23 @@ class MessageInputState extends State { } StreamSubscription _keyboardListener; + Subscription _videoCompressSubscription; + Completer _videoCompressCompleter = Completer(); @override void initState() { super.initState(); + VideoCompress.compressProgress$.subscribe( + (event) {}, + onDone: () { + _videoCompressCompleter.complete(); + }, + onError: (e) { + _videoCompressCompleter.completeError(e); + }, + ); + _focusNode = widget.focusNode ?? FocusNode(); _emojiNames = Emoji.all().map((e) => e.name); diff --git a/pubspec.yaml b/pubspec.yaml index f8705c22..1fec50c0 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -30,6 +30,7 @@ dependencies: flutter_keyboard_visibility: ^3.3.0 stream_chat: ^0.2.13+1 mime: ^0.9.6+3 + video_compress: ^2.1.1 visibility_detector: ^0.1.5 http_parser: ^3.1.4 substring_highlight: ^0.1.2 From 2ea38c128ba1788b26fccd1b6d9be62269cc2afb Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Wed, 25 Nov 2020 17:05:39 +0100 Subject: [PATCH 2/6] compress videos --- lib/src/channel_list_view.dart | 39 ++++++++++---------- lib/src/compress_video_service.dart | 19 ++++++++++ lib/src/message_input.dart | 56 ++++++++--------------------- 3 files changed, 53 insertions(+), 61 deletions(-) create mode 100644 lib/src/compress_video_service.dart diff --git a/lib/src/channel_list_view.dart b/lib/src/channel_list_view.dart index b7fbf408..45c53eb6 100644 --- a/lib/src/channel_list_view.dart +++ b/lib/src/channel_list_view.dart @@ -185,26 +185,25 @@ class _ChannelListViewState extends State child = widget.emptyBuilder(context); } - if (channels.isEmpty && widget.emptyBuilder == null) { - child = LayoutBuilder( - builder: (context, viewportConstraints) { - return SingleChildScrollView( - physics: AlwaysScrollableScrollPhysics(), - child: Stack( - children: [ - ConstrainedBox( - constraints: BoxConstraints( - minHeight: viewportConstraints.maxHeight, - ), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: StreamSvgIcon.message( - size: 136, - color: Color(0xffDBDBDB), - ), + if (channels.isEmpty && widget.emptyBuilder == null) { + child = LayoutBuilder( + builder: (context, viewportConstraints) { + return SingleChildScrollView( + physics: AlwaysScrollableScrollPhysics(), + child: Stack( + children: [ + ConstrainedBox( + constraints: BoxConstraints( + minHeight: viewportConstraints.maxHeight, + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: StreamSvgIcon.message( + size: 136, + color: Color(0xffDBDBDB), ), ), Padding( diff --git a/lib/src/compress_video_service.dart b/lib/src/compress_video_service.dart new file mode 100644 index 00000000..f8d63e0c --- /dev/null +++ b/lib/src/compress_video_service.dart @@ -0,0 +1,19 @@ +import 'dart:async'; +import 'package:video_compress/video_compress.dart'; + +class CompressVideoService { + static final CompressVideoService instance = CompressVideoService._(); + + CompressVideoService._(); + + Future compressVideo(String path) async { + MediaInfo mediaInfo; + while (VideoCompress.isCompressing) { + await Future.delayed(Duration(seconds: 1)); + } + mediaInfo = await VideoCompress.compressVideo( + path, + ); + return mediaInfo; + } +} diff --git a/lib/src/message_input.dart b/lib/src/message_input.dart index 25cc12db..9a8b1f75 100644 --- a/lib/src/message_input.dart +++ b/lib/src/message_input.dart @@ -14,6 +14,7 @@ import 'package:media_gallery/media_gallery.dart'; import 'package:mime/mime.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:stream_chat/stream_chat.dart'; +import 'package:stream_chat_flutter/src/compress_video_service.dart'; import 'package:stream_chat_flutter/src/media_list_view.dart'; import 'package:stream_chat_flutter/src/message_list_view.dart'; import 'package:stream_chat_flutter/src/stream_chat_theme.dart'; @@ -865,7 +866,18 @@ class MessageInputState extends State { if (file.size > _kMaxAttachmentSize) { if (medium.mediaType == MediaType.video) { - final mediaInfo = await _compressVideo(file); + final mediaInfo = + await CompressVideoService.instance.compressVideo(file.path); + + if (mediaInfo.filesize / (1024 * 1024) > _kMaxAttachmentSize) { + Scaffold.of(context).showSnackBar( + SnackBar( + content: Text( + 'The file is too large to upload. The file size limit is 20MB. We tried compressing it, but it was not enough.', + ), + ), + ); + } file = PlatformFile( name: file.name, size: mediaInfo.filesize, @@ -929,33 +941,6 @@ class MessageInputState extends State { } } - Future _compressVideo(PlatformFile file) async { - print('file.size: ${file.size}'); - print('VideoCompress.isCompressing: ${VideoCompress.isCompressing}'); - if (VideoCompress.isCompressing) { - final compressCompleter = Completer(); - VideoCompress.compressProgress$.subscribe( - (event) { - print('event: ${event}'); - }, - onDone: () { - compressCompleter.complete(); - }, - onError: (e) { - compressCompleter.completeError(e); - }, - ); - await compressCompleter.future; - } - final mediaInfo = await VideoCompress.compressVideo( - file.path, - ); - - print('mediaInfo.filesize: ${mediaInfo.filesize / 1024}'); - - return mediaInfo; - } - CircleAvatar _buildGiphyIcon() { if (kIsWeb) { return CircleAvatar( @@ -1571,7 +1556,8 @@ class MessageInputState extends State { if (file.size > _kMaxAttachmentSize) { if (attachmentType == 'video') { - final mediaInfo = await _compressVideo(file); + final mediaInfo = await CompressVideoService.instance + .compressVideo(file.path, _kMaxAttachmentSize); file = PlatformFile( name: mediaInfo.title, size: mediaInfo.filesize, @@ -1800,23 +1786,11 @@ class MessageInputState extends State { } StreamSubscription _keyboardListener; - Subscription _videoCompressSubscription; - Completer _videoCompressCompleter = Completer(); @override void initState() { super.initState(); - VideoCompress.compressProgress$.subscribe( - (event) {}, - onDone: () { - _videoCompressCompleter.complete(); - }, - onError: (e) { - _videoCompressCompleter.completeError(e); - }, - ); - _focusNode = widget.focusNode ?? FocusNode(); _emojiNames = Emoji.all().map((e) => e.name); From efd6bfdc8e64bdbddbb645417ac76cbd193d0b90 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Wed, 25 Nov 2020 17:19:38 +0100 Subject: [PATCH 3/6] fix error --- lib/src/message_input.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/message_input.dart b/lib/src/message_input.dart index 9a8b1f75..d3482806 100644 --- a/lib/src/message_input.dart +++ b/lib/src/message_input.dart @@ -1556,8 +1556,8 @@ class MessageInputState extends State { if (file.size > _kMaxAttachmentSize) { if (attachmentType == 'video') { - final mediaInfo = await CompressVideoService.instance - .compressVideo(file.path, _kMaxAttachmentSize); + final mediaInfo = + await CompressVideoService.instance.compressVideo(file.path); file = PlatformFile( name: mediaInfo.title, size: mediaInfo.filesize, From a636253e98a87c0dea3dbdbc1792429d3116d5af Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Thu, 26 Nov 2020 11:23:33 +0100 Subject: [PATCH 4/6] use lock in compress service --- lib/src/compress_video_service.dart | 17 ++++++++--------- lib/src/message_input.dart | 5 +++++ pubspec.yaml | 1 + 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/lib/src/compress_video_service.dart b/lib/src/compress_video_service.dart index f8d63e0c..abd4a045 100644 --- a/lib/src/compress_video_service.dart +++ b/lib/src/compress_video_service.dart @@ -1,19 +1,18 @@ import 'dart:async'; +import 'package:synchronized/synchronized.dart'; import 'package:video_compress/video_compress.dart'; class CompressVideoService { static final CompressVideoService instance = CompressVideoService._(); - + final _lock = Lock(); CompressVideoService._(); Future compressVideo(String path) async { - MediaInfo mediaInfo; - while (VideoCompress.isCompressing) { - await Future.delayed(Duration(seconds: 1)); - } - mediaInfo = await VideoCompress.compressVideo( - path, - ); - return mediaInfo; + print('VideoCompress.isCompressing: ${VideoCompress.isCompressing}'); + return _lock.synchronized(() { + return VideoCompress.compressVideo( + path, + ); + }); } } diff --git a/lib/src/message_input.dart b/lib/src/message_input.dart index d3482806..3487fb26 100644 --- a/lib/src/message_input.dart +++ b/lib/src/message_input.dart @@ -877,6 +877,11 @@ class MessageInputState extends State { ), ), ); + + setState(() { + _attachments.remove(attachment); + }); + return; } file = PlatformFile( name: file.name, diff --git a/pubspec.yaml b/pubspec.yaml index 88d8f216..412550ef 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -42,6 +42,7 @@ dependencies: permission_handler: ^5.0.1+1 transparent_image: ^1.0.0 ezanimation: ^0.4.1 + synchronized: ^2.2.0+2 flutter: assets: From eca446bcea6d1fcd6c3fc54223556b1a8202dfc2 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Thu, 26 Nov 2020 11:40:29 +0100 Subject: [PATCH 5/6] remove log --- lib/src/compress_video_service.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/src/compress_video_service.dart b/lib/src/compress_video_service.dart index abd4a045..56b11d1e 100644 --- a/lib/src/compress_video_service.dart +++ b/lib/src/compress_video_service.dart @@ -8,7 +8,6 @@ class CompressVideoService { CompressVideoService._(); Future compressVideo(String path) async { - print('VideoCompress.isCompressing: ${VideoCompress.isCompressing}'); return _lock.synchronized(() { return VideoCompress.compressVideo( path, From ebcaed87710640c9dfef3ce6c9ec0d787740a665 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Thu, 26 Nov 2020 11:44:14 +0100 Subject: [PATCH 6/6] add singleton trick --- lib/src/compress_video_service.dart | 9 ++++++--- lib/src/message_input.dart | 6 ++---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/src/compress_video_service.dart b/lib/src/compress_video_service.dart index 56b11d1e..43d2c79c 100644 --- a/lib/src/compress_video_service.dart +++ b/lib/src/compress_video_service.dart @@ -2,10 +2,10 @@ import 'dart:async'; import 'package:synchronized/synchronized.dart'; import 'package:video_compress/video_compress.dart'; -class CompressVideoService { - static final CompressVideoService instance = CompressVideoService._(); +class ICompressVideoService { + static final ICompressVideoService instance = ICompressVideoService._(); final _lock = Lock(); - CompressVideoService._(); + ICompressVideoService._(); Future compressVideo(String path) async { return _lock.synchronized(() { @@ -15,3 +15,6 @@ class CompressVideoService { }); } } + +ICompressVideoService get CompressVideoService => + ICompressVideoService.instance; diff --git a/lib/src/message_input.dart b/lib/src/message_input.dart index 3487fb26..c9ed15bb 100644 --- a/lib/src/message_input.dart +++ b/lib/src/message_input.dart @@ -866,8 +866,7 @@ class MessageInputState extends State { if (file.size > _kMaxAttachmentSize) { if (medium.mediaType == MediaType.video) { - final mediaInfo = - await CompressVideoService.instance.compressVideo(file.path); + final mediaInfo = await CompressVideoService.compressVideo(file.path); if (mediaInfo.filesize / (1024 * 1024) > _kMaxAttachmentSize) { Scaffold.of(context).showSnackBar( @@ -1561,8 +1560,7 @@ class MessageInputState extends State { if (file.size > _kMaxAttachmentSize) { if (attachmentType == 'video') { - final mediaInfo = - await CompressVideoService.instance.compressVideo(file.path); + final mediaInfo = await CompressVideoService.compressVideo(file.path); file = PlatformFile( name: mediaInfo.title, size: mediaInfo.filesize,