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:
@@ -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),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user