Merge remote-tracking branch 'origin/develop' into v7.0.0
# Conflicts: # packages/stream_chat/CHANGELOG.md # packages/stream_chat/lib/version.dart # packages/stream_chat/pubspec.yaml # packages/stream_chat_flutter/CHANGELOG.md # packages/stream_chat_flutter/lib/src/channel/channel_preview.dart # packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart # packages/stream_chat_flutter/lib/src/user/user_item.dart # packages/stream_chat_flutter/pubspec.yaml # packages/stream_chat_flutter_core/CHANGELOG.md # packages/stream_chat_flutter_core/pubspec.yaml # packages/stream_chat_localizations/CHANGELOG.md # packages/stream_chat_localizations/pubspec.yaml # packages/stream_chat_persistence/CHANGELOG.md # packages/stream_chat_persistence/pubspec.yaml
This commit is contained in:
@@ -1,3 +1,38 @@
|
||||
## 6.9.0
|
||||
|
||||
🐞 Fixed
|
||||
|
||||
- [[#1702]](https://github.com/GetStream/stream-chat-flutter/issues/1702)
|
||||
Fixed `Message.replaceMentions` not treating `@usernames` as mentions.
|
||||
- [[#1694]](https://github.com/GetStream/stream-chat-flutter/issues/1694) Fixed Video player buttons
|
||||
getting covered by bottom toolbar.
|
||||
|
||||
✅ Added
|
||||
|
||||
- Added support for listening error events in AttachmentPickerBottomSheet.
|
||||
- Added support for overriding the `MessageWidget.onReactionTap` callback.
|
||||
- Added support for `StreamMessageInput.contentInsertionConfiguration` to specify the content insertion configuration.
|
||||
[#1613](https://github.com/GetStream/stream-chat-flutter/issues/1613)
|
||||
|
||||
```dart
|
||||
StreamMessageInput(
|
||||
...,
|
||||
contentInsertionConfiguration: ContentInsertionConfiguration(
|
||||
onContentInserted: (content) {
|
||||
// Do something with the content.
|
||||
controller.addAttachment(...);
|
||||
},
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
🔄 Changed
|
||||
|
||||
- Updated minimum supported `SDK` version to Flutter 3.10/Dart 3.0
|
||||
- Updated `stream_chat_flutter_core` dependency
|
||||
to [`6.8.0`](https://pub.dev/packages/stream_chat_flutter_core/changelog).
|
||||
- Updated jiffy dependency to ^6.2.1.
|
||||
|
||||
## 7.0.0-beta.3
|
||||
|
||||
- Included the changes from version [6.8.1](#681).
|
||||
@@ -85,43 +120,57 @@
|
||||
|
||||
🐞 Fixed
|
||||
|
||||
- [[#1620]](https://github.com/GetStream/stream-chat-flutter/issues/1620) Fixed messages Are Not Hard Deleting even
|
||||
- [[#1620]](https://github.com/GetStream/stream-chat-flutter/issues/1620) Fixed messages Are Not
|
||||
Hard Deleting even
|
||||
after overriding the `onConfirmDeleteTap` callback.
|
||||
- [[#1621]](https://github.com/GetStream/stream-chat-flutter/issues/1621) Fixed `createdAtStyle` null check error
|
||||
- [[#1621]](https://github.com/GetStream/stream-chat-flutter/issues/1621) Fixed `createdAtStyle`
|
||||
null check error
|
||||
in `SendingIndicatorBuilder`.
|
||||
- [[#1069]](https://github.com/GetStream/stream-chat-flutter/issues/1069) Fixed message swipe to reply using same
|
||||
direction for both current user and other users. It now uses `SwipeDirection.startToEnd` for current user
|
||||
- [[#1069]](https://github.com/GetStream/stream-chat-flutter/issues/1069) Fixed message swipe to
|
||||
reply using same
|
||||
direction for both current user and other users. It now uses `SwipeDirection.startToEnd` for
|
||||
current user
|
||||
and `SwipeDirection.endToStart` for other users.
|
||||
- [[#1590]](https://github.com/GetStream/stream-chat-flutter/issues/1590)
|
||||
Fixed `StreamMessageWidget.showReactionPickerIndicator` not toggling the reaction picker indicator visibility.
|
||||
- [[#1639]](https://github.com/GetStream/stream-chat-flutter/issues/1639) Fixed attachments not showing in gallery view
|
||||
Fixed `StreamMessageWidget.showReactionPickerIndicator` not toggling the reaction picker indicator
|
||||
visibility.
|
||||
- [[#1639]](https://github.com/GetStream/stream-chat-flutter/issues/1639) Fixed attachments not
|
||||
showing in gallery view
|
||||
even after saving them to the device.
|
||||
> **Note**
|
||||
> This fix depends on the [image_gallery_saver](https://pub.dev/packages/image_gallery_saver) plugin. Make sure to add
|
||||
> This fix depends on the [image_gallery_saver](https://pub.dev/packages/image_gallery_saver)
|
||||
plugin. Make sure to add
|
||||
necessary permissions in your App as per the plugin documentation.
|
||||
- [[#1642]](https://github.com/GetStream/stream-chat-flutter/issues/1642) Fixed `StreamMessageWidget.widthFactor` not
|
||||
- [[#1642]](https://github.com/GetStream/stream-chat-flutter/issues/1642)
|
||||
Fixed `StreamMessageWidget.widthFactor` not
|
||||
working on web and desktop platforms.
|
||||
|
||||
✅ Added
|
||||
|
||||
- Added support for customizing attachments in `StreamMessageInput`. Use various properties mentioned
|
||||
- Added support for customizing attachments in `StreamMessageInput`. Use various properties
|
||||
mentioned
|
||||
below. [#1511](https://github.com/GetStream/stream-chat-flutter/issues/1511)
|
||||
* `StreamMessageInput.attachmentListBuilder` to customize the attachment list.
|
||||
* `StreamMessageInput.fileAttachmentListBuilder` to customize the file attachment list.
|
||||
* `StreamMessageInput.mediaAttachmentListBuilder` to customize the media attachment list. Includes images, videos
|
||||
* `StreamMessageInput.mediaAttachmentListBuilder` to customize the media attachment list.
|
||||
Includes images, videos
|
||||
and gifs.
|
||||
* `StreamMessageInput.fileAttachmentBuilder` to customize the file attachment item shown in `FileAttachmentList`.
|
||||
* `StreamMessageInput.fileAttachmentBuilder` to customize the file attachment item shown
|
||||
in `FileAttachmentList`.
|
||||
* `StreamMessageInput.mediaAttachmentBuilder` to customize the media attachment item shown in
|
||||
`MediaAttachmentList`.
|
||||
|
||||
|
||||
- Added `StreamMessageInput.quotedMessageAttachmentThumbnailBuilders` to customize the thumbnail builders for quoted
|
||||
- Added `StreamMessageInput.quotedMessageAttachmentThumbnailBuilders` to customize the thumbnail
|
||||
builders for quoted
|
||||
message attachments.
|
||||
|
||||
🔄 Changed
|
||||
|
||||
- Deprecated `StreamMessageInput.attachmentThumbnailBuilders` in favor of `StreamMessageInput.mediaAttachmentBuilder`.
|
||||
- Deprecated `StreamMessageListView.onMessageSwiped`. Try wrapping the `MessageWidget` with a `Swipeable`, `Dismissible`
|
||||
- Deprecated `StreamMessageInput.attachmentThumbnailBuilders` in favor
|
||||
of `StreamMessageInput.mediaAttachmentBuilder`.
|
||||
- Deprecated `StreamMessageListView.onMessageSwiped`. Try wrapping the `MessageWidget` with
|
||||
a `Swipeable`, `Dismissible`
|
||||
or a custom widget to achieve the swipe to reply behaviour.
|
||||
|
||||
```dart
|
||||
@@ -169,7 +218,8 @@
|
||||
},
|
||||
)
|
||||
```
|
||||
- Deprecated `StreamMessageWidget.showReactionPickerIndicator` in favor of `StreamMessageWidget.showReactionPicker`.
|
||||
- Deprecated `StreamMessageWidget.showReactionPickerIndicator` in favor
|
||||
of `StreamMessageWidget.showReactionPicker`.
|
||||
|
||||
```diff
|
||||
StreamMessageWidget(
|
||||
@@ -186,16 +236,20 @@
|
||||
|
||||
🐞 Fixed
|
||||
|
||||
- [[#1600]](https://github.com/GetStream/stream-chat-flutter/issues/1600) Fixed type `ImageDecoderCallback` not found
|
||||
- [[#1600]](https://github.com/GetStream/stream-chat-flutter/issues/1600) Fixed
|
||||
type `ImageDecoderCallback` not found
|
||||
error on pre-Flutter 3.10.0 versions.
|
||||
- [[#1605]](https://github.com/GetStream/stream-chat-flutter/issues/1605) Fixed Null exception is thrown on message list
|
||||
- [[#1605]](https://github.com/GetStream/stream-chat-flutter/issues/1605) Fixed Null exception is
|
||||
thrown on message list
|
||||
for unread messages when `ScrollToBottomButton` is pressed.
|
||||
- [[#1615]](https://github.com/GetStream/stream-chat-flutter/issues/1615) Fixed `StreamAttachmentPickerBottomSheet` not
|
||||
- [[#1615]](https://github.com/GetStream/stream-chat-flutter/issues/1615)
|
||||
Fixed `StreamAttachmentPickerBottomSheet` not
|
||||
able to find the `StreamChatTheme` when used in nested MaterialApp.
|
||||
|
||||
✅ Added
|
||||
|
||||
- Added support for `StreamMessageInput.allowedAttachmentPickerTypes` to specify the allowed attachment picker types.
|
||||
- Added support for `StreamMessageInput.allowedAttachmentPickerTypes` to specify the allowed
|
||||
attachment picker types.
|
||||
[#1601](https://github.com/GetStream/stream-chat-flutter/issues/1376)
|
||||
|
||||
```dart
|
||||
@@ -208,7 +262,8 @@
|
||||
)
|
||||
```
|
||||
|
||||
- Added support for `StreamMessageWidget.onConfirmDeleteTap` to override the default action on delete confirmation.
|
||||
- Added support for `StreamMessageWidget.onConfirmDeleteTap` to override the default action on
|
||||
delete confirmation.
|
||||
[#1604](https://github.com/GetStream/stream-chat-flutter/issues/1604)
|
||||
|
||||
```dart
|
||||
@@ -221,8 +276,10 @@
|
||||
)
|
||||
```
|
||||
|
||||
- Added support for `StreamMessageWidget.quotedMessageBuilder` and `StreamMessageInput.quotedMessageBuilder` to override
|
||||
the default quoted message widget. [#1547](https://github.com/GetStream/stream-chat-flutter/issues/1547)
|
||||
- Added support for `StreamMessageWidget.quotedMessageBuilder`
|
||||
and `StreamMessageInput.quotedMessageBuilder` to override
|
||||
the default quoted message
|
||||
widget. [#1547](https://github.com/GetStream/stream-chat-flutter/issues/1547)
|
||||
|
||||
```dart
|
||||
StreamMessageWidget(
|
||||
@@ -236,7 +293,8 @@
|
||||
)
|
||||
```
|
||||
|
||||
- Added support for `StreamChannelAvatar.ownSpaceAvatarBuilder`, `StreamChannelAvatar.oneToOneAvatarBuilder` and
|
||||
- Added support
|
||||
for `StreamChannelAvatar.ownSpaceAvatarBuilder`, `StreamChannelAvatar.oneToOneAvatarBuilder` and
|
||||
`StreamChannelAvatar.groupAvatarBuilder` to override the default avatar
|
||||
widget.[#1614](https://github.com/GetStream/stream-chat-flutter/issues/1614)
|
||||
|
||||
@@ -268,10 +326,13 @@
|
||||
|
||||
🐞 Fixed
|
||||
|
||||
- [[#1592]](https://github.com/GetStream/stream-chat-flutter/issues/1592) Fixed broken attachment download on web.
|
||||
- [[#1591]](https://github.com/GetStream/stream-chat-flutter/issues/1591) Fixed `StreamChannelInfoBottomSheet` not
|
||||
- [[#1592]](https://github.com/GetStream/stream-chat-flutter/issues/1592) Fixed broken attachment
|
||||
download on web.
|
||||
- [[#1591]](https://github.com/GetStream/stream-chat-flutter/issues/1591)
|
||||
Fixed `StreamChannelInfoBottomSheet` not
|
||||
rendering member list properly.
|
||||
- [[#1427]](https://github.com/GetStream/stream-chat-flutter/issues/1427) Fixed unable to load asset error for
|
||||
- [[#1427]](https://github.com/GetStream/stream-chat-flutter/issues/1427) Fixed unable to load asset
|
||||
error for
|
||||
`packages/stream_chat_flutter/lib/svgs/video_call_icon.svg`.
|
||||
|
||||
🔄 Changed
|
||||
@@ -284,30 +345,40 @@
|
||||
|
||||
- [[#1546]](https://github.com/GetStream/stream-chat-flutter/issues/1546)
|
||||
Fixed `StreamMessageInputTheme.linkHighlightColor` returning null for default theme.
|
||||
- [[#1548]](https://github.com/GetStream/stream-chat-flutter/issues/1548) Fixed `StreamMessageInput` urlRegex only
|
||||
- [[#1548]](https://github.com/GetStream/stream-chat-flutter/issues/1548) Fixed `StreamMessageInput`
|
||||
urlRegex only
|
||||
matching the lowercase `http(s)|ftp`.
|
||||
- [[#1542]](https://github.com/GetStream/stream-chat-flutter/issues/1542) Handle error thrown in `StreamMessageInput`
|
||||
- [[#1542]](https://github.com/GetStream/stream-chat-flutter/issues/1542) Handle error thrown
|
||||
in `StreamMessageInput`
|
||||
when unable to fetch a link preview.
|
||||
- [[#1540]](https://github.com/GetStream/stream-chat-flutter/issues/1540) Use `CircularProgressIndicator.adaptive`
|
||||
- [[#1540]](https://github.com/GetStream/stream-chat-flutter/issues/1540)
|
||||
Use `CircularProgressIndicator.adaptive`
|
||||
instead of material indicator.
|
||||
- [[#1490]](https://github.com/GetStream/stream-chat-flutter/issues/1490) Fixed `editMessageInputBuilder` property not
|
||||
- [[#1490]](https://github.com/GetStream/stream-chat-flutter/issues/1490)
|
||||
Fixed `editMessageInputBuilder` property not
|
||||
used in `MessageActionsModal.editMessage` option.
|
||||
- [[#1544]](https://github.com/GetStream/stream-chat-flutter/issues/1544) Fixed error thrown when unable to fetch
|
||||
- [[#1544]](https://github.com/GetStream/stream-chat-flutter/issues/1544) Fixed error thrown when
|
||||
unable to fetch
|
||||
image/data in Message link preview.
|
||||
- [[#1482]](https://github.com/GetStream/stream-chat-flutter/issues/1482) Fixed `StreaChannelListTile` not showing
|
||||
- [[#1482]](https://github.com/GetStream/stream-chat-flutter/issues/1482)
|
||||
Fixed `StreaChannelListTile` not showing
|
||||
unread indicator when `currentUser` is not present in the initial member list.
|
||||
- [[#1487]](https://github.com/GetStream/stream-chat-flutter/issues/1487) Use localized title
|
||||
for `WebOrDesktopAttachmentPickerOption` in `StreamMessageInput`.
|
||||
- [[#1250]](https://github.com/GetStream/stream-chat-flutter/issues/1250) Fixed bottomRow widgetSpans getting resized
|
||||
- [[#1250]](https://github.com/GetStream/stream-chat-flutter/issues/1250) Fixed bottomRow
|
||||
widgetSpans getting resized
|
||||
twice when `textScaling` is enabled.
|
||||
- [[#1498]](https://github.com/GetStream/stream-chat-flutter/issues/1498) Fixed `MessageInput` autocomplete not working
|
||||
- [[#1498]](https://github.com/GetStream/stream-chat-flutter/issues/1498) Fixed `MessageInput`
|
||||
autocomplete not working
|
||||
on non-mobile platforms.
|
||||
- [[#1576]](https://github.com/GetStream/stream-chat-flutter/issues/1576) Temporary fix for `StreamMessageListView`
|
||||
- [[#1576]](https://github.com/GetStream/stream-chat-flutter/issues/1576) Temporary fix
|
||||
for `StreamMessageListView`
|
||||
getting broken when loaded at a particular message and a new message is added.
|
||||
|
||||
✅ Added
|
||||
|
||||
- Added support for `StreamMessageThemeData.urlAttachmentTextMaxLine` to specify the `.maxLines` for the url attachment
|
||||
- Added support for `StreamMessageThemeData.urlAttachmentTextMaxLine` to specify the `.maxLines` for
|
||||
the url attachment
|
||||
text. [#1543](https://github.com/GetStream/stream-chat-flutter/issues/1543)
|
||||
|
||||
🔄 Changed
|
||||
@@ -322,24 +393,33 @@
|
||||
|
||||
🐞 Fixed
|
||||
|
||||
- [[#1502]](https://github.com/GetStream/stream-chat-flutter/issues/1502) Fixed `isOnlyEmoji` method Detects Single
|
||||
- [[#1502]](https://github.com/GetStream/stream-chat-flutter/issues/1502) Fixed `isOnlyEmoji` method
|
||||
Detects Single
|
||||
Hangul
|
||||
Consonants as Emoji.
|
||||
- [[#1505]](https://github.com/GetStream/stream-chat-flutter/issues/1505) Fixed Message bubble disappears for Hangul
|
||||
- [[#1505]](https://github.com/GetStream/stream-chat-flutter/issues/1505) Fixed Message bubble
|
||||
disappears for Hangul
|
||||
Consonants.
|
||||
- [[#1476]](https://github.com/GetStream/stream-chat-flutter/issues/1476) Fixed `UserAvatarTransform.userAvatarBuilder`
|
||||
- [[#1476]](https://github.com/GetStream/stream-chat-flutter/issues/1476)
|
||||
Fixed `UserAvatarTransform.userAvatarBuilder`
|
||||
works only for otherUser.
|
||||
- [[#1490]](https://github.com/GetStream/stream-chat-flutter/issues/1490) Fixed `editMessageInputBuilder` property not
|
||||
- [[#1490]](https://github.com/GetStream/stream-chat-flutter/issues/1490)
|
||||
Fixed `editMessageInputBuilder` property not
|
||||
used in message edit widget.
|
||||
- [[#1523]](https://github.com/GetStream/stream-chat-flutter/issues/1523) Fixed `StreamMessageThemeData` not being
|
||||
- [[#1523]](https://github.com/GetStream/stream-chat-flutter/issues/1523)
|
||||
Fixed `StreamMessageThemeData` not being
|
||||
applied correctly.
|
||||
- [[#1525]](https://github.com/GetStream/stream-chat-flutter/issues/1525) Fixed `StreamQuotedMessageWidget` message for
|
||||
- [[#1525]](https://github.com/GetStream/stream-chat-flutter/issues/1525)
|
||||
Fixed `StreamQuotedMessageWidget` message for
|
||||
deleted messages not being shown correctly.
|
||||
- [[#1529]](https://github.com/GetStream/stream-chat-flutter/issues/1529) Fixed `ClipboardData` requires non-nullable
|
||||
- [[#1529]](https://github.com/GetStream/stream-chat-flutter/issues/1529) Fixed `ClipboardData`
|
||||
requires non-nullable
|
||||
string as text on Flutter 3.10.
|
||||
- [[#1533]](https://github.com/GetStream/stream-chat-flutter/issues/1533) Fixed `StreamMessageListView` messages grouped
|
||||
- [[#1533]](https://github.com/GetStream/stream-chat-flutter/issues/1533)
|
||||
Fixed `StreamMessageListView` messages grouped
|
||||
incorrectly w.r.t. timestamp.
|
||||
- [[#1532]](https://github.com/GetStream/stream-chat-flutter/issues/1532) Fixed `StreamMessageWidget` actions dialog
|
||||
- [[#1532]](https://github.com/GetStream/stream-chat-flutter/issues/1532)
|
||||
Fixed `StreamMessageWidget` actions dialog
|
||||
backdrop filter is cut off by safe area.
|
||||
|
||||
✅ Added
|
||||
@@ -387,7 +467,8 @@
|
||||
🔄 Changed
|
||||
|
||||
- Updated `dart` sdk environment range to support `3.0.0`.
|
||||
- Deprecated `MessageTheme.linkBackgroundColor` in favor of `MessageTheme.urlAttachmentBackgroundColor`.
|
||||
- Deprecated `MessageTheme.linkBackgroundColor` in favor
|
||||
of `MessageTheme.urlAttachmentBackgroundColor`.
|
||||
- Updated `stream_chat_flutter_core` dependency
|
||||
to [`6.1.0`](https://pub.dev/packages/stream_chat_flutter_core/changelog).
|
||||
|
||||
@@ -395,18 +476,23 @@
|
||||
|
||||
🐞 Fixed
|
||||
|
||||
- [[#1456]](https://github.com/GetStream/stream-chat-flutter/issues/1456) Fixed logic for showing that a message was
|
||||
- [[#1456]](https://github.com/GetStream/stream-chat-flutter/issues/1456) Fixed logic for showing
|
||||
that a message was
|
||||
read using sending indicator.
|
||||
- [[#1462]](https://github.com/GetStream/stream-chat-flutter/issues/1462) Fixed support for iPad in the share button for
|
||||
- [[#1462]](https://github.com/GetStream/stream-chat-flutter/issues/1462) Fixed support for iPad in
|
||||
the share button for
|
||||
images.
|
||||
- [[#1475]](https://github.com/GetStream/stream-chat-flutter/issues/1475) Fixed typo to fix compilation.
|
||||
- [[#1475]](https://github.com/GetStream/stream-chat-flutter/issues/1475) Fixed typo to fix
|
||||
compilation.
|
||||
|
||||
✅ Added
|
||||
|
||||
- Now it is possible to customize the max lines of the title of a url attachment. Before it was always 1 line.
|
||||
- Now it is possible to customize the max lines of the title of a url attachment. Before it was
|
||||
always 1 line.
|
||||
- Added `attachmentActionsModalBuilder` parameter to `StreamMessageWidget` that allows to
|
||||
customize `AttachmentActionsModal`.
|
||||
- Added `StreamMessageInput.sendMessageKeyPredicate` and `StreamMessageInput.clearQuotedMessageKeyPredicate` to
|
||||
- Added `StreamMessageInput.sendMessageKeyPredicate`
|
||||
and `StreamMessageInput.clearQuotedMessageKeyPredicate` to
|
||||
customize the keys used to send and clear the quoted message.
|
||||
|
||||
🔄 Changed
|
||||
@@ -415,7 +501,8 @@
|
||||
|
||||
🚀 Improved
|
||||
|
||||
- Improved draw of reaction options. [#1455](https://github.com/GetStream/stream-chat-flutter/pull/1455)
|
||||
- Improved draw of reaction
|
||||
options. [#1455](https://github.com/GetStream/stream-chat-flutter/pull/1455)
|
||||
|
||||
## 5.3.0
|
||||
|
||||
@@ -425,7 +512,8 @@
|
||||
|
||||
🐞 Fixed
|
||||
|
||||
- [[#1424]](https://github.com/GetStream/stream-chat-flutter/issues/1424) Fixed a render issue when showing messages
|
||||
- [[#1424]](https://github.com/GetStream/stream-chat-flutter/issues/1424) Fixed a render issue when
|
||||
showing messages
|
||||
starting with 4 whitespaces.
|
||||
- Fixed a bug where the `AttachmentPickerBottomSheet` was not able to identify the mobile browser.
|
||||
- Fixed uploading files on Windows - fixed temp file path.
|
||||
@@ -438,7 +526,8 @@
|
||||
|
||||
✅ Added
|
||||
|
||||
- Added a new `bottomRowBuilderWithDefaultWidget` parameter to `StreamMessageWidget` which contains a third parameter (
|
||||
- Added a new `bottomRowBuilderWithDefaultWidget` parameter to `StreamMessageWidget` which contains
|
||||
a third parameter (
|
||||
default `BottomRow` widget with `copyWith` method available) to allow easier customization.
|
||||
|
||||
🔄 Changed
|
||||
@@ -448,18 +537,23 @@
|
||||
- Updated `connectivity_plus` dependency to `^3.0.2`
|
||||
- Updated `dart_vlc` dependency to `^0.4.0`
|
||||
- Updated `file_picker` dependency to `^5.2.4`
|
||||
- Deprecated `StreamMessageWidget.bottomRowBuilder` in favor of `StreamMessageWidget.bottomRowBuilderWithDefaultWidget`.
|
||||
- Deprecated `StreamMessageWidget.bottomRowBuilder` in favor
|
||||
of `StreamMessageWidget.bottomRowBuilderWithDefaultWidget`.
|
||||
- Deprecated `StreamMessageWidget.deletedBottomRowBuilder` in favor
|
||||
of `StreamMessageWidget.bottomRowBuilderWithDefaultWidget`.
|
||||
- Deprecated `StreamMessageWidget.usernameBuilder` in favor of `StreamMessageWidget.bottomRowBuilderWithDefaultWidget`.
|
||||
- Deprecated `StreamMessageWidget.usernameBuilder` in favor
|
||||
of `StreamMessageWidget.bottomRowBuilderWithDefaultWidget`.
|
||||
|
||||
🐞 Fixed
|
||||
|
||||
- [[#1379]](https://github.com/GetStream/stream-chat-flutter/issues/1379) Fixed "Issues with photo attachments on web",
|
||||
- [[#1379]](https://github.com/GetStream/stream-chat-flutter/issues/1379) Fixed "Issues with photo
|
||||
attachments on web",
|
||||
where the cached image attachment would not render while uploading.
|
||||
- Fix render overflow issue with `MessageSearchListTileTitle`. It now uses `Text.rich` instead of `Row`. Better default
|
||||
- Fix render overflow issue with `MessageSearchListTileTitle`. It now uses `Text.rich` instead
|
||||
of `Row`. Better default
|
||||
behaviour and allows `TextOverflow`.
|
||||
- [[1346]](https://github.com/GetStream/stream-chat-flutter/issues/1346) Fixed a render issue while uploading video on
|
||||
- [[1346]](https://github.com/GetStream/stream-chat-flutter/issues/1346) Fixed a render issue while
|
||||
uploading video on
|
||||
web.
|
||||
- [[#1347]](https://github.com/GetStream/stream-chat-flutter/issues/1347) `onReply` not working
|
||||
in `AttachmentActionsModal` which is used by `StreamImageAttachment` and `StreamImageGroup`.
|
||||
@@ -502,7 +596,8 @@
|
||||
* `textInputAction`
|
||||
* `keyboardType`
|
||||
* `textCapitalization`
|
||||
- Added `showStreamAttachmentPickerModalBottomSheet` to show the attachment picker modal bottom sheet.
|
||||
- Added `showStreamAttachmentPickerModalBottomSheet` to show the attachment picker modal bottom
|
||||
sheet.
|
||||
|
||||
🔄 Changed
|
||||
|
||||
|
||||
@@ -66,7 +66,8 @@ class StreamGroupAvatar extends StatelessWidget {
|
||||
Widget avatar = GestureDetector(
|
||||
onTap: onTap,
|
||||
child: ClipRRect(
|
||||
borderRadius: borderRadius ?? previewTheme?.borderRadius,
|
||||
borderRadius:
|
||||
borderRadius ?? previewTheme?.borderRadius ?? BorderRadius.zero,
|
||||
child: Container(
|
||||
constraints: constraints ?? previewTheme?.constraints,
|
||||
decoration: BoxDecoration(color: colorTheme.accentPrimary),
|
||||
|
||||
@@ -86,7 +86,8 @@ class StreamUserAvatar extends StatelessWidget {
|
||||
|
||||
final backupGradientAvatar = ClipRRect(
|
||||
borderRadius: borderRadius ??
|
||||
streamChatTheme.ownMessageTheme.avatarTheme?.borderRadius,
|
||||
streamChatTheme.ownMessageTheme.avatarTheme?.borderRadius ??
|
||||
BorderRadius.zero,
|
||||
child: streamChatConfig.defaultUserImage(context, user),
|
||||
);
|
||||
|
||||
|
||||
@@ -111,7 +111,8 @@ class StreamChannelAvatar extends StatelessWidget {
|
||||
initialData: channel.image,
|
||||
builder: (context, channelImage) {
|
||||
Widget child = ClipRRect(
|
||||
borderRadius: borderRadius ?? previewTheme?.borderRadius,
|
||||
borderRadius:
|
||||
borderRadius ?? previewTheme?.borderRadius ?? BorderRadius.zero,
|
||||
child: Container(
|
||||
constraints: constraints ?? previewTheme?.constraints,
|
||||
decoration: BoxDecoration(color: colorTheme.accentPrimary),
|
||||
|
||||
@@ -3,13 +3,11 @@ import 'dart:io';
|
||||
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:chewie/chewie.dart';
|
||||
import 'package:contextmenu/contextmenu.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:photo_view/photo_view.dart';
|
||||
import 'package:shimmer/shimmer.dart';
|
||||
import 'package:stream_chat_flutter/platform_widget_builder/platform_widget_builder.dart';
|
||||
import 'package:stream_chat_flutter/src/context_menu_items/download_menu_item.dart';
|
||||
import 'package:stream_chat_flutter/src/fullscreen_media/full_screen_media_widget.dart';
|
||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||
import 'package:video_player/video_player.dart';
|
||||
@@ -281,84 +279,83 @@ class _FullScreenMediaState extends State<StreamFullScreenMedia> {
|
||||
final currentAttachmentPackage =
|
||||
widget.mediaAttachmentPackages[index];
|
||||
final attachment = currentAttachmentPackage.attachment;
|
||||
if (attachment.type == 'image' || attachment.type == 'giphy') {
|
||||
final imageUrl = attachment.imageUrl ??
|
||||
attachment.assetUrl ??
|
||||
attachment.thumbUrl;
|
||||
return ValueListenableBuilder<bool>(
|
||||
valueListenable: _isDisplayingDetail,
|
||||
builder: (context, isDisplayingDetail, _) =>
|
||||
AnimatedContainer(
|
||||
return ValueListenableBuilder(
|
||||
valueListenable: _isDisplayingDetail,
|
||||
builder: (context, isDisplayingDetail, child) {
|
||||
return AnimatedContainer(
|
||||
duration: kThemeChangeDuration,
|
||||
color: isDisplayingDetail
|
||||
? StreamChannelHeaderTheme.of(context).color
|
||||
: Colors.black,
|
||||
duration: kThemeAnimationDuration,
|
||||
child: ContextMenuArea(
|
||||
verticalPadding: 0,
|
||||
builder: (_) => [
|
||||
DownloadMenuItem(
|
||||
attachment: attachment,
|
||||
),
|
||||
],
|
||||
child: PhotoView(
|
||||
imageProvider: (imageUrl == null &&
|
||||
attachment.localUri != null &&
|
||||
attachment.file?.bytes != null)
|
||||
? Image.memory(attachment.file!.bytes!).image
|
||||
: CachedNetworkImageProvider(imageUrl!),
|
||||
errorBuilder: (_, __, ___) => const AttachmentError(),
|
||||
loadingBuilder: (context, _) {
|
||||
final image = Image.asset(
|
||||
'images/placeholder.png',
|
||||
fit: BoxFit.cover,
|
||||
package: 'stream_chat_flutter',
|
||||
child: Builder(
|
||||
builder: (context) {
|
||||
if (attachment.type == 'image' ||
|
||||
attachment.type == 'giphy') {
|
||||
final imageUrl = attachment.imageUrl ??
|
||||
attachment.assetUrl ??
|
||||
attachment.thumbUrl;
|
||||
|
||||
return PhotoView(
|
||||
imageProvider: (imageUrl == null &&
|
||||
attachment.localUri != null &&
|
||||
attachment.file?.bytes != null)
|
||||
? Image.memory(attachment.file!.bytes!).image
|
||||
: CachedNetworkImageProvider(imageUrl!),
|
||||
errorBuilder: (_, __, ___) =>
|
||||
const AttachmentError(),
|
||||
loadingBuilder: (context, _) {
|
||||
final image = Image.asset(
|
||||
'images/placeholder.png',
|
||||
fit: BoxFit.cover,
|
||||
package: 'stream_chat_flutter',
|
||||
);
|
||||
final colorTheme =
|
||||
StreamChatTheme.of(context).colorTheme;
|
||||
return Shimmer.fromColors(
|
||||
baseColor: colorTheme.disabled,
|
||||
highlightColor: colorTheme.inputBg,
|
||||
child: image,
|
||||
);
|
||||
},
|
||||
maxScale: PhotoViewComputedScale.covered,
|
||||
minScale: PhotoViewComputedScale.contained,
|
||||
heroAttributes: PhotoViewHeroAttributes(
|
||||
tag: widget.mediaAttachmentPackages,
|
||||
),
|
||||
backgroundDecoration: const BoxDecoration(
|
||||
color: Colors.transparent,
|
||||
),
|
||||
);
|
||||
final colorTheme =
|
||||
StreamChatTheme.of(context).colorTheme;
|
||||
return Shimmer.fromColors(
|
||||
baseColor: colorTheme.disabled,
|
||||
highlightColor: colorTheme.inputBg,
|
||||
child: image,
|
||||
} else if (attachment.type == 'video') {
|
||||
final controller = videoPackages[attachment.id]!;
|
||||
if (!controller.initialized) {
|
||||
return const Center(
|
||||
child: CircularProgressIndicator.adaptive(),
|
||||
);
|
||||
}
|
||||
|
||||
final mediaQuery = MediaQuery.of(context);
|
||||
final bottomPadding = mediaQuery.padding.bottom;
|
||||
|
||||
return AnimatedPadding(
|
||||
duration: kThemeChangeDuration,
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: isDisplayingDetail
|
||||
? kToolbarHeight + bottomPadding
|
||||
: 0,
|
||||
),
|
||||
child: Chewie(
|
||||
controller: controller.chewieController!,
|
||||
),
|
||||
);
|
||||
},
|
||||
maxScale: PhotoViewComputedScale.covered,
|
||||
minScale: PhotoViewComputedScale.contained,
|
||||
heroAttributes: PhotoViewHeroAttributes(
|
||||
tag: widget.mediaAttachmentPackages,
|
||||
),
|
||||
backgroundDecoration: const BoxDecoration(
|
||||
color: Colors.transparent,
|
||||
),
|
||||
),
|
||||
}
|
||||
|
||||
return const SizedBox();
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
} else if (attachment.type == 'video') {
|
||||
final controller = videoPackages[attachment.id]!;
|
||||
if (!controller.initialized) {
|
||||
return const Center(
|
||||
child: CircularProgressIndicator.adaptive(),
|
||||
);
|
||||
}
|
||||
return InkWell(
|
||||
onTap: switchDisplayingDetail,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 50),
|
||||
child: ContextMenuArea(
|
||||
verticalPadding: 0,
|
||||
builder: (_) => [
|
||||
DownloadMenuItem(
|
||||
attachment: attachment,
|
||||
),
|
||||
],
|
||||
child: Chewie(
|
||||
controller: controller.chewieController!,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
return const SizedBox();
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
@@ -475,6 +472,7 @@ class VideoPackage {
|
||||
videoPlayerController: _videoPlayerController,
|
||||
autoInitialize: _autoInitialize,
|
||||
showControls: _showControls,
|
||||
showOptions: false,
|
||||
aspectRatio: _videoPlayerController.value.aspectRatio,
|
||||
);
|
||||
});
|
||||
|
||||
+84
-77
@@ -307,88 +307,95 @@ class _FullScreenMediaDesktopState extends State<FullScreenMediaDesktop> {
|
||||
final currentAttachmentPackage =
|
||||
widget.mediaAttachmentPackages[index];
|
||||
final attachment = currentAttachmentPackage.attachment;
|
||||
if (attachment.type == 'image' || attachment.type == 'giphy') {
|
||||
final imageUrl = attachment.imageUrl ??
|
||||
attachment.assetUrl ??
|
||||
attachment.thumbUrl;
|
||||
return ValueListenableBuilder<bool>(
|
||||
valueListenable: _isDisplayingDetail,
|
||||
builder: (context, isDisplayingDetail, _) =>
|
||||
AnimatedContainer(
|
||||
|
||||
return ValueListenableBuilder(
|
||||
valueListenable: _isDisplayingDetail,
|
||||
builder: (context, isDisplayingDetail, child) {
|
||||
return AnimatedContainer(
|
||||
duration: kThemeChangeDuration,
|
||||
color: isDisplayingDetail
|
||||
? StreamChannelHeaderTheme.of(context).color
|
||||
: Colors.black,
|
||||
duration: kThemeAnimationDuration,
|
||||
child: ContextMenuArea(
|
||||
verticalPadding: 0,
|
||||
builder: (_) => [
|
||||
DownloadMenuItem(
|
||||
attachment: attachment,
|
||||
),
|
||||
],
|
||||
child: PhotoView(
|
||||
imageProvider: (imageUrl == null &&
|
||||
attachment.localUri != null &&
|
||||
attachment.file?.bytes != null)
|
||||
? Image.memory(attachment.file!.bytes!).image
|
||||
: CachedNetworkImageProvider(imageUrl!),
|
||||
errorBuilder: (_, __, ___) => const AttachmentError(),
|
||||
loadingBuilder: (context, _) {
|
||||
final image = Image.asset(
|
||||
'images/placeholder.png',
|
||||
fit: BoxFit.cover,
|
||||
package: 'stream_chat_flutter',
|
||||
);
|
||||
final colorTheme =
|
||||
StreamChatTheme.of(context).colorTheme;
|
||||
return Shimmer.fromColors(
|
||||
baseColor: colorTheme.disabled,
|
||||
highlightColor: colorTheme.inputBg,
|
||||
child: image,
|
||||
);
|
||||
},
|
||||
maxScale: PhotoViewComputedScale.covered,
|
||||
minScale: PhotoViewComputedScale.contained,
|
||||
heroAttributes: PhotoViewHeroAttributes(
|
||||
tag: widget.mediaAttachmentPackages,
|
||||
),
|
||||
backgroundDecoration: const BoxDecoration(
|
||||
color: Colors.transparent,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else if (attachment.type == 'video') {
|
||||
final package = videoPackages[attachment.id]!;
|
||||
package.player.open(
|
||||
Playlist(
|
||||
medias: [
|
||||
Media.network(package.attachment.assetUrl),
|
||||
],
|
||||
),
|
||||
autoStart: widget.autoplayVideos,
|
||||
);
|
||||
child: Builder(
|
||||
builder: (context) {
|
||||
if (attachment.type == 'image' ||
|
||||
attachment.type == 'giphy') {
|
||||
final imageUrl = attachment.imageUrl ??
|
||||
attachment.assetUrl ??
|
||||
attachment.thumbUrl;
|
||||
|
||||
return InkWell(
|
||||
onTap: switchDisplayingDetail,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 50),
|
||||
child: ContextMenuArea(
|
||||
verticalPadding: 0,
|
||||
builder: (_) => [
|
||||
DownloadMenuItem(
|
||||
attachment: attachment,
|
||||
),
|
||||
],
|
||||
child: Video(
|
||||
player: package.player,
|
||||
),
|
||||
return PhotoView(
|
||||
imageProvider: (imageUrl == null &&
|
||||
attachment.localUri != null &&
|
||||
attachment.file?.bytes != null)
|
||||
? Image.memory(attachment.file!.bytes!).image
|
||||
: CachedNetworkImageProvider(imageUrl!),
|
||||
errorBuilder: (_, __, ___) =>
|
||||
const AttachmentError(),
|
||||
loadingBuilder: (context, _) {
|
||||
final image = Image.asset(
|
||||
'images/placeholder.png',
|
||||
fit: BoxFit.cover,
|
||||
package: 'stream_chat_flutter',
|
||||
);
|
||||
final colorTheme =
|
||||
StreamChatTheme.of(context).colorTheme;
|
||||
return Shimmer.fromColors(
|
||||
baseColor: colorTheme.disabled,
|
||||
highlightColor: colorTheme.inputBg,
|
||||
child: image,
|
||||
);
|
||||
},
|
||||
maxScale: PhotoViewComputedScale.covered,
|
||||
minScale: PhotoViewComputedScale.contained,
|
||||
heroAttributes: PhotoViewHeroAttributes(
|
||||
tag: widget.mediaAttachmentPackages,
|
||||
),
|
||||
backgroundDecoration: const BoxDecoration(
|
||||
color: Colors.transparent,
|
||||
),
|
||||
);
|
||||
} else if (attachment.type == 'video') {
|
||||
final package = videoPackages[attachment.id]!;
|
||||
package.player.open(
|
||||
Playlist(
|
||||
medias: [
|
||||
Media.network(package.attachment.assetUrl),
|
||||
],
|
||||
),
|
||||
autoStart: widget.autoplayVideos,
|
||||
);
|
||||
|
||||
final mediaQuery = MediaQuery.of(context);
|
||||
final bottomPadding = mediaQuery.padding.bottom;
|
||||
|
||||
return AnimatedPadding(
|
||||
duration: kThemeChangeDuration,
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: isDisplayingDetail
|
||||
? kToolbarHeight + bottomPadding
|
||||
: 0,
|
||||
),
|
||||
child: ContextMenuArea(
|
||||
verticalPadding: 0,
|
||||
builder: (_) => [
|
||||
DownloadMenuItem(
|
||||
attachment: attachment,
|
||||
),
|
||||
],
|
||||
child: Video(
|
||||
player: package.player,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return const SizedBox();
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
return const SizedBox();
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
+52
-17
@@ -698,6 +698,7 @@ Widget mobileAttachmentPickerBuilder({
|
||||
ThumbnailFormat attachmentThumbnailFormat = ThumbnailFormat.jpeg,
|
||||
int attachmentThumbnailQuality = 100,
|
||||
double attachmentThumbnailScale = 1,
|
||||
ErrorListener? onError,
|
||||
}) {
|
||||
return StreamMobileAttachmentPickerBottomSheet(
|
||||
controller: controller,
|
||||
@@ -721,10 +722,15 @@ Widget mobileAttachmentPickerBuilder({
|
||||
mediaThumbnailQuality: attachmentThumbnailQuality,
|
||||
mediaThumbnailScale: attachmentThumbnailScale,
|
||||
onMediaItemSelected: (media) async {
|
||||
if (selectedIds.contains(media.id)) {
|
||||
return controller.removeAssetAttachment(media);
|
||||
try {
|
||||
if (selectedIds.contains(media.id)) {
|
||||
return await controller.removeAssetAttachment(media);
|
||||
}
|
||||
return await controller.addAssetAttachment(media);
|
||||
} catch (e, stk) {
|
||||
if (onError != null) return onError.call(e, stk);
|
||||
rethrow;
|
||||
}
|
||||
return controller.addAssetAttachment(media);
|
||||
},
|
||||
);
|
||||
},
|
||||
@@ -736,8 +742,15 @@ Widget mobileAttachmentPickerBuilder({
|
||||
optionViewBuilder: (context, controller) {
|
||||
return StreamFilePicker(
|
||||
onFilePicked: (file) async {
|
||||
if (file != null) await controller.addAttachment(file);
|
||||
return Navigator.pop(context, controller.value);
|
||||
try {
|
||||
if (file != null) await controller.addAttachment(file);
|
||||
return Navigator.pop(context, controller.value);
|
||||
} catch (e, stk) {
|
||||
Navigator.pop(context, controller.value);
|
||||
if (onError != null) return onError.call(e, stk);
|
||||
|
||||
rethrow;
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
@@ -749,10 +762,17 @@ Widget mobileAttachmentPickerBuilder({
|
||||
optionViewBuilder: (context, controller) {
|
||||
return StreamImagePicker(
|
||||
onImagePicked: (image) async {
|
||||
if (image != null) {
|
||||
await controller.addAttachment(image);
|
||||
try {
|
||||
if (image != null) {
|
||||
await controller.addAttachment(image);
|
||||
}
|
||||
return Navigator.pop(context, controller.value);
|
||||
} catch (e, stk) {
|
||||
Navigator.pop(context, controller.value);
|
||||
if (onError != null) return onError.call(e, stk);
|
||||
|
||||
rethrow;
|
||||
}
|
||||
return Navigator.pop(context, controller.value);
|
||||
},
|
||||
);
|
||||
},
|
||||
@@ -764,10 +784,17 @@ Widget mobileAttachmentPickerBuilder({
|
||||
optionViewBuilder: (context, controller) {
|
||||
return StreamVideoPicker(
|
||||
onVideoPicked: (video) async {
|
||||
if (video != null) {
|
||||
await controller.addAttachment(video);
|
||||
try {
|
||||
if (video != null) {
|
||||
await controller.addAttachment(video);
|
||||
}
|
||||
return Navigator.pop(context, controller.value);
|
||||
} catch (e, stk) {
|
||||
Navigator.pop(context, controller.value);
|
||||
if (onError != null) return onError.call(e, stk);
|
||||
|
||||
rethrow;
|
||||
}
|
||||
return Navigator.pop(context, controller.value);
|
||||
},
|
||||
);
|
||||
},
|
||||
@@ -787,6 +814,7 @@ Widget webOrDesktopAttachmentPickerBuilder({
|
||||
ThumbnailFormat attachmentThumbnailFormat = ThumbnailFormat.jpeg,
|
||||
int attachmentThumbnailQuality = 100,
|
||||
double attachmentThumbnailScale = 1,
|
||||
ErrorListener? onError,
|
||||
}) {
|
||||
return StreamWebOrDesktopAttachmentPickerBottomSheet(
|
||||
controller: controller,
|
||||
@@ -814,13 +842,20 @@ Widget webOrDesktopAttachmentPickerBuilder({
|
||||
}.where((option) => option.supportedTypes.every(allowedTypes.contains)),
|
||||
},
|
||||
onOptionTap: (context, controller, option) async {
|
||||
final attachment = await StreamAttachmentHandler.instance.pickFile(
|
||||
type: option.type.fileType,
|
||||
);
|
||||
if (attachment != null) {
|
||||
await controller.addAttachment(attachment);
|
||||
try {
|
||||
final attachment = await StreamAttachmentHandler.instance.pickFile(
|
||||
type: option.type.fileType,
|
||||
);
|
||||
if (attachment != null) {
|
||||
await controller.addAttachment(attachment);
|
||||
}
|
||||
return Navigator.pop(context, controller.value);
|
||||
} catch (e, stk) {
|
||||
Navigator.pop(context, controller.value);
|
||||
if (onError != null) return onError.call(e, stk);
|
||||
|
||||
rethrow;
|
||||
}
|
||||
return Navigator.pop(context, controller.value);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
+3
@@ -69,6 +69,7 @@ Future<T?> showStreamAttachmentPickerModalBottomSheet<T>({
|
||||
List<AttachmentPickerType> allowedTypes = AttachmentPickerType.values,
|
||||
List<Attachment>? initialAttachments,
|
||||
StreamAttachmentPickerController? controller,
|
||||
ErrorListener? onError,
|
||||
Color? backgroundColor,
|
||||
double? elevation,
|
||||
BoxConstraints? constraints,
|
||||
@@ -117,6 +118,7 @@ Future<T?> showStreamAttachmentPickerModalBottomSheet<T>({
|
||||
if (isWebOrDesktop) {
|
||||
return webOrDesktopAttachmentPickerBuilder.call(
|
||||
context: context,
|
||||
onError: onError,
|
||||
controller: controller,
|
||||
allowedTypes: allowedTypes,
|
||||
customOptions: customOptions?.map(
|
||||
@@ -131,6 +133,7 @@ Future<T?> showStreamAttachmentPickerModalBottomSheet<T>({
|
||||
|
||||
return mobileAttachmentPickerBuilder.call(
|
||||
context: context,
|
||||
onError: onError,
|
||||
controller: controller,
|
||||
allowedTypes: allowedTypes,
|
||||
customOptions: customOptions,
|
||||
|
||||
@@ -811,6 +811,7 @@ class StreamMessageInputState extends State<StreamMessageInput>
|
||||
Future<void> _onAttachmentButtonPressed() async {
|
||||
final attachments = await showStreamAttachmentPickerModalBottomSheet(
|
||||
context: context,
|
||||
onError: widget.onError,
|
||||
allowedTypes: widget.allowedAttachmentPickerTypes,
|
||||
initialAttachments: _effectiveController.attachments,
|
||||
);
|
||||
|
||||
@@ -55,6 +55,7 @@ class StreamMessageWidget extends StatefulWidget {
|
||||
this.attachmentBorderRadiusGeometry,
|
||||
this.onMentionTap,
|
||||
this.onMessageTap,
|
||||
this.onReactionsTap,
|
||||
this.showReactionPicker = true,
|
||||
@internal this.showReactionPickerTail = false,
|
||||
this.showUserAvatar = DisplayWidget.show,
|
||||
@@ -524,6 +525,9 @@ class StreamMessageWidget extends StatefulWidget {
|
||||
/// {@macro onMessageTap}
|
||||
final void Function(Message)? onMessageTap;
|
||||
|
||||
/// {@macro onReactionsTap}
|
||||
final OnReactionsTap? onReactionsTap;
|
||||
|
||||
/// {@template customActions}
|
||||
/// List of custom actions shown on message long tap
|
||||
/// {@endtemplate}
|
||||
@@ -604,6 +608,7 @@ class StreamMessageWidget extends StatefulWidget {
|
||||
bool? translateUserAvatar,
|
||||
OnQuotedMessageTap? onQuotedMessageTap,
|
||||
void Function(Message)? onMessageTap,
|
||||
OnReactionsTap? onReactionsTap,
|
||||
List<StreamMessageAction>? customActions,
|
||||
void Function(Message message, Attachment attachment)? onAttachmentTap,
|
||||
Widget Function(BuildContext, User)? userAvatarBuilder,
|
||||
@@ -669,6 +674,7 @@ class StreamMessageWidget extends StatefulWidget {
|
||||
translateUserAvatar: translateUserAvatar ?? this.translateUserAvatar,
|
||||
onQuotedMessageTap: onQuotedMessageTap ?? this.onQuotedMessageTap,
|
||||
onMessageTap: onMessageTap ?? this.onMessageTap,
|
||||
onReactionsTap: onReactionsTap ?? this.onReactionsTap,
|
||||
customActions: customActions ?? this.customActions,
|
||||
onAttachmentTap: onAttachmentTap ?? this.onAttachmentTap,
|
||||
userAvatarBuilder: userAvatarBuilder ?? this.userAvatarBuilder,
|
||||
@@ -892,7 +898,11 @@ class _StreamMessageWidgetState extends State<StreamMessageWidget>
|
||||
showPinHighlight: widget.showPinHighlight,
|
||||
showReactionPickerTail: widget.showReactionPickerTail,
|
||||
showReactions: showReactions,
|
||||
onReactionsTap: () => _showMessageReactionsModal(context),
|
||||
onReactionsTap: () {
|
||||
widget.onReactionsTap != null
|
||||
? widget.onReactionsTap!(widget.message)
|
||||
: _showMessageReactionsModal(context);
|
||||
},
|
||||
showUserAvatar: widget.showUserAvatar,
|
||||
streamChat: _streamChat,
|
||||
translateUserAvatar: widget.translateUserAvatar,
|
||||
|
||||
@@ -352,12 +352,12 @@ extension MessageX on Message {
|
||||
final userName = user.name;
|
||||
if (linkify) {
|
||||
messageTextToRender = messageTextToRender?.replaceAll(
|
||||
'@$userId',
|
||||
'[@$userName](@${userName.replaceAll(' ', '')})',
|
||||
RegExp('@($userId|$userName)'),
|
||||
'[@$userName]($userId)',
|
||||
);
|
||||
} else {
|
||||
messageTextToRender = messageTextToRender?.replaceAll(
|
||||
'@$userId',
|
||||
RegExp('@($userId|$userName)'),
|
||||
'@$userName',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -221,6 +221,11 @@ typedef OnQuotedMessageTap = void Function(String?);
|
||||
/// {@endtemplate}
|
||||
typedef OnMessageTap = void Function(Message);
|
||||
|
||||
/// {@template onReactionsTap}
|
||||
/// The action to perform when a message's reactions are tapped.
|
||||
/// {@endtemplate}
|
||||
typedef OnReactionsTap = void Function(Message);
|
||||
|
||||
/// {@template messageSearchItemTapCallback}
|
||||
/// The action to perform when tapping or clicking on a user in a
|
||||
/// [MessageSearchListView].
|
||||
|
||||
@@ -17,26 +17,26 @@ dependencies:
|
||||
dart_vlc: ^0.4.0
|
||||
desktop_drop: ^0.4.1
|
||||
diacritic: ^0.1.4
|
||||
dio: ^5.2.1+1
|
||||
dio: ^5.3.2
|
||||
ezanimation: ^0.6.0
|
||||
file_picker: ^5.3.2
|
||||
file_picker: ^5.3.3
|
||||
file_selector: ^1.0.0
|
||||
flutter:
|
||||
sdk: flutter
|
||||
flutter_markdown: ^0.6.17
|
||||
flutter_markdown: ^0.6.17+1
|
||||
flutter_portal: ^1.1.4
|
||||
flutter_svg: ^2.0.7
|
||||
http_parser: ^4.0.2
|
||||
image_gallery_saver: ^2.0.3
|
||||
image_picker: ^1.0.1
|
||||
image_picker: ^1.0.2
|
||||
jiffy: ^6.2.1
|
||||
lottie: ^2.4.0
|
||||
lottie: ^2.6.0
|
||||
meta: ^1.9.1
|
||||
path_provider: ^2.0.15
|
||||
photo_manager: ^2.6.0
|
||||
path_provider: ^2.1.0
|
||||
photo_manager: ^2.7.1
|
||||
photo_view: ^0.14.0
|
||||
rxdart: ^0.27.7
|
||||
share_plus: ^7.0.2
|
||||
share_plus: ^7.1.0
|
||||
shimmer: ^3.0.0
|
||||
stream_chat_flutter_core: ^7.0.0-beta.2
|
||||
synchronized: ^3.1.0
|
||||
@@ -73,5 +73,5 @@ dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
golden_toolkit: ^0.15.0
|
||||
mocktail: ^0.3.0
|
||||
path: ^1.8.2
|
||||
mocktail: ^1.0.0
|
||||
path: ^1.8.3
|
||||
@@ -148,4 +148,126 @@ void main() {
|
||||
expect('ㅎㅎㅎㅎ'.isOnlyEmoji, false);
|
||||
});
|
||||
});
|
||||
|
||||
group('Message Extension Tests', () {
|
||||
test('replaceMentions should replace user mentions with names and IDs', () {
|
||||
final user1 = User(id: 'user1', name: 'Alice');
|
||||
final user2 = User(id: 'user2', name: 'Bob');
|
||||
|
||||
final message = Message(
|
||||
text: 'Hello, @user1 and @user2!',
|
||||
mentionedUsers: [user1, user2],
|
||||
);
|
||||
|
||||
final modifiedMessage = message.replaceMentions();
|
||||
|
||||
expect(modifiedMessage.text, contains('[@Alice](user1)'));
|
||||
expect(modifiedMessage.text, contains('[@Bob](user2)'));
|
||||
});
|
||||
|
||||
test('replaceMentions without linkify should not add links', () {
|
||||
final user = User(id: 'user1', name: 'Alice');
|
||||
|
||||
final message = Message(
|
||||
text: 'Hello, @user1!',
|
||||
mentionedUsers: [user],
|
||||
);
|
||||
|
||||
final modifiedMessage = message.replaceMentions(linkify: false);
|
||||
|
||||
expect(modifiedMessage.text, contains('@Alice'));
|
||||
});
|
||||
|
||||
test('replaceMentions should handle mentions with usernames', () {
|
||||
final user = User(id: 'user1', name: 'Alice');
|
||||
|
||||
final message = Message(
|
||||
text: 'Hello, @Alice!',
|
||||
mentionedUsers: [user],
|
||||
);
|
||||
|
||||
final modifiedMessage = message.replaceMentions();
|
||||
|
||||
expect(modifiedMessage.text, contains('[@Alice](user1)'));
|
||||
});
|
||||
|
||||
test(
|
||||
'''replaceMentions without linkify should not change mentions with usernames''',
|
||||
() {
|
||||
final user = User(id: 'user1', name: 'Alice');
|
||||
|
||||
final message = Message(
|
||||
text: 'Hello, @Alice!',
|
||||
mentionedUsers: [user],
|
||||
);
|
||||
|
||||
final modifiedMessage = message.replaceMentions(linkify: false);
|
||||
|
||||
expect(modifiedMessage.text, contains('@Alice'));
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
'replaceMentions should replace mixed user mentions with names and IDs',
|
||||
() {
|
||||
final user1 = User(id: 'user1', name: 'Alice');
|
||||
final user2 = User(id: 'user2', name: 'Bob');
|
||||
|
||||
final message = Message(
|
||||
text: 'Hello, @user1 and @Bob!',
|
||||
mentionedUsers: [user1, user2],
|
||||
);
|
||||
|
||||
final modifiedMessage = message.replaceMentions();
|
||||
|
||||
expect(modifiedMessage.text, contains('[@Alice](user1)'));
|
||||
expect(modifiedMessage.text, contains('[@Bob](user2)'));
|
||||
},
|
||||
);
|
||||
|
||||
test('replaceMentionsWithId should replace user names with IDs', () {
|
||||
final user1 = User(id: 'user1', name: 'Alice');
|
||||
final user2 = User(id: 'user2', name: 'Bob');
|
||||
|
||||
final message = Message(
|
||||
text: 'Hello, @Alice and @Bob!',
|
||||
mentionedUsers: [user1, user2],
|
||||
);
|
||||
|
||||
final modifiedMessage = message.replaceMentionsWithId();
|
||||
|
||||
expect(modifiedMessage.text, contains('@user1'));
|
||||
expect(modifiedMessage.text, contains('@user2'));
|
||||
expect(modifiedMessage.text, isNot(contains('@Alice')));
|
||||
expect(modifiedMessage.text, isNot(contains('@Bob')));
|
||||
});
|
||||
|
||||
test(
|
||||
'replaceMentionsWithId should not change message without mentions',
|
||||
() {
|
||||
final message = Message(
|
||||
text: 'Hello, @Alice!',
|
||||
);
|
||||
|
||||
final modifiedMessage = message.replaceMentionsWithId();
|
||||
|
||||
expect(modifiedMessage.text, equals('Hello, @Alice!'));
|
||||
expect(modifiedMessage.text, isNot(contains('@user1')));
|
||||
},
|
||||
);
|
||||
|
||||
test('replaceMentionsWithId should handle message with only mention', () {
|
||||
final user = User(id: 'user1', name: 'Alice');
|
||||
|
||||
final message = Message(
|
||||
text: '@Alice',
|
||||
mentionedUsers: [user],
|
||||
);
|
||||
|
||||
final modifiedMessage = message.replaceMentionsWithId();
|
||||
|
||||
expect(modifiedMessage.text, contains('@user1'));
|
||||
expect(modifiedMessage.text, isNot(contains('@Alice')));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user