Merge remote-tracking branch 'origin/v7.0.0' into refactor/attachments

# Conflicts:
#	packages/stream_chat_flutter/lib/src/fullscreen_media/full_screen_media.dart
#	packages/stream_chat_flutter/lib/src/fullscreen_media/full_screen_media_desktop.dart
#	packages/stream_chat_flutter/pubspec.yaml
This commit is contained in:
Sahil Kumar
2023-08-18 19:47:14 +05:30
38 changed files with 815 additions and 439 deletions
+32 -12
View File
@@ -1,7 +1,39 @@
## 7.0.0-beta.3
- Included the changes from version [6.8.0](#670).
- Updated minimum supported `SDK` version to Dart 3.1
## 6.8.0
🐞 Fixed
- Fixed `Channel.query` not initializing `ChannelState`.
✅ Added
- Added support for `channel.countUnreadMentions()` to get the count of unread messages mentioning the current user on a
channel. [#1692](https://github.com/GetStream/stream-chat-flutter/issues/1692)
🔄 Changed
- Updated minimum supported `SDK` version to Dart 3.0
## 7.0.0-beta.2
- Included the changes from version [6.7.0](#670).
## 6.7.0
✅ Added
- Added support for setting `Message.type`. [#1682](https://github.com/GetStream/stream-chat-flutter/issues/1682)
```
It is now possible to send system messages. System messages differ from normal messages in the way they are
presented to the user. Like the name says, system messages are normally send from the system itself, but a user is
able to send it as well by specifying type: 'system' with the message. The user who sends a system message client-side
should have the Create System Message permission. Server-side system messages don't need that permission.
```
## 7.0.0-beta.1
🛑️ Breaking
@@ -16,18 +48,6 @@
- Updated minimum supported `SDK` version to Dart 3.0
## 6.7.0
✅ Added
- Added support for setting `Message.type`. [#1682](https://github.com/GetStream/stream-chat-flutter/issues/1682)
```
It is now possible to send system messages. System messages differ from normal messages in the way they are
presented to the user. Like the name says, system messages are normally send from the system itself, but a user is
able to send it as well by specifying type: 'system' with the message. The user who sends a system message client-side
should have the Create System Message permission. Server-side system messages don't need that permission.
```
## 6.6.0
🔄 Changed
+2 -2
View File
@@ -5,8 +5,8 @@ publish_to: "none"
version: 1.0.0+1
environment:
sdk: ">=3.0.0 <4.0.0"
flutter: ">=3.10.0"
sdk: ">=3.1.0 <4.0.0"
flutter: ">=3.13.0"
dependencies:
cupertino_icons: ^1.0.5
@@ -1339,26 +1339,6 @@ class Channel {
return _client.markChannelRead(id!, type, messageId: messageId);
}
/// Loads the initial channel state and watches for changes.
Future<ChannelState> watch({bool presence = false}) async {
ChannelState response;
try {
response = await query(watch: true, presence: presence);
} catch (error, stackTrace) {
if (!_initializedCompleter.isCompleted) {
_initializedCompleter.completeError(error, stackTrace);
}
rethrow;
}
if (state == null) {
_initState(response);
}
return response;
}
void _initState(ChannelState channelState) {
state = ChannelClientState(this, channelState);
@@ -1370,6 +1350,22 @@ class Channel {
}
}
/// Loads the initial channel state and watches for changes.
Future<ChannelState> watch({
bool presence = false,
PaginationParams? messagesPagination,
PaginationParams? membersPagination,
PaginationParams? watchersPagination,
}) {
return query(
watch: true,
presence: presence,
messagesPagination: messagesPagination,
membersPagination: membersPagination,
watchersPagination: watchersPagination,
);
}
/// Stop watching the channel.
Future<EmptyResponse> stopWatching() async {
_checkInitialized();
@@ -1435,7 +1431,7 @@ class Channel {
);
/// Creates a new channel.
Future<ChannelState> create() async => query(state: false);
Future<ChannelState> create() => query(state: false);
/// Query the API, get messages, members or other channel fields.
///
@@ -1450,23 +1446,28 @@ class Channel {
PaginationParams? watchersPagination,
bool preferOffline = false,
}) async {
if (preferOffline && cid != null) {
final updatedState = await _client.chatPersistenceClient
?.getChannelStateByCid(cid!, messagePagination: messagesPagination);
if (updatedState != null &&
updatedState.messages != null &&
updatedState.messages!.isNotEmpty) {
if (this.state == null) {
_initState(updatedState);
} else {
this.state?.updateChannelState(updatedState);
}
return updatedState;
}
}
ChannelState? channelState;
try {
final updatedState = await _client.queryChannel(
// If we prefer offline, we first try to get the channel state from the
// offline storage.
if (preferOffline && !watch && cid != null) {
final persistenceClient = _client.chatPersistenceClient;
if (persistenceClient != null) {
final cachedState = await persistenceClient.getChannelStateByCid(
cid!,
messagePagination: messagesPagination,
);
// If the cached state contains messages, we can use it.
if (cachedState.messages?.isNotEmpty == true) {
channelState = cachedState;
}
}
}
// If we still don't have the channelState, we try to get it from the API.
channelState ??= await _client.queryChannel(
type,
channelId: id,
channelData: _extraData,
@@ -1479,18 +1480,35 @@ class Channel {
);
if (_id == null) {
_id = updatedState.channel!.id;
_cid = updatedState.channel!.cid;
_id = channelState.channel!.id;
_cid = channelState.channel!.cid;
}
this.state?.updateChannelState(updatedState);
return updatedState;
} catch (e) {
if (_client.persistenceEnabled) {
return _client.chatPersistenceClient!.getChannelStateByCid(
cid!,
messagePagination: messagesPagination,
);
// Initialize the channel state if it's not initialized yet.
if (this.state == null) {
_initState(channelState);
} else {
// Otherwise, update the channel state.
this.state?.updateChannelState(channelState);
}
return channelState;
} catch (e, stk) {
// If we failed to get the channel state from the API and we were not
// supposed to watch the channel, we will try to get the channel state
// from the offline storage.
if (watch == false) {
if (_client.persistenceEnabled) {
return _client.chatPersistenceClient!.getChannelStateByCid(
cid!,
messagePagination: messagesPagination,
);
}
}
// Otherwise, we will just rethrow the error.
if (!_initializedCompleter.isCompleted) {
_initializedCompleter.completeError(e, stk);
}
rethrow;
@@ -2334,6 +2352,26 @@ class ChannelClientState {
!isThreadMessage;
}
/// Counts the number of unread messages mentioning the current user.
///
/// **NOTE**: The method relies on the [Channel.messages] list and doesn't do
/// any API call. Therefore, the count might be not reliable as it relies on
/// the local data.
int countUnreadMentions() {
final lastRead = currentUserRead?.lastRead;
final userId = _channel.client.state.currentUser?.id;
var count = 0;
for (final message in messages) {
if (_countMessageAsUnread(message) &&
(lastRead == null || message.createdAt.isAfter(lastRead)) &&
message.mentionedUsers.any((user) => user.id == userId) == true) {
count++;
}
}
return count;
}
/// Update threads with updated information about messages.
void updateThreadInfo(String parentId, List<Message> messages) {
final newThreads = Map<String, List<Message>>.from(threads);
@@ -1685,7 +1685,7 @@ class ClientState {
void updateUsers(List<User?> userList) {
final newUsers = {
...users,
for (var user in userList)
for (final user in userList)
if (user != null) user.id: user,
};
_usersController.add(newUsers);
+1 -1
View File
@@ -3,4 +3,4 @@ import 'package:stream_chat/src/client/client.dart';
/// Current package version
/// Used in [StreamChatClient] to build the `x-stream-client` header
// ignore: constant_identifier_names
const PACKAGE_VERSION = '7.0.0-beta.2';
const PACKAGE_VERSION = '7.0.0-beta.3';
+8 -8
View File
@@ -1,21 +1,21 @@
name: stream_chat
homepage: https://getstream.io/
description: The official Dart client for Stream Chat, a service for building chat applications.
version: 7.0.0-beta.2
version: 7.0.0-beta.3
repository: https://github.com/GetStream/stream-chat-flutter
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
environment:
sdk: '>=3.0.0 <4.0.0'
sdk: '>=3.1.0 <4.0.0'
dependencies:
async: ^2.11.0
collection: ^1.17.1
dio: ^5.2.1+1
collection: ^1.17.2
dio: ^5.3.2
equatable: ^2.0.5
freezed_annotation: ^2.4.1
http_parser: ^4.0.2
jose: ^0.3.3
jose: ^0.3.4
json_annotation: ^4.8.1
logging: ^1.2.0
meta: ^1.9.1
@@ -28,7 +28,7 @@ dependencies:
dev_dependencies:
build_runner: ^2.4.6
freezed: ^2.4.1
freezed: ^2.4.2
json_serializable: ^6.7.1
mocktail: ^0.3.0
test: ^1.24.4
mocktail: ^1.0.0
test: ^1.24.6
@@ -975,7 +975,7 @@ void main() {
// skipping initial seed event -> {} users
client.state.usersStream.skip(1),
emitsInOrder([
{for (var user in users) user.id: user},
{for (final user in users) user.id: user},
]),
);
@@ -1,3 +1,5 @@
// ignore_for_file: invalid_use_of_protected_member
import 'package:dio/dio.dart';
import 'package:stream_chat/src/core/http/interceptor/additional_headers_interceptor.dart';
import 'package:stream_chat/stream_chat.dart';
@@ -1,3 +1,5 @@
// ignore_for_file: invalid_use_of_protected_member
import 'package:dio/dio.dart';
import 'package:mocktail/mocktail.dart';
import 'package:stream_chat/src/core/http/interceptor/auth_interceptor.dart';
@@ -1,3 +1,5 @@
// ignore_for_file: invalid_use_of_protected_member
import 'package:dio/dio.dart';
import 'package:mocktail/mocktail.dart';
import 'package:stream_chat/src/core/http/connection_id_manager.dart';