Merge branch 'develop' into feat/stream-channel-listview
This commit is contained in:
@@ -4,15 +4,9 @@ import 'dart:math';
|
||||
import 'package:collection/collection.dart'
|
||||
show IterableExtension, ListEquality;
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:rate_limiter/rate_limiter.dart';
|
||||
import 'package:rxdart/rxdart.dart';
|
||||
import 'package:stream_chat/src/client/retry_queue.dart';
|
||||
import 'package:stream_chat/src/core/error/error.dart';
|
||||
import 'package:stream_chat/src/core/models/attachment_file.dart';
|
||||
import 'package:stream_chat/src/core/models/channel_state.dart';
|
||||
import 'package:stream_chat/src/core/models/user.dart';
|
||||
import 'package:stream_chat/src/core/util/utils.dart';
|
||||
import 'package:stream_chat/src/event_type.dart';
|
||||
import 'package:stream_chat/stream_chat.dart';
|
||||
|
||||
/// Class that manages a specific channel.
|
||||
@@ -1268,6 +1262,21 @@ class Channel {
|
||||
pagination: pagination,
|
||||
);
|
||||
|
||||
/// Query channel banned users.
|
||||
Future<QueryBannedUsersResponse> queryBannedUsers({
|
||||
Filter? filter,
|
||||
List<SortOption>? sort,
|
||||
PaginationParams? pagination,
|
||||
}) {
|
||||
_checkInitialized();
|
||||
filter ??= Filter.equal('channel_cid', cid!);
|
||||
return _client.queryBannedUsers(
|
||||
filter: filter,
|
||||
sort: sort,
|
||||
pagination: pagination,
|
||||
);
|
||||
}
|
||||
|
||||
/// Mutes the channel.
|
||||
Future<EmptyResponse> mute({Duration? expiration}) {
|
||||
_checkInitialized();
|
||||
@@ -1281,9 +1290,17 @@ class Channel {
|
||||
}
|
||||
|
||||
/// Bans the user with given [userID] from the channel.
|
||||
@Deprecated("Use 'banMember' instead")
|
||||
Future<EmptyResponse> banUser(
|
||||
String userID,
|
||||
Map<String, dynamic> options,
|
||||
) =>
|
||||
banMember(userID, options);
|
||||
|
||||
/// Bans the member with given [userID] from the channel.
|
||||
Future<EmptyResponse> banMember(
|
||||
String userID,
|
||||
Map<String, dynamic> options,
|
||||
) async {
|
||||
_checkInitialized();
|
||||
final opts = Map<String, dynamic>.from(options)
|
||||
@@ -1295,7 +1312,11 @@ class Channel {
|
||||
}
|
||||
|
||||
/// Remove the ban for the user with given [userID] in the channel.
|
||||
Future<EmptyResponse> unbanUser(String userID) async {
|
||||
@Deprecated("Use 'unbanMember' instead")
|
||||
Future<EmptyResponse> unbanUser(String userID) => unbanMember(userID);
|
||||
|
||||
/// Remove the ban for the member with given [userID] in the channel.
|
||||
Future<EmptyResponse> unbanMember(String userID) async {
|
||||
_checkInitialized();
|
||||
return _client.unbanUser(userID, {
|
||||
'type': type,
|
||||
@@ -1466,6 +1487,10 @@ class ChannelClientState {
|
||||
|
||||
_listenMemberRemoved();
|
||||
|
||||
_listenMemberBanned();
|
||||
|
||||
_listenMemberUnbanned();
|
||||
|
||||
_startCleaning();
|
||||
|
||||
_startCleaningPinnedMessages();
|
||||
@@ -1538,6 +1563,7 @@ class ChannelClientState {
|
||||
members: List.from(
|
||||
channelState.members..removeWhere((m) => m.userId == user!.id),
|
||||
),
|
||||
read: channelState.read..removeWhere((r) => r.user.id == user!.id),
|
||||
));
|
||||
}));
|
||||
}
|
||||
@@ -1563,6 +1589,54 @@ class ChannelClientState {
|
||||
}));
|
||||
}
|
||||
|
||||
void _listenMemberBanned() {
|
||||
_subscriptions.add(_channel
|
||||
.on(EventType.userBanned)
|
||||
.where((it) => it.cid != null) // filters channel ban from app ban
|
||||
.listen(
|
||||
(event) async {
|
||||
final user = event.user!;
|
||||
final member = await _channel
|
||||
.queryMembers(filter: Filter.equal('id', user.id))
|
||||
.then((it) => it.members.first);
|
||||
|
||||
_updateMember(member);
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
void _listenMemberUnbanned() {
|
||||
_subscriptions.add(_channel
|
||||
.on(EventType.userUnbanned)
|
||||
.where((it) => it.cid != null) // filters channel ban from app ban
|
||||
.listen(
|
||||
(event) async {
|
||||
final user = event.user!;
|
||||
final member = await _channel
|
||||
.queryMembers(filter: Filter.equal('id', user.id))
|
||||
.then((it) => it.members.first);
|
||||
|
||||
_updateMember(member);
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
void _updateMember(Member member) {
|
||||
final currentMembers = [...members];
|
||||
final memberIndex = currentMembers.indexWhere(
|
||||
(m) => m.userId == member.userId,
|
||||
);
|
||||
|
||||
if (memberIndex == -1) return;
|
||||
currentMembers[memberIndex] = member;
|
||||
|
||||
updateChannelState(
|
||||
channelState.copyWith(
|
||||
members: currentMembers,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Flag which indicates if [ChannelClientState] contain latest/recent messages or not.
|
||||
///
|
||||
/// This flag should be managed by UI sdks.
|
||||
@@ -1729,7 +1803,13 @@ class ChannelClientState {
|
||||
if (replyCount == null || replyCount == 0) return;
|
||||
|
||||
addMessage(parentMessage.copyWith(replyCount: replyCount - 1));
|
||||
updateThreadInfo(parentId, threads[parentId]!..remove(message));
|
||||
updateThreadInfo(
|
||||
parentId,
|
||||
threads[parentId]!
|
||||
..removeWhere(
|
||||
(e) => e.id == message.id,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
// Remove regular message
|
||||
final allMessages = [...messages];
|
||||
|
||||
@@ -66,8 +66,11 @@ class StreamChatClient {
|
||||
this.logLevel = Level.WARNING,
|
||||
LogHandlerFunction? logHandlerFunction,
|
||||
RetryPolicy? retryPolicy,
|
||||
Location? location,
|
||||
@Deprecated('Use location to change baseUrl instead') String? baseURL,
|
||||
@Deprecated('''
|
||||
Location is now deprecated in favor of the new edge server. Will be removed in v4.0.0.
|
||||
Read more here: https://getstream.io/blog/chat-edge-infrastructure
|
||||
''') Location? location,
|
||||
String? baseURL,
|
||||
Duration connectTimeout = const Duration(seconds: 6),
|
||||
Duration receiveTimeout = const Duration(seconds: 6),
|
||||
StreamChatApi? chatApi,
|
||||
@@ -79,7 +82,6 @@ class StreamChatClient {
|
||||
|
||||
final options = StreamHttpClientOptions(
|
||||
baseUrl: baseURL,
|
||||
location: location,
|
||||
connectTimeout: connectTimeout,
|
||||
receiveTimeout: receiveTimeout,
|
||||
headers: {'X-Stream-Client': defaultUserAgent},
|
||||
@@ -685,6 +687,18 @@ class StreamChatClient {
|
||||
return response;
|
||||
}
|
||||
|
||||
/// Query banned users.
|
||||
Future<QueryBannedUsersResponse> queryBannedUsers({
|
||||
required Filter filter,
|
||||
List<SortOption>? sort,
|
||||
PaginationParams? pagination,
|
||||
}) =>
|
||||
_chatApi.moderation.queryBannedUsers(
|
||||
filter: filter,
|
||||
sort: sort,
|
||||
pagination: pagination,
|
||||
);
|
||||
|
||||
/// A message search.
|
||||
Future<SearchMessagesResponse> search(
|
||||
Filter filter, {
|
||||
@@ -1316,6 +1330,10 @@ class StreamChatClient {
|
||||
},
|
||||
);
|
||||
|
||||
/// Get OpenGraph data of the given [url].
|
||||
Future<OGAttachmentResponse> enrichUrl(String url) =>
|
||||
_chatApi.general.enrichUrl(url);
|
||||
|
||||
/// Closes the [_ws] connection and resets the [state]
|
||||
/// If [flushChatPersistence] is true the client deletes all offline
|
||||
/// user's data.
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:rxdart/rxdart.dart';
|
||||
import 'package:stream_chat/src/client/channel.dart';
|
||||
import 'package:stream_chat/src/client/retry_policy.dart';
|
||||
import 'package:stream_chat/src/core/error/error.dart';
|
||||
import 'package:stream_chat/src/core/models/message.dart';
|
||||
import 'package:stream_chat/src/event_type.dart';
|
||||
import 'package:stream_chat/stream_chat.dart';
|
||||
|
||||
/// The retry queue associated to a channel
|
||||
|
||||
Reference in New Issue
Block a user