Merge pull request #24 from GetStream/hotfix/attachments
Hotfix/attachments
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
+58
-24
@@ -56,13 +56,15 @@ import 'stream_channel.dart';
|
||||
/// The widget renders the ui based on the first ancestor of type [StreamChatTheme].
|
||||
/// Modify it to change the widget appearance.
|
||||
class MessageInput extends StatefulWidget {
|
||||
MessageInput(
|
||||
{Key key,
|
||||
this.onMessageSent,
|
||||
this.parentMessage,
|
||||
this.editMessage,
|
||||
this.maxHeight = 150})
|
||||
: super(key: key);
|
||||
MessageInput({
|
||||
Key key,
|
||||
this.onMessageSent,
|
||||
this.parentMessage,
|
||||
this.editMessage,
|
||||
this.maxHeight = 150,
|
||||
this.keyboardType = TextInputType.multiline,
|
||||
this.disableAttachments = false,
|
||||
}) : super(key: key);
|
||||
|
||||
/// Message to edit
|
||||
final Message editMessage;
|
||||
@@ -76,6 +78,12 @@ class MessageInput extends StatefulWidget {
|
||||
/// Maximum Height for the TextField to grow before it starts scrolling
|
||||
final double maxHeight;
|
||||
|
||||
/// The keyboard type assigned to the TextField
|
||||
final TextInputType keyboardType;
|
||||
|
||||
/// If true the attachments button will not be displayed
|
||||
final bool disableAttachments;
|
||||
|
||||
@override
|
||||
_MessageInputState createState() => _MessageInputState();
|
||||
}
|
||||
@@ -86,6 +94,7 @@ class _MessageInputState extends State<MessageInput> {
|
||||
final List<User> _mentionedUsers = [];
|
||||
|
||||
TextEditingController _textController;
|
||||
bool _inputEnabled = true;
|
||||
bool _messageIsPresent = false;
|
||||
bool _typingStarted = false;
|
||||
OverlayEntry _commandsOverlay, _mentionsOverlay;
|
||||
@@ -93,20 +102,27 @@ class _MessageInputState extends State<MessageInput> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SafeArea(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Stack(
|
||||
overflow: Overflow.visible,
|
||||
children: <Widget>[
|
||||
_buildBorder(context),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_buildAttachments(),
|
||||
_buildTextField(context),
|
||||
],
|
||||
),
|
||||
],
|
||||
child: GestureDetector(
|
||||
onPanUpdate: (details) {
|
||||
if (details.delta.dy > 0) {
|
||||
_focusNode.unfocus();
|
||||
}
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Stack(
|
||||
overflow: Overflow.visible,
|
||||
children: <Widget>[
|
||||
_buildBorder(context),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_buildAttachments(),
|
||||
_buildTextField(context),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -117,7 +133,7 @@ class _MessageInputState extends State<MessageInput> {
|
||||
direction: Axis.horizontal,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: <Widget>[
|
||||
_buildAttachmentButton(),
|
||||
if (!widget.disableAttachments) _buildAttachmentButton(),
|
||||
_buildTextInput(context),
|
||||
_animateSendButton(context),
|
||||
],
|
||||
@@ -126,7 +142,8 @@ class _MessageInputState extends State<MessageInput> {
|
||||
|
||||
AnimatedCrossFade _animateSendButton(BuildContext context) {
|
||||
return AnimatedCrossFade(
|
||||
crossFadeState: (_messageIsPresent || _attachments.isNotEmpty)
|
||||
crossFadeState: ((_messageIsPresent || _attachments.isNotEmpty) &&
|
||||
_attachments.every((a) => a.uploaded == true))
|
||||
? CrossFadeState.showFirst
|
||||
: CrossFadeState.showSecond,
|
||||
firstChild: _buildSendButton(context),
|
||||
@@ -142,11 +159,13 @@ class _MessageInputState extends State<MessageInput> {
|
||||
maxHeight: widget.maxHeight,
|
||||
child: TextField(
|
||||
key: Key('messageInputText'),
|
||||
enabled: _inputEnabled,
|
||||
minLines: null,
|
||||
maxLines: null,
|
||||
onSubmitted: (_) {
|
||||
_sendMessage(context);
|
||||
},
|
||||
keyboardType: widget.keyboardType,
|
||||
controller: _textController,
|
||||
focusNode: _focusNode,
|
||||
onChanged: (s) {
|
||||
@@ -506,6 +525,10 @@ class _MessageInputState extends State<MessageInput> {
|
||||
}
|
||||
|
||||
void _showAttachmentModal() {
|
||||
if (_focusNode.hasFocus) {
|
||||
_focusNode.unfocus();
|
||||
}
|
||||
|
||||
showModalBottomSheet(
|
||||
clipBehavior: Clip.hardEdge,
|
||||
shape: RoundedRectangleBorder(
|
||||
@@ -548,7 +571,6 @@ class _MessageInputState extends State<MessageInput> {
|
||||
leading: Icon(Icons.camera_alt),
|
||||
title: Text('Photo from camera'),
|
||||
onTap: () {
|
||||
ImagePicker.pickImage(source: ImageSource.camera);
|
||||
_pickFile(FileType.image, true);
|
||||
Navigator.pop(context);
|
||||
},
|
||||
@@ -575,6 +597,10 @@ class _MessageInputState extends State<MessageInput> {
|
||||
}
|
||||
|
||||
void _pickFile(FileType type, bool camera) async {
|
||||
setState(() {
|
||||
_inputEnabled = false;
|
||||
});
|
||||
|
||||
File file;
|
||||
|
||||
if (camera) {
|
||||
@@ -587,6 +613,14 @@ class _MessageInputState extends State<MessageInput> {
|
||||
file = await FilePicker.getFile(type: type);
|
||||
}
|
||||
|
||||
setState(() {
|
||||
_inputEnabled = true;
|
||||
});
|
||||
|
||||
if (file == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final channel = StreamChannel.of(context).channel;
|
||||
|
||||
final bytes = await file.readAsBytes();
|
||||
|
||||
+49
-34
@@ -39,6 +39,7 @@ class MessageWidget extends StatefulWidget {
|
||||
this.isParent = false,
|
||||
this.onMentionTap,
|
||||
this.showOtherMessageUsername = false,
|
||||
this.showVideoFullScreen = true,
|
||||
}) : super(key: key);
|
||||
|
||||
/// Function called on mention tap
|
||||
@@ -65,6 +66,9 @@ class MessageWidget extends StatefulWidget {
|
||||
/// True if this is the parent of the thread being showed
|
||||
final bool isParent;
|
||||
|
||||
/// True if the video player will allow fullscreen mode
|
||||
final bool showVideoFullScreen;
|
||||
|
||||
@override
|
||||
_MessageWidgetState createState() => _MessageWidgetState();
|
||||
}
|
||||
@@ -944,42 +948,53 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
_videoControllers[attachment.assetUrl] = videoController;
|
||||
}
|
||||
|
||||
ChewieController chewieController;
|
||||
if (_chuwieControllers.containsKey(attachment.assetUrl)) {
|
||||
chewieController = _chuwieControllers[attachment.assetUrl];
|
||||
} else {
|
||||
chewieController = ChewieController(
|
||||
videoPlayerController: videoController,
|
||||
autoInitialize: true,
|
||||
errorBuilder: (_, e) {
|
||||
return Stack(
|
||||
children: <Widget>[
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
fit: BoxFit.cover,
|
||||
image: CachedNetworkImageProvider(
|
||||
attachment.thumbUrl,
|
||||
return FutureBuilder<void>(
|
||||
future: videoController.initialize(),
|
||||
builder: (_, snapshot) {
|
||||
if (snapshot.connectionState != ConnectionState.done) {
|
||||
return Center(
|
||||
child: CircularProgressIndicator(),
|
||||
);
|
||||
}
|
||||
ChewieController chewieController;
|
||||
if (_chuwieControllers.containsKey(attachment.assetUrl)) {
|
||||
chewieController = _chuwieControllers[attachment.assetUrl];
|
||||
} else {
|
||||
chewieController = ChewieController(
|
||||
allowFullScreen: widget.showVideoFullScreen,
|
||||
videoPlayerController: videoController,
|
||||
autoInitialize: false,
|
||||
aspectRatio: videoController.value.aspectRatio,
|
||||
errorBuilder: (_, e) {
|
||||
return Stack(
|
||||
children: <Widget>[
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
fit: BoxFit.cover,
|
||||
image: CachedNetworkImageProvider(
|
||||
attachment.thumbUrl,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
onTap: () => _launchURL(attachment.titleLink),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
});
|
||||
_chuwieControllers[attachment.assetUrl] = chewieController;
|
||||
}
|
||||
|
||||
return Chewie(
|
||||
key: ValueKey<String>(
|
||||
'ATTACHMENT-${attachment.title}-${widget.message.id}'),
|
||||
controller: chewieController,
|
||||
Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
onTap: () => _launchURL(attachment.titleLink),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
});
|
||||
_chuwieControllers[attachment.assetUrl] = chewieController;
|
||||
}
|
||||
return Chewie(
|
||||
key: ValueKey<String>(
|
||||
'ATTACHMENT-${attachment.title}-${widget.message.id}'),
|
||||
controller: chewieController,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,8 +10,6 @@ dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
rxdart: ^0.23.1
|
||||
|
||||
|
||||
jiffy: ^3.0.1
|
||||
cached_network_image: ^2.0.0
|
||||
flutter_markdown: ^0.3.4
|
||||
|
||||
Reference in New Issue
Block a user