fix(ui): fix various message_list_view issues.
Signed-off-by: xsahil03x <[email protected]>
This commit is contained in:
@@ -59,6 +59,7 @@ class StreamGiphyAttachment extends StreamAttachmentWidget {
|
|||||||
color: StreamChatTheme.of(context).colorTheme.barsBg,
|
color: StreamChatTheme.of(context).colorTheme.barsBg,
|
||||||
elevation: 2,
|
elevation: 2,
|
||||||
clipBehavior: Clip.hardEdge,
|
clipBehavior: Clip.hardEdge,
|
||||||
|
margin: EdgeInsets.zero,
|
||||||
shape: const RoundedRectangleBorder(
|
shape: const RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.only(
|
borderRadius: BorderRadius.only(
|
||||||
topRight: Radius.circular(16),
|
topRight: Radius.circular(16),
|
||||||
@@ -241,10 +242,7 @@ class StreamGiphyAttachment extends StreamAttachmentWidget {
|
|||||||
const SizedBox(height: 4),
|
const SizedBox(height: 4),
|
||||||
const Align(
|
const Align(
|
||||||
alignment: Alignment.centerRight,
|
alignment: Alignment.centerRight,
|
||||||
child: Padding(
|
child: StreamVisibleFootnote(),
|
||||||
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
|
||||||
child: StreamVisibleFootnote(),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1372,10 +1372,10 @@ class StreamMessageInputState extends State<StreamMessageInput>
|
|||||||
}
|
}
|
||||||
|
|
||||||
final streamChannel = StreamChannel.of(context);
|
final streamChannel = StreamChannel.of(context);
|
||||||
|
final channel = streamChannel.channel;
|
||||||
var message = _effectiveController.value;
|
var message = _effectiveController.value;
|
||||||
|
|
||||||
if (!streamChannel.channel.ownCapabilities
|
if (!channel.ownCapabilities.contains(PermissionType.sendLinks) &&
|
||||||
.contains(PermissionType.sendLinks) &&
|
|
||||||
_urlRegex.allMatches(message.text ?? '').any((element) =>
|
_urlRegex.allMatches(message.text ?? '').any((element) =>
|
||||||
element.group(0)?.split('.').last.isValidTLD() == true)) {
|
element.group(0)?.split('.').last.isValidTLD() == true)) {
|
||||||
showInfoBottomSheet(
|
showInfoBottomSheet(
|
||||||
@@ -1401,8 +1401,8 @@ class StreamMessageInputState extends State<StreamMessageInput>
|
|||||||
final skipEnrichUrl = _effectiveController.ogAttachment == null;
|
final skipEnrichUrl = _effectiveController.ogAttachment == null;
|
||||||
|
|
||||||
var shouldKeepFocus = widget.shouldKeepFocusAfterMessage;
|
var shouldKeepFocus = widget.shouldKeepFocusAfterMessage;
|
||||||
|
|
||||||
shouldKeepFocus ??= !_commandEnabled;
|
shouldKeepFocus ??= !_commandEnabled;
|
||||||
|
|
||||||
widget.onQuotedMessageCleared?.call();
|
widget.onQuotedMessageCleared?.call();
|
||||||
|
|
||||||
_effectiveController.reset();
|
_effectiveController.reset();
|
||||||
@@ -1411,12 +1411,35 @@ class StreamMessageInputState extends State<StreamMessageInput>
|
|||||||
message = await widget.preMessageSending!(message);
|
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) {
|
if (!channel.state!.isUpToDate) {
|
||||||
await streamChannel.reloadChannel();
|
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 {
|
try {
|
||||||
Future sendingFuture;
|
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;
|
final resp = await sendingFuture;
|
||||||
if (resp.message?.type == 'error') {
|
if (resp.message?.type == 'error') {
|
||||||
_effectiveController.message = message;
|
_effectiveController.message = message;
|
||||||
|
|||||||
@@ -566,21 +566,30 @@ class _StreamMessageListViewState extends State<StreamMessageListView> {
|
|||||||
reverse: widget.reverse,
|
reverse: widget.reverse,
|
||||||
shrinkWrap: widget.shrinkWrap,
|
shrinkWrap: widget.shrinkWrap,
|
||||||
itemCount: itemCount,
|
itemCount: itemCount,
|
||||||
findChildIndexCallback: (Key key) {
|
|
||||||
final indexedKey = key as IndexedKey;
|
// Commented out as it is not working as expected.
|
||||||
final valueKey = indexedKey.key as ValueKey<String>?;
|
// The list view gets broken in the following case:
|
||||||
if (valueKey != null) {
|
// * The list view is loaded at a particular message (eg: Last Read, or a quoted message)
|
||||||
final index = messagesIndex[valueKey.value];
|
// and a new message is added to the list view.
|
||||||
if (index != null) {
|
//
|
||||||
// The calculation is as follows:
|
// Github faced: https://github.com/GetStream/stream-chat-flutter/issues/1576
|
||||||
// * Add 2 to the index retrieved to account for the footer and the bottom loader.
|
// Related issues: https://github.com/flutter/flutter/issues/107123
|
||||||
// * 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.
|
// findChildIndexCallback: (Key key) {
|
||||||
return ((index + 2) * 2) - 1;
|
// final indexedKey = key as IndexedKey;
|
||||||
}
|
// final valueKey = indexedKey.key as ValueKey<String>?;
|
||||||
}
|
// if (valueKey != null) {
|
||||||
return 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)
|
// 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)|
|
// eg: |Type| rev(|Index(item)|) rev(|Index(separator)|) |Index(item)| |Index(separator)|
|
||||||
@@ -899,7 +908,10 @@ class _StreamMessageListViewState extends State<StreamMessageListView> {
|
|||||||
final hasUrlAttachment =
|
final hasUrlAttachment =
|
||||||
message.attachments.any((it) => it.ogScrapeUrl != null);
|
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(
|
final defaultMessageWidget = StreamMessageWidget(
|
||||||
showReplyMessage: false,
|
showReplyMessage: false,
|
||||||
@@ -980,24 +992,7 @@ class _StreamMessageListViewState extends State<StreamMessageListView> {
|
|||||||
FloatingActionButton(
|
FloatingActionButton(
|
||||||
backgroundColor: _streamTheme.colorTheme.barsBg,
|
backgroundColor: _streamTheme.colorTheme.barsBg,
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
if (unreadCount > 0) {
|
return scrollToBottomDefaultTapAction(unreadCount);
|
||||||
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,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
child: widget.reverse
|
child: widget.reverse
|
||||||
? StreamSvgIcon.down(
|
? StreamSvgIcon.down(
|
||||||
@@ -1101,10 +1096,13 @@ class _StreamMessageListViewState extends State<StreamMessageListView> {
|
|||||||
final showThreadReplyIndicator = !_isThreadConversation && hasReplies;
|
final showThreadReplyIndicator = !_isThreadConversation && hasReplies;
|
||||||
final isOnlyEmoji = message.text?.isOnlyEmoji ?? false;
|
final isOnlyEmoji = message.text?.isOnlyEmoji ?? false;
|
||||||
|
|
||||||
|
final isEphemeral = message.isEphemeral;
|
||||||
|
|
||||||
final hasUrlAttachment =
|
final hasUrlAttachment =
|
||||||
message.attachments.any((it) => it.ogScrapeUrl != null);
|
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 currentUser = StreamChat.of(context).currentUser;
|
||||||
final members = StreamChannel.of(context).channel.state?.members ?? [];
|
final members = StreamChannel.of(context).channel.state?.members ?? [];
|
||||||
|
|||||||
@@ -217,17 +217,9 @@ class StreamMessageWidget extends StatefulWidget {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
'giphy': (context, message, attachments) {
|
'giphy': (context, message, attachments) {
|
||||||
final border = RoundedRectangleBorder(
|
final attachmentWidget = Column(
|
||||||
side: attachmentBorderSide ??
|
children: [
|
||||||
BorderSide(
|
...attachments.map((attachment) {
|
||||||
color: StreamChatTheme.of(context).colorTheme.borders,
|
|
||||||
),
|
|
||||||
borderRadius: attachmentBorderRadiusGeometry ?? BorderRadius.zero,
|
|
||||||
);
|
|
||||||
|
|
||||||
return WrapAttachmentWidget(
|
|
||||||
attachmentWidget: Column(
|
|
||||||
children: attachments.map((attachment) {
|
|
||||||
final mediaQueryData = MediaQuery.of(context);
|
final mediaQueryData = MediaQuery.of(context);
|
||||||
return StreamGiphyAttachment(
|
return StreamGiphyAttachment(
|
||||||
attachment: attachment,
|
attachment: attachment,
|
||||||
@@ -240,14 +232,25 @@ class StreamMessageWidget extends StatefulWidget {
|
|||||||
onShowMessage: onShowMessage,
|
onShowMessage: onShowMessage,
|
||||||
onReplyMessage: onReplyTap,
|
onReplyMessage: onReplyTap,
|
||||||
onAttachmentTap: onAttachmentTap != null
|
onAttachmentTap: onAttachmentTap != null
|
||||||
? () {
|
? () => onAttachmentTap(message, attachment)
|
||||||
onAttachmentTap(message, attachment);
|
|
||||||
}
|
|
||||||
: null,
|
: 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,
|
attachmentShape: border,
|
||||||
|
attachmentWidget: attachmentWidget,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
'file': (context, message, attachments) {
|
'file': (context, message, attachments) {
|
||||||
|
|||||||
Reference in New Issue
Block a user