add file upload

This commit is contained in:
Salvatore Giordano
2020-02-28 17:01:57 +01:00
parent 1fea1fd19b
commit b6f0b6f2c1
4 changed files with 144 additions and 29 deletions
+4
View File
@@ -48,6 +48,10 @@
</array>
<key>NSAppleMusicUsageDescription</key>
<string>Used to send message attachments</string>
<key>NSCameraUsageDescription</key>
<string>Used to send message attachments</string>
<key>NSMicrophoneUsageDescription</key>
<string>Used to send message attachments</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Used to send message attachments</string>
</dict>
+136 -25
View File
@@ -3,6 +3,7 @@ import 'dart:io';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:stream_chat/stream_chat.dart';
import 'package:stream_chat_flutter/src/stream_chat_theme.dart';
@@ -136,7 +137,7 @@ class _MessageInputState extends State<MessageInput> {
Container(
height: 50,
width: 50,
child: Image.file(attachment.file),
child: _buildAttachment(attachment),
),
Positioned(
height: 16,
@@ -176,6 +177,25 @@ class _MessageInputState extends State<MessageInput> {
);
}
Widget _buildAttachment(_SendingAttachment attachment) {
switch (attachment.type) {
case FileType.IMAGE:
return Image.file(attachment.file);
break;
case FileType.VIDEO:
return Container(
child: Icon(Icons.videocam),
color: Colors.black26,
);
break;
default:
return Container(
child: Icon(Icons.insert_drive_file),
color: Colors.black26,
);
}
}
Material _buildAttachmentButton() {
return Material(
clipBehavior: Clip.hardEdge,
@@ -184,25 +204,72 @@ class _MessageInputState extends State<MessageInput> {
),
color: Colors.transparent,
child: IconButton(
onPressed: () async {
final file = await FilePicker.getFile(type: FileType.IMAGE);
print(file.path);
final channel = StreamChannel.of(context).channel;
final bytes = await file.readAsBytes();
final res = await channel.sendFile(MultipartFile.fromBytes(
bytes,
filename: file.path.split('/').last,
));
setState(() {
_attachments.add(_SendingAttachment(
url: res.file,
extension: file.path.split('.').last,
file: file,
));
});
onPressed: () {
showModalBottomSheet(
clipBehavior: Clip.hardEdge,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(32),
topRight: Radius.circular(32),
),
),
context: context,
builder: (_) {
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
title: Text(
'Add a file',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
),
ListTile(
leading: Icon(Icons.image),
title: Text('Upload a photo'),
onTap: () {
_pickFile(FileType.IMAGE, false);
Navigator.pop(context);
},
),
ListTile(
leading: Icon(Icons.video_library),
title: Text('Upload a video'),
onTap: () {
_pickFile(FileType.VIDEO, false);
Navigator.pop(context);
},
),
ListTile(
leading: Icon(Icons.camera_alt),
title: Text('Photo from camera'),
onTap: () {
ImagePicker.pickImage(source: ImageSource.camera);
_pickFile(FileType.IMAGE, true);
Navigator.pop(context);
},
),
ListTile(
leading: Icon(Icons.videocam),
title: Text('Video from camera'),
onTap: () {
_pickFile(FileType.VIDEO, true);
Navigator.pop(context);
},
),
ListTile(
leading: Icon(Icons.insert_drive_file),
title: Text('Upload a file'),
onTap: () {
_pickFile(FileType.ANY, false);
Navigator.pop(context);
},
),
],
);
});
},
icon: Icon(
Icons.add_circle_outline,
@@ -211,6 +278,38 @@ class _MessageInputState extends State<MessageInput> {
);
}
void _pickFile(FileType type, bool camera) async {
File file;
if (camera) {
if (type == FileType.IMAGE) {
file = await ImagePicker.pickImage(source: ImageSource.camera);
} else if (type == FileType.VIDEO) {
file = await ImagePicker.pickVideo(source: ImageSource.camera);
}
} else {
file = await FilePicker.getFile(type: type);
}
final channel = StreamChannel.of(context).channel;
final bytes = await file.readAsBytes();
final res = await channel.sendFile(
MultipartFile.fromBytes(
bytes,
filename: file.path.split('/').last,
),
);
setState(() {
_attachments.add(_SendingAttachment(
url: res.file,
file: file,
type: type,
));
});
}
Widget _buildSendButton(BuildContext context) {
return IconTheme(
data:
@@ -239,7 +338,7 @@ class _MessageInputState extends State<MessageInput> {
return;
}
final attachments = List.from(_attachments);
final attachments = List<_SendingAttachment>.from(_attachments);
_textController.clear();
_attachments.clear();
@@ -257,10 +356,22 @@ class _MessageInputState extends State<MessageInput> {
parentId: widget.parentMessage?.id,
text: text,
attachments: attachments.map((attachment) {
String type;
switch (attachment.type) {
case FileType.IMAGE:
type = 'image';
break;
case FileType.VIDEO:
type = 'video';
break;
default:
type = 'file';
}
return Attachment(
imageUrl: attachment.url,
imageUrl:
attachment.type == FileType.IMAGE ? attachment.url : null,
assetUrl: attachment.url,
type: 'image',
type: type,
);
}).toList(),
),
@@ -275,12 +386,12 @@ class _MessageInputState extends State<MessageInput> {
class _SendingAttachment {
final String url;
final String extension;
final File file;
final FileType type;
_SendingAttachment({
this.url,
this.extension,
this.file,
this.type,
});
}
+2 -2
View File
@@ -211,7 +211,7 @@ class _MessageWidgetState extends State<MessageWidget>
borderRadius: boxDecoration.borderRadius,
child: Container(
decoration: boxDecoration,
constraints: BoxConstraints.loose(Size(300, 500)),
constraints: BoxConstraints.loose(Size.fromWidth(300)),
child: Stack(
children: <Widget>[
Column(
@@ -256,7 +256,7 @@ class _MessageWidgetState extends State<MessageWidget>
),
color: Color(0xffebebeb),
)
: Container(),
: SizedBox(),
],
),
attachment.type == 'image' && attachment.titleLink != null
+2 -2
View File
@@ -19,8 +19,8 @@ dependencies:
video_player: ^0.10.7
chewie: ^0.9.8+1
file_picker: ^1.4.3+2
stream_chat:
path: ../stream_chat_dart
image_picker: ^0.6.3+4
stream_chat: ^0.1.12
dev_dependencies:
pedantic: ^1.8.0+1