Merge remote-tracking branch 'origin/develop' into v4

# Conflicts:
#	packages/stream_chat/CHANGELOG.md
#	packages/stream_chat/lib/src/client/channel.dart
#	packages/stream_chat_flutter/CHANGELOG.md
This commit is contained in:
xsahil03x
2022-04-01 17:31:41 +05:30
19 changed files with 268 additions and 98 deletions
@@ -1620,9 +1620,7 @@ class ChannelClientState {
_subscriptions.add(_channel.on(EventType.channelUpdated).listen((Event e) {
final channel = e.channel!;
updateChannelState(channelState.copyWith(
channel: channel.copyWith(
ownCapabilities: channelState.channel?.ownCapabilities,
),
channel: channelState.channel?.merge(channel),
members: channel.members,
));
}));
@@ -1636,6 +1634,9 @@ class ChannelClientState {
await _channel._client.chatPersistenceClient
?.deleteMessageByCid(channel.cid);
truncate();
if (event.message != null) {
updateMessage(event.message!);
}
}));
}
@@ -2151,12 +2152,12 @@ class ChannelClientState {
final BehaviorSubject<Map<String, List<Message>>> _threadsController =
BehaviorSubject.seeded({});
set _threads(Map<String, List<Message>> v) {
_channel.client.chatPersistenceClient?.updateMessages(
set _threads(Map<String, List<Message>> threads) {
_threadsController.add(threads);
_channel.client.chatPersistenceClient?.updateChannelThreads(
_channel.cid!,
v.values.expand((v) => v).toList(),
threads,
);
_threadsController.add(v);
}
/// Channel related typing users last value.
@@ -181,7 +181,7 @@ class ChannelModel {
updatedAt: other.updatedAt,
deletedAt: other.deletedAt,
memberCount: other.memberCount,
extraData: other.extraData,
extraData: {...extraData, ...other.extraData},
team: other.team,
cooldown: other.cooldown,
);
@@ -0,0 +1,37 @@
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 'channel_mute.g.dart';
/// The class that contains the information about a muted channel
@JsonSerializable(createToJson: false)
class ChannelMute {
/// Constructor used for json serialization
ChannelMute({
required this.user,
required this.channel,
required this.createdAt,
required this.updatedAt,
this.expires,
});
/// Create a new instance from a json
factory ChannelMute.fromJson(Map<String, dynamic> json) =>
_$ChannelMuteFromJson(json);
/// The user that performed the muting action
final User user;
/// The target channel
final ChannelModel channel;
/// The date in which the channel was muted
final DateTime createdAt;
/// The date of the last update
final DateTime updatedAt;
/// The date in which the mute expires
final DateTime? expires;
}
@@ -0,0 +1,17 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'channel_mute.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
ChannelMute _$ChannelMuteFromJson(Map<String, dynamic> json) => ChannelMute(
user: User.fromJson(json['user'] as Map<String, dynamic>),
channel: ChannelModel.fromJson(json['channel'] as Map<String, dynamic>),
createdAt: DateTime.parse(json['created_at'] as String),
updatedAt: DateTime.parse(json['updated_at'] as String),
expires: json['expires'] == null
? null
: DateTime.parse(json['expires'] as String),
);
@@ -1,7 +1,5 @@
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';
import 'package:stream_chat/src/core/util/serializer.dart';
part 'mute.g.dart';
@@ -11,27 +9,27 @@ class Mute {
/// Constructor used for json serialization
Mute({
required this.user,
required this.channel,
required this.target,
required this.createdAt,
required this.updatedAt,
this.expires,
});
/// Create a new instance from a json
factory Mute.fromJson(Map<String, dynamic> json) => _$MuteFromJson(json);
/// The user that performed the muting action
@JsonKey(includeIfNull: false, toJson: Serializer.readOnly)
final User user;
/// The target user
@JsonKey(includeIfNull: false, toJson: Serializer.readOnly)
final ChannelModel channel;
final User target;
/// The date in which the use was muted
@JsonKey(includeIfNull: false, toJson: Serializer.readOnly)
final DateTime createdAt;
/// The date of the last update
@JsonKey(includeIfNull: false, toJson: Serializer.readOnly)
final DateTime updatedAt;
/// The date in which the mute expires
final DateTime? expires;
}
@@ -8,7 +8,10 @@ part of 'mute.dart';
Mute _$MuteFromJson(Map<String, dynamic> json) => Mute(
user: User.fromJson(json['user'] as Map<String, dynamic>),
channel: ChannelModel.fromJson(json['channel'] as Map<String, dynamic>),
target: User.fromJson(json['target'] as Map<String, dynamic>),
createdAt: DateTime.parse(json['created_at'] as String),
updatedAt: DateTime.parse(json['updated_at'] as String),
expires: json['expires'] == null
? null
: DateTime.parse(json['expires'] as String),
);
@@ -1,4 +1,5 @@
import 'package:json_annotation/json_annotation.dart';
import 'package:stream_chat/src/core/models/channel_mute.dart';
import 'package:stream_chat/src/core/util/serializer.dart';
import 'package:stream_chat/stream_chat.dart';
@@ -79,7 +80,7 @@ class OwnUser extends User {
bool? banned,
DateTime? banExpires,
List<String>? teams,
List<Mute>? channelMutes,
List<ChannelMute>? channelMutes,
List<Device>? devices,
List<Mute>? mutes,
int? totalUnreadCount,
@@ -142,7 +143,7 @@ class OwnUser extends User {
/// List of channels muted by the user.
@JsonKey(includeIfNull: false)
final List<Mute> channelMutes;
final List<ChannelMute> channelMutes;
/// Total unread messages by the user.
@JsonKey(includeIfNull: false)
@@ -18,7 +18,7 @@ OwnUser _$OwnUserFromJson(Map<String, dynamic> json) => OwnUser(
totalUnreadCount: json['total_unread_count'] as int? ?? 0,
unreadChannels: json['unread_channels'] as int? ?? 0,
channelMutes: (json['channel_mutes'] as List<dynamic>?)
?.map((e) => Mute.fromJson(e as Map<String, dynamic>))
?.map((e) => ChannelMute.fromJson(e as Map<String, dynamic>))
.toList() ??
const [],
id: json['id'] as String,
@@ -197,6 +197,28 @@ abstract class ChatPersistenceClient {
/// Deletes all the members by channel [cids]
Future<void> deleteMembersByCids(List<String> cids);
/// Updates the channel [cid] threads data along with reactions and users.
Future<void> updateChannelThreads(
String cid,
Map<String, List<Message>> threads,
) async {
final messages = threads.values.expand((it) => it).toList();
// Removing old reactions before saving the new
final oldReactions = messages.map((it) => it.id).toList();
await deleteReactionsByMessageId(oldReactions);
// Adding new reactions and users data
final reactions = messages.expand(_expandReactions).toList();
final users = messages.map((it) => it.user).withNullifyer.toList();
await Future.wait([
updateMessages(cid, messages),
updateReactions(reactions),
updateUsers(users),
]);
}
/// Update the channel state data using [channelState]
Future<void> updateChannelState(ChannelState channelState) =>
updateChannelStates([channelState]);
@@ -239,17 +261,8 @@ abstract class ChatPersistenceClient {
channelWithMessages[cid] = messages;
channelWithPinnedMessages[cid] = pinnedMessages;
List<Reaction> expandReactions(Message message) {
final own = message.ownReactions;
final latest = message.latestReactions;
return [
if (own != null) ...own.where((r) => r.userId != null),
if (latest != null) ...latest.where((r) => r.userId != null),
];
}
reactions.addAll(messages.expand(expandReactions));
pinnedReactions.addAll(pinnedMessages.expand(expandReactions));
reactions.addAll(messages.expand(_expandReactions));
pinnedReactions.addAll(pinnedMessages.expand(_expandReactions));
users.addAll([
channel.createdBy,
@@ -292,4 +305,13 @@ abstract class ChatPersistenceClient {
),
]);
}
List<Reaction> _expandReactions(Message message) {
final own = message.ownReactions;
final latest = message.latestReactions;
return [
if (own != null) ...own.where((r) => r.userId != null),
if (latest != null) ...latest.where((r) => r.userId != null),
];
}
}