Migrated llc Lists to be nullable instead of being an empty array
This commit is contained in:
@@ -1259,7 +1259,9 @@ class Channel {
|
|||||||
if (preferOffline && cid != null) {
|
if (preferOffline && cid != null) {
|
||||||
final updatedState = await _client.chatPersistenceClient
|
final updatedState = await _client.chatPersistenceClient
|
||||||
?.getChannelStateByCid(cid!, messagePagination: messagesPagination);
|
?.getChannelStateByCid(cid!, messagePagination: messagesPagination);
|
||||||
if (updatedState != null && updatedState.messages.isNotEmpty) {
|
if (updatedState != null &&
|
||||||
|
updatedState.messages != null &&
|
||||||
|
updatedState.messages!.isNotEmpty) {
|
||||||
if (this.state == null) {
|
if (this.state == null) {
|
||||||
_initState(updatedState);
|
_initState(updatedState);
|
||||||
} else {
|
} else {
|
||||||
@@ -1570,7 +1572,7 @@ class ChannelClientState {
|
|||||||
|
|
||||||
void _checkExpiredAttachmentMessages(ChannelState channelState) async {
|
void _checkExpiredAttachmentMessages(ChannelState channelState) async {
|
||||||
final expiredAttachmentMessagesId = channelState.messages
|
final expiredAttachmentMessagesId = channelState.messages
|
||||||
.where((m) =>
|
?.where((m) =>
|
||||||
!_updatedMessagesIds.contains(m.id) &&
|
!_updatedMessagesIds.contains(m.id) &&
|
||||||
m.attachments.isNotEmpty &&
|
m.attachments.isNotEmpty &&
|
||||||
m.attachments.any((e) {
|
m.attachments.any((e) {
|
||||||
@@ -1597,7 +1599,8 @@ class ChannelClientState {
|
|||||||
.map((e) => e.id)
|
.map((e) => e.id)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
if (expiredAttachmentMessagesId.isNotEmpty) {
|
if (expiredAttachmentMessagesId != null &&
|
||||||
|
expiredAttachmentMessagesId.isNotEmpty) {
|
||||||
await _channel._initializedCompleter.future;
|
await _channel._initializedCompleter.future;
|
||||||
_updatedMessagesIds.addAll(expiredAttachmentMessagesId);
|
_updatedMessagesIds.addAll(expiredAttachmentMessagesId);
|
||||||
_channel.getMessagesById(expiredAttachmentMessagesId);
|
_channel.getMessagesById(expiredAttachmentMessagesId);
|
||||||
@@ -1607,9 +1610,10 @@ class ChannelClientState {
|
|||||||
void _listenMemberAdded() {
|
void _listenMemberAdded() {
|
||||||
_subscriptions.add(_channel.on(EventType.memberAdded).listen((Event e) {
|
_subscriptions.add(_channel.on(EventType.memberAdded).listen((Event e) {
|
||||||
final member = e.member;
|
final member = e.member;
|
||||||
|
final existingMembers = channelState.members ?? [];
|
||||||
updateChannelState(channelState.copyWith(
|
updateChannelState(channelState.copyWith(
|
||||||
members: [
|
members: [
|
||||||
...channelState.members,
|
...existingMembers,
|
||||||
member!,
|
member!,
|
||||||
],
|
],
|
||||||
));
|
));
|
||||||
@@ -1619,11 +1623,13 @@ class ChannelClientState {
|
|||||||
void _listenMemberRemoved() {
|
void _listenMemberRemoved() {
|
||||||
_subscriptions.add(_channel.on(EventType.memberRemoved).listen((Event e) {
|
_subscriptions.add(_channel.on(EventType.memberRemoved).listen((Event e) {
|
||||||
final user = e.user;
|
final user = e.user;
|
||||||
|
final existingMembers = channelState.members ?? [];
|
||||||
|
final existingRead = channelState.read ?? [];
|
||||||
updateChannelState(channelState.copyWith(
|
updateChannelState(channelState.copyWith(
|
||||||
members: channelState.members
|
members: existingMembers
|
||||||
.where((m) => m.userId != user!.id)
|
.where((m) => m.userId != user!.id)
|
||||||
.toList(growable: false),
|
.toList(growable: false),
|
||||||
read: channelState.read
|
read: existingRead
|
||||||
.where((r) => r.user.id != user!.id)
|
.where((r) => r.user.id != user!.id)
|
||||||
.toList(growable: false),
|
.toList(growable: false),
|
||||||
));
|
));
|
||||||
@@ -1793,9 +1799,10 @@ class ChannelClientState {
|
|||||||
updateMessage(message);
|
updateMessage(message);
|
||||||
|
|
||||||
if (message.pinned) {
|
if (message.pinned) {
|
||||||
|
final _existingPinnedMessages = _channelState.pinnedMessages ?? [];
|
||||||
_channelState = _channelState.copyWith(
|
_channelState = _channelState.copyWith(
|
||||||
pinnedMessages: [
|
pinnedMessages: [
|
||||||
..._channelState.pinnedMessages,
|
..._existingPinnedMessages,
|
||||||
message,
|
message,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@@ -1931,7 +1938,7 @@ class ChannelClientState {
|
|||||||
)
|
)
|
||||||
.listen(
|
.listen(
|
||||||
(event) {
|
(event) {
|
||||||
final readList = List<Read>.from(_channelState.read);
|
final readList = List<Read>.from(_channelState.read ?? []);
|
||||||
final userReadIndex =
|
final userReadIndex =
|
||||||
read.indexWhere((r) => r.user.id == event.user!.id);
|
read.indexWhere((r) => r.user.id == event.user!.id);
|
||||||
|
|
||||||
@@ -1952,31 +1959,34 @@ class ChannelClientState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Channel message list.
|
/// Channel message list.
|
||||||
List<Message> get messages => _channelState.messages;
|
List<Message> get messages => _channelState.messages ?? <Message>[];
|
||||||
|
|
||||||
/// Channel message list as a stream.
|
/// Channel message list as a stream.
|
||||||
Stream<List<Message>> get messagesStream => channelStateStream
|
Stream<List<Message>> get messagesStream => channelStateStream
|
||||||
.map((cs) => cs.messages)
|
.map((cs) => cs.messages ?? <Message>[])
|
||||||
.distinct(const ListEquality().equals);
|
.distinct(const ListEquality().equals);
|
||||||
|
|
||||||
/// Channel pinned message list.
|
/// Channel pinned message list.
|
||||||
List<Message> get pinnedMessages => _channelState.pinnedMessages;
|
List<Message> get pinnedMessages =>
|
||||||
|
_channelState.pinnedMessages ?? <Message>[];
|
||||||
|
|
||||||
/// Channel pinned message list as a stream.
|
/// Channel pinned message list as a stream.
|
||||||
Stream<List<Message>> get pinnedMessagesStream => channelStateStream
|
Stream<List<Message>> get pinnedMessagesStream => channelStateStream
|
||||||
.map((cs) => cs.pinnedMessages)
|
.map((cs) => cs.pinnedMessages ?? <Message>[])
|
||||||
.distinct(const ListEquality().equals);
|
.distinct(const ListEquality().equals);
|
||||||
|
|
||||||
/// Get channel last message.
|
/// Get channel last message.
|
||||||
Message? get lastMessage =>
|
Message? get lastMessage =>
|
||||||
_channelState.messages.isNotEmpty ? _channelState.messages.last : null;
|
_channelState.messages != null && _channelState.messages!.isNotEmpty
|
||||||
|
? _channelState.messages!.last
|
||||||
|
: null;
|
||||||
|
|
||||||
/// Get channel last message.
|
/// Get channel last message.
|
||||||
Stream<Message?> get lastMessageStream =>
|
Stream<Message?> get lastMessageStream =>
|
||||||
messagesStream.map((event) => event.isNotEmpty ? event.last : null);
|
messagesStream.map((event) => event.isNotEmpty ? event.last : null);
|
||||||
|
|
||||||
/// Channel members list.
|
/// Channel members list.
|
||||||
List<Member> get members => _channelState.members
|
List<Member> get members => (_channelState.members ?? <Member>[])
|
||||||
.map((e) => e.copyWith(user: _channel.client.state.users[e.user!.id]))
|
.map((e) => e.copyWith(user: _channel.client.state.users[e.user!.id]))
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
@@ -1997,7 +2007,7 @@ class ChannelClientState {
|
|||||||
channelStateStream.map((cs) => cs.watcherCount);
|
channelStateStream.map((cs) => cs.watcherCount);
|
||||||
|
|
||||||
/// Channel watchers list.
|
/// Channel watchers list.
|
||||||
List<User> get watchers => _channelState.watchers
|
List<User> get watchers => (_channelState.watchers ?? <User>[])
|
||||||
.map((e) => _channel.client.state.users[e.id] ?? e)
|
.map((e) => _channel.client.state.users[e.id] ?? e)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
@@ -2018,10 +2028,11 @@ class ChannelClientState {
|
|||||||
String? get currentUserRole => currentUserMember?.role;
|
String? get currentUserRole => currentUserMember?.role;
|
||||||
|
|
||||||
/// Channel read list.
|
/// Channel read list.
|
||||||
List<Read> get read => _channelState.read;
|
List<Read> get read => _channelState.read ?? <Read>[];
|
||||||
|
|
||||||
/// Channel read list as a stream.
|
/// Channel read list as a stream.
|
||||||
Stream<List<Read>> get readStream => channelStateStream.map((cs) => cs.read);
|
Stream<List<Read>> get readStream =>
|
||||||
|
channelStateStream.map((cs) => cs.read ?? <Read>[]);
|
||||||
|
|
||||||
bool _isCurrentUserRead(Read read) =>
|
bool _isCurrentUserRead(Read read) =>
|
||||||
read.user.id == _channel._client.state.currentUser!.id;
|
read.user.id == _channel._client.state.currentUser!.id;
|
||||||
@@ -2042,7 +2053,7 @@ class ChannelClientState {
|
|||||||
|
|
||||||
/// Setter for unread count.
|
/// Setter for unread count.
|
||||||
set unreadCount(int count) {
|
set unreadCount(int count) {
|
||||||
final reads = [..._channelState.read];
|
final reads = [...read];
|
||||||
final currentUserReadIndex = reads.indexWhere(_isCurrentUserRead);
|
final currentUserReadIndex = reads.indexWhere(_isCurrentUserRead);
|
||||||
|
|
||||||
if (currentUserReadIndex < 0) return;
|
if (currentUserReadIndex < 0) return;
|
||||||
@@ -2097,31 +2108,37 @@ class ChannelClientState {
|
|||||||
|
|
||||||
/// Update channelState with updated information.
|
/// Update channelState with updated information.
|
||||||
void updateChannelState(ChannelState updatedState) {
|
void updateChannelState(ChannelState updatedState) {
|
||||||
|
final _existingStateMessages = _channelState.messages ?? [];
|
||||||
|
final _updatedStateMessages = updatedState.messages ?? [];
|
||||||
final newMessages = <Message>[
|
final newMessages = <Message>[
|
||||||
...updatedState.messages,
|
..._updatedStateMessages,
|
||||||
..._channelState.messages
|
..._existingStateMessages
|
||||||
.where((m) =>
|
.where((m) =>
|
||||||
!updatedState.messages.any((newMessage) => newMessage.id == m.id))
|
!_updatedStateMessages.any((newMessage) => newMessage.id == m.id))
|
||||||
.toList(),
|
.toList(),
|
||||||
]..sort(_sortByCreatedAt);
|
]..sort(_sortByCreatedAt);
|
||||||
|
|
||||||
|
final _existingStateWatchers = _channelState.watchers ?? [];
|
||||||
|
final _updatedStateWatchers = updatedState.watchers ?? [];
|
||||||
final newWatchers = <User>[
|
final newWatchers = <User>[
|
||||||
...updatedState.watchers,
|
..._updatedStateWatchers,
|
||||||
..._channelState.watchers
|
..._existingStateWatchers
|
||||||
.where((w) =>
|
.where((w) =>
|
||||||
!updatedState.watchers.any((newWatcher) => newWatcher.id == w.id))
|
!_updatedStateWatchers.any((newWatcher) => newWatcher.id == w.id))
|
||||||
.toList(),
|
.toList(),
|
||||||
];
|
];
|
||||||
|
|
||||||
final newMembers = <Member>[
|
final newMembers = <Member>[
|
||||||
...updatedState.members,
|
...updatedState.members ?? [],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
final _existingStateRead = _channelState.read ?? [];
|
||||||
|
final _updatedStateRead = updatedState.read ?? [];
|
||||||
final newReads = <Read>[
|
final newReads = <Read>[
|
||||||
...updatedState.read,
|
..._updatedStateRead,
|
||||||
..._channelState.read
|
..._existingStateRead
|
||||||
.where((r) =>
|
.where((r) =>
|
||||||
!updatedState.read.any((newRead) => newRead.user.id == r.user.id))
|
!_updatedStateRead.any((newRead) => newRead.user.id == r.user.id))
|
||||||
.toList(),
|
.toList(),
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -2273,9 +2290,9 @@ class ChannelClientState {
|
|||||||
_pinnedMessagesTimer = Timer.periodic(const Duration(seconds: 30), (_) {
|
_pinnedMessagesTimer = Timer.periodic(const Duration(seconds: 30), (_) {
|
||||||
final now = DateTime.now();
|
final now = DateTime.now();
|
||||||
var expiredMessages = channelState.pinnedMessages
|
var expiredMessages = channelState.pinnedMessages
|
||||||
.where((m) => m.pinExpires?.isBefore(now) == true)
|
?.where((m) => m.pinExpires?.isBefore(now) == true)
|
||||||
.toList();
|
.toList();
|
||||||
if (expiredMessages.isNotEmpty) {
|
if (expiredMessages != null && expiredMessages.isNotEmpty) {
|
||||||
expiredMessages = expiredMessages
|
expiredMessages = expiredMessages
|
||||||
.map((m) => m.copyWith(
|
.map((m) => m.copyWith(
|
||||||
pinExpires: null,
|
pinExpires: null,
|
||||||
|
|||||||
@@ -623,7 +623,7 @@ class StreamChatClient {
|
|||||||
final channels = res.channels;
|
final channels = res.channels;
|
||||||
|
|
||||||
final users = channels
|
final users = channels
|
||||||
.expand((it) => it.members)
|
.expand((it) => it.members ?? <Member>[])
|
||||||
.map((it) => it.user)
|
.map((it) => it.user)
|
||||||
.toList(growable: false);
|
.toList(growable: false);
|
||||||
|
|
||||||
|
|||||||
@@ -124,8 +124,7 @@ class Attachment extends Equatable {
|
|||||||
final String? assetUrl;
|
final String? assetUrl;
|
||||||
|
|
||||||
/// Actions from a command
|
/// Actions from a command
|
||||||
@JsonKey(defaultValue: [])
|
final List<Action>? actions;
|
||||||
final List<Action> actions;
|
|
||||||
|
|
||||||
final Uri? localUri;
|
final Uri? localUri;
|
||||||
|
|
||||||
|
|||||||
@@ -26,9 +26,8 @@ Attachment _$AttachmentFromJson(Map<String, dynamic> json) => Attachment(
|
|||||||
authorIcon: json['author_icon'] as String?,
|
authorIcon: json['author_icon'] as String?,
|
||||||
assetUrl: json['asset_url'] as String?,
|
assetUrl: json['asset_url'] as String?,
|
||||||
actions: (json['actions'] as List<dynamic>?)
|
actions: (json['actions'] as List<dynamic>?)
|
||||||
?.map((e) => Action.fromJson(e as Map<String, dynamic>))
|
?.map((e) => Action.fromJson(e as Map<String, dynamic>))
|
||||||
.toList() ??
|
.toList(),
|
||||||
[],
|
|
||||||
extraData: json['extra_data'] as Map<String, dynamic>? ?? const {},
|
extraData: json['extra_data'] as Map<String, dynamic>? ?? const {},
|
||||||
file: json['file'] == null
|
file: json['file'] == null
|
||||||
? null
|
? null
|
||||||
@@ -64,7 +63,7 @@ Map<String, dynamic> _$AttachmentToJson(Attachment instance) {
|
|||||||
writeNotNull('author_link', instance.authorLink);
|
writeNotNull('author_link', instance.authorLink);
|
||||||
writeNotNull('author_icon', instance.authorIcon);
|
writeNotNull('author_icon', instance.authorIcon);
|
||||||
writeNotNull('asset_url', instance.assetUrl);
|
writeNotNull('asset_url', instance.assetUrl);
|
||||||
val['actions'] = instance.actions.map((e) => e.toJson()).toList();
|
writeNotNull('actions', instance.actions?.map((e) => e.toJson()).toList());
|
||||||
writeNotNull('file', instance.file?.toJson());
|
writeNotNull('file', instance.file?.toJson());
|
||||||
val['upload_state'] = instance.uploadState.toJson();
|
val['upload_state'] = instance.uploadState.toJson();
|
||||||
val['extra_data'] = instance.extraData;
|
val['extra_data'] = instance.extraData;
|
||||||
|
|||||||
@@ -7,42 +7,40 @@ import 'package:stream_chat/src/core/models/user.dart';
|
|||||||
|
|
||||||
part 'channel_state.g.dart';
|
part 'channel_state.g.dart';
|
||||||
|
|
||||||
const _emptyPinnedMessages = <Message>[];
|
|
||||||
|
|
||||||
/// The class that contains the information about a channel
|
/// The class that contains the information about a channel
|
||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
class ChannelState {
|
class ChannelState {
|
||||||
/// Constructor used for json serialization
|
/// Constructor used for json serialization
|
||||||
ChannelState({
|
ChannelState({
|
||||||
this.channel,
|
this.channel,
|
||||||
this.messages = const [],
|
this.messages,
|
||||||
this.members = const [],
|
this.members,
|
||||||
this.pinnedMessages = _emptyPinnedMessages,
|
this.pinnedMessages,
|
||||||
this.watcherCount,
|
this.watcherCount,
|
||||||
this.watchers = const [],
|
this.watchers,
|
||||||
this.read = const [],
|
this.read,
|
||||||
});
|
});
|
||||||
|
|
||||||
/// The channel to which this state belongs
|
/// The channel to which this state belongs
|
||||||
final ChannelModel? channel;
|
final ChannelModel? channel;
|
||||||
|
|
||||||
/// A paginated list of channel messages
|
/// A paginated list of channel messages
|
||||||
final List<Message> messages;
|
final List<Message>? messages;
|
||||||
|
|
||||||
/// A paginated list of channel members
|
/// A paginated list of channel members
|
||||||
final List<Member> members;
|
final List<Member>? members;
|
||||||
|
|
||||||
/// A paginated list of pinned messages
|
/// A paginated list of pinned messages
|
||||||
final List<Message> pinnedMessages;
|
final List<Message>? pinnedMessages;
|
||||||
|
|
||||||
/// The count of users watching the channel
|
/// The count of users watching the channel
|
||||||
final int? watcherCount;
|
final int? watcherCount;
|
||||||
|
|
||||||
/// A paginated list of users watching the channel
|
/// A paginated list of users watching the channel
|
||||||
final List<User> watchers;
|
final List<User>? watchers;
|
||||||
|
|
||||||
/// The list of channel reads
|
/// The list of channel reads
|
||||||
final List<Read> read;
|
final List<Read>? read;
|
||||||
|
|
||||||
/// Create a new instance from a json
|
/// Create a new instance from a json
|
||||||
static ChannelState fromJson(Map<String, dynamic> json) =>
|
static ChannelState fromJson(Map<String, dynamic> json) =>
|
||||||
@@ -56,7 +54,7 @@ class ChannelState {
|
|||||||
ChannelModel? channel,
|
ChannelModel? channel,
|
||||||
List<Message>? messages,
|
List<Message>? messages,
|
||||||
List<Member>? members,
|
List<Member>? members,
|
||||||
List<Message> pinnedMessages = _emptyPinnedMessages,
|
List<Message>? pinnedMessages,
|
||||||
int? watcherCount,
|
int? watcherCount,
|
||||||
List<User>? watchers,
|
List<User>? watchers,
|
||||||
List<Read>? read,
|
List<Read>? read,
|
||||||
@@ -65,11 +63,7 @@ class ChannelState {
|
|||||||
channel: channel ?? this.channel,
|
channel: channel ?? this.channel,
|
||||||
messages: messages ?? this.messages,
|
messages: messages ?? this.messages,
|
||||||
members: members ?? this.members,
|
members: members ?? this.members,
|
||||||
// Hack to avoid using the default value in case nothing is provided.
|
pinnedMessages: pinnedMessages ?? this.pinnedMessages,
|
||||||
// FIXME: Use non-nullable by default instead of empty list.
|
|
||||||
pinnedMessages: pinnedMessages == _emptyPinnedMessages
|
|
||||||
? this.pinnedMessages
|
|
||||||
: pinnedMessages,
|
|
||||||
watcherCount: watcherCount ?? this.watcherCount,
|
watcherCount: watcherCount ?? this.watcherCount,
|
||||||
watchers: watchers ?? this.watchers,
|
watchers: watchers ?? this.watchers,
|
||||||
read: read ?? this.read,
|
read: read ?? this.read,
|
||||||
|
|||||||
@@ -11,36 +11,31 @@ ChannelState _$ChannelStateFromJson(Map<String, dynamic> json) => ChannelState(
|
|||||||
? null
|
? null
|
||||||
: ChannelModel.fromJson(json['channel'] as Map<String, dynamic>),
|
: ChannelModel.fromJson(json['channel'] as Map<String, dynamic>),
|
||||||
messages: (json['messages'] as List<dynamic>?)
|
messages: (json['messages'] as List<dynamic>?)
|
||||||
?.map((e) => Message.fromJson(e as Map<String, dynamic>))
|
?.map((e) => Message.fromJson(e as Map<String, dynamic>))
|
||||||
.toList() ??
|
.toList(),
|
||||||
const [],
|
|
||||||
members: (json['members'] as List<dynamic>?)
|
members: (json['members'] as List<dynamic>?)
|
||||||
?.map((e) => Member.fromJson(e as Map<String, dynamic>))
|
?.map((e) => Member.fromJson(e as Map<String, dynamic>))
|
||||||
.toList() ??
|
.toList(),
|
||||||
const [],
|
|
||||||
pinnedMessages: (json['pinned_messages'] as List<dynamic>?)
|
pinnedMessages: (json['pinned_messages'] as List<dynamic>?)
|
||||||
?.map((e) => Message.fromJson(e as Map<String, dynamic>))
|
?.map((e) => Message.fromJson(e as Map<String, dynamic>))
|
||||||
.toList() ??
|
.toList(),
|
||||||
_emptyPinnedMessages,
|
|
||||||
watcherCount: json['watcher_count'] as int?,
|
watcherCount: json['watcher_count'] as int?,
|
||||||
watchers: (json['watchers'] as List<dynamic>?)
|
watchers: (json['watchers'] as List<dynamic>?)
|
||||||
?.map((e) => User.fromJson(e as Map<String, dynamic>))
|
?.map((e) => User.fromJson(e as Map<String, dynamic>))
|
||||||
.toList() ??
|
.toList(),
|
||||||
const [],
|
|
||||||
read: (json['read'] as List<dynamic>?)
|
read: (json['read'] as List<dynamic>?)
|
||||||
?.map((e) => Read.fromJson(e as Map<String, dynamic>))
|
?.map((e) => Read.fromJson(e as Map<String, dynamic>))
|
||||||
.toList() ??
|
.toList(),
|
||||||
const [],
|
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$ChannelStateToJson(ChannelState instance) =>
|
Map<String, dynamic> _$ChannelStateToJson(ChannelState instance) =>
|
||||||
<String, dynamic>{
|
<String, dynamic>{
|
||||||
'channel': instance.channel?.toJson(),
|
'channel': instance.channel?.toJson(),
|
||||||
'messages': instance.messages.map((e) => e.toJson()).toList(),
|
'messages': instance.messages?.map((e) => e.toJson()).toList(),
|
||||||
'members': instance.members.map((e) => e.toJson()).toList(),
|
'members': instance.members?.map((e) => e.toJson()).toList(),
|
||||||
'pinned_messages':
|
'pinned_messages':
|
||||||
instance.pinnedMessages.map((e) => e.toJson()).toList(),
|
instance.pinnedMessages?.map((e) => e.toJson()).toList(),
|
||||||
'watcher_count': instance.watcherCount,
|
'watcher_count': instance.watcherCount,
|
||||||
'watchers': instance.watchers.map((e) => e.toJson()).toList(),
|
'watchers': instance.watchers?.map((e) => e.toJson()).toList(),
|
||||||
'read': instance.read.map((e) => e.toJson()).toList(),
|
'read': instance.read?.map((e) => e.toJson()).toList(),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -49,6 +49,9 @@ Message _$MessageFromJson(Map<String, dynamic> json) => Message(
|
|||||||
updatedAt: json['updated_at'] == null
|
updatedAt: json['updated_at'] == null
|
||||||
? null
|
? null
|
||||||
: DateTime.parse(json['updated_at'] as String),
|
: DateTime.parse(json['updated_at'] as String),
|
||||||
|
deletedAt: json['deleted_at'] == null
|
||||||
|
? null
|
||||||
|
: DateTime.parse(json['deleted_at'] as String),
|
||||||
user: json['user'] == null
|
user: json['user'] == null
|
||||||
? null
|
? null
|
||||||
: User.fromJson(json['user'] as Map<String, dynamic>),
|
: User.fromJson(json['user'] as Map<String, dynamic>),
|
||||||
@@ -63,9 +66,6 @@ Message _$MessageFromJson(Map<String, dynamic> json) => Message(
|
|||||||
? null
|
? null
|
||||||
: User.fromJson(json['pinned_by'] as Map<String, dynamic>),
|
: User.fromJson(json['pinned_by'] as Map<String, dynamic>),
|
||||||
extraData: json['extra_data'] as Map<String, dynamic>? ?? const {},
|
extraData: json['extra_data'] as Map<String, dynamic>? ?? const {},
|
||||||
deletedAt: json['deleted_at'] == null
|
|
||||||
? null
|
|
||||||
: DateTime.parse(json['deleted_at'] as String),
|
|
||||||
i18n: (json['i18n'] as Map<String, dynamic>?)?.map(
|
i18n: (json['i18n'] as Map<String, dynamic>?)?.map(
|
||||||
(k, e) => MapEntry(k, e as String),
|
(k, e) => MapEntry(k, e as String),
|
||||||
),
|
),
|
||||||
@@ -99,6 +99,7 @@ Map<String, dynamic> _$MessageToJson(Message instance) {
|
|||||||
val['silent'] = instance.silent;
|
val['silent'] = instance.silent;
|
||||||
writeNotNull('shadowed', readonly(instance.shadowed));
|
writeNotNull('shadowed', readonly(instance.shadowed));
|
||||||
writeNotNull('command', readonly(instance.command));
|
writeNotNull('command', readonly(instance.command));
|
||||||
|
writeNotNull('deleted_at', readonly(instance.deletedAt));
|
||||||
writeNotNull('created_at', readonly(instance.createdAt));
|
writeNotNull('created_at', readonly(instance.createdAt));
|
||||||
writeNotNull('updated_at', readonly(instance.updatedAt));
|
writeNotNull('updated_at', readonly(instance.updatedAt));
|
||||||
writeNotNull('user', readonly(instance.user));
|
writeNotNull('user', readonly(instance.user));
|
||||||
@@ -107,7 +108,6 @@ Map<String, dynamic> _$MessageToJson(Message instance) {
|
|||||||
val['pin_expires'] = instance.pinExpires?.toIso8601String();
|
val['pin_expires'] = instance.pinExpires?.toIso8601String();
|
||||||
val['pinned_by'] = readonly(instance.pinnedBy);
|
val['pinned_by'] = readonly(instance.pinnedBy);
|
||||||
val['extra_data'] = instance.extraData;
|
val['extra_data'] = instance.extraData;
|
||||||
writeNotNull('deleted_at', readonly(instance.deletedAt));
|
|
||||||
writeNotNull('i18n', instance.i18n);
|
writeNotNull('i18n', instance.i18n);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,10 +44,10 @@ abstract class ChatPersistenceClient {
|
|||||||
Future<ChannelModel?> getChannelByCid(String cid);
|
Future<ChannelModel?> getChannelByCid(String cid);
|
||||||
|
|
||||||
/// Get stored channel [Member]s by providing channel [cid]
|
/// Get stored channel [Member]s by providing channel [cid]
|
||||||
Future<List<Member>> getMembersByCid(String cid);
|
Future<List<Member>?> getMembersByCid(String cid);
|
||||||
|
|
||||||
/// Get stored channel [Read]s by providing channel [cid]
|
/// Get stored channel [Read]s by providing channel [cid]
|
||||||
Future<List<Read>> getReadsByCid(String cid);
|
Future<List<Read>?> getReadsByCid(String cid);
|
||||||
|
|
||||||
/// Get stored [Message]s by providing channel [cid]
|
/// Get stored [Message]s by providing channel [cid]
|
||||||
///
|
///
|
||||||
@@ -78,15 +78,11 @@ abstract class ChatPersistenceClient {
|
|||||||
getPinnedMessagesByCid(cid, messagePagination: pinnedMessagePagination),
|
getPinnedMessagesByCid(cid, messagePagination: pinnedMessagePagination),
|
||||||
]);
|
]);
|
||||||
return ChannelState(
|
return ChannelState(
|
||||||
// ignore: cast_nullable_to_non_nullable
|
members: data[0] as List<Member>?,
|
||||||
members: data[0] as List<Member>,
|
read: data[1] as List<Read>?,
|
||||||
// ignore: cast_nullable_to_non_nullable
|
|
||||||
read: data[1] as List<Read>,
|
|
||||||
channel: data[2] as ChannelModel?,
|
channel: data[2] as ChannelModel?,
|
||||||
// ignore: cast_nullable_to_non_nullable
|
messages: data[3] as List<Message>?,
|
||||||
messages: data[3] as List<Message>,
|
pinnedMessages: data[4] as List<Message>?,
|
||||||
// ignore: cast_nullable_to_non_nullable
|
|
||||||
pinnedMessages: data[4] as List<Message>,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,7 +142,7 @@ abstract class ChatPersistenceClient {
|
|||||||
bulkUpdateMessages({cid: messages});
|
bulkUpdateMessages({cid: messages});
|
||||||
|
|
||||||
/// Bulk updates the message data of multiple channels.
|
/// Bulk updates the message data of multiple channels.
|
||||||
Future<void> bulkUpdateMessages(Map<String, List<Message>> messages);
|
Future<void> bulkUpdateMessages(Map<String, List<Message>?> messages);
|
||||||
|
|
||||||
/// Updates the pinned message data of a particular channel [cid] with
|
/// Updates the pinned message data of a particular channel [cid] with
|
||||||
/// the new [messages] data
|
/// the new [messages] data
|
||||||
@@ -154,7 +150,7 @@ abstract class ChatPersistenceClient {
|
|||||||
bulkUpdatePinnedMessages({cid: messages});
|
bulkUpdatePinnedMessages({cid: messages});
|
||||||
|
|
||||||
/// Bulk updates the message data of multiple channels.
|
/// Bulk updates the message data of multiple channels.
|
||||||
Future<void> bulkUpdatePinnedMessages(Map<String, List<Message>> messages);
|
Future<void> bulkUpdatePinnedMessages(Map<String, List<Message>?> messages);
|
||||||
|
|
||||||
/// Returns all the threads by parent message of a particular channel by
|
/// Returns all the threads by parent message of a particular channel by
|
||||||
/// providing channel [cid]
|
/// providing channel [cid]
|
||||||
@@ -169,7 +165,7 @@ abstract class ChatPersistenceClient {
|
|||||||
bulkUpdateMembers({cid: members});
|
bulkUpdateMembers({cid: members});
|
||||||
|
|
||||||
/// Bulk updates the members data of multiple channels.
|
/// Bulk updates the members data of multiple channels.
|
||||||
Future<void> bulkUpdateMembers(Map<String, List<Member>> members);
|
Future<void> bulkUpdateMembers(Map<String, List<Member>?> members);
|
||||||
|
|
||||||
/// Updates the read data of a particular channel [cid] with
|
/// Updates the read data of a particular channel [cid] with
|
||||||
/// the new [reads] data
|
/// the new [reads] data
|
||||||
@@ -177,7 +173,7 @@ abstract class ChatPersistenceClient {
|
|||||||
bulkUpdateReads({cid: reads});
|
bulkUpdateReads({cid: reads});
|
||||||
|
|
||||||
/// Bulk updates the read data of multiple channels.
|
/// Bulk updates the read data of multiple channels.
|
||||||
Future<void> bulkUpdateReads(Map<String, List<Read>> reads);
|
Future<void> bulkUpdateReads(Map<String, List<Read>?> reads);
|
||||||
|
|
||||||
/// Updates the users data with the new [users] data
|
/// Updates the users data with the new [users] data
|
||||||
Future<void> updateUsers(List<User> users);
|
Future<void> updateUsers(List<User> users);
|
||||||
@@ -230,10 +226,10 @@ abstract class ChatPersistenceClient {
|
|||||||
final membersToDelete = <String>[];
|
final membersToDelete = <String>[];
|
||||||
|
|
||||||
final channels = <ChannelModel>[];
|
final channels = <ChannelModel>[];
|
||||||
final channelWithMessages = <String, List<Message>>{};
|
final channelWithMessages = <String, List<Message>?>{};
|
||||||
final channelWithPinnedMessages = <String, List<Message>>{};
|
final channelWithPinnedMessages = <String, List<Message>?>{};
|
||||||
final channelWithReads = <String, List<Read>>{};
|
final channelWithReads = <String, List<Read>?>{};
|
||||||
final channelWithMembers = <String, List<Member>>{};
|
final channelWithMembers = <String, List<Member>?>{};
|
||||||
|
|
||||||
final users = <User>[];
|
final users = <User>[];
|
||||||
final reactions = <Reaction>[];
|
final reactions = <Reaction>[];
|
||||||
@@ -252,8 +248,9 @@ abstract class ChatPersistenceClient {
|
|||||||
|
|
||||||
// Preparing deletion data
|
// Preparing deletion data
|
||||||
membersToDelete.add(cid);
|
membersToDelete.add(cid);
|
||||||
reactionsToDelete.addAll(state.messages.map((it) => it.id));
|
reactionsToDelete.addAll(state.messages?.map((it) => it.id) ?? []);
|
||||||
pinnedReactionsToDelete.addAll(state.pinnedMessages.map((it) => it.id));
|
pinnedReactionsToDelete
|
||||||
|
.addAll(state.pinnedMessages?.map((it) => it.id) ?? []);
|
||||||
|
|
||||||
// preparing addition data
|
// preparing addition data
|
||||||
channelWithReads[cid] = reads;
|
channelWithReads[cid] = reads;
|
||||||
@@ -261,14 +258,14 @@ abstract class ChatPersistenceClient {
|
|||||||
channelWithMessages[cid] = messages;
|
channelWithMessages[cid] = messages;
|
||||||
channelWithPinnedMessages[cid] = pinnedMessages;
|
channelWithPinnedMessages[cid] = pinnedMessages;
|
||||||
|
|
||||||
reactions.addAll(messages.expand(_expandReactions));
|
reactions.addAll(messages?.expand(_expandReactions) ?? []);
|
||||||
pinnedReactions.addAll(pinnedMessages.expand(_expandReactions));
|
pinnedReactions.addAll(pinnedMessages?.expand(_expandReactions) ?? []);
|
||||||
|
|
||||||
users.addAll([
|
users.addAll([
|
||||||
channel.createdBy,
|
channel.createdBy,
|
||||||
...messages.map((it) => it.user),
|
...messages?.map((it) => it.user) ?? <User>[],
|
||||||
...reads.map((it) => it.user),
|
...reads?.map((it) => it.user) ?? <User>[],
|
||||||
...members.map((it) => it.user),
|
...members?.map((it) => it.user) ?? <User>[],
|
||||||
...reactions.map((it) => it.user),
|
...reactions.map((it) => it.user),
|
||||||
...pinnedReactions.map((it) => it.user),
|
...pinnedReactions.map((it) => it.user),
|
||||||
].withNullifyer);
|
].withNullifyer);
|
||||||
|
|||||||
@@ -105,11 +105,11 @@ void main() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
expect(res, isNotNull);
|
expect(res, isNotNull);
|
||||||
expect(res.messages.length, channelState.messages.length);
|
expect(res.messages?.length, channelState.messages?.length);
|
||||||
expect(res.pinnedMessages.length, channelState.pinnedMessages.length);
|
expect(res.pinnedMessages?.length, channelState.pinnedMessages?.length);
|
||||||
expect(res.members.length, channelState.members.length);
|
expect(res.members?.length, channelState.members?.length);
|
||||||
expect(res.read.length, channelState.read.length);
|
expect(res.read?.length, channelState.read?.length);
|
||||||
expect(res.watchers.length, channelState.watchers.length);
|
expect(res.watchers?.length, channelState.watchers?.length);
|
||||||
expect(res.watcherCount, channelState.watcherCount);
|
expect(res.watcherCount, channelState.watcherCount);
|
||||||
|
|
||||||
verify(() => client.post(path, data: any(named: 'data'))).called(1);
|
verify(() => client.post(path, data: any(named: 'data'))).called(1);
|
||||||
|
|||||||
@@ -19,8 +19,10 @@ void main() {
|
|||||||
attachment.thumbUrl,
|
attachment.thumbUrl,
|
||||||
'https://media0.giphy.com/media/3o7TKnCdBx5cMg0qti/giphy.gif',
|
'https://media0.giphy.com/media/3o7TKnCdBx5cMg0qti/giphy.gif',
|
||||||
);
|
);
|
||||||
|
expect(attachment.actions, isNotNull);
|
||||||
|
expect(attachment.actions, isNotEmpty);
|
||||||
expect(attachment.actions, hasLength(3));
|
expect(attachment.actions, hasLength(3));
|
||||||
expect(attachment.actions[0], isA<Action>());
|
expect(attachment.actions![0], isA<Action>());
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should serialize to json correctly', () {
|
test('should serialize to json correctly', () {
|
||||||
|
|||||||
@@ -30,14 +30,16 @@ void main() {
|
|||||||
channelState.channel?.extraData['image'],
|
channelState.channel?.extraData['image'],
|
||||||
'https://cdn.chrisshort.net/testing-certificate-chains-in-go/GOPHER_MIC_DROP.png',
|
'https://cdn.chrisshort.net/testing-certificate-chains-in-go/GOPHER_MIC_DROP.png',
|
||||||
);
|
);
|
||||||
|
expect(channelState.messages, isNotNull);
|
||||||
|
expect(channelState.messages, isNotEmpty);
|
||||||
expect(channelState.messages, hasLength(25));
|
expect(channelState.messages, hasLength(25));
|
||||||
expect(channelState.messages[0], isA<Message>());
|
expect(channelState.messages![0], isA<Message>());
|
||||||
expect(channelState.messages[0], isNotNull);
|
expect(channelState.messages![0], isNotNull);
|
||||||
expect(
|
expect(
|
||||||
channelState.messages[0].createdAt,
|
channelState.messages![0].createdAt,
|
||||||
DateTime.parse('2020-01-29T03:23:02.843948Z'),
|
DateTime.parse('2020-01-29T03:23:02.843948Z'),
|
||||||
);
|
);
|
||||||
expect(channelState.messages[0].user, isA<User>());
|
expect(channelState.messages![0].user, isA<User>());
|
||||||
expect(channelState.watcherCount, 5);
|
expect(channelState.watcherCount, 5);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -117,19 +117,20 @@ class TestPersistenceClient extends ChatPersistenceClient {
|
|||||||
Future<void> updateUsers(List<User> users) => Future.value();
|
Future<void> updateUsers(List<User> users) => Future.value();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> bulkUpdateMembers(Map<String, List<Member>> members) =>
|
Future<void> bulkUpdateMembers(Map<String, List<Member>?> members) =>
|
||||||
Future.value();
|
Future.value();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> bulkUpdateMessages(Map<String, List<Message>> messages) =>
|
Future<void> bulkUpdateMessages(Map<String, List<Message>?> messages) =>
|
||||||
Future.value();
|
Future.value();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> bulkUpdatePinnedMessages(Map<String, List<Message>> messages) =>
|
Future<void> bulkUpdatePinnedMessages(Map<String, List<Message>?> messages) =>
|
||||||
Future.value();
|
Future.value();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> bulkUpdateReads(Map<String, List<Read>> reads) => Future.value();
|
Future<void> bulkUpdateReads(Map<String, List<Read>?> reads) =>
|
||||||
|
Future.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ class StreamGiphyAttachment extends StreamAttachmentWidget {
|
|||||||
if (imageUrl == null) {
|
if (imageUrl == null) {
|
||||||
return const AttachmentError();
|
return const AttachmentError();
|
||||||
}
|
}
|
||||||
if (attachment.actions.isNotEmpty) {
|
if (attachment.actions != null && attachment.actions!.isNotEmpty) {
|
||||||
return _buildSendingAttachment(context, imageUrl);
|
return _buildSendingAttachment(context, imageUrl);
|
||||||
}
|
}
|
||||||
return _buildSentAttachment(context, imageUrl);
|
return _buildSentAttachment(context, imageUrl);
|
||||||
|
|||||||
@@ -106,7 +106,9 @@ class StreamChannelState extends State<StreamChannel> {
|
|||||||
limit: limit,
|
limit: limit,
|
||||||
preferOffline: preferOffline,
|
preferOffline: preferOffline,
|
||||||
);
|
);
|
||||||
if (state.messages.isEmpty || state.messages.length < limit) {
|
if (state.messages == null ||
|
||||||
|
state.messages!.isEmpty ||
|
||||||
|
state.messages!.length < limit) {
|
||||||
_topPaginationEnded = true;
|
_topPaginationEnded = true;
|
||||||
}
|
}
|
||||||
_queryTopMessagesController.safeAdd(false);
|
_queryTopMessagesController.safeAdd(false);
|
||||||
@@ -137,7 +139,9 @@ class StreamChannelState extends State<StreamChannel> {
|
|||||||
limit: limit,
|
limit: limit,
|
||||||
preferOffline: preferOffline,
|
preferOffline: preferOffline,
|
||||||
);
|
);
|
||||||
if (state.messages.isEmpty || state.messages.length < limit) {
|
if (state.messages == null ||
|
||||||
|
state.messages!.isEmpty ||
|
||||||
|
state.messages!.length < limit) {
|
||||||
_bottomPaginationEnded = true;
|
_bottomPaginationEnded = true;
|
||||||
}
|
}
|
||||||
_queryBottomMessagesController.safeAdd(false);
|
_queryBottomMessagesController.safeAdd(false);
|
||||||
@@ -299,7 +303,9 @@ class StreamChannelState extends State<StreamChannel> {
|
|||||||
),
|
),
|
||||||
preferOffline: preferOffline,
|
preferOffline: preferOffline,
|
||||||
);
|
);
|
||||||
if (state.messages.isEmpty || state.messages.length < limit) {
|
if (state.messages == null ||
|
||||||
|
state.messages!.isEmpty ||
|
||||||
|
state.messages!.length < limit) {
|
||||||
channel.state?.isUpToDate = true;
|
channel.state?.isUpToDate = true;
|
||||||
}
|
}
|
||||||
return state;
|
return state;
|
||||||
|
|||||||
@@ -98,8 +98,9 @@ class HomeScreen extends StatelessWidget {
|
|||||||
AsyncSnapshot<ChannelState?> snapshot,
|
AsyncSnapshot<ChannelState?> snapshot,
|
||||||
) {
|
) {
|
||||||
if (snapshot.hasData && snapshot.data != null) {
|
if (snapshot.hasData && snapshot.data != null) {
|
||||||
|
final _messages = snapshot.data!.messages ?? [];
|
||||||
return MessageView(
|
return MessageView(
|
||||||
messages: snapshot.data!.messages.reversed.toList(),
|
messages: _messages.reversed.toList(),
|
||||||
channel: channel,
|
channel: channel,
|
||||||
);
|
);
|
||||||
} else if (snapshot.hasError) {
|
} else if (snapshot.hasError) {
|
||||||
|
|||||||
@@ -34,14 +34,20 @@ class MemberDao extends DatabaseAccessor<DriftChatDatabase>
|
|||||||
bulkUpdateMembers({cid: memberList});
|
bulkUpdateMembers({cid: memberList});
|
||||||
|
|
||||||
/// Bulk updates the members data of multiple channels
|
/// Bulk updates the members data of multiple channels
|
||||||
Future<void> bulkUpdateMembers(Map<String, List<Member>> channelWithMembers) {
|
Future<void> bulkUpdateMembers(
|
||||||
|
Map<String, List<Member>?> channelWithMembers,
|
||||||
|
) {
|
||||||
final entities = channelWithMembers.entries
|
final entities = channelWithMembers.entries
|
||||||
.map((entry) => entry.value.map(
|
.map((entry) =>
|
||||||
|
(entry.value?.map(
|
||||||
(member) => member.toEntity(cid: entry.key),
|
(member) => member.toEntity(cid: entry.key),
|
||||||
))
|
)) ??
|
||||||
|
[])
|
||||||
.expand((it) => it)
|
.expand((it) => it)
|
||||||
.toList(growable: false);
|
.toList(growable: false);
|
||||||
return batch((batch) => batch.insertAllOnConflictUpdate(members, entities));
|
return batch(
|
||||||
|
(batch) => batch.insertAllOnConflictUpdate(members, entities),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deletes all the members whose [Members.channelCid] is present in [cids]
|
/// Deletes all the members whose [Members.channelCid] is present in [cids]
|
||||||
|
|||||||
@@ -183,12 +183,14 @@ class MessageDao extends DatabaseAccessor<DriftChatDatabase>
|
|||||||
|
|
||||||
/// Bulk updates the message data of multiple channels
|
/// Bulk updates the message data of multiple channels
|
||||||
Future<void> bulkUpdateMessages(
|
Future<void> bulkUpdateMessages(
|
||||||
Map<String, List<Message>> channelWithMessages,
|
Map<String, List<Message>?> channelWithMessages,
|
||||||
) {
|
) {
|
||||||
final entities = channelWithMessages.entries
|
final entities = channelWithMessages.entries
|
||||||
.map((entry) => entry.value.map(
|
.map((entry) =>
|
||||||
|
entry.value?.map(
|
||||||
(message) => message.toEntity(cid: entry.key),
|
(message) => message.toEntity(cid: entry.key),
|
||||||
))
|
) ??
|
||||||
|
[])
|
||||||
.expand((it) => it)
|
.expand((it) => it)
|
||||||
.toList(growable: false);
|
.toList(growable: false);
|
||||||
return batch(
|
return batch(
|
||||||
|
|||||||
@@ -183,12 +183,14 @@ class PinnedMessageDao extends DatabaseAccessor<DriftChatDatabase>
|
|||||||
|
|
||||||
/// Bulk updates the message data of multiple channels
|
/// Bulk updates the message data of multiple channels
|
||||||
Future<void> bulkUpdateMessages(
|
Future<void> bulkUpdateMessages(
|
||||||
Map<String, List<Message>> channelWithMessages,
|
Map<String, List<Message>?> channelWithMessages,
|
||||||
) {
|
) {
|
||||||
final entities = channelWithMessages.entries
|
final entities = channelWithMessages.entries
|
||||||
.map((entry) => entry.value.map(
|
.map((entry) =>
|
||||||
|
entry.value?.map(
|
||||||
(message) => message.toPinnedEntity(cid: entry.key),
|
(message) => message.toPinnedEntity(cid: entry.key),
|
||||||
))
|
) ??
|
||||||
|
[])
|
||||||
.expand((it) => it)
|
.expand((it) => it)
|
||||||
.toList(growable: false);
|
.toList(growable: false);
|
||||||
return batch(
|
return batch(
|
||||||
|
|||||||
@@ -33,11 +33,13 @@ class ReadDao extends DatabaseAccessor<DriftChatDatabase> with _$ReadDaoMixin {
|
|||||||
bulkUpdateReads({cid: readList});
|
bulkUpdateReads({cid: readList});
|
||||||
|
|
||||||
/// Bulk updates the reads data of multiple channels
|
/// Bulk updates the reads data of multiple channels
|
||||||
Future<void> bulkUpdateReads(Map<String, List<Read>> channelWithReads) {
|
Future<void> bulkUpdateReads(Map<String, List<Read>?> channelWithReads) {
|
||||||
final entities = channelWithReads.entries
|
final entities = channelWithReads.entries
|
||||||
.map((entry) => entry.value.map(
|
.map((entry) =>
|
||||||
|
entry.value?.map(
|
||||||
(read) => read.toEntity(cid: entry.key),
|
(read) => read.toEntity(cid: entry.key),
|
||||||
))
|
) ??
|
||||||
|
[])
|
||||||
.expand((it) => it)
|
.expand((it) => it)
|
||||||
.toList(growable: false);
|
.toList(growable: false);
|
||||||
return batch((batch) => batch.insertAllOnConflictUpdate(reads, entities));
|
return batch((batch) => batch.insertAllOnConflictUpdate(reads, entities));
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ class DriftChatDatabase extends _$DriftChatDatabase {
|
|||||||
|
|
||||||
// you should bump this number whenever you change or add a table definition.
|
// you should bump this number whenever you change or add a table definition.
|
||||||
@override
|
@override
|
||||||
int get schemaVersion => 6;
|
int get schemaVersion => 7;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
MigrationStrategy get migration => MigrationStrategy(
|
MigrationStrategy get migration => MigrationStrategy(
|
||||||
|
|||||||
@@ -295,21 +295,21 @@ class StreamChatPersistenceClient extends ChatPersistenceClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> bulkUpdateMembers(Map<String, List<Member>> members) {
|
Future<void> bulkUpdateMembers(Map<String, List<Member>?> members) {
|
||||||
assert(_debugIsConnected, '');
|
assert(_debugIsConnected, '');
|
||||||
_logger.info('bulkUpdateMembers');
|
_logger.info('bulkUpdateMembers');
|
||||||
return _readProtected(() => db!.memberDao.bulkUpdateMembers(members));
|
return _readProtected(() => db!.memberDao.bulkUpdateMembers(members));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> bulkUpdateMessages(Map<String, List<Message>> messages) {
|
Future<void> bulkUpdateMessages(Map<String, List<Message>?> messages) {
|
||||||
assert(_debugIsConnected, '');
|
assert(_debugIsConnected, '');
|
||||||
_logger.info('bulkUpdateMessages');
|
_logger.info('bulkUpdateMessages');
|
||||||
return _readProtected(() => db!.messageDao.bulkUpdateMessages(messages));
|
return _readProtected(() => db!.messageDao.bulkUpdateMessages(messages));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> bulkUpdatePinnedMessages(Map<String, List<Message>> messages) {
|
Future<void> bulkUpdatePinnedMessages(Map<String, List<Message>?> messages) {
|
||||||
assert(_debugIsConnected, '');
|
assert(_debugIsConnected, '');
|
||||||
_logger.info('bulkUpdatePinnedMessages');
|
_logger.info('bulkUpdatePinnedMessages');
|
||||||
return _readProtected(
|
return _readProtected(
|
||||||
@@ -334,7 +334,7 @@ class StreamChatPersistenceClient extends ChatPersistenceClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> bulkUpdateReads(Map<String, List<Read>> reads) {
|
Future<void> bulkUpdateReads(Map<String, List<Read>?> reads) {
|
||||||
assert(_debugIsConnected, '');
|
assert(_debugIsConnected, '');
|
||||||
_logger.info('bulkUpdateReads');
|
_logger.info('bulkUpdateReads');
|
||||||
return _readProtected(() => db!.readDao.bulkUpdateReads(reads));
|
return _readProtected(() => db!.readDao.bulkUpdateReads(reads));
|
||||||
|
|||||||
@@ -61,10 +61,10 @@ void main() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
expect(channelState, isA<ChannelState>());
|
expect(channelState, isA<ChannelState>());
|
||||||
expect(channelState.members.length, members.length);
|
expect(channelState.members?.length, members.length);
|
||||||
expect(channelState.read.length, reads.length);
|
expect(channelState.read?.length, reads.length);
|
||||||
expect(channelState.messages.length, messages.length);
|
expect(channelState.messages?.length, messages.length);
|
||||||
expect(channelState.pinnedMessages.length, messages.length);
|
expect(channelState.pinnedMessages?.length, messages.length);
|
||||||
|
|
||||||
final channelModel = channelState.channel!;
|
final channelModel = channelState.channel!;
|
||||||
expect(channelModel.id, entity.id);
|
expect(channelModel.id, entity.id);
|
||||||
|
|||||||
@@ -219,10 +219,10 @@ void main() {
|
|||||||
.thenAnswer((_) async => messages);
|
.thenAnswer((_) async => messages);
|
||||||
|
|
||||||
final fetchedChannelState = await client.getChannelStateByCid(cid);
|
final fetchedChannelState = await client.getChannelStateByCid(cid);
|
||||||
expect(fetchedChannelState.messages.length, messages.length);
|
expect(fetchedChannelState.messages?.length, messages.length);
|
||||||
expect(fetchedChannelState.pinnedMessages.length, messages.length);
|
expect(fetchedChannelState.pinnedMessages?.length, messages.length);
|
||||||
expect(fetchedChannelState.members.length, members.length);
|
expect(fetchedChannelState.members?.length, members.length);
|
||||||
expect(fetchedChannelState.read.length, reads.length);
|
expect(fetchedChannelState.read?.length, reads.length);
|
||||||
expect(fetchedChannelState.channel!.cid, channel.cid);
|
expect(fetchedChannelState.channel!.cid, channel.cid);
|
||||||
|
|
||||||
verify(() => mockDatabase.memberDao.getMembersByCid(cid)).called(1);
|
verify(() => mockDatabase.memberDao.getMembersByCid(cid)).called(1);
|
||||||
@@ -277,10 +277,10 @@ void main() {
|
|||||||
for (var i = 0; i < fetchedChannelStates.length; i++) {
|
for (var i = 0; i < fetchedChannelStates.length; i++) {
|
||||||
final original = channelStates[i];
|
final original = channelStates[i];
|
||||||
final fetched = fetchedChannelStates[i];
|
final fetched = fetchedChannelStates[i];
|
||||||
expect(fetched.members.length, original.members.length);
|
expect(fetched.members?.length, original.members?.length);
|
||||||
expect(fetched.messages.length, original.messages.length);
|
expect(fetched.messages?.length, original.messages?.length);
|
||||||
expect(fetched.pinnedMessages.length, original.pinnedMessages.length);
|
expect(fetched.pinnedMessages?.length, original.pinnedMessages?.length);
|
||||||
expect(fetched.read.length, original.read.length);
|
expect(fetched.read?.length, original.read?.length);
|
||||||
expect(fetched.channel!.cid, original.channel!.cid);
|
expect(fetched.channel!.cid, original.channel!.cid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user