From 5371eb3aae8f5faa4c3d1b8ac61629ded5b14387 Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Fri, 6 Nov 2020 15:26:34 +0530 Subject: [PATCH] feat: Attachments are now supported --- lib/src/message_input.dart | 192 +++++++++++++++++++++++-------------- 1 file changed, 121 insertions(+), 71 deletions(-) diff --git a/lib/src/message_input.dart b/lib/src/message_input.dart index 3a8132e2..be06eb10 100644 --- a/lib/src/message_input.dart +++ b/lib/src/message_input.dart @@ -1,5 +1,4 @@ import 'dart:async'; -import 'dart:io'; import 'dart:math'; import 'package:file_picker/file_picker.dart'; @@ -176,6 +175,7 @@ class MessageInputState extends State { bool _sendAsDm = false; bool _openFilePickerSection = false; int _filePickerIndex = 0; + double _filePickerSize = 250.0; /// The editing controller passed to the input TextField TextEditingController textEditingController; @@ -539,7 +539,8 @@ class MessageInputState extends State { Widget _buildFilePickerSection() { return Container( - height: 200.0, + color: Color(0xFFF2F2F2), + height: _filePickerSize, child: Column( children: [ Row( @@ -566,9 +567,7 @@ class MessageInputState extends State { : Colors.black.withOpacity(0.5), ), onPressed: () { - setState(() { - _filePickerIndex = 1; - }); + pickFile(DefaultAttachmentTypes.file, false); }, ), IconButton( @@ -579,15 +578,54 @@ class MessageInputState extends State { : Colors.black.withOpacity(0.5), ), onPressed: () { - setState(() { - _filePickerIndex = 2; - }); + pickFile(DefaultAttachmentTypes.image, true); }, ), ], ), + Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only( + topLeft: Radius.circular(8.0), + topRight: Radius.circular(8.0), + ), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + GestureDetector( + onVerticalDragUpdate: (update) { + setState(() { + _filePickerSize -= update.delta.dy; + if (_filePickerSize < 100) { + _filePickerSize = 100.0; + } + }); + }, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Container( + width: 40.0, + height: 4.0, + decoration: BoxDecoration( + color: Color(0xFFF2F2F2), + borderRadius: BorderRadius.circular(4.0), + ), + ), + ), + ), + ], + ), + ), Expanded( - child: _buildPickerSection(), + child: Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8.0), + ), + child: _buildPickerSection(), + ), ), ], ), @@ -598,7 +636,7 @@ class MessageInputState extends State { switch (_filePickerIndex) { case 0: return FutureBuilder>( - future: _getAllMedia(MediumType.image), + future: _getAllMedia(), builder: (context, mediaData) { if (!mediaData.hasData) { return Center( @@ -635,7 +673,9 @@ class MessageInputState extends State { ), aspectRatio: 1.0, ), - onTap: () {}, + onTap: () { + _addAttachment(mediaData.data[position]); + }, ), ); }); @@ -644,59 +684,70 @@ class MessageInputState extends State { }); break; case 1: - return FutureBuilder>( - future: _getAllMedia(MediumType.video), - builder: (context, mediaData) { - if (!mediaData.hasData) { - return Center( - child: CircularProgressIndicator(), - ); - } - - return GridView.builder( - itemCount: mediaData.data.length, - gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 3), - itemBuilder: (context, position) { - return FutureBuilder>( - future: PhotoGallery.getThumbnail( - mediumId: mediaData.data[position].id), - builder: (context, snapshot) { - if (!snapshot.hasData) { - return Center( - child: CircularProgressIndicator(), - ); - } - - return Padding( - padding: const EdgeInsets.symmetric( - horizontal: 1.0, vertical: 1.0), - child: InkWell( - child: AspectRatio( - child: Image.memory( - snapshot.data, - fit: mediaData.data[position].height > - mediaData.data[position].width - ? BoxFit.fitWidth - : BoxFit.fitHeight, - ), - aspectRatio: 1.0, - ), - onTap: () {}, - ), - ); - }); - }, - ); - }); break; case 2: break; } } - Future> _getAllMedia(MediumType type) async { - var allAlbums = await PhotoGallery.listAlbums(mediumType: type); + void _addAttachment(Medium medium) async { + var mediaFile = await PhotoGallery.getFile(mediumId: medium.id); + + var file = PlatformFile( + path: mediaFile.path, + bytes: mediaFile.readAsBytesSync(), + ); + + setState(() { + _inputEnabled = true; + }); + + if (file == null) { + return; + } + + final channel = StreamChannel.of(context).channel; + final attachment = _SendingAttachment( + file: file, + attachment: Attachment( + localUri: file.path != null ? Uri.parse(file.path) : null, + type: medium.mediumType == MediumType.image ? 'image' : 'video', + ), + ); + + setState(() { + _attachments.add(attachment); + }); + + final url = await _uploadAttachment( + file, + medium.mediumType == MediumType.image + ? DefaultAttachmentTypes.image + : DefaultAttachmentTypes.video, + channel); + + var fileType = medium.mediumType == MediumType.image + ? DefaultAttachmentTypes.image + : DefaultAttachmentTypes.video; + + if (fileType == DefaultAttachmentTypes.image) { + attachment.attachment = attachment.attachment.copyWith( + imageUrl: url, + ); + } else { + attachment.attachment = attachment.attachment.copyWith( + assetUrl: url, + ); + } + + setState(() { + attachment.uploaded = true; + }); + } + + Future> _getAllMedia() async { + var allAlbums = await PhotoGallery.listAlbums(mediumType: MediumType.image); + //var allVideoAlbums = await PhotoGallery.listAlbums(mediumType: MediumType.video); List resultList = []; for (var album in allAlbums) { @@ -704,6 +755,11 @@ class MessageInputState extends State { resultList.addAll(data.items); } + // for (var album in allVideoAlbums) { + // var data = await album.listMedia(); + // resultList.addAll(data.items); + // } + resultList.sort((a, b) => a.modifiedDate.compareTo(b.modifiedDate)); return resultList; @@ -819,19 +875,6 @@ class MessageInputState extends State { _commandsOverlay = null; } - Gradient _getGradient(BuildContext context) { - if (_typingStarted) { - if (widget.editMessage == null) { - return StreamChatTheme.of(context).channelTheme.inputGradient; - } - return LinearGradient( - colors: [Colors.lightGreen, Colors.green], - ); - } else { - return null; - } - } - Widget _buildAttachments() { return _attachments.isEmpty ? Container() @@ -985,6 +1028,7 @@ class MessageInputState extends State { if (_openFilePickerSection) { setState(() { _openFilePickerSection = false; + _filePickerSize = 250.0; }); } else { showAttachmentModal(); @@ -1410,6 +1454,12 @@ class MessageInputState extends State { if (widget.editMessage != null || widget.initialMessage != null) { _parseExistingMessage(widget.editMessage ?? widget.initialMessage); } + + _focusNode.addListener(() { + if (_focusNode.hasFocus) { + _openFilePickerSection = false; + } + }); } void _parseExistingMessage(Message message) {