Merge branch 'develop'
This commit is contained in:
@@ -7,6 +7,7 @@ env:
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
|
types: [opened, synchronize, reopened, ready_for_review, converted_to_draft]
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
|
|||||||
+1
-1
@@ -82,7 +82,7 @@ To run a script, use `melos run <script name>`.
|
|||||||
|
|
||||||
# How can I contribute?
|
# How can I contribute?
|
||||||
|
|
||||||
Are you ready to dive into code? It's pretty easy to get up and running with your first Stream contribution. If this is your first time sending a PR to Stream, please read the above section on [local setup](https://www.notion.so/Stream-s-Contribution-Guide-e18e1d57295f4fa8836a115d3fa3d5e7) before continuing.
|
Are you ready to dive into code? It's pretty easy to get up and running with your first Stream contribution. If this is your first time sending a PR to Stream, please read the above section on [local setup](https://github.com/GetStream/stream-chat-flutter/blob/develop/CONTRIBUTING.md#local-setup) before continuing.
|
||||||
|
|
||||||
## Filing bugs 🐛
|
## Filing bugs 🐛
|
||||||
|
|
||||||
|
|||||||
@@ -24,26 +24,22 @@ Make sure to check the [StreamUserListController](./stream_user_list_controller.
|
|||||||
|
|
||||||
```dart
|
```dart
|
||||||
class UserListPage extends StatefulWidget {
|
class UserListPage extends StatefulWidget {
|
||||||
const UserListPage({
|
const UserListPage({Key? key}) : super(key: key);
|
||||||
Key? key,
|
|
||||||
required this.client,
|
|
||||||
}) : super(key: key);
|
|
||||||
|
|
||||||
final StreamChatClient client;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<UserListPage> createState() => _UserListPageState();
|
State<UserListPage> createState() => _UserListPageState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _UserListPageState extends State<UserListPage> {
|
class _UserListPageState extends State<UserListPage> {
|
||||||
late final _controller = StreamUserListController(
|
late final StreamUserListController _userListController =
|
||||||
client: widget.client,
|
StreamUserListController(
|
||||||
|
client: StreamChat.of(context).client,
|
||||||
limit: 25,
|
limit: 25,
|
||||||
filter: Filter.and([
|
filter: Filter.and(
|
||||||
Filter.notEqual('id', StreamChat.of(context).currentUser!.id),
|
[Filter.notEqual('id', StreamChat.of(context).currentUser!.id)],
|
||||||
]),
|
),
|
||||||
sort: [
|
sort: [
|
||||||
SortOption(
|
const SortOption(
|
||||||
'name',
|
'name',
|
||||||
direction: 1,
|
direction: 1,
|
||||||
),
|
),
|
||||||
@@ -51,29 +47,14 @@ class _UserListPageState extends State<UserListPage> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
Widget build(BuildContext context) {
|
||||||
_controller.dispose();
|
return RefreshIndicator(
|
||||||
super.dispose();
|
onRefresh: () => _userListController.refresh(),
|
||||||
|
child: StreamUserListView(
|
||||||
|
controller: _userListController,
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) => Scaffold(
|
|
||||||
body: RefreshIndicator(
|
|
||||||
onRefresh: _controller.refresh,
|
|
||||||
child: StreamChannelListView(
|
|
||||||
controller: _controller,
|
|
||||||
onChannelTap: (channel) => Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (_) => StreamChannel(
|
|
||||||
channel: channel,
|
|
||||||
child: const ChannelPage(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -89,3 +70,25 @@ StreamUsersListView(
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Selecting Users
|
||||||
|
|
||||||
|
The `StreamUserListView` widget allows selecting users in a list. The `defaultWidget` returned can be customized to indicate that it has been selected.
|
||||||
|
|
||||||
|
```dart
|
||||||
|
Set<User> _selectedUsers = {};
|
||||||
|
|
||||||
|
StreamUserListView(
|
||||||
|
controller: _userListController,
|
||||||
|
itemBuilder: (context, users, index, defaultWidget) {
|
||||||
|
return defaultWidget.copyWith(
|
||||||
|
selected: _selectedUsers.contains(users[index]),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
onUserTap: (user) {
|
||||||
|
setState(() {
|
||||||
|
_selectedUsers.add(user);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|||||||
@@ -1,3 +1,11 @@
|
|||||||
|
## 4.3.0
|
||||||
|
|
||||||
|
🐞 Fixed
|
||||||
|
|
||||||
|
- [[#1135]](https://github.com/GetStream/stream-chat-flutter/issues/1135) Persistence was not
|
||||||
|
removing the hidden channels.
|
||||||
|
- Fix `x-stream-client` header generation.
|
||||||
|
|
||||||
## 4.2.0
|
## 4.2.0
|
||||||
|
|
||||||
✅ Added
|
✅ Added
|
||||||
@@ -13,18 +21,20 @@
|
|||||||
|
|
||||||
🔄 Changed
|
🔄 Changed
|
||||||
|
|
||||||
- Deprecated `PaginationParams.before` and `PaginationParams.after`. Use `PaginationParams.limit` instead.
|
- Deprecated `PaginationParams.before` and `PaginationParams.after`. Use `PaginationParams.limit`
|
||||||
|
instead.
|
||||||
|
|
||||||
🐞 Fixed
|
🐞 Fixed
|
||||||
|
|
||||||
- [[#1147]](https://github.com/GetStream/stream-chat-flutter/issues/1147) `channel.unset` not updating the extra data
|
- [[#1147]](https://github.com/GetStream/stream-chat-flutter/issues/1147) `channel.unset` not
|
||||||
stream.
|
updating the extra data stream.
|
||||||
|
|
||||||
## 4.1.0
|
## 4.1.0
|
||||||
|
|
||||||
✅ Added
|
✅ Added
|
||||||
|
|
||||||
- Added support for extra data in attachment file uploader. Thanks, [@rlee1990](https://github.com/rlee1990).
|
- Added support for extra data in attachment file uploader.
|
||||||
|
Thanks, [@rlee1990](https://github.com/rlee1990).
|
||||||
|
|
||||||
🔄 Changed
|
🔄 Changed
|
||||||
|
|
||||||
@@ -49,14 +59,14 @@ the [V4 Migration Guide](https://getstream.io/chat/docs/sdk/flutter/guides/migra
|
|||||||
🐞 Fixed
|
🐞 Fixed
|
||||||
|
|
||||||
- Fixed reactions not working for threads in offline mode.
|
- Fixed reactions not working for threads in offline mode.
|
||||||
- [[#1046]](https://github.com/GetStream/stream-chat-flutter/issues/1046) After `/mute` command on reload cannot access
|
- [[#1046]](https://github.com/GetStream/stream-chat-flutter/issues/1046) After `/mute` command on
|
||||||
any channel.
|
reload cannot access any channel.
|
||||||
- [[#1047]](https://github.com/GetStream/stream-chat-flutter/issues/1047) `own_capabilities` extraData missing after
|
- [[#1047]](https://github.com/GetStream/stream-chat-flutter/issues/1047) `own_capabilities`
|
||||||
channel update.
|
extraData missing after channel update.
|
||||||
- [[#1054]](https://github.com/GetStream/stream-chat-flutter/issues/1054)
|
- [[#1054]](https://github.com/GetStream/stream-chat-flutter/issues/1054)
|
||||||
Fix `Unsupported operation: Cannot remove from an unmodifiable list`.
|
Fix `Unsupported operation: Cannot remove from an unmodifiable list`.
|
||||||
- [[#1033]](https://github.com/GetStream/stream-chat-flutter/issues/1033) Hard delete from dashboard does not delete
|
- [[#1033]](https://github.com/GetStream/stream-chat-flutter/issues/1033) Hard delete from dashboard
|
||||||
message from client.
|
does not delete message from client.
|
||||||
- Send only `user_id` while reconnecting.
|
- Send only `user_id` while reconnecting.
|
||||||
|
|
||||||
✅ Added
|
✅ Added
|
||||||
@@ -78,21 +88,22 @@ the [V4 Migration Guide](https://getstream.io/chat/docs/sdk/flutter/guides/migra
|
|||||||
|
|
||||||
🐞 Fixed
|
🐞 Fixed
|
||||||
|
|
||||||
- [[#1081]](https://github.com/GetStream/stream-chat-flutter/issues/1081) Fixed a bug with user reconnection.
|
- [[#1081]](https://github.com/GetStream/stream-chat-flutter/issues/1081) Fixed a bug with user
|
||||||
|
reconnection.
|
||||||
|
|
||||||
## 3.6.0
|
## 3.6.0
|
||||||
|
|
||||||
🐞 Fixed
|
🐞 Fixed
|
||||||
|
|
||||||
- Fixed reactions not working for threads in offline mode.
|
- Fixed reactions not working for threads in offline mode.
|
||||||
- [[#1046]](https://github.com/GetStream/stream-chat-flutter/issues/1046) After `/mute` command on reload cannot access
|
- [[#1046]](https://github.com/GetStream/stream-chat-flutter/issues/1046) After `/mute` command on
|
||||||
any channel.
|
reload cannot access any channel.
|
||||||
- [[#1047]](https://github.com/GetStream/stream-chat-flutter/issues/1047) `own_capabilities` extraData missing after
|
- [[#1047]](https://github.com/GetStream/stream-chat-flutter/issues/1047) `own_capabilities`
|
||||||
channel update.
|
extraData missing after channel update.
|
||||||
- [[#1054]](https://github.com/GetStream/stream-chat-flutter/issues/1054)
|
- [[#1054]](https://github.com/GetStream/stream-chat-flutter/issues/1054)
|
||||||
Fix `Unsupported operation: Cannot remove from an unmodifiable list`.
|
Fix `Unsupported operation: Cannot remove from an unmodifiable list`.
|
||||||
- [[#1033]](https://github.com/GetStream/stream-chat-flutter/issues/1033) Hard delete from dashboard does not delete
|
- [[#1033]](https://github.com/GetStream/stream-chat-flutter/issues/1033) Hard delete from dashboard
|
||||||
message from client.
|
does not delete message from client.
|
||||||
- Send only `user_id` while reconnecting.
|
- Send only `user_id` while reconnecting.
|
||||||
|
|
||||||
✅ Added
|
✅ Added
|
||||||
@@ -116,24 +127,26 @@ the [V4 Migration Guide](https://getstream.io/chat/docs/sdk/flutter/guides/migra
|
|||||||
|
|
||||||
🐞 Fixed
|
🐞 Fixed
|
||||||
|
|
||||||
- [[#890]](https://github.com/GetStream/stream-chat-flutter/pull/890) Fixed Reactions not updating on thread messages.
|
- [[#890]](https://github.com/GetStream/stream-chat-flutter/pull/890) Fixed Reactions not updating
|
||||||
Thanks [bstolinski](https://github.com/bstolinski).
|
on thread messages. Thanks [bstolinski](https://github.com/bstolinski).
|
||||||
- [[#897]](https://github.com/GetStream/stream-chat-flutter/issues/897) Fixed error type mis-match in `AuthInterceptor`.
|
- [[#897]](https://github.com/GetStream/stream-chat-flutter/issues/897) Fixed error type mis-match
|
||||||
- [[#891]](https://github.com/GetStream/stream-chat-flutter/pull/891) Fixed reply counter for parent message not
|
in `AuthInterceptor`.
|
||||||
updating correctly after deleting thread message.
|
- [[#891]](https://github.com/GetStream/stream-chat-flutter/pull/891) Fixed reply counter for parent
|
||||||
|
message not updating correctly after deleting thread message.
|
||||||
- Fix `channelState.copyWith` with respect to pinnedMessages.
|
- Fix `channelState.copyWith` with respect to pinnedMessages.
|
||||||
|
|
||||||
## 3.4.0
|
## 3.4.0
|
||||||
|
|
||||||
🐞 Fixed
|
🐞 Fixed
|
||||||
|
|
||||||
- [[#857]](https://github.com/GetStream/stream-chat-flutter/issues/857) Channel now listens for member ban/unban and
|
- [[#857]](https://github.com/GetStream/stream-chat-flutter/issues/857) Channel now listens for
|
||||||
updates the channel state with the latest data.
|
member ban/unban and updates the channel state with the latest data.
|
||||||
- [[#748]](https://github.com/GetStream/stream-chat-flutter/issues/748) `Message.user` is now also included while saving
|
- [[#748]](https://github.com/GetStream/stream-chat-flutter/issues/748) `Message.user` is now also
|
||||||
users in persistence.
|
included while saving users in persistence.
|
||||||
- [[#871]](https://github.com/GetStream/stream-chat-flutter/issues/871) Fixed thread message deletion.
|
- [[#871]](https://github.com/GetStream/stream-chat-flutter/issues/871) Fixed thread message
|
||||||
- [[#846]](https://github.com/GetStream/stream-chat-flutter/issues/846) Fixed `message.ownReactions` getting truncated
|
deletion.
|
||||||
when receiving a reaction event.
|
- [[#846]](https://github.com/GetStream/stream-chat-flutter/issues/846) Fixed `message.ownReactions`
|
||||||
|
getting truncated when receiving a reaction event.
|
||||||
- Add check for invalid image URLs
|
- Add check for invalid image URLs
|
||||||
- Fix `channelState.pinnedMessagesStream` getting reset to `0` after a channel update.
|
- Fix `channelState.pinnedMessagesStream` getting reset to `0` after a channel update.
|
||||||
- Fixed `unreadCount` after removing user from a channel.
|
- Fixed `unreadCount` after removing user from a channel.
|
||||||
@@ -141,7 +154,8 @@ the [V4 Migration Guide](https://getstream.io/chat/docs/sdk/flutter/guides/migra
|
|||||||
🔄 Changed
|
🔄 Changed
|
||||||
|
|
||||||
- `client.location` is now deprecated in favor of the
|
- `client.location` is now deprecated in favor of the
|
||||||
new [edge server](https://getstream.io/blog/chat-edge-infrastructure) and will be removed in v4.0.0.
|
new [edge server](https://getstream.io/blog/chat-edge-infrastructure) and will be removed in
|
||||||
|
v4.0.0.
|
||||||
- `channel.banUser`, `channel.unbanUser` is now deprecated in favor of the new `channel.banMember`
|
- `channel.banUser`, `channel.unbanUser` is now deprecated in favor of the new `channel.banMember`
|
||||||
and `channel.unbanMember`. These deprecated methods will be removed in v4.0.0.
|
and `channel.unbanMember`. These deprecated methods will be removed in v4.0.0.
|
||||||
- Added `banExpires` property of type `DateTime` on the `Member`, `OwnUser`, and `User` models.
|
- Added `banExpires` property of type `DateTime` on the `Member`, `OwnUser`, and `User` models.
|
||||||
@@ -155,8 +169,8 @@ the [V4 Migration Guide](https://getstream.io/chat/docs/sdk/flutter/guides/migra
|
|||||||
|
|
||||||
🐞 Fixed
|
🐞 Fixed
|
||||||
|
|
||||||
- [[#799]](https://github.com/GetStream/stream-chat-flutter/issues/799) Fixed `totalUnreadCount` is not updating when
|
- [[#799]](https://github.com/GetStream/stream-chat-flutter/issues/799) Fixed `totalUnreadCount` is
|
||||||
app is resumed from background mode.
|
not updating when app is resumed from background mode.
|
||||||
- Fix retry mechanism failing in some cases.
|
- Fix retry mechanism failing in some cases.
|
||||||
|
|
||||||
## 3.3.0
|
## 3.3.0
|
||||||
@@ -171,7 +185,8 @@ the [V4 Migration Guide](https://getstream.io/chat/docs/sdk/flutter/guides/migra
|
|||||||
- `closeConnection()` now uses `normalClosure` status when closing websocket.
|
- `closeConnection()` now uses `normalClosure` status when closing websocket.
|
||||||
- Fixed local unread count indicator increasing for thread replies.
|
- Fixed local unread count indicator increasing for thread replies.
|
||||||
- Fixed user presence indicator not updating correctly.
|
- Fixed user presence indicator not updating correctly.
|
||||||
- `ChannelEvent.membersCount` defaults to 0 avoiding parsing errors due to missing `members_count` field.
|
- `ChannelEvent.membersCount` defaults to 0 avoiding parsing errors due to missing `members_count`
|
||||||
|
field.
|
||||||
|
|
||||||
## 3.2.1
|
## 3.2.1
|
||||||
|
|
||||||
@@ -184,7 +199,8 @@ the [V4 Migration Guide](https://getstream.io/chat/docs/sdk/flutter/guides/migra
|
|||||||
🐞 Fixed
|
🐞 Fixed
|
||||||
|
|
||||||
- `markAllRead()` now updates local channel states.
|
- `markAllRead()` now updates local channel states.
|
||||||
- [[#744]](https://github.com/GetStream/stream-chat-flutter/issues/744) Fixed unread count not updating correctly
|
- [[#744]](https://github.com/GetStream/stream-chat-flutter/issues/744) Fixed unread count not
|
||||||
|
updating correctly
|
||||||
|
|
||||||
## 3.1.1
|
## 3.1.1
|
||||||
|
|
||||||
@@ -194,7 +210,8 @@ the [V4 Migration Guide](https://getstream.io/chat/docs/sdk/flutter/guides/migra
|
|||||||
|
|
||||||
🐞 Fixed
|
🐞 Fixed
|
||||||
|
|
||||||
- [[#710]](https://github.com/GetStream/stream-chat-flutter/issues/710) Fixed JWT requiring using `String` as id.
|
- [[#710]](https://github.com/GetStream/stream-chat-flutter/issues/710) Fixed JWT requiring
|
||||||
|
using `String` as id.
|
||||||
- Fixed expired CDN attachment links not updating correctly.
|
- Fixed expired CDN attachment links not updating correctly.
|
||||||
|
|
||||||
## 3.0.0
|
## 3.0.0
|
||||||
@@ -214,16 +231,19 @@ the [V4 Migration Guide](https://getstream.io/chat/docs/sdk/flutter/guides/migra
|
|||||||
- Added `Filter.contains` and `Filter.empty`
|
- Added `Filter.contains` and `Filter.empty`
|
||||||
- Added support for `next`, `previous` value pagination in `client.search`
|
- Added support for `next`, `previous` value pagination in `client.search`
|
||||||
, [read more.](https://getstream.io/chat/docs/other-rest/search/#pagination)
|
, [read more.](https://getstream.io/chat/docs/other-rest/search/#pagination)
|
||||||
- `Attachment` class now has a `fileSize` and `mimeType` property. Setting a `file` will also set the `file_size`
|
- `Attachment` class now has a `fileSize` and `mimeType` property. Setting a `file` will also set
|
||||||
|
the `file_size`
|
||||||
, `mime_type` key on `extraData`, so `attachment.fileSize`, `attachment.mimetype`
|
, `mime_type` key on `extraData`, so `attachment.fileSize`, `attachment.mimetype`
|
||||||
and `attachment.extraData['file_size']`
|
and `attachment.extraData['file_size']`
|
||||||
, `attachment.extraData['mime_type]` is same respectively.
|
, `attachment.extraData['mime_type]` is same respectively.
|
||||||
|
|
||||||
🐞 Fixed
|
🐞 Fixed
|
||||||
|
|
||||||
- [[#659]](https://github.com/GetStream/stream-chat-flutter/issues/659) Fixed unread count not updating correctly.
|
- [[#659]](https://github.com/GetStream/stream-chat-flutter/issues/659) Fixed unread count not
|
||||||
|
updating correctly.
|
||||||
- Fix `Filter.empty()` json encoding.
|
- Fix `Filter.empty()` json encoding.
|
||||||
- [[#700]](https://github.com/GetStream/stream-chat-flutter/issues/700) Connecting user without providing `name`
|
- [[#700]](https://github.com/GetStream/stream-chat-flutter/issues/700) Connecting user without
|
||||||
|
providing `name`
|
||||||
uses `id` instead for setting `user.name`.
|
uses `id` instead for setting `user.name`.
|
||||||
|
|
||||||
## 2.2.1
|
## 2.2.1
|
||||||
@@ -241,14 +261,14 @@ the [V4 Migration Guide](https://getstream.io/chat/docs/sdk/flutter/guides/migra
|
|||||||
|
|
||||||
✅ Added
|
✅ Added
|
||||||
|
|
||||||
- `User` and `OwnUser` classes now have an `image` property. Setting an image will also set the 'image' key
|
- `User` and `OwnUser` classes now have an `image` property. Setting an image will also set the '
|
||||||
on `extraData`, so `user.image` and `user.extraData['image']` is the same.
|
image' key on `extraData`, so `user.image` and `user.extraData['image']` is the same.
|
||||||
- `User` and `OwnUser` classes now have a `name` property. Setting a name will also set the 'name' key on `extraData`,
|
- `User` and `OwnUser` classes now have a `name` property. Setting a name will also set the 'name'
|
||||||
so `user.name` and `user.extraData['name']` is the same.
|
key on `extraData`, so `user.name` and `user.extraData['name']` is the same.
|
||||||
- `Channel` class now has extra `image` getter and setter. As well as an `updateImage` to do a partial update after a
|
- `Channel` class now has extra `image` getter and setter. As well as an `updateImage` to do a
|
||||||
channel has been initialized.
|
partial update after a channel has been initialized.
|
||||||
- `Channel` class now has extra `name` getter and setter. As well as an `updateName` to do a partial update after a
|
- `Channel` class now has extra `name` getter and setter. As well as an `updateName` to do a partial
|
||||||
channel has been initialized.
|
update after a channel has been initialized.
|
||||||
- Added slow mode which allows a cooldown period after a user sends a message.
|
- Added slow mode which allows a cooldown period after a user sends a message.
|
||||||
|
|
||||||
## 2.1.1
|
## 2.1.1
|
||||||
@@ -261,7 +281,8 @@ the [V4 Migration Guide](https://getstream.io/chat/docs/sdk/flutter/guides/migra
|
|||||||
|
|
||||||
🛑️ Removed
|
🛑️ Removed
|
||||||
|
|
||||||
- The `MessageTranslation` class has been removed. Use the new `i18n` field in the `Message` class instead.
|
- The `MessageTranslation` class has been removed. Use the new `i18n` field in the `Message` class
|
||||||
|
instead.
|
||||||
|
|
||||||
✅ Added
|
✅ Added
|
||||||
|
|
||||||
@@ -275,7 +296,8 @@ the [V4 Migration Guide](https://getstream.io/chat/docs/sdk/flutter/guides/migra
|
|||||||
|
|
||||||
🐞 Fixed
|
🐞 Fixed
|
||||||
|
|
||||||
- [#563](https://github.com/GetStream/stream-chat-flutter/issues/563): `Channel.stopWatching()` not working
|
- [#563](https://github.com/GetStream/stream-chat-flutter/issues/563): `Channel.stopWatching()` not
|
||||||
|
working
|
||||||
- [#575](https://github.com/GetStream/stream-chat-flutter/issues/575): Wrong `OwnUser.*`
|
- [#575](https://github.com/GetStream/stream-chat-flutter/issues/575): Wrong `OwnUser.*`
|
||||||
|
|
||||||
## 2.0.0
|
## 2.0.0
|
||||||
@@ -283,7 +305,8 @@ the [V4 Migration Guide](https://getstream.io/chat/docs/sdk/flutter/guides/migra
|
|||||||
🛑️ Breaking Changes from `1.5.3`
|
🛑️ Breaking Changes from `1.5.3`
|
||||||
|
|
||||||
- migrate this package to null safety
|
- migrate this package to null safety
|
||||||
- `ConnectUserWithProvider` now requires `tokenProvider` as a required param. (Removed from the constructor)
|
- `ConnectUserWithProvider` now requires `tokenProvider` as a required param. (Removed from the
|
||||||
|
constructor)
|
||||||
- `client.disconnect()` is now divided into two different functions
|
- `client.disconnect()` is now divided into two different functions
|
||||||
- `client.closeConnection()` -> for closing user websocket connection.
|
- `client.closeConnection()` -> for closing user websocket connection.
|
||||||
- `client.disconnectUser()` -> for disconnecting user and resetting client state.
|
- `client.disconnectUser()` -> for disconnecting user and resetting client state.
|
||||||
@@ -303,15 +326,16 @@ the [V4 Migration Guide](https://getstream.io/chat/docs/sdk/flutter/guides/migra
|
|||||||
|
|
||||||
🐞 Fixed
|
🐞 Fixed
|
||||||
|
|
||||||
- [#369](https://github.com/GetStream/stream-chat-flutter/issues/369): Client does not return without internet
|
- [#369](https://github.com/GetStream/stream-chat-flutter/issues/369): Client does not return
|
||||||
connection
|
without internet connection
|
||||||
- several minor fixes
|
- several minor fixes
|
||||||
- performance improvements
|
- performance improvements
|
||||||
|
|
||||||
✅ Added
|
✅ Added
|
||||||
|
|
||||||
- New `Location` enum is introduced for easily changing the client location/baseUrl.
|
- New `Location` enum is introduced for easily changing the client location/baseUrl.
|
||||||
- New `client.openConnection()` and `client.closeConnection()` is introduced to connect/disconnect user ws connection.
|
- New `client.openConnection()` and `client.closeConnection()` is introduced to connect/disconnect
|
||||||
|
user ws connection.
|
||||||
- New `client.partialUpdateMessage` and `channel.partialUpdateMessage` methods
|
- New `client.partialUpdateMessage` and `channel.partialUpdateMessage` methods
|
||||||
- `connectWebSocket` parameter in connect user calls to use the client in "connection-less" mode.
|
- `connectWebSocket` parameter in connect user calls to use the client in "connection-less" mode.
|
||||||
|
|
||||||
@@ -329,7 +353,8 @@ the [V4 Migration Guide](https://getstream.io/chat/docs/sdk/flutter/guides/migra
|
|||||||
|
|
||||||
🛑️ Breaking Changes from `2.0.0-nullsafety.6`
|
🛑️ Breaking Changes from `2.0.0-nullsafety.6`
|
||||||
|
|
||||||
- `ConnectUserWithProvider` now requires `tokenProvider` as a required param. (Removed from the constructor)
|
- `ConnectUserWithProvider` now requires `tokenProvider` as a required param. (Removed from the
|
||||||
|
constructor)
|
||||||
- `client.disconnect()` is now divided into two different functions
|
- `client.disconnect()` is now divided into two different functions
|
||||||
- `client.closeConnection()` -> for closing user websocket connection.
|
- `client.closeConnection()` -> for closing user websocket connection.
|
||||||
- `client.disconnectUser()` -> for disconnecting user and resetting client state.
|
- `client.disconnectUser()` -> for disconnecting user and resetting client state.
|
||||||
@@ -348,7 +373,8 @@ the [V4 Migration Guide](https://getstream.io/chat/docs/sdk/flutter/guides/migra
|
|||||||
✅ Added
|
✅ Added
|
||||||
|
|
||||||
- New `Location` enum is introduced for easily changing the client location/baseUrl.
|
- New `Location` enum is introduced for easily changing the client location/baseUrl.
|
||||||
- New `client.openConnection()` and `client.closeConnection()` is introduced to connect/disconnect user ws connection.
|
- New `client.openConnection()` and `client.closeConnection()` is introduced to connect/disconnect
|
||||||
|
user ws connection.
|
||||||
|
|
||||||
🔄 Changed
|
🔄 Changed
|
||||||
|
|
||||||
@@ -412,14 +438,16 @@ the [V4 Migration Guide](https://getstream.io/chat/docs/sdk/flutter/guides/migra
|
|||||||
|
|
||||||
- Save pinned messages in offline storage
|
- Save pinned messages in offline storage
|
||||||
- Minor fixes
|
- Minor fixes
|
||||||
- `StreamClient.QueryChannels` now returns a Stream and fetches the channels from storage before calling the api
|
- `StreamClient.QueryChannels` now returns a Stream and fetches the channels from storage before
|
||||||
- Added `StreamClient.QueryChannelsOnline` and `StreamClient.QueryChannelsOffline` to fetch channels only from online or
|
calling the api
|
||||||
offline
|
- Added `StreamClient.QueryChannelsOnline` and `StreamClient.QueryChannelsOffline` to fetch channels
|
||||||
|
only from online or offline
|
||||||
|
|
||||||
## 1.2.0-beta
|
## 1.2.0-beta
|
||||||
|
|
||||||
- 🛑 **BREAKING** Changed signature of `StreamClient.search` method
|
- 🛑 **BREAKING** Changed signature of `StreamClient.search` method
|
||||||
- Added `pinMessage` feature [docs here](https://getstream.io/chat/docs/flutter-dart/pinned_messages/?language=dart)
|
- Added `pinMessage`
|
||||||
|
feature [docs here](https://getstream.io/chat/docs/flutter-dart/pinned_messages/?language=dart)
|
||||||
- Fixed minor bugs
|
- Fixed minor bugs
|
||||||
|
|
||||||
## 1.1.0-beta
|
## 1.1.0-beta
|
||||||
@@ -436,7 +464,8 @@ the [V4 Migration Guide](https://getstream.io/chat/docs/sdk/flutter/guides/migra
|
|||||||
|
|
||||||
## 1.0.2-beta
|
## 1.0.2-beta
|
||||||
|
|
||||||
- Deprecated `setUser`, `setGuestUser`, `setUserWithProvider` in favor of `connectUser`, `connectGuestUser`
|
- Deprecated `setUser`, `setGuestUser`, `setUserWithProvider` in favor of `connectUser`
|
||||||
|
, `connectGuestUser`
|
||||||
, `connectUserWithProvider`
|
, `connectUserWithProvider`
|
||||||
- Optimised reaction updates - i.e., Update first call Api later.
|
- Optimised reaction updates - i.e., Update first call Api later.
|
||||||
|
|
||||||
@@ -449,9 +478,11 @@ the [V4 Migration Guide](https://getstream.io/chat/docs/sdk/flutter/guides/migra
|
|||||||
- 🛑 **BREAKING** Renamed `Client` to less generic `StreamChatClient`
|
- 🛑 **BREAKING** Renamed `Client` to less generic `StreamChatClient`
|
||||||
- 🛑 **BREAKING** Segregated the persistence layer into separate
|
- 🛑 **BREAKING** Segregated the persistence layer into separate
|
||||||
package [stream_chat_persistence](https://pub.dev/packages/stream_chat_persistence)
|
package [stream_chat_persistence](https://pub.dev/packages/stream_chat_persistence)
|
||||||
- 🛑 **BREAKING** Moved `Client.backgroundKeepAlive` to [core package](https://pub.dev/packages/stream_chat_core)
|
- 🛑 **BREAKING** Moved `Client.backgroundKeepAlive`
|
||||||
- 🛑 **BREAKING** Moved `Client.showLocalNotification` to [core package](https://pub.dev/packages/stream_chat_core) and
|
to [core package](https://pub.dev/packages/stream_chat_core)
|
||||||
renamed it to `StreamChatCore.onBackgroundEventReceived`
|
- 🛑 **BREAKING** Moved `Client.showLocalNotification`
|
||||||
|
to [core package](https://pub.dev/packages/stream_chat_core) and renamed it
|
||||||
|
to `StreamChatCore.onBackgroundEventReceived`
|
||||||
- Removed `flutter` dependency. This is now a pure Dart package 🥳
|
- Removed `flutter` dependency. This is now a pure Dart package 🥳
|
||||||
- Minor improvements and bugfixes
|
- Minor improvements and bugfixes
|
||||||
|
|
||||||
@@ -475,7 +506,8 @@ the [V4 Migration Guide](https://getstream.io/chat/docs/sdk/flutter/guides/migra
|
|||||||
|
|
||||||
## 0.2.23+2
|
## 0.2.23+2
|
||||||
|
|
||||||
- Do not throw an error when calling queryChannels without an active connection if the offline storage is enabled
|
- Do not throw an error when calling queryChannels without an active connection if the offline
|
||||||
|
storage is enabled
|
||||||
|
|
||||||
## 0.2.23+1
|
## 0.2.23+1
|
||||||
|
|
||||||
@@ -506,8 +538,8 @@ the [V4 Migration Guide](https://getstream.io/chat/docs/sdk/flutter/guides/migra
|
|||||||
|
|
||||||
## 0.2.20
|
## 0.2.20
|
||||||
|
|
||||||
- Return offline data only if the backend is unreachable. This avoids the glitch of the ChannelListView because we
|
- Return offline data only if the backend is unreachable. This avoids the glitch of the
|
||||||
cannot sort by custom properties.
|
ChannelListView because we cannot sort by custom properties.
|
||||||
|
|
||||||
## 0.2.19
|
## 0.2.19
|
||||||
|
|
||||||
@@ -561,7 +593,8 @@ the [V4 Migration Guide](https://getstream.io/chat/docs/sdk/flutter/guides/migra
|
|||||||
|
|
||||||
## 0.2.12
|
## 0.2.12
|
||||||
|
|
||||||
- Do not save channels in memory if not being watched. This was leading to some bugs in some specific use-cases.
|
- Do not save channels in memory if not being watched. This was leading to some bugs in some
|
||||||
|
specific use-cases.
|
||||||
|
|
||||||
## 0.2.11
|
## 0.2.11
|
||||||
|
|
||||||
|
|||||||
@@ -98,7 +98,9 @@ class StreamChatClient {
|
|||||||
tokenManager: _tokenManager,
|
tokenManager: _tokenManager,
|
||||||
handler: handleEvent,
|
handler: handleEvent,
|
||||||
logger: detachedLogger('🔌'),
|
logger: detachedLogger('🔌'),
|
||||||
queryParameters: {'X-Stream-Client': defaultUserAgent},
|
queryParameters: {
|
||||||
|
'X-Stream-Client': '$defaultUserAgent-$packageVersion',
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
_retryPolicy = retryPolicy ??
|
_retryPolicy = retryPolicy ??
|
||||||
@@ -124,13 +126,15 @@ class StreamChatClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Default user agent for all requests
|
/// Default user agent for all requests
|
||||||
static String defaultUserAgent = 'stream-chat-dart-client-'
|
static String defaultUserAgent =
|
||||||
'${CurrentPlatform.name}-'
|
'stream-chat-dart-client-${CurrentPlatform.name}';
|
||||||
'${PACKAGE_VERSION.split('+')[0]}';
|
|
||||||
|
|
||||||
/// Additional headers for all requests
|
/// Additional headers for all requests
|
||||||
static Map<String, Object?> additionalHeaders = {};
|
static Map<String, Object?> additionalHeaders = {};
|
||||||
|
|
||||||
|
/// The current package version
|
||||||
|
static const packageVersion = PACKAGE_VERSION;
|
||||||
|
|
||||||
ChatPersistenceClient? _originalChatPersistenceClient;
|
ChatPersistenceClient? _originalChatPersistenceClient;
|
||||||
|
|
||||||
/// Chat persistence client
|
/// Chat persistence client
|
||||||
@@ -1489,13 +1493,12 @@ class ClientState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _listenChannelHidden() {
|
void _listenChannelHidden() {
|
||||||
_subscriptions.add(_client.on(EventType.channelHidden).listen((event) {
|
_subscriptions
|
||||||
final cid = event.cid;
|
.add(_client.on(EventType.channelHidden).listen((event) async {
|
||||||
|
final eventChannel = event.channel!;
|
||||||
if (cid != null) {
|
await _client.chatPersistenceClient?.deleteChannels([eventChannel.cid]);
|
||||||
_client.chatPersistenceClient?.deleteChannels([cid]);
|
channels[eventChannel.cid]?.dispose();
|
||||||
}
|
channels = channels..remove(eventChannel.cid);
|
||||||
channels = channels..removeWhere((cid, ch) => cid == event.cid);
|
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import 'package:stream_chat/src/core/http/token_manager.dart';
|
|||||||
|
|
||||||
/// Authentication interceptor that refreshes the token if
|
/// Authentication interceptor that refreshes the token if
|
||||||
/// an auth error is received
|
/// an auth error is received
|
||||||
class AuthInterceptor extends Interceptor {
|
class AuthInterceptor extends QueuedInterceptor {
|
||||||
/// Initialize a new auth interceptor
|
/// Initialize a new auth interceptor
|
||||||
AuthInterceptor(this._client, this._tokenManager);
|
AuthInterceptor(this._client, this._tokenManager);
|
||||||
|
|
||||||
@@ -57,35 +57,10 @@ class AuthInterceptor extends Interceptor {
|
|||||||
final error = ErrorResponse.fromJson(data);
|
final error = ErrorResponse.fromJson(data);
|
||||||
if (error.code == ChatErrorCode.tokenExpired.code) {
|
if (error.code == ChatErrorCode.tokenExpired.code) {
|
||||||
if (_tokenManager.isStatic) return handler.next(err);
|
if (_tokenManager.isStatic) return handler.next(err);
|
||||||
_client.lock();
|
|
||||||
await _tokenManager.loadToken(refresh: true);
|
await _tokenManager.loadToken(refresh: true);
|
||||||
_client.unlock();
|
|
||||||
try {
|
try {
|
||||||
final options = err.requestOptions;
|
final options = err.requestOptions;
|
||||||
final response = await _client.request(
|
final response = await _client.fetch(options);
|
||||||
options.path,
|
|
||||||
cancelToken: options.cancelToken,
|
|
||||||
data: options.data,
|
|
||||||
onReceiveProgress: options.onReceiveProgress,
|
|
||||||
onSendProgress: options.onSendProgress,
|
|
||||||
queryParameters: options.queryParameters,
|
|
||||||
options: Options(
|
|
||||||
method: options.method,
|
|
||||||
sendTimeout: options.sendTimeout,
|
|
||||||
receiveTimeout: options.receiveTimeout,
|
|
||||||
extra: options.extra,
|
|
||||||
headers: options.headers,
|
|
||||||
responseType: options.responseType,
|
|
||||||
contentType: options.contentType,
|
|
||||||
validateStatus: options.validateStatus,
|
|
||||||
receiveDataWhenStatusError: options.receiveDataWhenStatusError,
|
|
||||||
followRedirects: options.followRedirects,
|
|
||||||
maxRedirects: options.maxRedirects,
|
|
||||||
requestEncoder: options.requestEncoder,
|
|
||||||
responseDecoder: options.responseDecoder,
|
|
||||||
listFormat: options.listFormat,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
return handler.resolve(response);
|
return handler.resolve(response);
|
||||||
} on DioError catch (error) {
|
} on DioError catch (error) {
|
||||||
return handler.next(error);
|
return handler.next(error);
|
||||||
|
|||||||
@@ -76,20 +76,6 @@ class StreamHttpClient {
|
|||||||
@visibleForTesting
|
@visibleForTesting
|
||||||
final Dio httpClient;
|
final Dio httpClient;
|
||||||
|
|
||||||
/// Lock the current [StreamHttpClient] instance.
|
|
||||||
///
|
|
||||||
/// [StreamHttpClient] will enqueue the incoming request tasks instead
|
|
||||||
/// send them directly when [interceptor.requestOptions] is locked.
|
|
||||||
void lock() => httpClient.lock();
|
|
||||||
|
|
||||||
/// Unlock the current [StreamHttpClient] instance.
|
|
||||||
///
|
|
||||||
/// [StreamHttpClient] instance dequeue the request task。
|
|
||||||
void unlock() => httpClient.unlock();
|
|
||||||
|
|
||||||
/// Clear the current [StreamHttpClient] instance waiting queue.
|
|
||||||
void clear() => httpClient.clear();
|
|
||||||
|
|
||||||
/// Shuts down the [StreamHttpClient].
|
/// Shuts down the [StreamHttpClient].
|
||||||
///
|
///
|
||||||
/// If [force] is `false` the [StreamHttpClient] will be kept alive
|
/// If [force] is `false` the [StreamHttpClient] will be kept alive
|
||||||
@@ -280,4 +266,17 @@ class StreamHttpClient {
|
|||||||
throw _parseError(error);
|
throw _parseError(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Handy method to make http requests from [RequestOptions]
|
||||||
|
/// with error parsing.
|
||||||
|
Future<Response<T>> fetch<T>(
|
||||||
|
RequestOptions requestOptions,
|
||||||
|
) async {
|
||||||
|
try {
|
||||||
|
final response = await httpClient.fetch<T>(requestOptions);
|
||||||
|
return response;
|
||||||
|
} on DioError catch (error) {
|
||||||
|
throw _parseError(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ class User extends Equatable {
|
|||||||
/// {@macro name}
|
/// {@macro name}
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(ignore: true)
|
||||||
String get name {
|
String get name {
|
||||||
if (extraData.containsKey('name')) {
|
if (extraData.containsKey('name') && extraData['name'] != null) {
|
||||||
final name = extraData['name']! as String;
|
final name = extraData['name']! as String;
|
||||||
if (name.isNotEmpty) return name;
|
if (name.isNotEmpty) return name;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,4 +3,4 @@ import 'package:stream_chat/src/client/client.dart';
|
|||||||
/// Current package version
|
/// Current package version
|
||||||
/// Used in [StreamChatClient] to build the `x-stream-client` header
|
/// Used in [StreamChatClient] to build the `x-stream-client` header
|
||||||
// ignore: constant_identifier_names
|
// ignore: constant_identifier_names
|
||||||
const PACKAGE_VERSION = '4.2.0';
|
const PACKAGE_VERSION = '4.3.0';
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
name: stream_chat
|
name: stream_chat
|
||||||
homepage: https://getstream.io/
|
homepage: https://getstream.io/
|
||||||
description: The official Dart client for Stream Chat, a service for building chat applications.
|
description: The official Dart client for Stream Chat, a service for building chat applications.
|
||||||
version: 4.2.0
|
version: 4.3.0
|
||||||
repository: https://github.com/GetStream/stream-chat-flutter
|
repository: https://github.com/GetStream/stream-chat-flutter
|
||||||
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
|
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
|
||||||
|
|
||||||
|
|||||||
@@ -2513,7 +2513,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test(
|
test(
|
||||||
'setting the `currentUser` should also compute and update the unreadCounts',
|
'''setting the `currentUser` should also compute and update the unreadCounts''',
|
||||||
() {
|
() {
|
||||||
final state = client.state;
|
final state = client.state;
|
||||||
final initialUser = OwnUser.fromUser(user);
|
final initialUser = OwnUser.fromUser(user);
|
||||||
|
|||||||
@@ -93,23 +93,11 @@ void main() {
|
|||||||
|
|
||||||
when(() => tokenManager.isStatic).thenReturn(false);
|
when(() => tokenManager.isStatic).thenReturn(false);
|
||||||
|
|
||||||
when(() => client.lock()).thenReturn(() {});
|
|
||||||
|
|
||||||
final token = Token.development('test-user-id');
|
final token = Token.development('test-user-id');
|
||||||
when(() => tokenManager.loadToken(refresh: true))
|
when(() => tokenManager.loadToken(refresh: true))
|
||||||
.thenAnswer((_) async => token);
|
.thenAnswer((_) async => token);
|
||||||
|
|
||||||
when(() => client.unlock()).thenReturn(() {});
|
when(() => client.fetch(options)).thenAnswer((_) async => Response(
|
||||||
|
|
||||||
when(() => client.request(
|
|
||||||
path,
|
|
||||||
data: options.data,
|
|
||||||
onReceiveProgress: options.onReceiveProgress,
|
|
||||||
onSendProgress: options.onSendProgress,
|
|
||||||
queryParameters: options.queryParameters,
|
|
||||||
cancelToken: options.cancelToken,
|
|
||||||
options: any(named: 'options'),
|
|
||||||
)).thenAnswer((_) async => Response(
|
|
||||||
requestOptions: options,
|
requestOptions: options,
|
||||||
statusCode: 200,
|
statusCode: 200,
|
||||||
));
|
));
|
||||||
@@ -127,21 +115,10 @@ void main() {
|
|||||||
|
|
||||||
verify(() => tokenManager.isStatic).called(1);
|
verify(() => tokenManager.isStatic).called(1);
|
||||||
|
|
||||||
verify(() => client.lock()).called(1);
|
|
||||||
|
|
||||||
verify(() => tokenManager.loadToken(refresh: true)).called(1);
|
verify(() => tokenManager.loadToken(refresh: true)).called(1);
|
||||||
verifyNoMoreInteractions(tokenManager);
|
verifyNoMoreInteractions(tokenManager);
|
||||||
|
|
||||||
verify(() => client.unlock()).called(1);
|
verify(() => client.fetch(options)).called(1);
|
||||||
verify(() => client.request(
|
|
||||||
path,
|
|
||||||
data: options.data,
|
|
||||||
onReceiveProgress: options.onReceiveProgress,
|
|
||||||
onSendProgress: options.onSendProgress,
|
|
||||||
queryParameters: options.queryParameters,
|
|
||||||
cancelToken: options.cancelToken,
|
|
||||||
options: any(named: 'options'),
|
|
||||||
)).called(1);
|
|
||||||
verifyNoMoreInteractions(client);
|
verifyNoMoreInteractions(client);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -163,23 +140,11 @@ void main() {
|
|||||||
|
|
||||||
when(() => tokenManager.isStatic).thenReturn(false);
|
when(() => tokenManager.isStatic).thenReturn(false);
|
||||||
|
|
||||||
when(() => client.lock()).thenReturn(() {});
|
|
||||||
|
|
||||||
final token = Token.development('test-user-id');
|
final token = Token.development('test-user-id');
|
||||||
when(() => tokenManager.loadToken(refresh: true))
|
when(() => tokenManager.loadToken(refresh: true))
|
||||||
.thenAnswer((_) async => token);
|
.thenAnswer((_) async => token);
|
||||||
|
|
||||||
when(() => client.unlock()).thenReturn(() {});
|
when(() => client.fetch(options)).thenThrow(err);
|
||||||
|
|
||||||
when(() => client.request(
|
|
||||||
path,
|
|
||||||
data: options.data,
|
|
||||||
onReceiveProgress: options.onReceiveProgress,
|
|
||||||
onSendProgress: options.onSendProgress,
|
|
||||||
queryParameters: options.queryParameters,
|
|
||||||
cancelToken: options.cancelToken,
|
|
||||||
options: any(named: 'options'),
|
|
||||||
)).thenThrow(err);
|
|
||||||
|
|
||||||
authInterceptor.onError(err, handler);
|
authInterceptor.onError(err, handler);
|
||||||
|
|
||||||
@@ -193,21 +158,10 @@ void main() {
|
|||||||
|
|
||||||
verify(() => tokenManager.isStatic).called(1);
|
verify(() => tokenManager.isStatic).called(1);
|
||||||
|
|
||||||
verify(() => client.lock()).called(1);
|
|
||||||
|
|
||||||
verify(() => tokenManager.loadToken(refresh: true)).called(1);
|
verify(() => tokenManager.loadToken(refresh: true)).called(1);
|
||||||
verifyNoMoreInteractions(tokenManager);
|
verifyNoMoreInteractions(tokenManager);
|
||||||
|
|
||||||
verify(() => client.unlock()).called(1);
|
verify(() => client.fetch(options)).called(1);
|
||||||
verify(() => client.request(
|
|
||||||
path,
|
|
||||||
data: options.data,
|
|
||||||
onReceiveProgress: options.onReceiveProgress,
|
|
||||||
onSendProgress: options.onSendProgress,
|
|
||||||
queryParameters: options.queryParameters,
|
|
||||||
cancelToken: options.cancelToken,
|
|
||||||
options: any(named: 'options'),
|
|
||||||
)).called(1);
|
|
||||||
verifyNoMoreInteractions(client);
|
verifyNoMoreInteractions(client);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,45 +1,77 @@
|
|||||||
|
## 4.3.0
|
||||||
|
|
||||||
|
- Updated `photo_view` dependency to [`0.14.0`](https://pub.dev/packages/photo_view/changelog).
|
||||||
|
|
||||||
|
🐞 Fixed
|
||||||
|
|
||||||
|
- [[#1180]](https://github.com/GetStream/stream-chat-flutter/issues/1180) Fix file download.
|
||||||
|
- Fix commands resetting the `StreamMessageInputController.value`.
|
||||||
|
- [[#996]](https://github.com/GetStream/stream-chat-flutter/issues/996) Videos break bottom photo
|
||||||
|
carousal.
|
||||||
|
- Fix: URLs with path and/or query params are not enriched.
|
||||||
|
- [[#1194]](https://github.com/GetStream/stream-chat-flutter/issues/1194) Request permission to access gallery when opening the file picker.
|
||||||
|
|
||||||
|
✅ Added
|
||||||
|
|
||||||
|
- [[#1011]](https://github.com/GetStream/stream-chat-flutter/issues/1011) Animate the background
|
||||||
|
color of pinned messages.
|
||||||
|
- Added unread messages divider in `StreamMessageListView`.
|
||||||
|
- Added `StreamMessageListView.unreadMessagesSeparatorBuilder`.
|
||||||
|
- Now `StreamMessageListView` opens to the oldest unread message by default.
|
||||||
|
|
||||||
## 4.2.0
|
## 4.2.0
|
||||||
|
|
||||||
🐞 Fixed
|
🐞 Fixed
|
||||||
|
|
||||||
- [[#1133]](https://github.com/GetStream/stream-chat-flutter/issues/1133) Visibility override flags not being passed to `StreamMessageActionsModal`
|
- [[#1133]](https://github.com/GetStream/stream-chat-flutter/issues/1133) Visibility override flags
|
||||||
|
not being passed to `StreamMessageActionsModal`
|
||||||
|
|
||||||
## 4.1.0
|
## 4.1.0
|
||||||
|
|
||||||
✅ Added
|
✅ Added
|
||||||
|
|
||||||
- [[#1119]](https://github.com/GetStream/stream-chat-flutter/issues/1119) Added an option to disable mentions overlay in `StreamMessageInput`
|
- [[#1119]](https://github.com/GetStream/stream-chat-flutter/issues/1119) Added an option to disable
|
||||||
- Deprecated `disableEmojiSuggestionsOverlay` in favor of `enableEmojiSuggestionsOverlay` in `StreamMessageInput`
|
mentions overlay in `StreamMessageInput`
|
||||||
|
- Deprecated `disableEmojiSuggestionsOverlay` in favor of `enableEmojiSuggestionsOverlay`
|
||||||
|
in `StreamMessageInput`
|
||||||
|
|
||||||
🐞 Fixed
|
🐞 Fixed
|
||||||
|
|
||||||
- Fixed attachment picker ui.
|
- Fixed attachment picker ui.
|
||||||
- Fixed StreamChannelHeader and StreamThreadHeader subtitle alignment.
|
- Fixed StreamChannelHeader and StreamThreadHeader subtitle alignment.
|
||||||
- Fixed message widget thread indicator in reverse mode.
|
- Fixed message widget thread indicator in reverse mode.
|
||||||
- [[#1044]](https://github.com/GetStream/stream-chat-flutter/issues/1044): Refactor StreamMessageWidget bottom row to use Text.rich.
|
- [[#1044]](https://github.com/GetStream/stream-chat-flutter/issues/1044): Refactor
|
||||||
|
StreamMessageWidget bottom row to use Text.rich.
|
||||||
|
|
||||||
🔄 Changed
|
🔄 Changed
|
||||||
|
|
||||||
- Removed `isOwner` condition from `ChannelBottomSheet` and `StreamChannelInfoBottomSheet` for delete option tile.
|
- Removed `isOwner` condition from `ChannelBottomSheet` and `StreamChannelInfoBottomSheet` for
|
||||||
|
delete option tile.
|
||||||
|
|
||||||
## 4.0.1
|
## 4.0.1
|
||||||
|
|
||||||
- Minor fixes
|
- Minor fixes
|
||||||
- Updated `stream_chat_flutter_core` dependency to [`4.0.1`](https://pub.dev/packages/stream_chat_flutter_core/changelog).
|
- Updated `stream_chat_flutter_core` dependency
|
||||||
|
to [`4.0.1`](https://pub.dev/packages/stream_chat_flutter_core/changelog).
|
||||||
|
|
||||||
## 4.0.0
|
## 4.0.0
|
||||||
|
|
||||||
For upgrading to V4, please refer to the [V4 Migration Guide](https://getstream.io/chat/docs/sdk/flutter/guides/migration_guide_4_0/)
|
For upgrading to V4, please refer to
|
||||||
|
the [V4 Migration Guide](https://getstream.io/chat/docs/sdk/flutter/guides/migration_guide_4_0/)
|
||||||
|
|
||||||
✅ Added
|
✅ Added
|
||||||
|
|
||||||
- [[#1087]](https://github.com/GetStream/stream-chat-flutter/issues/1087): Handle limited access to camera on iOS.
|
- [[#1087]](https://github.com/GetStream/stream-chat-flutter/issues/1087): Handle limited access to
|
||||||
- `centerTitle` and `elevation` properties to `ChannelHeader`, `ThreadHeader` and `ChannelListHeader`.
|
camera on iOS.
|
||||||
|
- `centerTitle` and `elevation` properties to `ChannelHeader`, `ThreadHeader`
|
||||||
|
and `ChannelListHeader`.
|
||||||
|
|
||||||
🐞 Fixed
|
🐞 Fixed
|
||||||
|
|
||||||
- [[#1067]](https://github.com/GetStream/stream-chat-flutter/issues/1067): Fix name text overflow in reaction card.
|
- [[#1067]](https://github.com/GetStream/stream-chat-flutter/issues/1067): Fix name text overflow in
|
||||||
- [[#842]](https://github.com/GetStream/stream-chat-flutter/issues/842): show date divider for first message.
|
reaction card.
|
||||||
|
- [[#842]](https://github.com/GetStream/stream-chat-flutter/issues/842): show date divider for first
|
||||||
|
message.
|
||||||
- Loosen up url check for attachment download.
|
- Loosen up url check for attachment download.
|
||||||
- Use `ogScrapeUrl` for LinkAttachments.
|
- Use `ogScrapeUrl` for LinkAttachments.
|
||||||
|
|
||||||
@@ -48,16 +80,20 @@ For upgrading to V4, please refer to the [V4 Migration Guide](https://getstream.
|
|||||||
✅ Added
|
✅ Added
|
||||||
|
|
||||||
- Added support to pass `autoCorrect` to `StreamMessageInput` for the text input field
|
- Added support to pass `autoCorrect` to `StreamMessageInput` for the text input field
|
||||||
- Added support to control the visibility of the default emoji suggestions overlay in `StreamMessageInput`
|
- Added support to control the visibility of the default emoji suggestions overlay
|
||||||
|
in `StreamMessageInput`
|
||||||
- Added support to build custom widget for scrollToBottom in `StreamMessageListView`
|
- Added support to build custom widget for scrollToBottom in `StreamMessageListView`
|
||||||
|
|
||||||
🐞 Fixed
|
🐞 Fixed
|
||||||
|
|
||||||
- Minor fixes and improvements
|
- Minor fixes and improvements
|
||||||
-[[#892]](https://github.com/GetStream/stream-chat-flutter/issues/892): Fix default `initialAlignment` in `MessageListView`.
|
-[[#892]](https://github.com/GetStream/stream-chat-flutter/issues/892): Fix
|
||||||
- Fix `MessageInputTheme.inputBackgroundColor` color not being used in some widgets of `MessageInput`
|
default `initialAlignment` in `MessageListView`.
|
||||||
|
- Fix `MessageInputTheme.inputBackgroundColor` color not being used in some widgets
|
||||||
|
of `MessageInput`
|
||||||
- Removed dependency on `visibility_detector`
|
- Removed dependency on `visibility_detector`
|
||||||
- [[#1071]](https://github.com/GetStream/stream-chat-flutter/issues/1071): Fixed the way attachment actions were handled in full screen
|
- [[#1071]](https://github.com/GetStream/stream-chat-flutter/issues/1071): Fixed the way attachment
|
||||||
|
actions were handled in full screen
|
||||||
|
|
||||||
## 4.0.0-beta.1
|
## 4.0.0-beta.1
|
||||||
|
|
||||||
@@ -70,22 +106,27 @@ For upgrading to V4, please refer to the [V4 Migration Guide](https://getstream.
|
|||||||
- Deprecated `ChannelAvatar` in favor of `StreamChannelAvatar`.
|
- Deprecated `ChannelAvatar` in favor of `StreamChannelAvatar`.
|
||||||
- Deprecated `ChannelName` in favor of `StreamChannelName`.
|
- Deprecated `ChannelName` in favor of `StreamChannelName`.
|
||||||
- Deprecated `MessageInput` in favor of `StreamMessageInput`.
|
- Deprecated `MessageInput` in favor of `StreamMessageInput`.
|
||||||
- Separated `MessageInput` widget in smaller components. (For example `CountDownButton`, `StreamAttachmentPicker`...)
|
- Separated `MessageInput` widget in smaller components. (For example `CountDownButton`
|
||||||
- Updated `stream_chat_flutter_core` dependency to [`4.0.0-beta.0`](https://pub.dev/packages/stream_chat_flutter_core/changelog).
|
, `StreamAttachmentPicker`...)
|
||||||
|
- Updated `stream_chat_flutter_core` dependency
|
||||||
|
to [`4.0.0-beta.0`](https://pub.dev/packages/stream_chat_flutter_core/changelog).
|
||||||
- Added OpenGraph preview support for links in `StreamMessageInput`.
|
- Added OpenGraph preview support for links in `StreamMessageInput`.
|
||||||
- Removed video compression.
|
- Removed video compression.
|
||||||
|
|
||||||
## 3.6.1
|
## 3.6.1
|
||||||
|
|
||||||
- Updated `stream_chat_flutter_core` dependency to [`3.6.1`](https://pub.dev/packages/stream_chat_flutter_core/changelog).
|
- Updated `stream_chat_flutter_core` dependency
|
||||||
|
to [`3.6.1`](https://pub.dev/packages/stream_chat_flutter_core/changelog).
|
||||||
|
|
||||||
## 3.6.0
|
## 3.6.0
|
||||||
|
|
||||||
🐞 Fixed
|
🐞 Fixed
|
||||||
|
|
||||||
- Minor fixes and improvements
|
- Minor fixes and improvements
|
||||||
-[[#892]](https://github.com/GetStream/stream-chat-flutter/issues/892): Fix default `initialAlignment` in `MessageListView`.
|
-[[#892]](https://github.com/GetStream/stream-chat-flutter/issues/892): Fix
|
||||||
- Fix `MessageInputTheme.inputBackgroundColor` color not being used in some widgets of `MessageInput`
|
default `initialAlignment` in `MessageListView`.
|
||||||
|
- Fix `MessageInputTheme.inputBackgroundColor` color not being used in some widgets
|
||||||
|
of `MessageInput`
|
||||||
- Removed dependency on `visibility_detector`
|
- Removed dependency on `visibility_detector`
|
||||||
|
|
||||||
## 3.5.1
|
## 3.5.1
|
||||||
@@ -98,32 +139,35 @@ For upgrading to V4, please refer to the [V4 Migration Guide](https://getstream.
|
|||||||
🐞 Fixed
|
🐞 Fixed
|
||||||
|
|
||||||
- Mentions overlay now doesn't overflow when there is not enough height available
|
- Mentions overlay now doesn't overflow when there is not enough height available
|
||||||
- Updated `stream_chat_flutter_core` dependency to [`3.5.1`](https://pub.dev/packages/stream_chat_flutter_core/changelog).
|
- Updated `stream_chat_flutter_core` dependency
|
||||||
|
to [`3.5.1`](https://pub.dev/packages/stream_chat_flutter_core/changelog).
|
||||||
|
|
||||||
✅ Added
|
✅ Added
|
||||||
|
|
||||||
- `onLinkTap` for `MessageWidget` can now be passed down to `UrlAttachment`.
|
- `onLinkTap` for `MessageWidget` can now be passed down to `UrlAttachment`.
|
||||||
|
|
||||||
|
|
||||||
## 3.5.0
|
## 3.5.0
|
||||||
|
|
||||||
🐞 Fixed
|
🐞 Fixed
|
||||||
|
|
||||||
- [[#888]](https://github.com/GetStream/stream-chat-flutter/issues/888) Fix `unban` command not working in `MessageInput`.
|
- [[#888]](https://github.com/GetStream/stream-chat-flutter/issues/888) Fix `unban` command not
|
||||||
- [[#805]](https://github.com/GetStream/stream-chat-flutter/issues/805) Updated chewie dependency version to 1.3.0
|
working in `MessageInput`.
|
||||||
|
- [[#805]](https://github.com/GetStream/stream-chat-flutter/issues/805) Updated chewie dependency
|
||||||
|
version to 1.3.0
|
||||||
- Fix `showScrollToBottom` in `MessageListView` not respecting false value.
|
- Fix `showScrollToBottom` in `MessageListView` not respecting false value.
|
||||||
- Fix default `Channel` route not opening from `ChannelListView` when `ChannelAvatar` is tapped
|
- Fix default `Channel` route not opening from `ChannelListView` when `ChannelAvatar` is tapped
|
||||||
|
|
||||||
## 3.4.0
|
## 3.4.0
|
||||||
|
|
||||||
- Updated `stream_chat_flutter_core` dependency to [`3.4.0`](https://pub.dev/packages/stream_chat_flutter_core/changelog).
|
- Updated `stream_chat_flutter_core` dependency
|
||||||
|
to [`3.4.0`](https://pub.dev/packages/stream_chat_flutter_core/changelog).
|
||||||
|
|
||||||
🐞 Fixed
|
🐞 Fixed
|
||||||
|
|
||||||
- SVG rendering fixes.
|
- SVG rendering fixes.
|
||||||
- Use file extension instead of mimeType for downloading files.
|
- Use file extension instead of mimeType for downloading files.
|
||||||
- [[#860]](https://github.com/GetStream/stream-chat-flutter/issues/860) CastError while compressing Videos.
|
- [[#860]](https://github.com/GetStream/stream-chat-flutter/issues/860) CastError while compressing
|
||||||
|
Videos.
|
||||||
|
|
||||||
✅ Added
|
✅ Added
|
||||||
|
|
||||||
@@ -136,22 +180,26 @@ For upgrading to V4, please refer to the [V4 Migration Guide](https://getstream.
|
|||||||
|
|
||||||
## 3.3.2
|
## 3.3.2
|
||||||
|
|
||||||
- Updated `stream_chat_flutter_core` dependency to [`3.3.1`](https://pub.dev/packages/stream_chat_flutter_core/changelog).
|
- Updated `stream_chat_flutter_core` dependency
|
||||||
|
to [`3.3.1`](https://pub.dev/packages/stream_chat_flutter_core/changelog).
|
||||||
|
|
||||||
## 3.3.1
|
## 3.3.1
|
||||||
|
|
||||||
✅ Added
|
✅ Added
|
||||||
|
|
||||||
- `MessageListView` now allows more better control over spacing after messages using `spacingWidgetBuilder`.
|
- `MessageListView` now allows more better control over spacing after messages
|
||||||
|
using `spacingWidgetBuilder`.
|
||||||
- `StreamChannel` can now fetch messages around a message ID with the `queryAroundMessage` call.
|
- `StreamChannel` can now fetch messages around a message ID with the `queryAroundMessage` call.
|
||||||
- Added `MessageListView.keyboardDismissBehavior` property.
|
- Added `MessageListView.keyboardDismissBehavior` property.
|
||||||
|
|
||||||
🐞 Fixed
|
🐞 Fixed
|
||||||
|
|
||||||
- [[#766]](https://github.com/GetStream/stream-chat-flutter/issues/766) `AttachmentActionsModal` now has customisation options for actions.
|
- [[#766]](https://github.com/GetStream/stream-chat-flutter/issues/766) `AttachmentActionsModal` now
|
||||||
|
has customisation options for actions.
|
||||||
- Fixed `MessageWidget` null errors associated with `channel.memberCount`.
|
- Fixed `MessageWidget` null errors associated with `channel.memberCount`.
|
||||||
- Fixed adding attachments on web.
|
- Fixed adding attachments on web.
|
||||||
- [[#767]](https://github.com/GetStream/stream-chat-flutter/issues/767): Fix `MessageInput` focus behaviour when sending messages.
|
- [[#767]](https://github.com/GetStream/stream-chat-flutter/issues/767): Fix `MessageInput` focus
|
||||||
|
behaviour when sending messages.
|
||||||
- Fixed user presence indicator not updating correctly.
|
- Fixed user presence indicator not updating correctly.
|
||||||
- Do not use `withData: true` in `FilePicker` calls.
|
- Do not use `withData: true` in `FilePicker` calls.
|
||||||
- Fixed read indicator not updating correctly in specific situations.
|
- Fixed read indicator not updating correctly in specific situations.
|
||||||
@@ -159,29 +207,35 @@ For upgrading to V4, please refer to the [V4 Migration Guide](https://getstream.
|
|||||||
## 3.2.0
|
## 3.2.0
|
||||||
|
|
||||||
- Updated Dart SDK constraints to `>=2.14.0 <3.0.0`.
|
- Updated Dart SDK constraints to `>=2.14.0 <3.0.0`.
|
||||||
- Updated `stream_chat_flutter_core` dependency to [`3.2.0`](https://pub.dev/packages/stream_chat_flutter_core/changelog).
|
- Updated `stream_chat_flutter_core` dependency
|
||||||
|
to [`3.2.0`](https://pub.dev/packages/stream_chat_flutter_core/changelog).
|
||||||
|
|
||||||
🐞 Fixed
|
🐞 Fixed
|
||||||
|
|
||||||
- Fixed message highlight animation alignment in `MessageListView`.
|
- Fixed message highlight animation alignment in `MessageListView`.
|
||||||
- [[#491]](https://github.com/GetStream/stream-chat-flutter/issues/491): Fix `MediaListView` showing media in wrong order.
|
- [[#491]](https://github.com/GetStream/stream-chat-flutter/issues/491): Fix `MediaListView` showing
|
||||||
|
media in wrong order.
|
||||||
- Fixed `MessageListView` initialIndex not working in some cases.
|
- Fixed `MessageListView` initialIndex not working in some cases.
|
||||||
- Improved `MessageListView` rendering in case of reordering.
|
- Improved `MessageListView` rendering in case of reordering.
|
||||||
- Fix image thumbnail generation when using Stream CDN.
|
- Fix image thumbnail generation when using Stream CDN.
|
||||||
|
|
||||||
✅ Added
|
✅ Added
|
||||||
|
|
||||||
- `MessageListViewThemeData` now accepts a `DecorationImage` as a background image for `MessageListView`.
|
- `MessageListViewThemeData` now accepts a `DecorationImage` as a background image
|
||||||
|
for `MessageListView`.
|
||||||
|
|
||||||
## 3.1.1
|
## 3.1.1
|
||||||
|
|
||||||
- Updated `stream_chat_flutter_core` dependency to [`3.1.1`](https://pub.dev/packages/stream_chat_flutter_core/changelog).
|
- Updated `stream_chat_flutter_core` dependency
|
||||||
|
to [`3.1.1`](https://pub.dev/packages/stream_chat_flutter_core/changelog).
|
||||||
- Updated `file_picker`, `image_gallery_saver`, and `video_thumbnail` to the latest versions.
|
- Updated `file_picker`, `image_gallery_saver`, and `video_thumbnail` to the latest versions.
|
||||||
|
|
||||||
🐞 Fixed
|
🐞 Fixed
|
||||||
|
|
||||||
- [[#687]](https://github.com/GetStream/stream-chat-flutter/issues/687): Fix Users losing their place in the conversation after replying in threads.
|
- [[#687]](https://github.com/GetStream/stream-chat-flutter/issues/687): Fix Users losing their
|
||||||
- Fixed floating date stream subscription causing "Bad state: stream has already been listened.” error.
|
place in the conversation after replying in threads.
|
||||||
|
- Fixed floating date stream subscription causing "Bad state: stream has already been listened.”
|
||||||
|
error.
|
||||||
- Fixed `String` capitalize extension not working on empty strings.
|
- Fixed `String` capitalize extension not working on empty strings.
|
||||||
|
|
||||||
✅ Added
|
✅ Added
|
||||||
@@ -189,17 +243,21 @@ For upgrading to V4, please refer to the [V4 Migration Guide](https://getstream.
|
|||||||
- Added `MessageInput.customOverlays` property to add custom overlays to the message input.
|
- Added `MessageInput.customOverlays` property to add custom overlays to the message input.
|
||||||
- Added `MessageInput.mentionAllAppUsers` property to mention all app users in the message input.
|
- Added `MessageInput.mentionAllAppUsers` property to mention all app users in the message input.
|
||||||
- The `MessageInput` now supports local search for channels with less than 100 members.
|
- The `MessageInput` now supports local search for channels with less than 100 members.
|
||||||
- Added `MessageListView.paginationLoadingIndicatorBuilder` to override the default loading indicator shown while paginating the message list.
|
- Added `MessageListView.paginationLoadingIndicatorBuilder` to override the default loading
|
||||||
- Added new `linkBackgroundColor` in `MessageTheme` for setting background colors of link attachments.
|
indicator shown while paginating the message list.
|
||||||
|
- Added new `linkBackgroundColor` in `MessageTheme` for setting background colors of link
|
||||||
|
attachments.
|
||||||
|
|
||||||
⚠️ Deprecated
|
⚠️ Deprecated
|
||||||
|
|
||||||
- `MessageInput.mentionsTileBuilder` is now deprecated in favor of `MessageInput.userMentionsTileBuilder`.
|
- `MessageInput.mentionsTileBuilder` is now deprecated in favor
|
||||||
|
of `MessageInput.userMentionsTileBuilder`.
|
||||||
- `MentionTile` is now deprecated in favor of `UserMentionsTile`.
|
- `MentionTile` is now deprecated in favor of `UserMentionsTile`.
|
||||||
|
|
||||||
## 3.0.0
|
## 3.0.0
|
||||||
|
|
||||||
- Updated `stream_chat_flutter_core` dependency to [`3.0.0`](https://pub.dev/packages/stream_chat_flutter_core/changelog).
|
- Updated `stream_chat_flutter_core` dependency
|
||||||
|
to [`3.0.0`](https://pub.dev/packages/stream_chat_flutter_core/changelog).
|
||||||
|
|
||||||
🛑️ Breaking Changes from `2.2.1`
|
🛑️ Breaking Changes from `2.2.1`
|
||||||
|
|
||||||
@@ -207,16 +265,19 @@ For upgrading to V4, please refer to the [V4 Migration Guide](https://getstream.
|
|||||||
|
|
||||||
🐞 Fixed
|
🐞 Fixed
|
||||||
|
|
||||||
- [[#668]](https://github.com/GetStream/stream-chat-flutter/issues/668): Fix `MessageInput` rendering errors in case
|
- [[#668]](https://github.com/GetStream/stream-chat-flutter/issues/668): Fix `MessageInput`
|
||||||
there are no actions available to show.
|
rendering errors in case there are no actions available to show.
|
||||||
- [[#349]](https://github.com/GetStream/stream-chat-flutter/issues/349): Fix `MessageInput` attachment render overflow error.
|
- [[#349]](https://github.com/GetStream/stream-chat-flutter/issues/349): Fix `MessageInput`
|
||||||
|
attachment render overflow error.
|
||||||
- `MessageInput` overlays now follow the `MessageInput` focus.
|
- `MessageInput` overlays now follow the `MessageInput` focus.
|
||||||
- [[#674]](https://github.com/GetStream/stream-chat-flutter/issues/674): Check scrollController is attached before calling jump in MessageListView.
|
- [[#674]](https://github.com/GetStream/stream-chat-flutter/issues/674): Check scrollController is
|
||||||
|
attached before calling jump in MessageListView.
|
||||||
- Fixed `MessageListView` header and footer when `reverse: false`.
|
- Fixed `MessageListView` header and footer when `reverse: false`.
|
||||||
|
|
||||||
🔄 Changed
|
🔄 Changed
|
||||||
|
|
||||||
- Animation curves changed from default `Curves.linear` to `Curves.easeOut` and `Curves.easeIn` for attachment controls.
|
- Animation curves changed from default `Curves.linear` to `Curves.easeOut` and `Curves.easeIn` for
|
||||||
|
attachment controls.
|
||||||
- Removed default padding in `DateDivider` in `MessageListView`
|
- Removed default padding in `DateDivider` in `MessageListView`
|
||||||
|
|
||||||
✅ Added
|
✅ Added
|
||||||
@@ -273,17 +334,20 @@ For upgrading to V4, please refer to the [V4 Migration Guide](https://getstream.
|
|||||||
✅ Added
|
✅ Added
|
||||||
|
|
||||||
- [#516](https://github.com/GetStream/stream-chat-flutter/issues/516):
|
- [#516](https://github.com/GetStream/stream-chat-flutter/issues/516):
|
||||||
Added `StreamChatThemeData.placeholderUserImage` for building a widget when the `UserAvatar` image is loading
|
Added `StreamChatThemeData.placeholderUserImage` for building a widget when the `UserAvatar` image
|
||||||
|
is loading
|
||||||
- Added a `backgroundColor` property to the following widgets:
|
- Added a `backgroundColor` property to the following widgets:
|
||||||
- `ChannelHeader`
|
- `ChannelHeader`
|
||||||
- `ChannelListHeader`
|
- `ChannelListHeader`
|
||||||
- `GalleryHeader`
|
- `GalleryHeader`
|
||||||
- `GalleryFooter`
|
- `GalleryFooter`
|
||||||
- `ThreadHeader`
|
- `ThreadHeader`
|
||||||
- Added `MessageInput.attachmentLimit` in order to limit the no. of attachments that can be sent with a single message.
|
- Added `MessageInput.attachmentLimit` in order to limit the no. of attachments that can be sent
|
||||||
- Added `MessageInput.onAttachmentLimitExceed` callback which will be called when the `attachmentLimit` is exceeded.
|
with a single message.
|
||||||
This will override the default error alert behaviour.
|
- Added `MessageInput.onAttachmentLimitExceed` callback which will be called when
|
||||||
- Added `MessageInput.attachmentButtonBuilder` and `MessageInput.commandButtonBuilder` for more customizations.
|
the `attachmentLimit` is exceeded. This will override the default error alert behaviour.
|
||||||
|
- Added `MessageInput.attachmentButtonBuilder` and `MessageInput.commandButtonBuilder` for more
|
||||||
|
customizations.
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
typedef ActionButtonBuilder = Widget Function(
|
typedef ActionButtonBuilder = Widget Function(
|
||||||
@@ -299,8 +363,9 @@ You can call `.copyWith` to customize just a subset of properties.
|
|||||||
|
|
||||||
🔄 Changed
|
🔄 Changed
|
||||||
|
|
||||||
Theming has been upgraded! Most theme classes now have `InheritedTheme` classes associated with them, and have been
|
Theming has been upgraded! Most theme classes now have `InheritedTheme` classes associated with
|
||||||
upgraded with some goodies like `lerp` functions. Here's the full naming breakdown:
|
them, and have been upgraded with some goodies like `lerp` functions. Here's the full naming
|
||||||
|
breakdown:
|
||||||
|
|
||||||
* `AvatarTheme` is now `AvatarThemeData`
|
* `AvatarTheme` is now `AvatarThemeData`
|
||||||
* `ChannelHeaderTheme` is now `ChannelHeaderThemeData`
|
* `ChannelHeaderTheme` is now `ChannelHeaderThemeData`
|
||||||
@@ -317,18 +382,20 @@ upgraded with some goodies like `lerp` functions. Here's the full naming breakdo
|
|||||||
|
|
||||||
🐞 Fixed
|
🐞 Fixed
|
||||||
|
|
||||||
- Fixed `MessageInput` textField case where `input` is not enabled if the file picked from the camera is null.
|
- Fixed `MessageInput` textField case where `input` is not enabled if the file picked from the
|
||||||
|
camera is null.
|
||||||
- Fixed date dividers position/alignment in non reversed `MessageListView`.
|
- Fixed date dividers position/alignment in non reversed `MessageListView`.
|
||||||
- Fixed `MessageListView` not opening to the right initialMessage if `StreamChannel.initialMessageId` is set.
|
- Fixed `MessageListView` not opening to the right initialMessage
|
||||||
- Fixed null check errors when accessing `message.text` in `MessageWidget` and `MessageListView`; this occurred when
|
if `StreamChannel.initialMessageId` is set.
|
||||||
sending a message with no text.
|
- Fixed null check errors when accessing `message.text` in `MessageWidget` and `MessageListView`;
|
||||||
|
this occurred when sending a message with no text.
|
||||||
|
|
||||||
## 2.1.2
|
## 2.1.2
|
||||||
|
|
||||||
🐞 Fixed
|
🐞 Fixed
|
||||||
|
|
||||||
- [#590](https://github.com/GetStream/stream-chat-flutter/issues/590): livestream use case, no members when sending
|
- [#590](https://github.com/GetStream/stream-chat-flutter/issues/590): livestream use case, no
|
||||||
message
|
members when sending message
|
||||||
|
|
||||||
## 2.1.1
|
## 2.1.1
|
||||||
|
|
||||||
@@ -346,7 +413,8 @@ upgraded with some goodies like `lerp` functions. Here's the full naming breakdo
|
|||||||
🔄 Changed
|
🔄 Changed
|
||||||
|
|
||||||
- `StreamChat.of(context).user` is now deprecated in favor of `StreamChat.of(context).currentUser`.
|
- `StreamChat.of(context).user` is now deprecated in favor of `StreamChat.of(context).currentUser`.
|
||||||
- `StreamChat.of(context).userStream` is now deprecated in favor of `StreamChat.of(context).currentUserStream`.
|
- `StreamChat.of(context).userStream` is now deprecated in favor
|
||||||
|
of `StreamChat.of(context).currentUserStream`.
|
||||||
|
|
||||||
🐞 Fixed
|
🐞 Fixed
|
||||||
|
|
||||||
@@ -399,7 +467,8 @@ You can call `.copyWith` to customize just a subset of properties
|
|||||||
|
|
||||||
- Added video compress options (frame and quality) to `MessageInput`
|
- Added video compress options (frame and quality) to `MessageInput`
|
||||||
- TypingIndicator now has a property called `parentId` to show typing indicator specific to threads
|
- TypingIndicator now has a property called `parentId` to show typing indicator specific to threads
|
||||||
- [#493](https://github.com/GetStream/stream-chat-flutter/pull/493): add support for messageListView header/footer
|
- [#493](https://github.com/GetStream/stream-chat-flutter/pull/493): add support for messageListView
|
||||||
|
header/footer
|
||||||
- `MessageWidget` accepts a `userAvatarBuilder`
|
- `MessageWidget` accepts a `userAvatarBuilder`
|
||||||
- Added pinMessage ui support
|
- Added pinMessage ui support
|
||||||
- Added `MessageListView.threadSeparatorBuilder` property
|
- Added `MessageListView.threadSeparatorBuilder` property
|
||||||
@@ -408,10 +477,12 @@ You can call `.copyWith` to customize just a subset of properties
|
|||||||
|
|
||||||
🐞 Fixed
|
🐞 Fixed
|
||||||
|
|
||||||
- [#483](https://github.com/GetStream/stream-chat-flutter/issues/483): Keyboard covers input text box when editing
|
- [#483](https://github.com/GetStream/stream-chat-flutter/issues/483): Keyboard covers input text
|
||||||
message
|
box when editing message
|
||||||
- Modals are shown using the nearest `Navigator` to make using the SDK easier in a nested navigator use case
|
- Modals are shown using the nearest `Navigator` to make using the SDK easier in a nested navigator
|
||||||
- [#484](https://github.com/GetStream/stream-chat-flutter/issues/484): messages don't update without a reload
|
use case
|
||||||
|
- [#484](https://github.com/GetStream/stream-chat-flutter/issues/484): messages don't update without
|
||||||
|
a reload
|
||||||
- `MessageListView` not rendering if the user is not a member of the channel
|
- `MessageListView` not rendering if the user is not a member of the channel
|
||||||
- Fix `MessageInput` overflow when there are no actions
|
- Fix `MessageInput` overflow when there are no actions
|
||||||
- Minor fixes and improvements
|
- Minor fixes and improvements
|
||||||
@@ -464,15 +535,18 @@ You can call `.copyWith` to customize just a subset of properties.
|
|||||||
✅ Added
|
✅ Added
|
||||||
|
|
||||||
- TypingIndicator now has a property called `parentId` to show typing indicator specific to threads
|
- TypingIndicator now has a property called `parentId` to show typing indicator specific to threads
|
||||||
- [#493](https://github.com/GetStream/stream-chat-flutter/pull/493): add support for messageListView header/footer
|
- [#493](https://github.com/GetStream/stream-chat-flutter/pull/493): add support for messageListView
|
||||||
|
header/footer
|
||||||
- `MessageWidget` accepts a `userAvatarBuilder`
|
- `MessageWidget` accepts a `userAvatarBuilder`
|
||||||
|
|
||||||
🐞 Fixed
|
🐞 Fixed
|
||||||
|
|
||||||
- [#483](https://github.com/GetStream/stream-chat-flutter/issues/483): Keyboard covers input text box when editing
|
- [#483](https://github.com/GetStream/stream-chat-flutter/issues/483): Keyboard covers input text
|
||||||
message
|
box when editing message
|
||||||
- Modals are shown using the nearest `Navigator` to make using the SDK easier in a nested navigator use case
|
- Modals are shown using the nearest `Navigator` to make using the SDK easier in a nested navigator
|
||||||
- [#484](https://github.com/GetStream/stream-chat-flutter/issues/484): messages don't update without a reload
|
use case
|
||||||
|
- [#484](https://github.com/GetStream/stream-chat-flutter/issues/484): messages don't update without
|
||||||
|
a reload
|
||||||
- `MessageListView` not rendering if the user is not a member of the channel
|
- `MessageListView` not rendering if the user is not a member of the channel
|
||||||
|
|
||||||
## 2.0.0-nullsafety.7
|
## 2.0.0-nullsafety.7
|
||||||
@@ -542,7 +616,8 @@ You can call `.copyWith` to customize just a subset of properties.
|
|||||||
- Show error messages as system and keep them in the message input
|
- Show error messages as system and keep them in the message input
|
||||||
- Remove notification badge logic
|
- Remove notification badge logic
|
||||||
- Use shimmer while loading images
|
- Use shimmer while loading images
|
||||||
- Polished `StreamChatTheme` adding more options and a new `MessageInputTheme` dedicated to `MessageInput`
|
- Polished `StreamChatTheme` adding more options and a new `MessageInputTheme` dedicated
|
||||||
|
to `MessageInput`
|
||||||
- Add possibility to specify custom message actions using `MessageWidget.customActions`
|
- Add possibility to specify custom message actions using `MessageWidget.customActions`
|
||||||
- Added `MessageListView.onAttachmentTap` callback
|
- Added `MessageListView.onAttachmentTap` callback
|
||||||
- Fixed message newline issue
|
- Fixed message newline issue
|
||||||
@@ -599,7 +674,8 @@ You can call `.copyWith` to customize just a subset of properties.
|
|||||||
- Improved api documentation
|
- Improved api documentation
|
||||||
- Updated `stream_chat` dependency to `^1.0.0-beta`
|
- Updated `stream_chat` dependency to `^1.0.0-beta`
|
||||||
- Extracted sample app into dedicated [repo](https://github.com/GetStream/flutter-samples)
|
- Extracted sample app into dedicated [repo](https://github.com/GetStream/flutter-samples)
|
||||||
- Reimplemented existing widgets using [stream_chat_flutter_core](https://pub.dev/packages/stream_chat_flutter_core)
|
- Reimplemented existing widgets
|
||||||
|
using [stream_chat_flutter_core](https://pub.dev/packages/stream_chat_flutter_core)
|
||||||
|
|
||||||
## 0.2.21
|
## 0.2.21
|
||||||
|
|
||||||
@@ -616,8 +692,8 @@ You can call `.copyWith` to customize just a subset of properties.
|
|||||||
|
|
||||||
## 0.2.20+2
|
## 0.2.20+2
|
||||||
|
|
||||||
- Added `shouldAddChannel` to ChannelsBloc in order to check if a channel has to be added to the list when a new message
|
- Added `shouldAddChannel` to ChannelsBloc in order to check if a channel has to be added to the
|
||||||
arrives
|
list when a new message arrives
|
||||||
|
|
||||||
## 0.2.20+1
|
## 0.2.20+1
|
||||||
|
|
||||||
@@ -651,7 +727,8 @@ You can call `.copyWith` to customize just a subset of properties.
|
|||||||
|
|
||||||
## 0.2.16
|
## 0.2.16
|
||||||
|
|
||||||
- Do not wrap channel preview builder. Users will have to implement they're custom onTap/onLongPress implementation
|
- Do not wrap channel preview builder. Users will have to implement they're custom onTap/onLongPress
|
||||||
|
implementation
|
||||||
- Make public autofocus field of the TextField of message_input
|
- Make public autofocus field of the TextField of message_input
|
||||||
|
|
||||||
## 0.2.15
|
## 0.2.15
|
||||||
@@ -836,10 +913,11 @@ You can call `.copyWith` to customize just a subset of properties.
|
|||||||
|
|
||||||
## 0.2.1-alpha+1
|
## 0.2.1-alpha+1
|
||||||
|
|
||||||
- Removed the additional `Navigator` in `StreamChat` widget. It was added to make the app have the `StreamChat` widget
|
- Removed the additional `Navigator` in `StreamChat` widget. It was added to make the app have
|
||||||
as ancestor in every route. Now the recommended way to add `StreamChat` to your app is using the `builder` property of
|
the `StreamChat` widget as ancestor in every route. Now the recommended way to add `StreamChat` to
|
||||||
your `MaterialApp` widget. Otherwise you can use it in the usual way, but you need to add a `StreamChat` widget to
|
your app is using the `builder` property of your `MaterialApp` widget. Otherwise you can use it in
|
||||||
every route of your app. Read [this issue](https://github.com/GetStream/stream-chat-flutter/issues/47) for more
|
the usual way, but you need to add a `StreamChat` widget to every route of your app.
|
||||||
|
Read [this issue](https://github.com/GetStream/stream-chat-flutter/issues/47) for more
|
||||||
information.
|
information.
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
@@ -941,8 +1019,8 @@ Widget build(BuildContext context) {
|
|||||||
|
|
||||||
- Add gesture (vertical drag down) to close the keyboard
|
- Add gesture (vertical drag down) to close the keyboard
|
||||||
|
|
||||||
- Add keyboard type parameters (set it to TextInputType.text to show the submit button that will even close the
|
- Add keyboard type parameters (set it to TextInputType.text to show the submit button that will
|
||||||
keyboard)
|
even close the keyboard)
|
||||||
|
|
||||||
The property showVideoFullScreen was added mainly because of this issue brianegan/chewie#261
|
The property showVideoFullScreen was added mainly because of this issue brianegan/chewie#261
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -10,8 +10,8 @@ class Application : FlutterApplication(), PluginRegistrantCallback {
|
|||||||
super.onCreate()
|
super.onCreate()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun registerWith(registry: PluginRegistry?) {
|
override fun registerWith(registry: PluginRegistry) {
|
||||||
PathProviderPlugin.registerWith(registry?.registrarFor(
|
PathProviderPlugin.registerWith(registry.registrarFor(
|
||||||
"io.flutter.plugins.pathprovider.PathProviderPlugin"))
|
"io.flutter.plugins.pathprovider.PathProviderPlugin"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -59,5 +59,7 @@
|
|||||||
|
|
||||||
<key>NSMicrophoneUsageDescription</key>
|
<key>NSMicrophoneUsageDescription</key>
|
||||||
<string>Explain why your app uses the mic</string>
|
<string>Explain why your app uses the mic</string>
|
||||||
|
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||||
|
<true/>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|||||||
@@ -225,11 +225,12 @@ class _StreamGalleryFooterState extends State<StreamGalleryFooter> {
|
|||||||
if (attachment.type == 'video') {
|
if (attachment.type == 'video') {
|
||||||
media = InkWell(
|
media = InkWell(
|
||||||
onTap: () => widget.mediaSelectedCallBack!(index),
|
onTap: () => widget.mediaSelectedCallBack!(index),
|
||||||
child: FittedBox(
|
child: AspectRatio(
|
||||||
fit: BoxFit.cover,
|
aspectRatio: 1,
|
||||||
child: StreamVideoThumbnailImage(
|
child: StreamVideoThumbnailImage(
|
||||||
video: (attachment.file?.path ??
|
video: (attachment.file?.path ??
|
||||||
attachment.assetUrl)!,
|
attachment.assetUrl)!,
|
||||||
|
fit: BoxFit.cover,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -77,6 +77,10 @@ abstract class Translations {
|
|||||||
/// contains a parent message
|
/// contains a parent message
|
||||||
String threadSeparatorText(int replyCount);
|
String threadSeparatorText(int replyCount);
|
||||||
|
|
||||||
|
/// The text for showing the unread messages count
|
||||||
|
/// in the [StreamMessageListView]
|
||||||
|
String unreadMessagesSeparatorText(int unreadCount);
|
||||||
|
|
||||||
/// The label for "connected" in [StreamConnectionStatusBuilder]
|
/// The label for "connected" in [StreamConnectionStatusBuilder]
|
||||||
String get connectedLabel;
|
String get connectedLabel;
|
||||||
|
|
||||||
@@ -711,4 +715,12 @@ Attachment limit exceeded: it's not possible to add more than $limit attachments
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String get linkDisabledError => 'Links are disabled';
|
String get linkDisabledError => 'Links are disabled';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String unreadMessagesSeparatorText(int unreadCount) {
|
||||||
|
if (unreadCount == 1) {
|
||||||
|
return '1 unread message';
|
||||||
|
}
|
||||||
|
return '$unreadCount unread messages';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ typedef UserMentionTileBuilder = Widget Function(
|
|||||||
/// Widget builder for action button.
|
/// Widget builder for action button.
|
||||||
///
|
///
|
||||||
/// [defaultActionButton] is the default [IconButton] configuration,
|
/// [defaultActionButton] is the default [IconButton] configuration,
|
||||||
/// use [defaultActionButton.copyWith] to easily customize it.
|
/// use .copyWith to easily customize it.
|
||||||
typedef ActionButtonBuilder = Widget Function(
|
typedef ActionButtonBuilder = Widget Function(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
IconButton defaultActionButton,
|
IconButton defaultActionButton,
|
||||||
|
|||||||
@@ -200,6 +200,7 @@ class StreamMessageListView extends StatefulWidget {
|
|||||||
this.onSystemMessageTap,
|
this.onSystemMessageTap,
|
||||||
this.showFloatingDateDivider = true,
|
this.showFloatingDateDivider = true,
|
||||||
this.threadSeparatorBuilder,
|
this.threadSeparatorBuilder,
|
||||||
|
this.unreadMessagesSeparatorBuilder,
|
||||||
this.messageListController,
|
this.messageListController,
|
||||||
this.reverse = true,
|
this.reverse = true,
|
||||||
this.paginationLimit = 20,
|
this.paginationLimit = 20,
|
||||||
@@ -337,6 +338,10 @@ class StreamMessageListView extends StatefulWidget {
|
|||||||
/// Builder used to build the thread separator in case it's a thread view
|
/// Builder used to build the thread separator in case it's a thread view
|
||||||
final WidgetBuilder? threadSeparatorBuilder;
|
final WidgetBuilder? threadSeparatorBuilder;
|
||||||
|
|
||||||
|
/// Builder used to build the unread message separator
|
||||||
|
final Widget Function(BuildContext context, int unreadCount)?
|
||||||
|
unreadMessagesSeparatorBuilder;
|
||||||
|
|
||||||
/// A [MessageListController] allows pagination.
|
/// A [MessageListController] allows pagination.
|
||||||
/// Use [ChannelListController.paginateData] pagination.
|
/// Use [ChannelListController.paginateData] pagination.
|
||||||
final MessageListController? messageListController;
|
final MessageListController? messageListController;
|
||||||
@@ -363,6 +368,7 @@ class _StreamMessageListViewState extends State<StreamMessageListView> {
|
|||||||
StreamChannelState? streamChannel;
|
StreamChannelState? streamChannel;
|
||||||
late StreamChatThemeData _streamTheme;
|
late StreamChatThemeData _streamTheme;
|
||||||
late List<String> _userPermissions;
|
late List<String> _userPermissions;
|
||||||
|
late int unreadCount;
|
||||||
|
|
||||||
int get _initialIndex {
|
int get _initialIndex {
|
||||||
final initialScrollIndex = widget.initialScrollIndex;
|
final initialScrollIndex = widget.initialScrollIndex;
|
||||||
@@ -381,6 +387,11 @@ class _StreamMessageListViewState extends State<StreamMessageListView> {
|
|||||||
if (index != 0) return index + 1;
|
if (index != 0) return index + 1;
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (unreadCount > 0) {
|
||||||
|
return unreadCount + 1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -596,9 +607,12 @@ class _StreamMessageListViewState extends State<StreamMessageListView> {
|
|||||||
return const SizedBox(height: 8);
|
return const SizedBox(height: 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == 1 || i == itemCount - 4) return const Offstage();
|
if (i == 1 || i == itemCount - 4) {
|
||||||
|
return const Offstage();
|
||||||
|
}
|
||||||
|
|
||||||
late final Message message, nextMessage;
|
late final Message message, nextMessage;
|
||||||
|
late Widget separator;
|
||||||
if (widget.reverse) {
|
if (widget.reverse) {
|
||||||
message = messages[i - 1];
|
message = messages[i - 1];
|
||||||
nextMessage = messages[i - 2];
|
nextMessage = messages[i - 2];
|
||||||
@@ -611,7 +625,7 @@ class _StreamMessageListViewState extends State<StreamMessageListView> {
|
|||||||
nextMessage.createdAt.toLocal(),
|
nextMessage.createdAt.toLocal(),
|
||||||
Units.DAY,
|
Units.DAY,
|
||||||
)) {
|
)) {
|
||||||
return _buildDateDivider(nextMessage);
|
separator = _buildDateDivider(nextMessage);
|
||||||
}
|
}
|
||||||
final timeDiff =
|
final timeDiff =
|
||||||
Jiffy(nextMessage.createdAt.toLocal()).diff(
|
Jiffy(nextMessage.createdAt.toLocal()).diff(
|
||||||
@@ -644,13 +658,52 @@ class _StreamMessageListViewState extends State<StreamMessageListView> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (spacingRules.isNotEmpty) {
|
if (spacingRules.isNotEmpty) {
|
||||||
return widget.spacingWidgetBuilder
|
separator = widget.spacingWidgetBuilder
|
||||||
?.call(context, spacingRules) ??
|
?.call(context, spacingRules) ??
|
||||||
const SizedBox(height: 8);
|
const SizedBox(height: 8);
|
||||||
}
|
}
|
||||||
return widget.spacingWidgetBuilder
|
separator = widget.spacingWidgetBuilder
|
||||||
?.call(context, [SpacingType.defaultSpacing]) ??
|
?.call(context, [SpacingType.defaultSpacing]) ??
|
||||||
const SizedBox(height: 2);
|
const SizedBox(height: 2);
|
||||||
|
|
||||||
|
if (!isThread && unreadCount > 0 && unreadCount == i - 1) {
|
||||||
|
final unreadMessagesSeparator = widget
|
||||||
|
.unreadMessagesSeparatorBuilder
|
||||||
|
?.call(context, unreadCount);
|
||||||
|
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
children: [
|
||||||
|
separator,
|
||||||
|
unreadMessagesSeparator ??
|
||||||
|
Padding(
|
||||||
|
padding:
|
||||||
|
const EdgeInsets.symmetric(vertical: 8),
|
||||||
|
child: DecoratedBox(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
gradient:
|
||||||
|
_streamTheme.colorTheme.bgGradient,
|
||||||
|
),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(8),
|
||||||
|
child: Text(
|
||||||
|
context.translations
|
||||||
|
.unreadMessagesSeparatorText(
|
||||||
|
unreadCount,
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style:
|
||||||
|
StreamChannelHeaderTheme.of(context)
|
||||||
|
.subtitleStyle,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return separator;
|
||||||
},
|
},
|
||||||
itemBuilder: (context, i) {
|
itemBuilder: (context, i) {
|
||||||
if (i == itemCount - 1) {
|
if (i == itemCount - 1) {
|
||||||
@@ -880,9 +933,13 @@ class _StreamMessageListViewState extends State<StreamMessageListView> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> scrollToBottomDefaultTapAction(int unreadCount) async {
|
Future<void> scrollToBottomDefaultTapAction(int unreadCount) async {
|
||||||
|
this.unreadCount = unreadCount;
|
||||||
if (unreadCount > 0) {
|
if (unreadCount > 0) {
|
||||||
streamChannel!.channel.markRead();
|
streamChannel!.channel.markRead();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final index = unreadCount > 0 ? unreadCount + 1 : 0;
|
||||||
|
|
||||||
if (!_upToDate) {
|
if (!_upToDate) {
|
||||||
_bottomPaginationActive = false;
|
_bottomPaginationActive = false;
|
||||||
initialAlignment = 0;
|
initialAlignment = 0;
|
||||||
@@ -890,11 +947,11 @@ class _StreamMessageListViewState extends State<StreamMessageListView> {
|
|||||||
await streamChannel!.reloadChannel();
|
await streamChannel!.reloadChannel();
|
||||||
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
_scrollController!.jumpTo(index: 0);
|
_scrollController!.jumpTo(index: index);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
_scrollController!.scrollTo(
|
_scrollController!.scrollTo(
|
||||||
index: 0,
|
index: index,
|
||||||
duration: const Duration(seconds: 1),
|
duration: const Duration(seconds: 1),
|
||||||
curve: Curves.easeInOut,
|
curve: Curves.easeInOut,
|
||||||
);
|
);
|
||||||
@@ -1317,6 +1374,8 @@ class _StreamMessageListViewState extends State<StreamMessageListView> {
|
|||||||
if (newStreamChannel != streamChannel) {
|
if (newStreamChannel != streamChannel) {
|
||||||
streamChannel = newStreamChannel;
|
streamChannel = newStreamChannel;
|
||||||
_messageNewListener?.cancel();
|
_messageNewListener?.cancel();
|
||||||
|
|
||||||
|
unreadCount = streamChannel?.channel.state?.unreadCount ?? 0;
|
||||||
initialIndex = _initialIndex;
|
initialIndex = _initialIndex;
|
||||||
initialAlignment = _initialAlignment;
|
initialAlignment = _initialAlignment;
|
||||||
|
|
||||||
@@ -1328,25 +1387,38 @@ class _StreamMessageListViewState extends State<StreamMessageListView> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_messageNewListener =
|
_messageNewListener =
|
||||||
streamChannel!.channel.on(EventType.messageNew).listen((event) {
|
streamChannel!.channel.on(EventType.messageNew).skip(1)
|
||||||
|
//skipping the first event because
|
||||||
|
//the StreamController is a BehaviorSubject
|
||||||
|
.listen((event) {
|
||||||
if (_upToDate) {
|
if (_upToDate) {
|
||||||
_bottomPaginationActive = false;
|
_bottomPaginationActive = false;
|
||||||
}
|
}
|
||||||
if (event.message?.parentId == widget.parentMessage?.id &&
|
if (event.message?.parentId == widget.parentMessage?.id &&
|
||||||
event.message!.user!.id ==
|
event.message!.user!.id ==
|
||||||
streamChannel!.channel.client.state.currentUser!.id) {
|
streamChannel!.channel.client.state.currentUser!.id) {
|
||||||
|
setState(() {
|
||||||
|
unreadCount = 0;
|
||||||
|
});
|
||||||
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
_scrollController?.scrollTo(
|
_scrollController?.scrollTo(
|
||||||
index: 0,
|
index: 0,
|
||||||
duration: const Duration(seconds: 1),
|
duration: const Duration(seconds: 1),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
} else if (streamChannel?.channel.state?.unreadCount != 0) {
|
||||||
|
setState(() {
|
||||||
|
unreadCount = unreadCount + 1;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (_isThreadConversation) {
|
if (_isThreadConversation) {
|
||||||
streamChannel!.getReplies(widget.parentMessage!.id);
|
streamChannel!.getReplies(widget.parentMessage!.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unreadCount = streamChannel?.channel.state?.unreadCount ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
super.didChangeDependencies();
|
super.didChangeDependencies();
|
||||||
|
|||||||
@@ -596,240 +596,252 @@ class _StreamMessageWidgetState extends State<StreamMessageWidget>
|
|||||||
|
|
||||||
final showReactions = _shouldShowReactions;
|
final showReactions = _shouldShowReactions;
|
||||||
|
|
||||||
|
final onMessageTap = widget.onMessageTap;
|
||||||
|
|
||||||
return Material(
|
return Material(
|
||||||
type: widget.message.pinned && widget.showPinHighlight
|
type: MaterialType.transparency,
|
||||||
? MaterialType.card
|
child: AnimatedContainer(
|
||||||
: MaterialType.transparency,
|
duration: const Duration(seconds: 1),
|
||||||
color: widget.message.pinned && widget.showPinHighlight
|
color: widget.message.pinned && widget.showPinHighlight
|
||||||
? _streamChatTheme.colorTheme.highlight
|
? _streamChatTheme.colorTheme.highlight
|
||||||
: null,
|
: _streamChatTheme.colorTheme.barsBg.withOpacity(0),
|
||||||
child: Portal(
|
child: Portal(
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: () {
|
onTap: onMessageTap == null
|
||||||
widget.onMessageTap!(widget.message);
|
? null
|
||||||
},
|
: () => onMessageTap(widget.message),
|
||||||
onLongPress: widget.message.isDeleted && !isFailedState
|
onLongPress: widget.message.isDeleted && !isFailedState
|
||||||
? null
|
? null
|
||||||
: () => onLongPress(context),
|
: () => onLongPress(context),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: widget.padding ?? const EdgeInsets.all(8),
|
padding: widget.padding ?? const EdgeInsets.all(8),
|
||||||
child: FractionallySizedBox(
|
child: FractionallySizedBox(
|
||||||
alignment:
|
alignment: widget.reverse
|
||||||
widget.reverse ? Alignment.centerRight : Alignment.centerLeft,
|
? Alignment.centerRight
|
||||||
widthFactor: 0.78,
|
: Alignment.centerLeft,
|
||||||
child: Column(
|
widthFactor: 0.78,
|
||||||
crossAxisAlignment: widget.reverse
|
child: Column(
|
||||||
? CrossAxisAlignment.end
|
crossAxisAlignment: widget.reverse
|
||||||
: CrossAxisAlignment.start,
|
? CrossAxisAlignment.end
|
||||||
mainAxisSize: MainAxisSize.min,
|
: CrossAxisAlignment.start,
|
||||||
children: <Widget>[
|
mainAxisSize: MainAxisSize.min,
|
||||||
Stack(
|
children: <Widget>[
|
||||||
clipBehavior: Clip.none,
|
Stack(
|
||||||
alignment: widget.reverse
|
clipBehavior: Clip.none,
|
||||||
? AlignmentDirectional.bottomEnd
|
alignment: widget.reverse
|
||||||
: AlignmentDirectional.bottomStart,
|
? AlignmentDirectional.bottomEnd
|
||||||
children: [
|
: AlignmentDirectional.bottomStart,
|
||||||
Padding(
|
children: [
|
||||||
padding: EdgeInsets.only(
|
|
||||||
bottom:
|
|
||||||
isPinned && widget.showPinHighlight ? 8.0 : 0.0,
|
|
||||||
),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: widget.reverse
|
|
||||||
? CrossAxisAlignment.end
|
|
||||||
: CrossAxisAlignment.start,
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
if (widget.message.pinned &&
|
|
||||||
widget.message.pinnedBy != null &&
|
|
||||||
widget.showPinHighlight)
|
|
||||||
_buildPinnedMessage(widget.message),
|
|
||||||
Row(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: <Widget>[
|
|
||||||
if (!widget.reverse &&
|
|
||||||
widget.showUserAvatar ==
|
|
||||||
DisplayWidget.show &&
|
|
||||||
widget.message.user != null) ...[
|
|
||||||
_buildUserAvatar(),
|
|
||||||
const SizedBox(width: 4),
|
|
||||||
],
|
|
||||||
if (widget.showUserAvatar == DisplayWidget.hide)
|
|
||||||
SizedBox(width: avatarWidth + 4),
|
|
||||||
Flexible(
|
|
||||||
child: PortalTarget(
|
|
||||||
visible: showReactions,
|
|
||||||
portalFollower: showReactions
|
|
||||||
? Container(
|
|
||||||
transform:
|
|
||||||
Matrix4.translationValues(
|
|
||||||
widget.reverse ? 12 : -12,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
),
|
|
||||||
constraints: const BoxConstraints(
|
|
||||||
maxWidth: 22 * 6.0,
|
|
||||||
),
|
|
||||||
child: _buildReactionIndicator(
|
|
||||||
context,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: null,
|
|
||||||
anchor: Aligned(
|
|
||||||
follower: Alignment(
|
|
||||||
widget.reverse ? 1 : -1,
|
|
||||||
-1,
|
|
||||||
),
|
|
||||||
target: Alignment(
|
|
||||||
widget.reverse ? -1 : 1,
|
|
||||||
-1,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Stack(
|
|
||||||
clipBehavior: Clip.none,
|
|
||||||
children: [
|
|
||||||
Padding(
|
|
||||||
padding: widget.showReactions
|
|
||||||
? EdgeInsets.only(
|
|
||||||
top: widget
|
|
||||||
.message
|
|
||||||
.reactionCounts
|
|
||||||
?.isNotEmpty ==
|
|
||||||
true
|
|
||||||
? 18
|
|
||||||
: 0,
|
|
||||||
)
|
|
||||||
: EdgeInsets.zero,
|
|
||||||
child: (widget.message.isDeleted &&
|
|
||||||
!isFailedState)
|
|
||||||
? Container(
|
|
||||||
// ignore: lines_longer_than_80_chars
|
|
||||||
margin: EdgeInsets.symmetric(
|
|
||||||
horizontal:
|
|
||||||
// ignore: lines_longer_than_80_chars
|
|
||||||
widget.showUserAvatar ==
|
|
||||||
// ignore: lines_longer_than_80_chars
|
|
||||||
DisplayWidget
|
|
||||||
.gone
|
|
||||||
? 0
|
|
||||||
: 4.0,
|
|
||||||
),
|
|
||||||
child: StreamDeletedMessage(
|
|
||||||
borderRadiusGeometry: widget
|
|
||||||
.borderRadiusGeometry,
|
|
||||||
borderSide:
|
|
||||||
widget.borderSide,
|
|
||||||
shape: widget.shape,
|
|
||||||
messageTheme:
|
|
||||||
widget.messageTheme,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: Card(
|
|
||||||
clipBehavior: Clip.hardEdge,
|
|
||||||
elevation: 0,
|
|
||||||
margin: EdgeInsets.symmetric(
|
|
||||||
horizontal: (isFailedState
|
|
||||||
? 15.0
|
|
||||||
: 0.0) +
|
|
||||||
// ignore: lines_longer_than_80_chars
|
|
||||||
(widget.showUserAvatar ==
|
|
||||||
DisplayWidget
|
|
||||||
.gone
|
|
||||||
? 0
|
|
||||||
: 4.0),
|
|
||||||
),
|
|
||||||
shape: widget.shape ??
|
|
||||||
RoundedRectangleBorder(
|
|
||||||
side: widget
|
|
||||||
.borderSide ??
|
|
||||||
BorderSide(
|
|
||||||
color: widget
|
|
||||||
// ignore: lines_longer_than_80_chars
|
|
||||||
.messageTheme
|
|
||||||
// ignore: lines_longer_than_80_chars
|
|
||||||
.messageBorderColor ??
|
|
||||||
Colors.grey,
|
|
||||||
),
|
|
||||||
borderRadius: widget
|
|
||||||
// ignore: lines_longer_than_80_chars
|
|
||||||
.borderRadiusGeometry ??
|
|
||||||
BorderRadius.zero,
|
|
||||||
),
|
|
||||||
color: _getBackgroundColor(),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment:
|
|
||||||
CrossAxisAlignment.end,
|
|
||||||
mainAxisSize:
|
|
||||||
MainAxisSize.min,
|
|
||||||
children: <Widget>[
|
|
||||||
if (hasQuotedMessage)
|
|
||||||
_buildQuotedMessage(),
|
|
||||||
if (hasNonUrlAttachments)
|
|
||||||
_parseAttachments(),
|
|
||||||
if (!isGiphy)
|
|
||||||
_buildTextBubble(),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (widget.showReactionPickerIndicator)
|
|
||||||
Positioned(
|
|
||||||
right: widget.reverse ? null : 4,
|
|
||||||
left: widget.reverse ? 4 : null,
|
|
||||||
top: -8,
|
|
||||||
child: CustomPaint(
|
|
||||||
painter: ReactionBubblePainter(
|
|
||||||
_streamChatTheme
|
|
||||||
.colorTheme.barsBg,
|
|
||||||
Colors.transparent,
|
|
||||||
Colors.transparent,
|
|
||||||
tailCirclesSpace: 1,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (widget.reverse &&
|
|
||||||
widget.showUserAvatar ==
|
|
||||||
DisplayWidget.show &&
|
|
||||||
widget.message.user != null) ...[
|
|
||||||
_buildUserAvatar(),
|
|
||||||
const SizedBox(width: 4),
|
|
||||||
],
|
|
||||||
],
|
|
||||||
),
|
|
||||||
if (showBottomRow)
|
|
||||||
SizedBox(height: context.textScaleFactor * 18.0),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (showBottomRow)
|
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.only(
|
padding: EdgeInsets.only(
|
||||||
left: !widget.reverse ? bottomRowPadding : 0,
|
|
||||||
right: widget.reverse ? bottomRowPadding : 0,
|
|
||||||
bottom:
|
bottom:
|
||||||
isPinned && widget.showPinHighlight ? 6.0 : 0.0,
|
isPinned && widget.showPinHighlight ? 8.0 : 0.0,
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: widget.reverse
|
||||||
|
? CrossAxisAlignment.end
|
||||||
|
: CrossAxisAlignment.start,
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
if (widget.message.pinned &&
|
||||||
|
widget.message.pinnedBy != null &&
|
||||||
|
widget.showPinHighlight)
|
||||||
|
_buildPinnedMessage(widget.message),
|
||||||
|
Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: <Widget>[
|
||||||
|
if (!widget.reverse &&
|
||||||
|
widget.showUserAvatar ==
|
||||||
|
DisplayWidget.show &&
|
||||||
|
widget.message.user != null) ...[
|
||||||
|
_buildUserAvatar(),
|
||||||
|
const SizedBox(width: 4),
|
||||||
|
],
|
||||||
|
if (widget.showUserAvatar ==
|
||||||
|
DisplayWidget.hide)
|
||||||
|
SizedBox(width: avatarWidth + 4),
|
||||||
|
Flexible(
|
||||||
|
child: PortalTarget(
|
||||||
|
visible: showReactions,
|
||||||
|
portalFollower: showReactions
|
||||||
|
? Container(
|
||||||
|
transform:
|
||||||
|
Matrix4.translationValues(
|
||||||
|
widget.reverse ? 12 : -12,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
constraints: const BoxConstraints(
|
||||||
|
maxWidth: 22 * 6.0,
|
||||||
|
),
|
||||||
|
child: _buildReactionIndicator(
|
||||||
|
context,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: null,
|
||||||
|
anchor: Aligned(
|
||||||
|
follower: Alignment(
|
||||||
|
widget.reverse ? 1 : -1,
|
||||||
|
-1,
|
||||||
|
),
|
||||||
|
target: Alignment(
|
||||||
|
widget.reverse ? -1 : 1,
|
||||||
|
-1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Stack(
|
||||||
|
clipBehavior: Clip.none,
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: widget.showReactions
|
||||||
|
? EdgeInsets.only(
|
||||||
|
top: widget
|
||||||
|
.message
|
||||||
|
.reactionCounts
|
||||||
|
?.isNotEmpty ==
|
||||||
|
true
|
||||||
|
? 18
|
||||||
|
: 0,
|
||||||
|
)
|
||||||
|
: EdgeInsets.zero,
|
||||||
|
child: (widget.message.isDeleted &&
|
||||||
|
!isFailedState)
|
||||||
|
? Container(
|
||||||
|
margin:
|
||||||
|
EdgeInsets.symmetric(
|
||||||
|
horizontal:
|
||||||
|
// ignore: lines_longer_than_80_chars
|
||||||
|
widget.showUserAvatar ==
|
||||||
|
// ignore: lines_longer_than_80_chars
|
||||||
|
DisplayWidget.gone
|
||||||
|
? 0
|
||||||
|
: 4.0,
|
||||||
|
),
|
||||||
|
child: StreamDeletedMessage(
|
||||||
|
// ignore: lines_longer_than_80_chars
|
||||||
|
borderRadiusGeometry: widget
|
||||||
|
.borderRadiusGeometry,
|
||||||
|
borderSide:
|
||||||
|
widget.borderSide,
|
||||||
|
shape: widget.shape,
|
||||||
|
messageTheme:
|
||||||
|
widget.messageTheme,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: Card(
|
||||||
|
clipBehavior: Clip.hardEdge,
|
||||||
|
elevation: 0,
|
||||||
|
margin:
|
||||||
|
EdgeInsets.symmetric(
|
||||||
|
horizontal: (isFailedState
|
||||||
|
? 15.0
|
||||||
|
: 0.0) +
|
||||||
|
// ignore: lines_longer_than_80_chars
|
||||||
|
(widget.showUserAvatar ==
|
||||||
|
DisplayWidget
|
||||||
|
.gone
|
||||||
|
? 0
|
||||||
|
: 4.0),
|
||||||
|
),
|
||||||
|
shape: widget.shape ??
|
||||||
|
RoundedRectangleBorder(
|
||||||
|
side: widget
|
||||||
|
.borderSide ??
|
||||||
|
BorderSide(
|
||||||
|
color: widget
|
||||||
|
// ignore: lines_longer_than_80_chars
|
||||||
|
.messageTheme
|
||||||
|
// ignore: lines_longer_than_80_chars
|
||||||
|
.messageBorderColor ??
|
||||||
|
Colors.grey,
|
||||||
|
),
|
||||||
|
borderRadius: widget
|
||||||
|
// ignore: lines_longer_than_80_chars
|
||||||
|
.borderRadiusGeometry ??
|
||||||
|
BorderRadius.zero,
|
||||||
|
),
|
||||||
|
color: _backgroundColor,
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment:
|
||||||
|
CrossAxisAlignment
|
||||||
|
.end,
|
||||||
|
mainAxisSize:
|
||||||
|
MainAxisSize.min,
|
||||||
|
children: <Widget>[
|
||||||
|
if (hasQuotedMessage)
|
||||||
|
_buildQuotedMessage(),
|
||||||
|
// ignore: lines_longer_than_80_chars
|
||||||
|
if (hasNonUrlAttachments)
|
||||||
|
_parseAttachments(),
|
||||||
|
if (!isGiphy)
|
||||||
|
_buildTextBubble(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (widget
|
||||||
|
.showReactionPickerIndicator)
|
||||||
|
Positioned(
|
||||||
|
right: widget.reverse ? null : 4,
|
||||||
|
left: widget.reverse ? 4 : null,
|
||||||
|
top: -8,
|
||||||
|
child: CustomPaint(
|
||||||
|
painter: ReactionBubblePainter(
|
||||||
|
_streamChatTheme
|
||||||
|
.colorTheme.barsBg,
|
||||||
|
Colors.transparent,
|
||||||
|
Colors.transparent,
|
||||||
|
tailCirclesSpace: 1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (widget.reverse &&
|
||||||
|
widget.showUserAvatar ==
|
||||||
|
DisplayWidget.show &&
|
||||||
|
widget.message.user != null) ...[
|
||||||
|
_buildUserAvatar(),
|
||||||
|
const SizedBox(width: 4),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
),
|
||||||
|
if (showBottomRow)
|
||||||
|
SizedBox(
|
||||||
|
height: context.textScaleFactor * 18.0,
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
child: widget.bottomRowBuilder?.call(
|
|
||||||
context,
|
|
||||||
widget.message,
|
|
||||||
) ??
|
|
||||||
_bottomRow,
|
|
||||||
),
|
),
|
||||||
if (isFailedState)
|
if (showBottomRow)
|
||||||
Positioned(
|
Padding(
|
||||||
right: widget.reverse ? 0 : null,
|
padding: EdgeInsets.only(
|
||||||
left: widget.reverse ? null : 0,
|
left: !widget.reverse ? bottomRowPadding : 0,
|
||||||
bottom: showBottomRow ? 18 : -2,
|
right: widget.reverse ? bottomRowPadding : 0,
|
||||||
child: StreamSvgIcon.error(size: 20),
|
bottom: isPinned && widget.showPinHighlight
|
||||||
),
|
? 6.0
|
||||||
],
|
: 0.0,
|
||||||
),
|
),
|
||||||
],
|
child: widget.bottomRowBuilder?.call(
|
||||||
|
context,
|
||||||
|
widget.message,
|
||||||
|
) ??
|
||||||
|
_bottomRow,
|
||||||
|
),
|
||||||
|
if (isFailedState)
|
||||||
|
Positioned(
|
||||||
|
right: widget.reverse ? 0 : null,
|
||||||
|
left: widget.reverse ? null : 0,
|
||||||
|
bottom: showBottomRow ? 18 : -2,
|
||||||
|
child: StreamSvgIcon.error(size: 20),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -1343,12 +1355,8 @@ class _StreamMessageWidgetState extends State<StreamMessageWidget>
|
|||||||
child: Row(
|
child: Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
StreamSvgIcon.pin(
|
StreamSvgIcon.pin(size: 16),
|
||||||
size: 16,
|
const SizedBox(width: 4),
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
width: 4,
|
|
||||||
),
|
|
||||||
Text(
|
Text(
|
||||||
context.translations.pinnedByUserText(
|
context.translations.pinnedByUserText(
|
||||||
pinnedBy: pinnedBy,
|
pinnedBy: pinnedBy,
|
||||||
@@ -1367,7 +1375,7 @@ class _StreamMessageWidgetState extends State<StreamMessageWidget>
|
|||||||
|
|
||||||
bool get isPinned => widget.message.pinned;
|
bool get isPinned => widget.message.pinned;
|
||||||
|
|
||||||
Color? _getBackgroundColor() {
|
Color? get _backgroundColor {
|
||||||
if (hasQuotedMessage) {
|
if (hasQuotedMessage) {
|
||||||
return widget.messageTheme.messageBackgroundColor;
|
return widget.messageTheme.messageBackgroundColor;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,8 +109,8 @@ class StreamChatState extends State<StreamChat> {
|
|||||||
child: Builder(
|
child: Builder(
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
StreamChatClient.additionalHeaders = {
|
StreamChatClient.additionalHeaders = {
|
||||||
'X-Stream-Client':
|
'X-Stream-Client': '${StreamChatClient.defaultUserAgent}-'
|
||||||
'${StreamChatClient.defaultUserAgent}-ui',
|
'ui-${StreamChatClient.packageVersion}',
|
||||||
};
|
};
|
||||||
return widget.child ?? const Offstage();
|
return widget.child ?? const Offstage();
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -9,7 +9,10 @@ import 'package:url_launcher/url_launcher.dart';
|
|||||||
/// Launch URL
|
/// Launch URL
|
||||||
Future<void> launchURL(BuildContext context, String url) async {
|
Future<void> launchURL(BuildContext context, String url) async {
|
||||||
try {
|
try {
|
||||||
await launchUrl(Uri.parse(url).withScheme);
|
await launchUrl(
|
||||||
|
Uri.parse(url).withScheme,
|
||||||
|
mode: LaunchMode.externalApplication,
|
||||||
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(content: Text(context.translations.launchUrlError)),
|
SnackBar(content: Text(context.translations.launchUrlError)),
|
||||||
|
|||||||
+19
-18
@@ -282,25 +282,26 @@ class _StreamAttachmentPickerState extends State<StreamAttachmentPicker> {
|
|||||||
.iconBuilder(context, _filePickerIndex == i + 1),
|
.iconBuilder(context, _filePickerIndex == i + 1),
|
||||||
),
|
),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
FutureBuilder(
|
if (widget.isOpen)
|
||||||
future: PhotoManager.requestPermissionExtend(),
|
FutureBuilder(
|
||||||
builder: (context, snapshot) {
|
future: PhotoManager.requestPermissionExtend(),
|
||||||
if (snapshot.hasData &&
|
builder: (context, snapshot) {
|
||||||
snapshot.data == PermissionState.limited) {
|
if (snapshot.hasData &&
|
||||||
return TextButton(
|
snapshot.data == PermissionState.limited) {
|
||||||
child: Text(context.translations.viewLibrary),
|
return TextButton(
|
||||||
onPressed: () async {
|
child: Text(context.translations.viewLibrary),
|
||||||
await PhotoManager.presentLimited();
|
onPressed: () async {
|
||||||
_mediaListViewController.updateMedia(
|
await PhotoManager.presentLimited();
|
||||||
newValue: true,
|
_mediaListViewController.updateMedia(
|
||||||
);
|
newValue: true,
|
||||||
},
|
);
|
||||||
);
|
},
|
||||||
}
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
DecoratedBox(
|
DecoratedBox(
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ typedef UserMentionTileBuilder = Widget Function(
|
|||||||
/// Widget builder for action button.
|
/// Widget builder for action button.
|
||||||
///
|
///
|
||||||
/// [defaultActionButton] is the default [IconButton] configuration,
|
/// [defaultActionButton] is the default [IconButton] configuration,
|
||||||
/// use [defaultActionButton.copyWith] to easily customize it.
|
/// use .copyWith to easily customize it.
|
||||||
typedef ActionButtonBuilder = Widget Function(
|
typedef ActionButtonBuilder = Widget Function(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
IconButton defaultActionButton,
|
IconButton defaultActionButton,
|
||||||
@@ -998,7 +998,10 @@ class StreamMessageInputState extends State<StreamMessageInput>
|
|||||||
_lastSearchedContainsUrlText = value;
|
_lastSearchedContainsUrlText = value;
|
||||||
|
|
||||||
final matchedUrls = _urlRegex.allMatches(value).toList()
|
final matchedUrls = _urlRegex.allMatches(value).toList()
|
||||||
..removeWhere((it) => it.group(0)?.split('.').last.isValidTLD() == false);
|
..removeWhere((it) {
|
||||||
|
final _parsedMatch = Uri.tryParse(it.group(0) ?? '')?.withScheme;
|
||||||
|
return _parsedMatch?.host.split('.').last.isValidTLD() == false;
|
||||||
|
});
|
||||||
|
|
||||||
// Reset the og attachment if the text doesn't contain any url
|
// Reset the og attachment if the text doesn't contain any url
|
||||||
if (matchedUrls.isEmpty ||
|
if (matchedUrls.isEmpty ||
|
||||||
@@ -1221,7 +1224,7 @@ class StreamMessageInputState extends State<StreamMessageInput>
|
|||||||
|
|
||||||
void _setCommand(Command c) {
|
void _setCommand(Command c) {
|
||||||
_effectiveController
|
_effectiveController
|
||||||
..clear()
|
..reset()
|
||||||
..command = c;
|
..command = c;
|
||||||
setState(() {
|
setState(() {
|
||||||
_showCommandsOverlay = false;
|
_showCommandsOverlay = false;
|
||||||
|
|||||||
@@ -97,8 +97,9 @@ class _StreamVideoThumbnailImageState extends State<StreamVideoThumbnailImage> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (!snapshot.hasData) {
|
if (!snapshot.hasData) {
|
||||||
return Container(
|
return SizedBox(
|
||||||
constraints: const BoxConstraints.expand(),
|
height: double.maxFinite,
|
||||||
|
width: double.maxFinite,
|
||||||
child: widget.placeholderBuilder?.call(context) ??
|
child: widget.placeholderBuilder?.call(context) ??
|
||||||
Shimmer.fromColors(
|
Shimmer.fromColors(
|
||||||
baseColor: _streamChatTheme.colorTheme.disabled,
|
baseColor: _streamChatTheme.colorTheme.disabled,
|
||||||
@@ -106,16 +107,22 @@ class _StreamVideoThumbnailImageState extends State<StreamVideoThumbnailImage> {
|
|||||||
child: Image.asset(
|
child: Image.asset(
|
||||||
'images/placeholder.png',
|
'images/placeholder.png',
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
|
height: widget.height,
|
||||||
|
width: widget.width,
|
||||||
package: 'stream_chat_flutter',
|
package: 'stream_chat_flutter',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return Image.memory(
|
return SizedBox(
|
||||||
snapshot.data!,
|
height: double.maxFinite,
|
||||||
fit: widget.fit,
|
width: double.maxFinite,
|
||||||
height: widget.height,
|
child: Image.memory(
|
||||||
width: widget.width,
|
snapshot.data!,
|
||||||
|
fit: widget.fit,
|
||||||
|
height: widget.height,
|
||||||
|
width: widget.width,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
name: stream_chat_flutter
|
name: stream_chat_flutter
|
||||||
homepage: https://github.com/GetStream/stream-chat-flutter
|
homepage: https://github.com/GetStream/stream-chat-flutter
|
||||||
description: Stream Chat official Flutter SDK. Build your own chat experience using Dart and Flutter.
|
description: Stream Chat official Flutter SDK. Build your own chat experience using Dart and Flutter.
|
||||||
version: 4.2.0
|
version: 4.3.0
|
||||||
repository: https://github.com/GetStream/stream-chat-flutter
|
repository: https://github.com/GetStream/stream-chat-flutter
|
||||||
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
|
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
|
||||||
|
|
||||||
@@ -32,11 +32,11 @@ dependencies:
|
|||||||
meta: ^1.3.0
|
meta: ^1.3.0
|
||||||
path_provider: ^2.0.1
|
path_provider: ^2.0.1
|
||||||
photo_manager: ^2.0.1
|
photo_manager: ^2.0.1
|
||||||
photo_view: ^0.13.0
|
photo_view: ^0.14.0
|
||||||
rxdart: ^0.27.0
|
rxdart: ^0.27.0
|
||||||
share_plus: ^4.0.1
|
share_plus: ^4.0.1
|
||||||
shimmer: ^2.0.0
|
shimmer: ^2.0.0
|
||||||
stream_chat_flutter_core: ^4.2.0
|
stream_chat_flutter_core: ^4.3.0
|
||||||
substring_highlight: ^1.0.26
|
substring_highlight: ^1.0.26
|
||||||
url_launcher: ^6.1.0
|
url_launcher: ^6.1.0
|
||||||
video_player: ^2.1.0
|
video_player: ^2.1.0
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
## 4.3.0
|
||||||
|
|
||||||
|
- Updated `stream_chat` dependency to [`4.3.0`](https://pub.dev/packages/stream_chat/changelog).
|
||||||
|
|
||||||
## 4.2.0
|
## 4.2.0
|
||||||
|
|
||||||
- Updated `stream_chat` dependency to [`4.2.0`](https://pub.dev/packages/stream_chat/changelog).
|
- Updated `stream_chat` dependency to [`4.2.0`](https://pub.dev/packages/stream_chat/changelog).
|
||||||
|
|||||||
@@ -26,8 +26,7 @@ dependencies:
|
|||||||
cupertino_icons: ^1.0.3
|
cupertino_icons: ^1.0.3
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
stream_chat_flutter_core: ^2.2.1
|
stream_chat_flutter_core: ^4.3.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|||||||
@@ -96,7 +96,8 @@ class StreamChatCoreState extends State<StreamChatCore>
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
StreamChatClient.additionalHeaders = {
|
StreamChatClient.additionalHeaders = {
|
||||||
'X-Stream-Client': '${StreamChatClient.defaultUserAgent}-core',
|
'X-Stream-Client': '${StreamChatClient.defaultUserAgent}-'
|
||||||
|
'core-${StreamChatClient.packageVersion}',
|
||||||
};
|
};
|
||||||
return widget.child;
|
return widget.child;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
name: stream_chat_flutter_core
|
name: stream_chat_flutter_core
|
||||||
homepage: https://github.com/GetStream/stream-chat-flutter
|
homepage: https://github.com/GetStream/stream-chat-flutter
|
||||||
description: Stream Chat official Flutter SDK Core. Build your own chat experience using Dart and Flutter.
|
description: Stream Chat official Flutter SDK Core. Build your own chat experience using Dart and Flutter.
|
||||||
version: 4.2.0
|
version: 4.3.0
|
||||||
repository: https://github.com/GetStream/stream-chat-flutter
|
repository: https://github.com/GetStream/stream-chat-flutter
|
||||||
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
|
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
|
||||||
|
|
||||||
@@ -17,8 +17,7 @@ dependencies:
|
|||||||
freezed_annotation: ^2.0.3
|
freezed_annotation: ^2.0.3
|
||||||
meta: ^1.3.0
|
meta: ^1.3.0
|
||||||
rxdart: ^0.27.0
|
rxdart: ^0.27.0
|
||||||
stream_chat: ^4.2.0
|
stream_chat: ^4.3.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
build_runner: ^2.0.1
|
build_runner: ^2.0.1
|
||||||
dart_code_metrics: ^4.4.0
|
dart_code_metrics: ^4.4.0
|
||||||
|
|||||||
@@ -1,3 +1,9 @@
|
|||||||
|
## 3.2.0
|
||||||
|
|
||||||
|
✅ Added
|
||||||
|
|
||||||
|
* Added support for `unreadMessagesSeparatorText` translation.
|
||||||
|
|
||||||
## 3.1.0
|
## 3.1.0
|
||||||
|
|
||||||
* Added support for [German](https://github.com/GetStream/stream-chat-flutter/blob/master/packages/stream_chat_localizations/lib/src/stream_chat_localizations_de.dart) locale.
|
* Added support for [German](https://github.com/GetStream/stream-chat-flutter/blob/master/packages/stream_chat_localizations/lib/src/stream_chat_localizations_de.dart) locale.
|
||||||
|
|||||||
@@ -405,6 +405,14 @@ class NnStreamChatLocalizations extends GlobalStreamChatLocalizations {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String get viewLibrary => 'View library';
|
String get viewLibrary => 'View library';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String unreadMessagesSeparatorText(int unreadCount) {
|
||||||
|
if (unreadCount == 1) {
|
||||||
|
return '1 unread message';
|
||||||
|
}
|
||||||
|
return '$unreadCount unread messages';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ class StreamChatLocalizationsDe extends GlobalStreamChatLocalizations {
|
|||||||
String get allowGalleryAccessMessage => 'Zugang zu Ihrer Galerie gewähren';
|
String get allowGalleryAccessMessage => 'Zugang zu Ihrer Galerie gewähren';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get flagMessageLabel => 'Markierte Nachricht';
|
String get flagMessageLabel => 'Nachricht melden';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get flagMessageQuestion =>
|
String get flagMessageQuestion =>
|
||||||
@@ -171,13 +171,13 @@ class StreamChatLocalizationsDe extends GlobalStreamChatLocalizations {
|
|||||||
'\nModerator für weitere Untersuchungen senden?';
|
'\nModerator für weitere Untersuchungen senden?';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get flagLabel => 'MARKIEREN';
|
String get flagLabel => 'MELDEN';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get cancelLabel => 'ABBRECHEN';
|
String get cancelLabel => 'ABBRECHEN';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get flagMessageSuccessfulLabel => 'Nachricht markiert';
|
String get flagMessageSuccessfulLabel => 'Nachricht gemeldet';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get flagMessageSuccessfulText =>
|
String get flagMessageSuccessfulText =>
|
||||||
@@ -283,7 +283,7 @@ class StreamChatLocalizationsDe extends GlobalStreamChatLocalizations {
|
|||||||
String get streamChatLabel => 'Stream Chat';
|
String get streamChatLabel => 'Stream Chat';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get searchingForNetworkText => 'Searching for Network';
|
String get searchingForNetworkText => 'Netzwerk wird gesucht';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get offlineLabel => 'Offline...';
|
String get offlineLabel => 'Offline...';
|
||||||
@@ -380,5 +380,13 @@ class StreamChatLocalizationsDe extends GlobalStreamChatLocalizations {
|
|||||||
'Sie sind nicht berechtigt Nachrichten zu senden';
|
'Sie sind nicht berechtigt Nachrichten zu senden';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get viewLibrary => 'Bibliothek ansehen';
|
String get viewLibrary => 'Bibliothek öffnen';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String unreadMessagesSeparatorText(int unreadCount) {
|
||||||
|
if (unreadCount == 1) {
|
||||||
|
return '1 ungelesene Nachricht';
|
||||||
|
}
|
||||||
|
return '$unreadCount ungelesene Nachrichten';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -381,4 +381,12 @@ class StreamChatLocalizationsEn extends GlobalStreamChatLocalizations {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String get viewLibrary => 'View library';
|
String get viewLibrary => 'View library';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String unreadMessagesSeparatorText(int unreadCount) {
|
||||||
|
if (unreadCount == 1) {
|
||||||
|
return '1 unread message';
|
||||||
|
}
|
||||||
|
return '$unreadCount unread messages';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -387,4 +387,12 @@ No es posible añadir más de $limit archivos adjuntos
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String get linkDisabledError => 'Los enlaces están deshabilitados';
|
String get linkDisabledError => 'Los enlaces están deshabilitados';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String unreadMessagesSeparatorText(int unreadCount) {
|
||||||
|
if (unreadCount == 1) {
|
||||||
|
return '1 mensaje no leído';
|
||||||
|
}
|
||||||
|
return '$unreadCount mensajes no leídos';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -386,4 +386,12 @@ Limite de pièces jointes dépassée : il n'est pas possible d'ajouter plus de $
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String get linkDisabledError => 'Les liens sont désactivés';
|
String get linkDisabledError => 'Les liens sont désactivés';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String unreadMessagesSeparatorText(int unreadCount) {
|
||||||
|
if (unreadCount == 1) {
|
||||||
|
return '1 message non lu';
|
||||||
|
}
|
||||||
|
return '$unreadCount messages non lus';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -380,4 +380,12 @@ class StreamChatLocalizationsHi extends GlobalStreamChatLocalizations {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String get linkDisabledError => 'लिंक भेजना प्रतिबंधित';
|
String get linkDisabledError => 'लिंक भेजना प्रतिबंधित';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String unreadMessagesSeparatorText(int unreadCount) {
|
||||||
|
if (unreadCount == 1) {
|
||||||
|
return '1 अपठित संदेश';
|
||||||
|
}
|
||||||
|
return '$unreadCount अपठित संदेश';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,12 @@ class StreamChatLocalizationsIt extends GlobalStreamChatLocalizations {
|
|||||||
String get onlyVisibleToYouText => 'Visible solo a te';
|
String get onlyVisibleToYouText => 'Visible solo a te';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String threadReplyCountText(int count) => '$count risposte al thread';
|
String threadReplyCountText(int count) {
|
||||||
|
if (count == 1) {
|
||||||
|
return '1 risposta al thread';
|
||||||
|
}
|
||||||
|
return '$count risposte al thread';
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String attachmentsUploadProgressText({
|
String attachmentsUploadProgressText({
|
||||||
@@ -383,4 +388,12 @@ Attenzione: il limite massimo di $limit file è stato superato.
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String get linkDisabledError => 'I links sono disattivati';
|
String get linkDisabledError => 'I links sono disattivati';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String unreadMessagesSeparatorText(int unreadCount) {
|
||||||
|
if (unreadCount == 1) {
|
||||||
|
return '1 messaggio non letto';
|
||||||
|
}
|
||||||
|
return '$unreadCount messaggi non letti';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -365,4 +365,12 @@ class StreamChatLocalizationsJa extends GlobalStreamChatLocalizations {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String get linkDisabledError => 'リンクが無効になっています';
|
String get linkDisabledError => 'リンクが無効になっています';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String unreadMessagesSeparatorText(int unreadCount) {
|
||||||
|
if (unreadCount == 1) {
|
||||||
|
return '未読メッセージ1通';
|
||||||
|
}
|
||||||
|
return '$unreadCountつの未読メッセージ';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -366,4 +366,12 @@ class StreamChatLocalizationsKo extends GlobalStreamChatLocalizations {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String get linkDisabledError => '링크가 비활성화되었습니다.';
|
String get linkDisabledError => '링크가 비활성화되었습니다.';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String unreadMessagesSeparatorText(int unreadCount) {
|
||||||
|
if (unreadCount == 1) {
|
||||||
|
return '읽지 않은 메시지 1개';
|
||||||
|
}
|
||||||
|
return '읽지 않은 메시지 $unreadCount개';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -384,4 +384,12 @@ Não é possível adicionar mais de $limit arquivos de uma vez
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String get viewLibrary => 'Ver biblioteca';
|
String get viewLibrary => 'Ver biblioteca';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String unreadMessagesSeparatorText(int unreadCount) {
|
||||||
|
if (unreadCount == 1) {
|
||||||
|
return '1 mensagem não lida';
|
||||||
|
}
|
||||||
|
return '$unreadCount mensagens não lidas';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
name: stream_chat_localizations
|
name: stream_chat_localizations
|
||||||
description: The Official localizations for Stream Chat Flutter, a service for building chat applications
|
description: The Official localizations for Stream Chat Flutter, a service for building chat applications
|
||||||
version: 3.1.0
|
version: 3.2.0
|
||||||
homepage: https://github.com/GetStream/stream-chat-flutter
|
homepage: https://github.com/GetStream/stream-chat-flutter
|
||||||
repository: https://github.com/GetStream/stream-chat-flutter
|
repository: https://github.com/GetStream/stream-chat-flutter
|
||||||
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
|
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
|
||||||
@@ -14,8 +14,7 @@ dependencies:
|
|||||||
sdk: flutter
|
sdk: flutter
|
||||||
flutter_localizations:
|
flutter_localizations:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
stream_chat_flutter: ^4.1.0
|
stream_chat_flutter: ^4.3.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
dart_code_metrics: ^4.4.0
|
dart_code_metrics: ^4.4.0
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
## 4.2.0
|
||||||
|
|
||||||
|
- Added support for `Channel.ownCapabilities`
|
||||||
|
|
||||||
## 4.1.0
|
## 4.1.0
|
||||||
|
|
||||||
🔄 Changed
|
🔄 Changed
|
||||||
|
|||||||
@@ -11,9 +11,8 @@ dependencies:
|
|||||||
cupertino_icons: ^1.0.3
|
cupertino_icons: ^1.0.3
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
stream_chat: ^2.2.1
|
stream_chat: ^4.3.0
|
||||||
stream_chat_persistence: ^2.2.0
|
stream_chat_persistence: ^4.2.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ class DriftChatDatabase extends _$DriftChatDatabase {
|
|||||||
|
|
||||||
// you should bump this number whenever you change or add a table definition.
|
// you should bump this number whenever you change or add a table definition.
|
||||||
@override
|
@override
|
||||||
int get schemaVersion => 8;
|
int get schemaVersion => 9;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
MigrationStrategy get migration => MigrationStrategy(
|
MigrationStrategy get migration => MigrationStrategy(
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ part of 'drift_chat_database.dart';
|
|||||||
// MoorGenerator
|
// MoorGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
// ignore_for_file: unnecessary_brace_in_string_interps, unnecessary_this
|
// ignore_for_file: type=lint
|
||||||
class ChannelEntity extends DataClass implements Insertable<ChannelEntity> {
|
class ChannelEntity extends DataClass implements Insertable<ChannelEntity> {
|
||||||
/// The id of this channel
|
/// The id of this channel
|
||||||
final String id;
|
final String id;
|
||||||
@@ -17,6 +17,9 @@ class ChannelEntity extends DataClass implements Insertable<ChannelEntity> {
|
|||||||
/// The cid of this channel
|
/// The cid of this channel
|
||||||
final String cid;
|
final String cid;
|
||||||
|
|
||||||
|
/// List of user permissions on this channel
|
||||||
|
final List<String>? ownCapabilities;
|
||||||
|
|
||||||
/// The channel configuration data
|
/// The channel configuration data
|
||||||
final Map<String, dynamic> config;
|
final Map<String, dynamic> config;
|
||||||
|
|
||||||
@@ -47,6 +50,7 @@ class ChannelEntity extends DataClass implements Insertable<ChannelEntity> {
|
|||||||
{required this.id,
|
{required this.id,
|
||||||
required this.type,
|
required this.type,
|
||||||
required this.cid,
|
required this.cid,
|
||||||
|
this.ownCapabilities,
|
||||||
required this.config,
|
required this.config,
|
||||||
required this.frozen,
|
required this.frozen,
|
||||||
this.lastMessageAt,
|
this.lastMessageAt,
|
||||||
@@ -65,7 +69,9 @@ class ChannelEntity extends DataClass implements Insertable<ChannelEntity> {
|
|||||||
.mapFromDatabaseResponse(data['${effectivePrefix}type'])!,
|
.mapFromDatabaseResponse(data['${effectivePrefix}type'])!,
|
||||||
cid: const StringType()
|
cid: const StringType()
|
||||||
.mapFromDatabaseResponse(data['${effectivePrefix}cid'])!,
|
.mapFromDatabaseResponse(data['${effectivePrefix}cid'])!,
|
||||||
config: $ChannelsTable.$converter0.mapToDart(const StringType()
|
ownCapabilities: $ChannelsTable.$converter0.mapToDart(const StringType()
|
||||||
|
.mapFromDatabaseResponse(data['${effectivePrefix}own_capabilities'])),
|
||||||
|
config: $ChannelsTable.$converter1.mapToDart(const StringType()
|
||||||
.mapFromDatabaseResponse(data['${effectivePrefix}config']))!,
|
.mapFromDatabaseResponse(data['${effectivePrefix}config']))!,
|
||||||
frozen: const BoolType()
|
frozen: const BoolType()
|
||||||
.mapFromDatabaseResponse(data['${effectivePrefix}frozen'])!,
|
.mapFromDatabaseResponse(data['${effectivePrefix}frozen'])!,
|
||||||
@@ -81,7 +87,7 @@ class ChannelEntity extends DataClass implements Insertable<ChannelEntity> {
|
|||||||
.mapFromDatabaseResponse(data['${effectivePrefix}member_count'])!,
|
.mapFromDatabaseResponse(data['${effectivePrefix}member_count'])!,
|
||||||
createdById: const StringType()
|
createdById: const StringType()
|
||||||
.mapFromDatabaseResponse(data['${effectivePrefix}created_by_id']),
|
.mapFromDatabaseResponse(data['${effectivePrefix}created_by_id']),
|
||||||
extraData: $ChannelsTable.$converter1.mapToDart(const StringType()
|
extraData: $ChannelsTable.$converter2.mapToDart(const StringType()
|
||||||
.mapFromDatabaseResponse(data['${effectivePrefix}extra_data'])),
|
.mapFromDatabaseResponse(data['${effectivePrefix}extra_data'])),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -91,8 +97,13 @@ class ChannelEntity extends DataClass implements Insertable<ChannelEntity> {
|
|||||||
map['id'] = Variable<String>(id);
|
map['id'] = Variable<String>(id);
|
||||||
map['type'] = Variable<String>(type);
|
map['type'] = Variable<String>(type);
|
||||||
map['cid'] = Variable<String>(cid);
|
map['cid'] = Variable<String>(cid);
|
||||||
{
|
if (!nullToAbsent || ownCapabilities != null) {
|
||||||
final converter = $ChannelsTable.$converter0;
|
final converter = $ChannelsTable.$converter0;
|
||||||
|
map['own_capabilities'] =
|
||||||
|
Variable<String?>(converter.mapToSql(ownCapabilities));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
final converter = $ChannelsTable.$converter1;
|
||||||
map['config'] = Variable<String>(converter.mapToSql(config)!);
|
map['config'] = Variable<String>(converter.mapToSql(config)!);
|
||||||
}
|
}
|
||||||
map['frozen'] = Variable<bool>(frozen);
|
map['frozen'] = Variable<bool>(frozen);
|
||||||
@@ -109,7 +120,7 @@ class ChannelEntity extends DataClass implements Insertable<ChannelEntity> {
|
|||||||
map['created_by_id'] = Variable<String?>(createdById);
|
map['created_by_id'] = Variable<String?>(createdById);
|
||||||
}
|
}
|
||||||
if (!nullToAbsent || extraData != null) {
|
if (!nullToAbsent || extraData != null) {
|
||||||
final converter = $ChannelsTable.$converter1;
|
final converter = $ChannelsTable.$converter2;
|
||||||
map['extra_data'] = Variable<String?>(converter.mapToSql(extraData));
|
map['extra_data'] = Variable<String?>(converter.mapToSql(extraData));
|
||||||
}
|
}
|
||||||
return map;
|
return map;
|
||||||
@@ -122,6 +133,8 @@ class ChannelEntity extends DataClass implements Insertable<ChannelEntity> {
|
|||||||
id: serializer.fromJson<String>(json['id']),
|
id: serializer.fromJson<String>(json['id']),
|
||||||
type: serializer.fromJson<String>(json['type']),
|
type: serializer.fromJson<String>(json['type']),
|
||||||
cid: serializer.fromJson<String>(json['cid']),
|
cid: serializer.fromJson<String>(json['cid']),
|
||||||
|
ownCapabilities:
|
||||||
|
serializer.fromJson<List<String>?>(json['ownCapabilities']),
|
||||||
config: serializer.fromJson<Map<String, dynamic>>(json['config']),
|
config: serializer.fromJson<Map<String, dynamic>>(json['config']),
|
||||||
frozen: serializer.fromJson<bool>(json['frozen']),
|
frozen: serializer.fromJson<bool>(json['frozen']),
|
||||||
lastMessageAt: serializer.fromJson<DateTime?>(json['lastMessageAt']),
|
lastMessageAt: serializer.fromJson<DateTime?>(json['lastMessageAt']),
|
||||||
@@ -140,6 +153,7 @@ class ChannelEntity extends DataClass implements Insertable<ChannelEntity> {
|
|||||||
'id': serializer.toJson<String>(id),
|
'id': serializer.toJson<String>(id),
|
||||||
'type': serializer.toJson<String>(type),
|
'type': serializer.toJson<String>(type),
|
||||||
'cid': serializer.toJson<String>(cid),
|
'cid': serializer.toJson<String>(cid),
|
||||||
|
'ownCapabilities': serializer.toJson<List<String>?>(ownCapabilities),
|
||||||
'config': serializer.toJson<Map<String, dynamic>>(config),
|
'config': serializer.toJson<Map<String, dynamic>>(config),
|
||||||
'frozen': serializer.toJson<bool>(frozen),
|
'frozen': serializer.toJson<bool>(frozen),
|
||||||
'lastMessageAt': serializer.toJson<DateTime?>(lastMessageAt),
|
'lastMessageAt': serializer.toJson<DateTime?>(lastMessageAt),
|
||||||
@@ -156,6 +170,7 @@ class ChannelEntity extends DataClass implements Insertable<ChannelEntity> {
|
|||||||
{String? id,
|
{String? id,
|
||||||
String? type,
|
String? type,
|
||||||
String? cid,
|
String? cid,
|
||||||
|
Value<List<String>?> ownCapabilities = const Value.absent(),
|
||||||
Map<String, dynamic>? config,
|
Map<String, dynamic>? config,
|
||||||
bool? frozen,
|
bool? frozen,
|
||||||
Value<DateTime?> lastMessageAt = const Value.absent(),
|
Value<DateTime?> lastMessageAt = const Value.absent(),
|
||||||
@@ -169,6 +184,9 @@ class ChannelEntity extends DataClass implements Insertable<ChannelEntity> {
|
|||||||
id: id ?? this.id,
|
id: id ?? this.id,
|
||||||
type: type ?? this.type,
|
type: type ?? this.type,
|
||||||
cid: cid ?? this.cid,
|
cid: cid ?? this.cid,
|
||||||
|
ownCapabilities: ownCapabilities.present
|
||||||
|
? ownCapabilities.value
|
||||||
|
: this.ownCapabilities,
|
||||||
config: config ?? this.config,
|
config: config ?? this.config,
|
||||||
frozen: frozen ?? this.frozen,
|
frozen: frozen ?? this.frozen,
|
||||||
lastMessageAt:
|
lastMessageAt:
|
||||||
@@ -186,6 +204,7 @@ class ChannelEntity extends DataClass implements Insertable<ChannelEntity> {
|
|||||||
..write('id: $id, ')
|
..write('id: $id, ')
|
||||||
..write('type: $type, ')
|
..write('type: $type, ')
|
||||||
..write('cid: $cid, ')
|
..write('cid: $cid, ')
|
||||||
|
..write('ownCapabilities: $ownCapabilities, ')
|
||||||
..write('config: $config, ')
|
..write('config: $config, ')
|
||||||
..write('frozen: $frozen, ')
|
..write('frozen: $frozen, ')
|
||||||
..write('lastMessageAt: $lastMessageAt, ')
|
..write('lastMessageAt: $lastMessageAt, ')
|
||||||
@@ -200,8 +219,20 @@ class ChannelEntity extends DataClass implements Insertable<ChannelEntity> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(id, type, cid, config, frozen, lastMessageAt,
|
int get hashCode => Object.hash(
|
||||||
createdAt, updatedAt, deletedAt, memberCount, createdById, extraData);
|
id,
|
||||||
|
type,
|
||||||
|
cid,
|
||||||
|
ownCapabilities,
|
||||||
|
config,
|
||||||
|
frozen,
|
||||||
|
lastMessageAt,
|
||||||
|
createdAt,
|
||||||
|
updatedAt,
|
||||||
|
deletedAt,
|
||||||
|
memberCount,
|
||||||
|
createdById,
|
||||||
|
extraData);
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) =>
|
bool operator ==(Object other) =>
|
||||||
identical(this, other) ||
|
identical(this, other) ||
|
||||||
@@ -209,6 +240,7 @@ class ChannelEntity extends DataClass implements Insertable<ChannelEntity> {
|
|||||||
other.id == this.id &&
|
other.id == this.id &&
|
||||||
other.type == this.type &&
|
other.type == this.type &&
|
||||||
other.cid == this.cid &&
|
other.cid == this.cid &&
|
||||||
|
other.ownCapabilities == this.ownCapabilities &&
|
||||||
other.config == this.config &&
|
other.config == this.config &&
|
||||||
other.frozen == this.frozen &&
|
other.frozen == this.frozen &&
|
||||||
other.lastMessageAt == this.lastMessageAt &&
|
other.lastMessageAt == this.lastMessageAt &&
|
||||||
@@ -224,6 +256,7 @@ class ChannelsCompanion extends UpdateCompanion<ChannelEntity> {
|
|||||||
final Value<String> id;
|
final Value<String> id;
|
||||||
final Value<String> type;
|
final Value<String> type;
|
||||||
final Value<String> cid;
|
final Value<String> cid;
|
||||||
|
final Value<List<String>?> ownCapabilities;
|
||||||
final Value<Map<String, dynamic>> config;
|
final Value<Map<String, dynamic>> config;
|
||||||
final Value<bool> frozen;
|
final Value<bool> frozen;
|
||||||
final Value<DateTime?> lastMessageAt;
|
final Value<DateTime?> lastMessageAt;
|
||||||
@@ -237,6 +270,7 @@ class ChannelsCompanion extends UpdateCompanion<ChannelEntity> {
|
|||||||
this.id = const Value.absent(),
|
this.id = const Value.absent(),
|
||||||
this.type = const Value.absent(),
|
this.type = const Value.absent(),
|
||||||
this.cid = const Value.absent(),
|
this.cid = const Value.absent(),
|
||||||
|
this.ownCapabilities = const Value.absent(),
|
||||||
this.config = const Value.absent(),
|
this.config = const Value.absent(),
|
||||||
this.frozen = const Value.absent(),
|
this.frozen = const Value.absent(),
|
||||||
this.lastMessageAt = const Value.absent(),
|
this.lastMessageAt = const Value.absent(),
|
||||||
@@ -251,6 +285,7 @@ class ChannelsCompanion extends UpdateCompanion<ChannelEntity> {
|
|||||||
required String id,
|
required String id,
|
||||||
required String type,
|
required String type,
|
||||||
required String cid,
|
required String cid,
|
||||||
|
this.ownCapabilities = const Value.absent(),
|
||||||
required Map<String, dynamic> config,
|
required Map<String, dynamic> config,
|
||||||
this.frozen = const Value.absent(),
|
this.frozen = const Value.absent(),
|
||||||
this.lastMessageAt = const Value.absent(),
|
this.lastMessageAt = const Value.absent(),
|
||||||
@@ -268,6 +303,7 @@ class ChannelsCompanion extends UpdateCompanion<ChannelEntity> {
|
|||||||
Expression<String>? id,
|
Expression<String>? id,
|
||||||
Expression<String>? type,
|
Expression<String>? type,
|
||||||
Expression<String>? cid,
|
Expression<String>? cid,
|
||||||
|
Expression<List<String>?>? ownCapabilities,
|
||||||
Expression<Map<String, dynamic>>? config,
|
Expression<Map<String, dynamic>>? config,
|
||||||
Expression<bool>? frozen,
|
Expression<bool>? frozen,
|
||||||
Expression<DateTime?>? lastMessageAt,
|
Expression<DateTime?>? lastMessageAt,
|
||||||
@@ -282,6 +318,7 @@ class ChannelsCompanion extends UpdateCompanion<ChannelEntity> {
|
|||||||
if (id != null) 'id': id,
|
if (id != null) 'id': id,
|
||||||
if (type != null) 'type': type,
|
if (type != null) 'type': type,
|
||||||
if (cid != null) 'cid': cid,
|
if (cid != null) 'cid': cid,
|
||||||
|
if (ownCapabilities != null) 'own_capabilities': ownCapabilities,
|
||||||
if (config != null) 'config': config,
|
if (config != null) 'config': config,
|
||||||
if (frozen != null) 'frozen': frozen,
|
if (frozen != null) 'frozen': frozen,
|
||||||
if (lastMessageAt != null) 'last_message_at': lastMessageAt,
|
if (lastMessageAt != null) 'last_message_at': lastMessageAt,
|
||||||
@@ -298,6 +335,7 @@ class ChannelsCompanion extends UpdateCompanion<ChannelEntity> {
|
|||||||
{Value<String>? id,
|
{Value<String>? id,
|
||||||
Value<String>? type,
|
Value<String>? type,
|
||||||
Value<String>? cid,
|
Value<String>? cid,
|
||||||
|
Value<List<String>?>? ownCapabilities,
|
||||||
Value<Map<String, dynamic>>? config,
|
Value<Map<String, dynamic>>? config,
|
||||||
Value<bool>? frozen,
|
Value<bool>? frozen,
|
||||||
Value<DateTime?>? lastMessageAt,
|
Value<DateTime?>? lastMessageAt,
|
||||||
@@ -311,6 +349,7 @@ class ChannelsCompanion extends UpdateCompanion<ChannelEntity> {
|
|||||||
id: id ?? this.id,
|
id: id ?? this.id,
|
||||||
type: type ?? this.type,
|
type: type ?? this.type,
|
||||||
cid: cid ?? this.cid,
|
cid: cid ?? this.cid,
|
||||||
|
ownCapabilities: ownCapabilities ?? this.ownCapabilities,
|
||||||
config: config ?? this.config,
|
config: config ?? this.config,
|
||||||
frozen: frozen ?? this.frozen,
|
frozen: frozen ?? this.frozen,
|
||||||
lastMessageAt: lastMessageAt ?? this.lastMessageAt,
|
lastMessageAt: lastMessageAt ?? this.lastMessageAt,
|
||||||
@@ -335,8 +374,13 @@ class ChannelsCompanion extends UpdateCompanion<ChannelEntity> {
|
|||||||
if (cid.present) {
|
if (cid.present) {
|
||||||
map['cid'] = Variable<String>(cid.value);
|
map['cid'] = Variable<String>(cid.value);
|
||||||
}
|
}
|
||||||
if (config.present) {
|
if (ownCapabilities.present) {
|
||||||
final converter = $ChannelsTable.$converter0;
|
final converter = $ChannelsTable.$converter0;
|
||||||
|
map['own_capabilities'] =
|
||||||
|
Variable<String?>(converter.mapToSql(ownCapabilities.value));
|
||||||
|
}
|
||||||
|
if (config.present) {
|
||||||
|
final converter = $ChannelsTable.$converter1;
|
||||||
map['config'] = Variable<String>(converter.mapToSql(config.value)!);
|
map['config'] = Variable<String>(converter.mapToSql(config.value)!);
|
||||||
}
|
}
|
||||||
if (frozen.present) {
|
if (frozen.present) {
|
||||||
@@ -361,7 +405,7 @@ class ChannelsCompanion extends UpdateCompanion<ChannelEntity> {
|
|||||||
map['created_by_id'] = Variable<String?>(createdById.value);
|
map['created_by_id'] = Variable<String?>(createdById.value);
|
||||||
}
|
}
|
||||||
if (extraData.present) {
|
if (extraData.present) {
|
||||||
final converter = $ChannelsTable.$converter1;
|
final converter = $ChannelsTable.$converter2;
|
||||||
map['extra_data'] =
|
map['extra_data'] =
|
||||||
Variable<String?>(converter.mapToSql(extraData.value));
|
Variable<String?>(converter.mapToSql(extraData.value));
|
||||||
}
|
}
|
||||||
@@ -374,6 +418,7 @@ class ChannelsCompanion extends UpdateCompanion<ChannelEntity> {
|
|||||||
..write('id: $id, ')
|
..write('id: $id, ')
|
||||||
..write('type: $type, ')
|
..write('type: $type, ')
|
||||||
..write('cid: $cid, ')
|
..write('cid: $cid, ')
|
||||||
|
..write('ownCapabilities: $ownCapabilities, ')
|
||||||
..write('config: $config, ')
|
..write('config: $config, ')
|
||||||
..write('frozen: $frozen, ')
|
..write('frozen: $frozen, ')
|
||||||
..write('lastMessageAt: $lastMessageAt, ')
|
..write('lastMessageAt: $lastMessageAt, ')
|
||||||
@@ -409,12 +454,20 @@ class $ChannelsTable extends Channels
|
|||||||
late final GeneratedColumn<String?> cid = GeneratedColumn<String?>(
|
late final GeneratedColumn<String?> cid = GeneratedColumn<String?>(
|
||||||
'cid', aliasedName, false,
|
'cid', aliasedName, false,
|
||||||
type: const StringType(), requiredDuringInsert: true);
|
type: const StringType(), requiredDuringInsert: true);
|
||||||
|
final VerificationMeta _ownCapabilitiesMeta =
|
||||||
|
const VerificationMeta('ownCapabilities');
|
||||||
|
@override
|
||||||
|
late final GeneratedColumnWithTypeConverter<List<String>, String?>
|
||||||
|
ownCapabilities = GeneratedColumn<String?>(
|
||||||
|
'own_capabilities', aliasedName, true,
|
||||||
|
type: const StringType(), requiredDuringInsert: false)
|
||||||
|
.withConverter<List<String>>($ChannelsTable.$converter0);
|
||||||
final VerificationMeta _configMeta = const VerificationMeta('config');
|
final VerificationMeta _configMeta = const VerificationMeta('config');
|
||||||
@override
|
@override
|
||||||
late final GeneratedColumnWithTypeConverter<Map<String, dynamic>, String?>
|
late final GeneratedColumnWithTypeConverter<Map<String, dynamic>, String?>
|
||||||
config = GeneratedColumn<String?>('config', aliasedName, false,
|
config = GeneratedColumn<String?>('config', aliasedName, false,
|
||||||
type: const StringType(), requiredDuringInsert: true)
|
type: const StringType(), requiredDuringInsert: true)
|
||||||
.withConverter<Map<String, dynamic>>($ChannelsTable.$converter0);
|
.withConverter<Map<String, dynamic>>($ChannelsTable.$converter1);
|
||||||
final VerificationMeta _frozenMeta = const VerificationMeta('frozen');
|
final VerificationMeta _frozenMeta = const VerificationMeta('frozen');
|
||||||
@override
|
@override
|
||||||
late final GeneratedColumn<bool?> frozen = GeneratedColumn<bool?>(
|
late final GeneratedColumn<bool?> frozen = GeneratedColumn<bool?>(
|
||||||
@@ -467,12 +520,13 @@ class $ChannelsTable extends Channels
|
|||||||
late final GeneratedColumnWithTypeConverter<Map<String, Object?>, String?>
|
late final GeneratedColumnWithTypeConverter<Map<String, Object?>, String?>
|
||||||
extraData = GeneratedColumn<String?>('extra_data', aliasedName, true,
|
extraData = GeneratedColumn<String?>('extra_data', aliasedName, true,
|
||||||
type: const StringType(), requiredDuringInsert: false)
|
type: const StringType(), requiredDuringInsert: false)
|
||||||
.withConverter<Map<String, Object?>>($ChannelsTable.$converter1);
|
.withConverter<Map<String, Object?>>($ChannelsTable.$converter2);
|
||||||
@override
|
@override
|
||||||
List<GeneratedColumn> get $columns => [
|
List<GeneratedColumn> get $columns => [
|
||||||
id,
|
id,
|
||||||
type,
|
type,
|
||||||
cid,
|
cid,
|
||||||
|
ownCapabilities,
|
||||||
config,
|
config,
|
||||||
frozen,
|
frozen,
|
||||||
lastMessageAt,
|
lastMessageAt,
|
||||||
@@ -509,6 +563,7 @@ class $ChannelsTable extends Channels
|
|||||||
} else if (isInserting) {
|
} else if (isInserting) {
|
||||||
context.missing(_cidMeta);
|
context.missing(_cidMeta);
|
||||||
}
|
}
|
||||||
|
context.handle(_ownCapabilitiesMeta, const VerificationResult.success());
|
||||||
context.handle(_configMeta, const VerificationResult.success());
|
context.handle(_configMeta, const VerificationResult.success());
|
||||||
if (data.containsKey('frozen')) {
|
if (data.containsKey('frozen')) {
|
||||||
context.handle(_frozenMeta,
|
context.handle(_frozenMeta,
|
||||||
@@ -561,9 +616,11 @@ class $ChannelsTable extends Channels
|
|||||||
return $ChannelsTable(attachedDatabase, alias);
|
return $ChannelsTable(attachedDatabase, alias);
|
||||||
}
|
}
|
||||||
|
|
||||||
static TypeConverter<Map<String, dynamic>, String> $converter0 =
|
static TypeConverter<List<String>, String> $converter0 =
|
||||||
|
ListConverter<String>();
|
||||||
|
static TypeConverter<Map<String, dynamic>, String> $converter1 =
|
||||||
MapConverter();
|
MapConverter();
|
||||||
static TypeConverter<Map<String, Object?>, String> $converter1 =
|
static TypeConverter<Map<String, Object?>, String> $converter2 =
|
||||||
MapConverter<Object?>();
|
MapConverter<Object?>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// coverage:ignore-file
|
// coverage:ignore-file
|
||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:stream_chat_persistence/src/converter/map_converter.dart';
|
import 'package:stream_chat_persistence/src/converter/converter.dart';
|
||||||
|
|
||||||
/// Represents a [Channels] table in [MoorChatDatabase].
|
/// Represents a [Channels] table in [MoorChatDatabase].
|
||||||
@DataClassName('ChannelEntity')
|
@DataClassName('ChannelEntity')
|
||||||
@@ -14,6 +14,10 @@ class Channels extends Table {
|
|||||||
/// The cid of this channel
|
/// The cid of this channel
|
||||||
TextColumn get cid => text()();
|
TextColumn get cid => text()();
|
||||||
|
|
||||||
|
/// List of user permissions on this channel
|
||||||
|
TextColumn get ownCapabilities =>
|
||||||
|
text().nullable().map(ListConverter<String>())();
|
||||||
|
|
||||||
/// The channel configuration data
|
/// The channel configuration data
|
||||||
TextColumn get config => text().map(MapConverter())();
|
TextColumn get config => text().map(MapConverter())();
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ extension ChannelEntityX on ChannelEntity {
|
|||||||
final config = ChannelConfig.fromJson(this.config);
|
final config = ChannelConfig.fromJson(this.config);
|
||||||
return ChannelModel(
|
return ChannelModel(
|
||||||
id: id,
|
id: id,
|
||||||
|
ownCapabilities: ownCapabilities,
|
||||||
config: config,
|
config: config,
|
||||||
type: type,
|
type: type,
|
||||||
frozen: frozen,
|
frozen: frozen,
|
||||||
@@ -46,6 +47,7 @@ extension ChannelModelX on ChannelModel {
|
|||||||
id: id,
|
id: id,
|
||||||
type: type,
|
type: type,
|
||||||
cid: cid,
|
cid: cid,
|
||||||
|
ownCapabilities: ownCapabilities,
|
||||||
config: config.toJson(),
|
config: config.toJson(),
|
||||||
frozen: frozen,
|
frozen: frozen,
|
||||||
lastMessageAt: lastMessageAt,
|
lastMessageAt: lastMessageAt,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
name: stream_chat_persistence
|
name: stream_chat_persistence
|
||||||
homepage: https://github.com/GetStream/stream-chat-flutter
|
homepage: https://github.com/GetStream/stream-chat-flutter
|
||||||
description: Official Stream Chat Persistence library. Build your own chat experience using Dart and Flutter.
|
description: Official Stream Chat Persistence library. Build your own chat experience using Dart and Flutter.
|
||||||
version: 4.1.0
|
version: 4.2.0
|
||||||
repository: https://github.com/GetStream/stream-chat-flutter
|
repository: https://github.com/GetStream/stream-chat-flutter
|
||||||
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
|
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
|
||||||
|
|
||||||
@@ -19,8 +19,7 @@ dependencies:
|
|||||||
path: ^1.8.0
|
path: ^1.8.0
|
||||||
path_provider: ^2.0.1
|
path_provider: ^2.0.1
|
||||||
sqlite3_flutter_libs: ^0.5.0
|
sqlite3_flutter_libs: ^0.5.0
|
||||||
stream_chat: ^4.1.0
|
stream_chat: ^4.3.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
build_runner: ^2.0.1
|
build_runner: ^2.0.1
|
||||||
dart_code_metrics: ^4.4.0
|
dart_code_metrics: ^4.4.0
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ void main() {
|
|||||||
id: 'testId',
|
id: 'testId',
|
||||||
type: 'testType',
|
type: 'testType',
|
||||||
cid: 'testCid',
|
cid: 'testCid',
|
||||||
|
ownCapabilities: ['testCapability'],
|
||||||
config: {'max_message_length': 33},
|
config: {'max_message_length': 33},
|
||||||
frozen: math.Random().nextBool(),
|
frozen: math.Random().nextBool(),
|
||||||
lastMessageAt: DateTime.now(),
|
lastMessageAt: DateTime.now(),
|
||||||
@@ -29,6 +30,7 @@ void main() {
|
|||||||
final channelModel = entity.toChannelModel(createdBy: user);
|
final channelModel = entity.toChannelModel(createdBy: user);
|
||||||
expect(channelModel, isA<ChannelModel>());
|
expect(channelModel, isA<ChannelModel>());
|
||||||
expect(channelModel.id, entity.id);
|
expect(channelModel.id, entity.id);
|
||||||
|
expect(channelModel.ownCapabilities, entity.ownCapabilities);
|
||||||
expect(channelModel.config.toJson()['max_message_length'], 33);
|
expect(channelModel.config.toJson()['max_message_length'], 33);
|
||||||
expect(channelModel.frozen, entity.frozen);
|
expect(channelModel.frozen, entity.frozen);
|
||||||
expect(channelModel.createdAt, isSameDateAs(entity.createdAt));
|
expect(channelModel.createdAt, isSameDateAs(entity.createdAt));
|
||||||
@@ -68,6 +70,7 @@ void main() {
|
|||||||
|
|
||||||
final channelModel = channelState.channel!;
|
final channelModel = channelState.channel!;
|
||||||
expect(channelModel.id, entity.id);
|
expect(channelModel.id, entity.id);
|
||||||
|
expect(channelModel.ownCapabilities, entity.ownCapabilities);
|
||||||
expect(channelModel.config.toJson()['max_message_length'], 33);
|
expect(channelModel.config.toJson()['max_message_length'], 33);
|
||||||
expect(channelModel.frozen, entity.frozen);
|
expect(channelModel.frozen, entity.frozen);
|
||||||
expect(channelModel.createdAt, isSameDateAs(entity.createdAt));
|
expect(channelModel.createdAt, isSameDateAs(entity.createdAt));
|
||||||
@@ -87,6 +90,7 @@ void main() {
|
|||||||
id: 'testId',
|
id: 'testId',
|
||||||
type: 'testType',
|
type: 'testType',
|
||||||
cid: 'testCid',
|
cid: 'testCid',
|
||||||
|
ownCapabilities: ['testCapability'],
|
||||||
config: ChannelConfig(maxMessageLength: 33),
|
config: ChannelConfig(maxMessageLength: 33),
|
||||||
frozen: math.Random().nextBool(),
|
frozen: math.Random().nextBool(),
|
||||||
lastMessageAt: DateTime.now(),
|
lastMessageAt: DateTime.now(),
|
||||||
@@ -101,6 +105,7 @@ void main() {
|
|||||||
final channelEntity = model.toEntity();
|
final channelEntity = model.toEntity();
|
||||||
expect(channelEntity, isA<ChannelEntity>());
|
expect(channelEntity, isA<ChannelEntity>());
|
||||||
expect(channelEntity.id, model.id);
|
expect(channelEntity.id, model.id);
|
||||||
|
expect(channelEntity.ownCapabilities, model.ownCapabilities);
|
||||||
expect(
|
expect(
|
||||||
channelEntity.config['max_message_length'],
|
channelEntity.config['max_message_length'],
|
||||||
model.config.maxMessageLength,
|
model.config.maxMessageLength,
|
||||||
|
|||||||
Reference in New Issue
Block a user