diff --git a/packages/stream_chat/lib/src/client/channel.dart b/packages/stream_chat/lib/src/client/channel.dart index 6a8a13ec..28266b14 100644 --- a/packages/stream_chat/lib/src/client/channel.dart +++ b/packages/stream_chat/lib/src/client/channel.dart @@ -1290,6 +1290,21 @@ class Channel { pagination: pagination, ); + /// Query channel banned users. + Future queryBannedUsers({ + Filter? filter, + List? sort, + PaginationParams? pagination, + }) { + _checkInitialized(); + filter ??= Filter.equal('channel_cid', cid!); + return _client.queryBannedUsers( + filter: filter, + sort: sort, + pagination: pagination, + ); + } + /// Mutes the channel. Future mute({Duration? expiration}) { _checkInitialized(); diff --git a/packages/stream_chat/lib/src/client/client.dart b/packages/stream_chat/lib/src/client/client.dart index 080a1923..52d72620 100644 --- a/packages/stream_chat/lib/src/client/client.dart +++ b/packages/stream_chat/lib/src/client/client.dart @@ -687,6 +687,18 @@ class StreamChatClient { return response; } + /// Query banned users. + Future queryBannedUsers({ + required Filter filter, + List? sort, + PaginationParams? pagination, + }) => + _chatApi.moderation.queryBannedUsers( + filter: filter, + sort: sort, + pagination: pagination, + ); + /// A message search. Future search( Filter filter, { diff --git a/packages/stream_chat/lib/src/core/api/moderation_api.dart b/packages/stream_chat/lib/src/core/api/moderation_api.dart index 533fbf63..30633458 100644 --- a/packages/stream_chat/lib/src/core/api/moderation_api.dart +++ b/packages/stream_chat/lib/src/core/api/moderation_api.dart @@ -1,5 +1,7 @@ -import 'package:stream_chat/src/core/api/responses.dart'; +import 'dart:convert'; + import 'package:stream_chat/src/core/http/stream_http_client.dart'; +import 'package:stream_chat/stream_chat.dart'; /// Defines the api dedicated to moderation operations class ModerationApi { @@ -125,4 +127,24 @@ class ModerationApi { ); return EmptyResponse.fromJson(response.data); } + + /// Queries banned users. + Future queryBannedUsers({ + Filter? filter, + List? sort, + PaginationParams? pagination, + }) async { + final response = await _client.get( + '/query_banned_users', + queryParameters: { + 'payload': jsonEncode({ + if (sort != null) 'sort': sort, + if (filter != null) 'filter_conditions': filter, + if (pagination != null) ...pagination.toJson(), + }), + }, + ); + + return QueryBannedUsersResponse.fromJson(response.data); + } } diff --git a/packages/stream_chat/lib/src/core/api/responses.dart b/packages/stream_chat/lib/src/core/api/responses.dart index 937e0150..d608c5aa 100644 --- a/packages/stream_chat/lib/src/core/api/responses.dart +++ b/packages/stream_chat/lib/src/core/api/responses.dart @@ -1,6 +1,7 @@ import 'package:json_annotation/json_annotation.dart'; import 'package:stream_chat/src/client/client.dart'; import 'package:stream_chat/src/core/error/error.dart'; +import 'package:stream_chat/src/core/models/banned_user.dart'; import 'package:stream_chat/src/core/models/channel_model.dart'; import 'package:stream_chat/src/core/models/channel_state.dart'; import 'package:stream_chat/src/core/models/device.dart'; @@ -106,6 +107,18 @@ class QueryUsersResponse extends _BaseResponse { _$QueryUsersResponseFromJson(json); } +/// Model response for [StreamChatClient.queryBannedUsers] api call +@JsonSerializable(createToJson: false) +class QueryBannedUsersResponse extends _BaseResponse { + /// List of users returned by the query + @JsonKey(defaultValue: []) + late List bans; + + /// Create a new instance from a json + static QueryBannedUsersResponse fromJson(Map json) => + _$QueryBannedUsersResponseFromJson(json); +} + /// Model response for [channel.getReactions] api call @JsonSerializable(createToJson: false) class QueryReactionsResponse extends _BaseResponse { diff --git a/packages/stream_chat/lib/src/core/api/responses.g.dart b/packages/stream_chat/lib/src/core/api/responses.g.dart index fbcdd252..991b39f6 100644 --- a/packages/stream_chat/lib/src/core/api/responses.g.dart +++ b/packages/stream_chat/lib/src/core/api/responses.g.dart @@ -62,6 +62,15 @@ QueryUsersResponse _$QueryUsersResponseFromJson(Map json) => .toList() ?? []; +QueryBannedUsersResponse _$QueryBannedUsersResponseFromJson( + Map json) => + QueryBannedUsersResponse() + ..duration = json['duration'] as String? + ..bans = (json['bans'] as List?) + ?.map((e) => BannedUser.fromJson(e as Map)) + .toList() ?? + []; + QueryReactionsResponse _$QueryReactionsResponseFromJson( Map json) => QueryReactionsResponse() diff --git a/packages/stream_chat/lib/src/core/models/banned_user.dart b/packages/stream_chat/lib/src/core/models/banned_user.dart new file mode 100644 index 00000000..d5576615 --- /dev/null +++ b/packages/stream_chat/lib/src/core/models/banned_user.dart @@ -0,0 +1,80 @@ +import 'package:equatable/equatable.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:stream_chat/src/core/models/channel_model.dart'; +import 'package:stream_chat/src/core/models/user.dart'; + +part 'banned_user.g.dart'; + +/// Contains information about a [User] that was banned from a [Channel] or App. +@JsonSerializable() +class BannedUser extends Equatable { + /// Creates a new instance of [BannedUser] + const BannedUser({ + required this.user, + this.bannedBy, + this.channel, + this.createdAt, + this.expires, + this.shadow = false, + this.reason, + }); + + /// Create a new instance from a json + factory BannedUser.fromJson(Map json) => + _$BannedUserFromJson(json); + + /// Banned user. + final User user; + + /// User that banned the [user]. + final User? bannedBy; + + /// Channel where the [user] was banned. + final ChannelModel? channel; + + /// Timestamp when the [user] was banned. + final DateTime? createdAt; + + /// Timestamp when the [user] will be unbanned. + final DateTime? expires; + + /// Whether the [user] is a shadow banned user. + final bool shadow; + + /// Reason for the ban. + final String? reason; + + /// Serialize to json + Map toJson() => _$BannedUserToJson(this); + + /// Returns a copy of this object with the given fields updated. + BannedUser copyWith({ + User? user, + User? bannedBy, + ChannelModel? channel, + DateTime? createdAt, + DateTime? expires, + bool? shadow, + String? reason, + }) => + BannedUser( + user: user ?? this.user, + bannedBy: bannedBy ?? this.bannedBy, + channel: channel ?? this.channel, + createdAt: createdAt ?? this.createdAt, + expires: expires ?? this.expires, + shadow: shadow ?? this.shadow, + reason: reason ?? this.reason, + ); + + @override + List get props => [ + user, + bannedBy, + channel, + createdAt, + expires, + shadow, + reason, + ]; +} diff --git a/packages/stream_chat/lib/src/core/models/banned_user.g.dart b/packages/stream_chat/lib/src/core/models/banned_user.g.dart new file mode 100644 index 00000000..1f2a335b --- /dev/null +++ b/packages/stream_chat/lib/src/core/models/banned_user.g.dart @@ -0,0 +1,36 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'banned_user.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +BannedUser _$BannedUserFromJson(Map json) => BannedUser( + user: User.fromJson(json['user'] as Map), + bannedBy: json['banned_by'] == null + ? null + : User.fromJson(json['banned_by'] as Map), + channel: json['channel'] == null + ? null + : ChannelModel.fromJson(json['channel'] as Map), + createdAt: json['created_at'] == null + ? null + : DateTime.parse(json['created_at'] as String), + expires: json['expires'] == null + ? null + : DateTime.parse(json['expires'] as String), + shadow: json['shadow'] as bool? ?? false, + reason: json['reason'] as String?, + ); + +Map _$BannedUserToJson(BannedUser instance) => + { + 'user': instance.user.toJson(), + 'banned_by': instance.bannedBy?.toJson(), + 'channel': instance.channel?.toJson(), + 'created_at': instance.createdAt?.toIso8601String(), + 'expires': instance.expires?.toIso8601String(), + 'shadow': instance.shadow, + 'reason': instance.reason, + };