@@ -25,7 +25,7 @@ import 'package:video_compress/video_compress.dart';
|
|||||||
import 'extension.dart';
|
import 'extension.dart';
|
||||||
|
|
||||||
import '../stream_chat_flutter.dart';
|
import '../stream_chat_flutter.dart';
|
||||||
import 'reply_message_widget.dart';
|
import 'quoted_message_widget.dart';
|
||||||
import 'stream_channel.dart';
|
import 'stream_channel.dart';
|
||||||
|
|
||||||
typedef FileUploader = Future<String> Function(PlatformFile, Channel);
|
typedef FileUploader = Future<String> Function(PlatformFile, Channel);
|
||||||
@@ -2015,7 +2015,9 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
|
|
||||||
textEditingController.clear();
|
textEditingController.clear();
|
||||||
_attachments.clear();
|
_attachments.clear();
|
||||||
widget.onQuotedMessageCleared();
|
if (widget.onQuotedMessageCleared != null) {
|
||||||
|
widget.onQuotedMessageCleared();
|
||||||
|
}
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
_messageIsPresent = false;
|
_messageIsPresent = false;
|
||||||
|
|||||||
+35
-32
@@ -11,7 +11,7 @@ import 'package:jiffy/jiffy.dart';
|
|||||||
import 'package:stream_chat_flutter/src/message_actions_modal.dart';
|
import 'package:stream_chat_flutter/src/message_actions_modal.dart';
|
||||||
import 'package:stream_chat_flutter/src/message_reactions_modal.dart';
|
import 'package:stream_chat_flutter/src/message_reactions_modal.dart';
|
||||||
import 'package:stream_chat_flutter/src/reaction_bubble.dart';
|
import 'package:stream_chat_flutter/src/reaction_bubble.dart';
|
||||||
import 'package:stream_chat_flutter/src/reply_message_widget.dart';
|
import 'package:stream_chat_flutter/src/quoted_message_widget.dart';
|
||||||
import 'package:stream_chat_flutter/src/url_attachment.dart';
|
import 'package:stream_chat_flutter/src/url_attachment.dart';
|
||||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||||
|
|
||||||
@@ -356,37 +356,39 @@ class _MessageWidgetState extends State<MessageWidget> {
|
|||||||
widget.messageTheme,
|
widget.messageTheme,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: GestureDetector(
|
: Material(
|
||||||
onLongPress: () =>
|
clipBehavior: Clip.antiAlias,
|
||||||
onLongPress(context),
|
shape: widget.shape ??
|
||||||
child: Material(
|
RoundedRectangleBorder(
|
||||||
clipBehavior:
|
side: isOnlyEmoji
|
||||||
Clip.antiAlias,
|
? BorderSide.none
|
||||||
shape: widget.shape ??
|
: widget.borderSide ??
|
||||||
RoundedRectangleBorder(
|
BorderSide(
|
||||||
side: isOnlyEmoji
|
color: Theme.of(context)
|
||||||
? BorderSide.none
|
.brightness ==
|
||||||
: widget.borderSide ??
|
Brightness
|
||||||
BorderSide(
|
.dark
|
||||||
color: Theme.of(context).brightness ==
|
? StreamChatTheme.of(
|
||||||
Brightness
|
context)
|
||||||
.dark
|
.colorTheme
|
||||||
? StreamChatTheme.of(context)
|
.white
|
||||||
.colorTheme
|
.withAlpha(
|
||||||
.white
|
24)
|
||||||
.withAlpha(
|
: StreamChatTheme.of(
|
||||||
24)
|
context)
|
||||||
: StreamChatTheme.of(context)
|
.colorTheme
|
||||||
.colorTheme
|
.black
|
||||||
.black
|
.withAlpha(
|
||||||
.withAlpha(24),
|
24),
|
||||||
),
|
),
|
||||||
borderRadius: widget
|
borderRadius: widget
|
||||||
.borderRadiusGeometry ??
|
.borderRadiusGeometry ??
|
||||||
BorderRadius.zero,
|
BorderRadius.zero,
|
||||||
),
|
),
|
||||||
color:
|
color: _getBackgroundColor(),
|
||||||
_getBackgroundColor(),
|
child: InkWell(
|
||||||
|
onLongPress: () =>
|
||||||
|
onLongPress(context),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.all(
|
padding: EdgeInsets.all(
|
||||||
hasFiles ? 2.0 : 0.0),
|
hasFiles ? 2.0 : 0.0),
|
||||||
@@ -399,6 +401,7 @@ class _MessageWidgetState extends State<MessageWidget> {
|
|||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
if (_hasQuotedMessage)
|
if (_hasQuotedMessage)
|
||||||
QuotedMessageWidget(
|
QuotedMessageWidget(
|
||||||
|
onTap: () {},
|
||||||
message: widget
|
message: widget
|
||||||
.message
|
.message
|
||||||
.quotedMessage,
|
.quotedMessage,
|
||||||
|
|||||||
@@ -12,8 +12,9 @@ import 'message_text.dart';
|
|||||||
import 'stream_chat_theme.dart';
|
import 'stream_chat_theme.dart';
|
||||||
import 'user_avatar.dart';
|
import 'user_avatar.dart';
|
||||||
import 'utils.dart';
|
import 'utils.dart';
|
||||||
|
import 'extension.dart';
|
||||||
|
|
||||||
typedef ReplyMessageAttachmentThumbnailBuilder = Widget Function(
|
typedef QuotedMessageAttachmentThumbnailBuilder = Widget Function(
|
||||||
BuildContext,
|
BuildContext,
|
||||||
Attachment,
|
Attachment,
|
||||||
);
|
);
|
||||||
@@ -80,9 +81,11 @@ class QuotedMessageWidget extends StatelessWidget {
|
|||||||
final int textLimit;
|
final int textLimit;
|
||||||
|
|
||||||
/// Map that defines a thumbnail builder for an attachment type
|
/// Map that defines a thumbnail builder for an attachment type
|
||||||
final Map<String, ReplyMessageAttachmentThumbnailBuilder>
|
final Map<String, QuotedMessageAttachmentThumbnailBuilder>
|
||||||
attachmentThumbnailBuilders;
|
attachmentThumbnailBuilders;
|
||||||
|
|
||||||
|
final GestureTapCallback onTap;
|
||||||
|
|
||||||
///
|
///
|
||||||
QuotedMessageWidget({
|
QuotedMessageWidget({
|
||||||
Key key,
|
Key key,
|
||||||
@@ -92,6 +95,7 @@ class QuotedMessageWidget extends StatelessWidget {
|
|||||||
this.showBorder = false,
|
this.showBorder = false,
|
||||||
this.textLimit = 170,
|
this.textLimit = 170,
|
||||||
this.attachmentThumbnailBuilders,
|
this.attachmentThumbnailBuilders,
|
||||||
|
this.onTap,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
bool get _hasAttachments => message.attachments?.isNotEmpty == true;
|
bool get _hasAttachments => message.attachments?.isNotEmpty == true;
|
||||||
@@ -104,32 +108,54 @@ class QuotedMessageWidget extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Padding(
|
return InkWell(
|
||||||
padding: const EdgeInsets.only(top: 8, bottom: 6, right: 4, left: 8),
|
onTap: onTap,
|
||||||
child: Row(
|
child: Padding(
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
padding: const EdgeInsets.only(top: 8, bottom: 6, right: 4, left: 8),
|
||||||
mainAxisSize: MainAxisSize.min,
|
child: Row(
|
||||||
children: [
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
Flexible(child: _buildMessage(context)),
|
mainAxisSize: MainAxisSize.min,
|
||||||
SizedBox(width: 4),
|
children: [
|
||||||
_buildUserAvatar(),
|
Flexible(child: _buildMessage(context)),
|
||||||
],
|
SizedBox(width: 4),
|
||||||
|
_buildUserAvatar(),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildMessage(BuildContext context) {
|
Widget _buildMessage(BuildContext context) {
|
||||||
|
final isOnlyEmoji =
|
||||||
|
message.text.characters.every((c) => Emoji.byChar(c) != null);
|
||||||
|
var msg = _hasAttachments && !_containsText
|
||||||
|
? message.copyWith(text: message.attachments.last?.title ?? '')
|
||||||
|
: message;
|
||||||
|
if (msg.text.length > textLimit) {
|
||||||
|
msg = msg.copyWith(text: '${msg.text.substring(0, textLimit - 3)}...');
|
||||||
|
}
|
||||||
|
|
||||||
final children = [
|
final children = [
|
||||||
if (_hasAttachments) ...[
|
if (_hasAttachments) _parseAttachments(context),
|
||||||
_parseAttachments(context),
|
if (msg.text.isNotEmpty)
|
||||||
SizedBox(width: 8),
|
Flexible(
|
||||||
],
|
child: Transform(
|
||||||
Flexible(child: _buildTextMessage()),
|
transform: Matrix4.rotationY(reverse ? pi : 0),
|
||||||
];
|
alignment: Alignment.center,
|
||||||
|
child: MessageText(
|
||||||
|
message: msg,
|
||||||
|
messageTheme: isOnlyEmoji && _containsText
|
||||||
|
? messageTheme.copyWith(
|
||||||
|
messageText: messageTheme.messageText.copyWith(
|
||||||
|
fontSize: 24,
|
||||||
|
))
|
||||||
|
: messageTheme,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
].insertBetween(const SizedBox(width: 8));
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
constraints: BoxConstraints(
|
|
||||||
minHeight: 48.0,
|
|
||||||
),
|
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: _getBackgroundColor(context),
|
color: _getBackgroundColor(context),
|
||||||
border: showBorder
|
border: showBorder
|
||||||
@@ -146,6 +172,7 @@ class QuotedMessageWidget extends StatelessWidget {
|
|||||||
padding: const EdgeInsets.all(8),
|
padding: const EdgeInsets.all(8),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
mainAxisAlignment:
|
mainAxisAlignment:
|
||||||
reverse ? MainAxisAlignment.end : MainAxisAlignment.start,
|
reverse ? MainAxisAlignment.end : MainAxisAlignment.start,
|
||||||
children: reverse ? children.reversed.toList() : children,
|
children: reverse ? children.reversed.toList() : children,
|
||||||
@@ -153,30 +180,6 @@ class QuotedMessageWidget extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildTextMessage() {
|
|
||||||
final isOnlyEmoji =
|
|
||||||
message.text.characters.every((c) => Emoji.byChar(c) != null);
|
|
||||||
var msg = _hasAttachments && !_containsText
|
|
||||||
? message.copyWith(text: message.attachments.last?.title ?? '')
|
|
||||||
: message;
|
|
||||||
if (msg.text.length > textLimit) {
|
|
||||||
msg = msg.copyWith(text: '${msg.text.substring(0, textLimit - 3)}...');
|
|
||||||
}
|
|
||||||
return Transform(
|
|
||||||
transform: Matrix4.rotationY(reverse ? pi : 0),
|
|
||||||
alignment: Alignment.center,
|
|
||||||
child: MessageText(
|
|
||||||
message: msg,
|
|
||||||
messageTheme: isOnlyEmoji && _containsText
|
|
||||||
? messageTheme.copyWith(
|
|
||||||
messageText: messageTheme.messageText.copyWith(
|
|
||||||
fontSize: 24,
|
|
||||||
))
|
|
||||||
: messageTheme,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildUrlAttachment(Attachment attachment) {
|
Widget _buildUrlAttachment(Attachment attachment) {
|
||||||
final size = Size(32, 32);
|
final size = Size(32, 32);
|
||||||
if (attachment.thumbUrl != null) {
|
if (attachment.thumbUrl != null) {
|
||||||
@@ -208,7 +211,7 @@ class QuotedMessageWidget extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
child = _buildUrlAttachment(attachment);
|
child = _buildUrlAttachment(attachment);
|
||||||
} else {
|
} else {
|
||||||
ReplyMessageAttachmentThumbnailBuilder attachmentBuilder;
|
QuotedMessageAttachmentThumbnailBuilder attachmentBuilder;
|
||||||
attachment = message.attachments.last;
|
attachment = message.attachments.last;
|
||||||
if (attachmentThumbnailBuilders?.containsKey(attachment?.type) == true) {
|
if (attachmentThumbnailBuilders?.containsKey(attachment?.type) == true) {
|
||||||
attachmentBuilder = attachmentThumbnailBuilders[attachment?.type];
|
attachmentBuilder = attachmentThumbnailBuilders[attachment?.type];
|
||||||
@@ -219,6 +222,7 @@ class QuotedMessageWidget extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
child = attachmentBuilder(context, attachment);
|
child = attachmentBuilder(context, attachment);
|
||||||
}
|
}
|
||||||
|
child = AbsorbPointer(child: child);
|
||||||
return Transform(
|
return Transform(
|
||||||
transform: Matrix4.rotationY(reverse ? pi : 0),
|
transform: Matrix4.rotationY(reverse ? pi : 0),
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
@@ -258,7 +262,7 @@ class QuotedMessageWidget extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, ReplyMessageAttachmentThumbnailBuilder>
|
Map<String, QuotedMessageAttachmentThumbnailBuilder>
|
||||||
get _defaultAttachmentBuilder {
|
get _defaultAttachmentBuilder {
|
||||||
return {
|
return {
|
||||||
'image': (_, attachment) {
|
'image': (_, attachment) {
|
||||||
Reference in New Issue
Block a user