fix(ui): fix various message_list_view issues.
Signed-off-by: xsahil03x <xdsahil@gmail.com>
This commit is contained in:
@@ -59,6 +59,7 @@ class StreamGiphyAttachment extends StreamAttachmentWidget {
|
||||
color: StreamChatTheme.of(context).colorTheme.barsBg,
|
||||
elevation: 2,
|
||||
clipBehavior: Clip.hardEdge,
|
||||
margin: EdgeInsets.zero,
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.only(
|
||||
topRight: Radius.circular(16),
|
||||
@@ -241,10 +242,7 @@ class StreamGiphyAttachment extends StreamAttachmentWidget {
|
||||
const SizedBox(height: 4),
|
||||
const Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
child: StreamVisibleFootnote(),
|
||||
),
|
||||
child: StreamVisibleFootnote(),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -1372,10 +1372,10 @@ class StreamMessageInputState extends State<StreamMessageInput>
|
||||
}
|
||||
|
||||
final streamChannel = StreamChannel.of(context);
|
||||
final channel = streamChannel.channel;
|
||||
var message = _effectiveController.value;
|
||||
|
||||
if (!streamChannel.channel.ownCapabilities
|
||||
.contains(PermissionType.sendLinks) &&
|
||||
if (!channel.ownCapabilities.contains(PermissionType.sendLinks) &&
|
||||
_urlRegex.allMatches(message.text ?? '').any((element) =>
|
||||
element.group(0)?.split('.').last.isValidTLD() == true)) {
|
||||
showInfoBottomSheet(
|
||||
@@ -1401,8 +1401,8 @@ class StreamMessageInputState extends State<StreamMessageInput>
|
||||
final skipEnrichUrl = _effectiveController.ogAttachment == null;
|
||||
|
||||
var shouldKeepFocus = widget.shouldKeepFocusAfterMessage;
|
||||
|
||||
shouldKeepFocus ??= !_commandEnabled;
|
||||
|
||||
widget.onQuotedMessageCleared?.call();
|
||||
|
||||
_effectiveController.reset();
|
||||
@@ -1411,12 +1411,35 @@ class StreamMessageInputState extends State<StreamMessageInput>
|
||||
message = await widget.preMessageSending!(message);
|
||||
}
|
||||
|
||||
final channel = streamChannel.channel;
|
||||
message = message.replaceMentionsWithId();
|
||||
|
||||
// If the channel is not up to date, we should reload it before sending
|
||||
// the message.
|
||||
if (!channel.state!.isUpToDate) {
|
||||
await streamChannel.reloadChannel();
|
||||
|
||||
// We need to wait for the frame to be rendered with the updated channel
|
||||
// state before sending the message.
|
||||
await WidgetsBinding.instance.endOfFrame;
|
||||
}
|
||||
|
||||
message = message.replaceMentionsWithId();
|
||||
await sendOrUpdateMessage(
|
||||
message: message,
|
||||
skipEnrichUrl: skipEnrichUrl,
|
||||
);
|
||||
|
||||
if (shouldKeepFocus) {
|
||||
FocusScope.of(context).requestFocus(_effectiveFocusNode);
|
||||
} else {
|
||||
FocusScope.of(context).unfocus();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> sendOrUpdateMessage({
|
||||
required Message message,
|
||||
bool skipEnrichUrl = false,
|
||||
}) async {
|
||||
final channel = StreamChannel.of(context).channel;
|
||||
|
||||
try {
|
||||
Future sendingFuture;
|
||||
@@ -1432,12 +1455,6 @@ class StreamMessageInputState extends State<StreamMessageInput>
|
||||
);
|
||||
}
|
||||
|
||||
if (shouldKeepFocus) {
|
||||
FocusScope.of(context).requestFocus(_effectiveFocusNode);
|
||||
} else {
|
||||
FocusScope.of(context).unfocus();
|
||||
}
|
||||
|
||||
final resp = await sendingFuture;
|
||||
if (resp.message?.type == 'error') {
|
||||
_effectiveController.message = message;
|
||||
|
||||
@@ -566,21 +566,30 @@ class _StreamMessageListViewState extends State<StreamMessageListView> {
|
||||
reverse: widget.reverse,
|
||||
shrinkWrap: widget.shrinkWrap,
|
||||
itemCount: itemCount,
|
||||
findChildIndexCallback: (Key key) {
|
||||
final indexedKey = key as IndexedKey;
|
||||
final valueKey = indexedKey.key as ValueKey<String>?;
|
||||
if (valueKey != null) {
|
||||
final index = messagesIndex[valueKey.value];
|
||||
if (index != null) {
|
||||
// The calculation is as follows:
|
||||
// * Add 2 to the index retrieved to account for the footer and the bottom loader.
|
||||
// * Multiply the result by 2 to account for the separators between each pair of items.
|
||||
// * Subtract 1 to adjust for the 0-based indexing of the list view.
|
||||
return ((index + 2) * 2) - 1;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
// Commented out as it is not working as expected.
|
||||
// The list view gets broken in the following case:
|
||||
// * The list view is loaded at a particular message (eg: Last Read, or a quoted message)
|
||||
// and a new message is added to the list view.
|
||||
//
|
||||
// Github faced: https://github.com/GetStream/stream-chat-flutter/issues/1576
|
||||
// Related issues: https://github.com/flutter/flutter/issues/107123
|
||||
//
|
||||
// findChildIndexCallback: (Key key) {
|
||||
// final indexedKey = key as IndexedKey;
|
||||
// final valueKey = indexedKey.key as ValueKey<String>?;
|
||||
// if (valueKey != null) {
|
||||
// final index = messagesIndex[valueKey.value];
|
||||
// if (index != null) {
|
||||
// // The calculation is as follows:
|
||||
// // * Add 2 to the index retrieved to account for the footer and the bottom loader.
|
||||
// // * Multiply the result by 2 to account for the separators between each pair of items.
|
||||
// // * Subtract 1 to adjust for the 0-based indexing of the list view.
|
||||
// return ((index + 2) * 2) - 1;
|
||||
// }
|
||||
// }
|
||||
// return null;
|
||||
// },
|
||||
|
||||
// Item Count -> 8 (1 parent, 2 header+footer, 2 top+bottom, 3 messages)
|
||||
// eg: |Type| rev(|Index(item)|) rev(|Index(separator)|) |Index(item)| |Index(separator)|
|
||||
@@ -899,7 +908,10 @@ class _StreamMessageListViewState extends State<StreamMessageListView> {
|
||||
final hasUrlAttachment =
|
||||
message.attachments.any((it) => it.ogScrapeUrl != null);
|
||||
|
||||
final borderSide = isOnlyEmoji || hasUrlAttachment ? BorderSide.none : null;
|
||||
final isEphemeral = message.isEphemeral;
|
||||
|
||||
final borderSide =
|
||||
isOnlyEmoji || hasUrlAttachment || isEphemeral ? BorderSide.none : null;
|
||||
|
||||
final defaultMessageWidget = StreamMessageWidget(
|
||||
showReplyMessage: false,
|
||||
@@ -980,24 +992,7 @@ class _StreamMessageListViewState extends State<StreamMessageListView> {
|
||||
FloatingActionButton(
|
||||
backgroundColor: _streamTheme.colorTheme.barsBg,
|
||||
onPressed: () async {
|
||||
if (unreadCount > 0) {
|
||||
streamChannel!.channel.markRead();
|
||||
}
|
||||
if (!_upToDate) {
|
||||
_bottomPaginationActive = false;
|
||||
initialAlignment = 0;
|
||||
initialIndex = 0;
|
||||
await streamChannel!.reloadChannel();
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
_scrollController!.jumpTo(index: 0);
|
||||
});
|
||||
} else {
|
||||
_showScrollToBottom.value = false;
|
||||
_scrollController!.jumpTo(
|
||||
index: 0,
|
||||
);
|
||||
}
|
||||
return scrollToBottomDefaultTapAction(unreadCount);
|
||||
},
|
||||
child: widget.reverse
|
||||
? StreamSvgIcon.down(
|
||||
@@ -1101,10 +1096,13 @@ class _StreamMessageListViewState extends State<StreamMessageListView> {
|
||||
final showThreadReplyIndicator = !_isThreadConversation && hasReplies;
|
||||
final isOnlyEmoji = message.text?.isOnlyEmoji ?? false;
|
||||
|
||||
final isEphemeral = message.isEphemeral;
|
||||
|
||||
final hasUrlAttachment =
|
||||
message.attachments.any((it) => it.ogScrapeUrl != null);
|
||||
|
||||
final borderSide = isOnlyEmoji || hasUrlAttachment ? BorderSide.none : null;
|
||||
final borderSide =
|
||||
isOnlyEmoji || hasUrlAttachment || isEphemeral ? BorderSide.none : null;
|
||||
|
||||
final currentUser = StreamChat.of(context).currentUser;
|
||||
final members = StreamChannel.of(context).channel.state?.members ?? [];
|
||||
|
||||
@@ -217,17 +217,9 @@ class StreamMessageWidget extends StatefulWidget {
|
||||
);
|
||||
},
|
||||
'giphy': (context, message, attachments) {
|
||||
final border = RoundedRectangleBorder(
|
||||
side: attachmentBorderSide ??
|
||||
BorderSide(
|
||||
color: StreamChatTheme.of(context).colorTheme.borders,
|
||||
),
|
||||
borderRadius: attachmentBorderRadiusGeometry ?? BorderRadius.zero,
|
||||
);
|
||||
|
||||
return WrapAttachmentWidget(
|
||||
attachmentWidget: Column(
|
||||
children: attachments.map((attachment) {
|
||||
final attachmentWidget = Column(
|
||||
children: [
|
||||
...attachments.map((attachment) {
|
||||
final mediaQueryData = MediaQuery.of(context);
|
||||
return StreamGiphyAttachment(
|
||||
attachment: attachment,
|
||||
@@ -240,14 +232,25 @@ class StreamMessageWidget extends StatefulWidget {
|
||||
onShowMessage: onShowMessage,
|
||||
onReplyMessage: onReplyTap,
|
||||
onAttachmentTap: onAttachmentTap != null
|
||||
? () {
|
||||
onAttachmentTap(message, attachment);
|
||||
}
|
||||
? () => onAttachmentTap(message, attachment)
|
||||
: null,
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
}),
|
||||
],
|
||||
);
|
||||
|
||||
// If the message is ephemeral, we don't want to show the border.
|
||||
if (message.isEphemeral) return attachmentWidget;
|
||||
|
||||
final color = StreamChatTheme.of(context).colorTheme.borders;
|
||||
final border = RoundedRectangleBorder(
|
||||
side: attachmentBorderSide ?? BorderSide(color: color),
|
||||
borderRadius: attachmentBorderRadiusGeometry ?? BorderRadius.zero,
|
||||
);
|
||||
|
||||
return WrapAttachmentWidget(
|
||||
attachmentShape: border,
|
||||
attachmentWidget: attachmentWidget,
|
||||
);
|
||||
},
|
||||
'file': (context, message, attachments) {
|
||||
|
||||
Reference in New Issue
Block a user