[Persistence] Add support for pinned messages
Signed-off-by: Sahil Kumar <[email protected]>
This commit is contained in:
@@ -56,10 +56,17 @@ abstract class ChatPersistenceClient {
|
|||||||
PaginationParams messagePagination,
|
PaginationParams messagePagination,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/// Get stored pinned [Message]s by providing channel [cid]
|
||||||
|
Future<List<Message>> getPinnedMessagesByCid(
|
||||||
|
String cid, {
|
||||||
|
PaginationParams messagePagination,
|
||||||
|
});
|
||||||
|
|
||||||
/// Get [ChannelState] data by providing channel [cid]
|
/// Get [ChannelState] data by providing channel [cid]
|
||||||
Future<ChannelState> getChannelStateByCid(
|
Future<ChannelState> getChannelStateByCid(
|
||||||
String cid, {
|
String cid, {
|
||||||
PaginationParams messagePagination,
|
PaginationParams messagePagination,
|
||||||
|
PaginationParams pinnedMessagePagination,
|
||||||
}) async {
|
}) async {
|
||||||
final members = await getMembersByCid(cid);
|
final members = await getMembersByCid(cid);
|
||||||
final reads = await getReadsByCid(cid);
|
final reads = await getReadsByCid(cid);
|
||||||
@@ -68,10 +75,15 @@ abstract class ChatPersistenceClient {
|
|||||||
cid,
|
cid,
|
||||||
messagePagination: messagePagination,
|
messagePagination: messagePagination,
|
||||||
);
|
);
|
||||||
|
final pinnedMessages = await getPinnedMessagesByCid(
|
||||||
|
cid,
|
||||||
|
messagePagination: pinnedMessagePagination,
|
||||||
|
);
|
||||||
return ChannelState(
|
return ChannelState(
|
||||||
members: members,
|
members: members,
|
||||||
read: reads,
|
read: reads,
|
||||||
messages: messages,
|
messages: messages,
|
||||||
|
pinnedMessages: pinnedMessages,
|
||||||
channel: channel,
|
channel: channel,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -101,17 +113,33 @@ abstract class ChatPersistenceClient {
|
|||||||
return deleteMessageByIds([messageId]);
|
return deleteMessageByIds([messageId]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Remove a pinned message by [messageId]
|
||||||
|
Future<void> deletePinnedMessageById(String messageId) {
|
||||||
|
return deletePinnedMessageByIds([messageId]);
|
||||||
|
}
|
||||||
|
|
||||||
/// Remove a message by [messageIds]
|
/// Remove a message by [messageIds]
|
||||||
Future<void> deleteMessageByIds(List<String> messageIds);
|
Future<void> deleteMessageByIds(List<String> messageIds);
|
||||||
|
|
||||||
|
/// Remove a pinned message by [messageIds]
|
||||||
|
Future<void> deletePinnedMessageByIds(List<String> messageIds);
|
||||||
|
|
||||||
/// Remove a message by channel [cid]
|
/// Remove a message by channel [cid]
|
||||||
Future<void> deleteMessageByCid(String cid) {
|
Future<void> deleteMessageByCid(String cid) {
|
||||||
return deleteMessageByCids([cid]);
|
return deleteMessageByCids([cid]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Remove a pinned message by channel [cid]
|
||||||
|
Future<void> deletePinnedMessageByCid(String cid) {
|
||||||
|
return deletePinnedMessageByCids([cid]);
|
||||||
|
}
|
||||||
|
|
||||||
/// Remove a message by message [cids]
|
/// Remove a message by message [cids]
|
||||||
Future<void> deleteMessageByCids(List<String> cids);
|
Future<void> deleteMessageByCids(List<String> cids);
|
||||||
|
|
||||||
|
/// Remove a pinned message by message [cids]
|
||||||
|
Future<void> deletePinnedMessageByCids(List<String> cids);
|
||||||
|
|
||||||
/// Remove a channel by [cid]
|
/// Remove a channel by [cid]
|
||||||
Future<void> deleteChannels(List<String> cids);
|
Future<void> deleteChannels(List<String> cids);
|
||||||
|
|
||||||
@@ -119,6 +147,10 @@ abstract class ChatPersistenceClient {
|
|||||||
/// the new [messages] data
|
/// the new [messages] data
|
||||||
Future<void> updateMessages(String cid, List<Message> messages);
|
Future<void> updateMessages(String cid, List<Message> messages);
|
||||||
|
|
||||||
|
/// Updates the pinned message data of a particular channel [cid] with
|
||||||
|
/// the new [messages] data
|
||||||
|
Future<void> updatePinnedMessages(String cid, 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]
|
||||||
Future<Map<String, List<Message>>> getChannelThreads(String cid);
|
Future<Map<String, List<Message>>> getChannelThreads(String cid);
|
||||||
@@ -204,6 +236,12 @@ abstract class ChatPersistenceClient {
|
|||||||
return updateMessages(cid, messages.toList(growable: false));
|
return updateMessages(cid, messages.toList(growable: false));
|
||||||
}).toList(growable: false);
|
}).toList(growable: false);
|
||||||
|
|
||||||
|
final updatePinnedMessagesFuture = channelStates.map((it) {
|
||||||
|
final cid = it.channel.cid;
|
||||||
|
final messages = it.pinnedMessages.where((it) => it != null);
|
||||||
|
return updatePinnedMessages(cid, messages.toList(growable: false));
|
||||||
|
}).toList(growable: false);
|
||||||
|
|
||||||
final updateReadsFuture = channelStates.map((it) {
|
final updateReadsFuture = channelStates.map((it) {
|
||||||
final cid = it.channel.cid;
|
final cid = it.channel.cid;
|
||||||
final reads = it.read?.where((it) => it != null) ?? [];
|
final reads = it.read?.where((it) => it != null) ?? [];
|
||||||
@@ -218,6 +256,7 @@ abstract class ChatPersistenceClient {
|
|||||||
|
|
||||||
await Future.wait([
|
await Future.wait([
|
||||||
...updateMessagesFuture,
|
...updateMessagesFuture,
|
||||||
|
...updatePinnedMessagesFuture,
|
||||||
...updateReadsFuture,
|
...updateReadsFuture,
|
||||||
...updateMembersFuture,
|
...updateMembersFuture,
|
||||||
updateUsers(users.toList(growable: false)),
|
updateUsers(users.toList(growable: false)),
|
||||||
|
|||||||
@@ -101,12 +101,14 @@ class ChannelQueryDao extends DatabaseAccessor<MoorChatDatabase>
|
|||||||
final members = await _db.memberDao.getMembersByCid(cid);
|
final members = await _db.memberDao.getMembersByCid(cid);
|
||||||
final reads = await _db.readDao.getReadsByCid(cid);
|
final reads = await _db.readDao.getReadsByCid(cid);
|
||||||
final messages = await _db.messageDao.getMessagesByCid(cid);
|
final messages = await _db.messageDao.getMessagesByCid(cid);
|
||||||
|
final pinnedMessages = await _db.pinnedMessageDao.getMessagesByCid(cid);
|
||||||
|
|
||||||
return channelEntity.toChannelState(
|
return channelEntity.toChannelState(
|
||||||
createdBy: userEntity?.toUser(),
|
createdBy: userEntity?.toUser(),
|
||||||
members: members,
|
members: members,
|
||||||
reads: reads,
|
reads: reads,
|
||||||
messages: messages,
|
messages: messages,
|
||||||
|
pinnedMessages: pinnedMessages,
|
||||||
);
|
);
|
||||||
}).get();
|
}).get();
|
||||||
}));
|
}));
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
export 'user_dao.dart';
|
export 'user_dao.dart';
|
||||||
export 'channel_dao.dart';
|
export 'channel_dao.dart';
|
||||||
export 'message_dao.dart';
|
export 'message_dao.dart';
|
||||||
|
export 'pinned_message_dao.dart';
|
||||||
export 'member_dao.dart';
|
export 'member_dao.dart';
|
||||||
export 'connection_event_dao.dart';
|
export 'connection_event_dao.dart';
|
||||||
export 'reaction_dao.dart';
|
export 'reaction_dao.dart';
|
||||||
|
|||||||
@@ -17,6 +17,10 @@ class MessageDao extends DatabaseAccessor<MoorChatDatabase>
|
|||||||
|
|
||||||
final MoorChatDatabase _db;
|
final MoorChatDatabase _db;
|
||||||
|
|
||||||
|
$UsersTable get _users => alias(users, 'users');
|
||||||
|
|
||||||
|
$UsersTable get _pinnedByUsers => alias(users, 'pinnedByUsers');
|
||||||
|
|
||||||
/// Removes all the messages by matching [Messages.id] in [messageIds]
|
/// Removes all the messages by matching [Messages.id] in [messageIds]
|
||||||
///
|
///
|
||||||
/// This will automatically delete the following linked records
|
/// This will automatically delete the following linked records
|
||||||
@@ -34,7 +38,8 @@ class MessageDao extends DatabaseAccessor<MoorChatDatabase>
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<Message> _messageFromJoinRow(TypedResult rows) async {
|
Future<Message> _messageFromJoinRow(TypedResult rows) async {
|
||||||
final userEntity = rows.readTable(users);
|
final userEntity = rows.readTable(_users);
|
||||||
|
final pinnedByEntity = rows.readTable(_pinnedByUsers);
|
||||||
final msgEntity = rows.readTable(messages);
|
final msgEntity = rows.readTable(messages);
|
||||||
final latestReactions = await _db.reactionDao.getReactions(msgEntity.id);
|
final latestReactions = await _db.reactionDao.getReactions(msgEntity.id);
|
||||||
final ownReactions = await _db.reactionDao.getReactionsByUserId(
|
final ownReactions = await _db.reactionDao.getReactionsByUserId(
|
||||||
@@ -47,6 +52,7 @@ class MessageDao extends DatabaseAccessor<MoorChatDatabase>
|
|||||||
}
|
}
|
||||||
return msgEntity.toMessage(
|
return msgEntity.toMessage(
|
||||||
user: userEntity?.toUser(),
|
user: userEntity?.toUser(),
|
||||||
|
pinnedBy: pinnedByEntity?.toUser(),
|
||||||
latestReactions: latestReactions,
|
latestReactions: latestReactions,
|
||||||
ownReactions: ownReactions,
|
ownReactions: ownReactions,
|
||||||
quotedMessage: quotedMessage,
|
quotedMessage: quotedMessage,
|
||||||
@@ -56,7 +62,9 @@ class MessageDao extends DatabaseAccessor<MoorChatDatabase>
|
|||||||
/// Returns a single message by matching the [Messages.id] with [id]
|
/// Returns a single message by matching the [Messages.id] with [id]
|
||||||
Future<Message> getMessageById(String id) async {
|
Future<Message> getMessageById(String id) async {
|
||||||
return await (select(messages).join([
|
return await (select(messages).join([
|
||||||
leftOuterJoin(users, messages.userId.equalsExp(users.id)),
|
leftOuterJoin(_users, messages.userId.equalsExp(_users.id)),
|
||||||
|
leftOuterJoin(
|
||||||
|
_pinnedByUsers, messages.pinnedByUserId.equalsExp(_pinnedByUsers.id)),
|
||||||
])
|
])
|
||||||
..where(messages.id.equals(id)))
|
..where(messages.id.equals(id)))
|
||||||
.map(_messageFromJoinRow)
|
.map(_messageFromJoinRow)
|
||||||
@@ -67,7 +75,9 @@ class MessageDao extends DatabaseAccessor<MoorChatDatabase>
|
|||||||
/// [Messages.channelCid] with [cid]
|
/// [Messages.channelCid] with [cid]
|
||||||
Future<List<Message>> getThreadMessages(String cid) async {
|
Future<List<Message>> getThreadMessages(String cid) async {
|
||||||
return Future.wait(await (select(messages).join([
|
return Future.wait(await (select(messages).join([
|
||||||
leftOuterJoin(users, messages.userId.equalsExp(users.id)),
|
leftOuterJoin(users, messages.userId.equalsExp(_users.id)),
|
||||||
|
leftOuterJoin(
|
||||||
|
_pinnedByUsers, messages.pinnedByUserId.equalsExp(_pinnedByUsers.id)),
|
||||||
])
|
])
|
||||||
..where(messages.channelCid.equals(cid))
|
..where(messages.channelCid.equals(cid))
|
||||||
..where(isNotNull(messages.parentId))
|
..where(isNotNull(messages.parentId))
|
||||||
@@ -83,7 +93,9 @@ class MessageDao extends DatabaseAccessor<MoorChatDatabase>
|
|||||||
PaginationParams options,
|
PaginationParams options,
|
||||||
}) async {
|
}) async {
|
||||||
final msgList = await Future.wait(await (select(messages).join([
|
final msgList = await Future.wait(await (select(messages).join([
|
||||||
innerJoin(users, messages.userId.equalsExp(users.id)),
|
innerJoin(_users, messages.userId.equalsExp(_users.id)),
|
||||||
|
innerJoin(
|
||||||
|
_pinnedByUsers, messages.pinnedByUserId.equalsExp(_pinnedByUsers.id)),
|
||||||
])
|
])
|
||||||
..where(messages.parentId.equals(parentId))
|
..where(messages.parentId.equals(parentId))
|
||||||
..orderBy([OrderingTerm.asc(messages.createdAt)]))
|
..orderBy([OrderingTerm.asc(messages.createdAt)]))
|
||||||
@@ -104,7 +116,9 @@ class MessageDao extends DatabaseAccessor<MoorChatDatabase>
|
|||||||
PaginationParams messagePagination,
|
PaginationParams messagePagination,
|
||||||
}) async {
|
}) async {
|
||||||
final msgList = await Future.wait(await (select(messages).join([
|
final msgList = await Future.wait(await (select(messages).join([
|
||||||
leftOuterJoin(users, messages.userId.equalsExp(users.id)),
|
leftOuterJoin(_users, messages.userId.equalsExp(_users.id)),
|
||||||
|
leftOuterJoin(
|
||||||
|
_pinnedByUsers, messages.pinnedByUserId.equalsExp(_pinnedByUsers.id)),
|
||||||
])
|
])
|
||||||
..where(messages.channelCid.equals(cid))
|
..where(messages.channelCid.equals(cid))
|
||||||
..where(
|
..where(
|
||||||
|
|||||||
@@ -0,0 +1,169 @@
|
|||||||
|
import 'package:moor/moor.dart';
|
||||||
|
import 'package:stream_chat/stream_chat.dart';
|
||||||
|
import 'package:stream_chat_persistence/src/db/moor_chat_database.dart';
|
||||||
|
import 'package:stream_chat_persistence/src/entity/pinned_messages.dart';
|
||||||
|
import 'package:stream_chat_persistence/src/entity/users.dart';
|
||||||
|
|
||||||
|
import '../mapper/mapper.dart';
|
||||||
|
|
||||||
|
part 'pinned_message_dao.g.dart';
|
||||||
|
|
||||||
|
/// The Data Access Object for operations in [Messages] table.
|
||||||
|
@UseDao(tables: [PinnedMessages, Users])
|
||||||
|
class PinnedMessageDao extends DatabaseAccessor<MoorChatDatabase>
|
||||||
|
with _$PinnedMessageDaoMixin {
|
||||||
|
/// Creates a new message dao instance
|
||||||
|
PinnedMessageDao(this._db) : super(_db);
|
||||||
|
|
||||||
|
final MoorChatDatabase _db;
|
||||||
|
|
||||||
|
$UsersTable get _users => alias(users, 'users');
|
||||||
|
|
||||||
|
$UsersTable get _pinnedByUsers => alias(users, 'pinnedByUsers');
|
||||||
|
|
||||||
|
/// Removes all the messages by matching [PinnedMessages.id] in [messageIds]
|
||||||
|
///
|
||||||
|
/// This will automatically delete the following linked records
|
||||||
|
/// 1. Message Reactions
|
||||||
|
Future<void> deleteMessageByIds(List<String> messageIds) {
|
||||||
|
return (delete(pinnedMessages)..where((tbl) => tbl.id.isIn(messageIds)))
|
||||||
|
.go();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Removes all the messages by matching [PinnedMessages.channelCid] in [cids]
|
||||||
|
///
|
||||||
|
/// This will automatically delete the following linked records
|
||||||
|
/// 1. Message Reactions
|
||||||
|
Future<void> deleteMessageByCids(List<String> cids) async {
|
||||||
|
return (delete(pinnedMessages)..where((tbl) => tbl.channelCid.isIn(cids)))
|
||||||
|
.go();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Message> _messageFromJoinRow(TypedResult rows) async {
|
||||||
|
final userEntity = rows.readTable(users);
|
||||||
|
final pinnedByEntity = rows.readTable(_pinnedByUsers);
|
||||||
|
final msgEntity = rows.readTable(pinnedMessages);
|
||||||
|
final latestReactions = await _db.reactionDao.getReactions(msgEntity.id);
|
||||||
|
final ownReactions = await _db.reactionDao.getReactionsByUserId(
|
||||||
|
msgEntity.id,
|
||||||
|
_db.userId,
|
||||||
|
);
|
||||||
|
Message quotedMessage;
|
||||||
|
if (msgEntity.quotedMessageId != null) {
|
||||||
|
quotedMessage = await getMessageById(msgEntity.quotedMessageId);
|
||||||
|
}
|
||||||
|
return msgEntity.toMessage(
|
||||||
|
user: userEntity?.toUser(),
|
||||||
|
pinnedBy: pinnedByEntity?.toUser(),
|
||||||
|
latestReactions: latestReactions,
|
||||||
|
ownReactions: ownReactions,
|
||||||
|
quotedMessage: quotedMessage,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a single message by matching the [PinnedMessages.id] with [id]
|
||||||
|
Future<Message> getMessageById(String id) async {
|
||||||
|
return await (select(pinnedMessages).join([
|
||||||
|
leftOuterJoin(_users, pinnedMessages.userId.equalsExp(_users.id)),
|
||||||
|
leftOuterJoin(_pinnedByUsers,
|
||||||
|
pinnedMessages.pinnedByUserId.equalsExp(_pinnedByUsers.id)),
|
||||||
|
])
|
||||||
|
..where(pinnedMessages.id.equals(id)))
|
||||||
|
.map(_messageFromJoinRow)
|
||||||
|
.getSingle();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns all the messages of a particular thread by matching
|
||||||
|
/// [PinnedMessages.channelCid] with [cid]
|
||||||
|
Future<List<Message>> getThreadMessages(String cid) async {
|
||||||
|
return Future.wait(await (select(pinnedMessages).join([
|
||||||
|
leftOuterJoin(_users, pinnedMessages.userId.equalsExp(_users.id)),
|
||||||
|
leftOuterJoin(_pinnedByUsers,
|
||||||
|
pinnedMessages.pinnedByUserId.equalsExp(_pinnedByUsers.id)),
|
||||||
|
])
|
||||||
|
..where(pinnedMessages.channelCid.equals(cid))
|
||||||
|
..where(isNotNull(pinnedMessages.parentId))
|
||||||
|
..orderBy([OrderingTerm.asc(pinnedMessages.createdAt)]))
|
||||||
|
.map(_messageFromJoinRow)
|
||||||
|
.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns all the messages of a particular thread by matching
|
||||||
|
/// [PinnedMessages.parentId] with [parentId]
|
||||||
|
Future<List<Message>> getThreadMessagesByParentId(
|
||||||
|
String parentId, {
|
||||||
|
PaginationParams options,
|
||||||
|
}) async {
|
||||||
|
final msgList = await Future.wait(await (select(pinnedMessages).join([
|
||||||
|
innerJoin(_users, pinnedMessages.userId.equalsExp(_users.id)),
|
||||||
|
innerJoin(_pinnedByUsers,
|
||||||
|
pinnedMessages.pinnedByUserId.equalsExp(_pinnedByUsers.id)),
|
||||||
|
])
|
||||||
|
..where(pinnedMessages.parentId.equals(parentId))
|
||||||
|
..orderBy([OrderingTerm.asc(pinnedMessages.createdAt)]))
|
||||||
|
.map(_messageFromJoinRow)
|
||||||
|
.get());
|
||||||
|
|
||||||
|
if (options?.lessThan != null) {
|
||||||
|
final lessThanIndex = msgList.indexWhere((m) => m.id == options.lessThan);
|
||||||
|
msgList.removeRange(lessThanIndex, msgList.length);
|
||||||
|
}
|
||||||
|
return msgList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns all the messages of a channel by matching
|
||||||
|
/// [PinnedMessages.channelCid] with [parentId]
|
||||||
|
Future<List<Message>> getMessagesByCid(
|
||||||
|
String cid, {
|
||||||
|
PaginationParams messagePagination,
|
||||||
|
}) async {
|
||||||
|
final msgList = await Future.wait(await (select(pinnedMessages).join([
|
||||||
|
leftOuterJoin(_users, pinnedMessages.userId.equalsExp(_users.id)),
|
||||||
|
leftOuterJoin(_pinnedByUsers,
|
||||||
|
pinnedMessages.pinnedByUserId.equalsExp(_pinnedByUsers.id)),
|
||||||
|
])
|
||||||
|
..where(pinnedMessages.channelCid.equals(cid))
|
||||||
|
..where(isNull(pinnedMessages.parentId) |
|
||||||
|
pinnedMessages.showInChannel.equals(true))
|
||||||
|
..orderBy([OrderingTerm.asc(pinnedMessages.createdAt)]))
|
||||||
|
.map(_messageFromJoinRow)
|
||||||
|
.get());
|
||||||
|
|
||||||
|
if (messagePagination?.lessThan != null) {
|
||||||
|
final lessThanIndex = msgList.indexWhere(
|
||||||
|
(m) => m.id == messagePagination.lessThan,
|
||||||
|
);
|
||||||
|
if (lessThanIndex != -1) {
|
||||||
|
msgList.removeRange(lessThanIndex, msgList.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (messagePagination?.greaterThanOrEqual != null) {
|
||||||
|
final greaterThanIndex = msgList.indexWhere(
|
||||||
|
(m) => m.id == messagePagination.greaterThanOrEqual,
|
||||||
|
);
|
||||||
|
if (greaterThanIndex != -1) {
|
||||||
|
msgList.removeRange(0, greaterThanIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (messagePagination?.limit != null) {
|
||||||
|
return msgList.take(messagePagination.limit).toList();
|
||||||
|
}
|
||||||
|
return msgList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Updates the message data of a particular channel with
|
||||||
|
/// the new [messageList] data
|
||||||
|
Future<void> updateMessages(String cid, List<Message> messageList) async {
|
||||||
|
if (messageList == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return batch((batch) {
|
||||||
|
batch.insertAll(
|
||||||
|
pinnedMessages,
|
||||||
|
messageList.map((it) => it.toPinnedEntity(cid: cid)).toList(),
|
||||||
|
mode: InsertMode.insertOrReplace,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'pinned_message_dao.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// DaoGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
mixin _$PinnedMessageDaoMixin on DatabaseAccessor<MoorChatDatabase> {
|
||||||
|
$PinnedMessagesTable get pinnedMessages => attachedDatabase.pinnedMessages;
|
||||||
|
$UsersTable get users => attachedDatabase.users;
|
||||||
|
}
|
||||||
@@ -25,6 +25,7 @@ LazyDatabase _openConnection(
|
|||||||
@UseMoor(tables: [
|
@UseMoor(tables: [
|
||||||
Channels,
|
Channels,
|
||||||
Messages,
|
Messages,
|
||||||
|
PinnedMessages,
|
||||||
Reactions,
|
Reactions,
|
||||||
Users,
|
Users,
|
||||||
Members,
|
Members,
|
||||||
@@ -35,6 +36,7 @@ LazyDatabase _openConnection(
|
|||||||
UserDao,
|
UserDao,
|
||||||
ChannelDao,
|
ChannelDao,
|
||||||
MessageDao,
|
MessageDao,
|
||||||
|
PinnedMessageDao,
|
||||||
MemberDao,
|
MemberDao,
|
||||||
ReactionDao,
|
ReactionDao,
|
||||||
ReadDao,
|
ReadDao,
|
||||||
@@ -67,7 +69,7 @@ class MoorChatDatabase extends _$MoorChatDatabase {
|
|||||||
|
|
||||||
// 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 => 1;
|
int get schemaVersion => 2;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
MigrationStrategy get migration => MigrationStrategy(
|
MigrationStrategy get migration => MigrationStrategy(
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,6 @@
|
|||||||
export 'channels.dart';
|
export 'channels.dart';
|
||||||
export 'messages.dart';
|
export 'messages.dart';
|
||||||
|
export 'pinned_messages.dart';
|
||||||
export 'reactions.dart';
|
export 'reactions.dart';
|
||||||
export 'users.dart';
|
export 'users.dart';
|
||||||
export 'members.dart';
|
export 'members.dart';
|
||||||
|
|||||||
@@ -64,6 +64,18 @@ class Messages extends Table {
|
|||||||
/// Id of the User who sent the message
|
/// Id of the User who sent the message
|
||||||
TextColumn get userId => text().nullable()();
|
TextColumn get userId => text().nullable()();
|
||||||
|
|
||||||
|
/// Whether the message is pinned or not
|
||||||
|
BoolColumn get pinned => boolean().withDefault(const Constant(false))();
|
||||||
|
|
||||||
|
/// The DateTime at which the message was pinned
|
||||||
|
DateTimeColumn get pinnedAt => dateTime().nullable()();
|
||||||
|
|
||||||
|
/// The DateTime on which the message pin expires
|
||||||
|
DateTimeColumn get pinExpires => dateTime().nullable()();
|
||||||
|
|
||||||
|
/// Id of the User who pinned the message
|
||||||
|
TextColumn get pinnedByUserId => text().nullable()();
|
||||||
|
|
||||||
/// The channel cid of which this message is part of
|
/// The channel cid of which this message is part of
|
||||||
TextColumn get channelCid => text().nullable().customConstraint(
|
TextColumn get channelCid => text().nullable().customConstraint(
|
||||||
'NULLABLE REFERENCES channels(cid) ON DELETE CASCADE')();
|
'NULLABLE REFERENCES channels(cid) ON DELETE CASCADE')();
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import 'package:moor/moor.dart';
|
||||||
|
|
||||||
|
import 'messages.dart';
|
||||||
|
|
||||||
|
/// Represents a [PinnedMessages] table in [MoorChatDatabase].
|
||||||
|
@DataClassName('PinnedMessageEntity')
|
||||||
|
class PinnedMessages extends Messages {}
|
||||||
@@ -28,11 +28,13 @@ extension ChannelEntityX on ChannelEntity {
|
|||||||
List<Member> members,
|
List<Member> members,
|
||||||
List<Read> reads,
|
List<Read> reads,
|
||||||
List<Message> messages,
|
List<Message> messages,
|
||||||
|
List<Message> pinnedMessages,
|
||||||
}) {
|
}) {
|
||||||
return ChannelState(
|
return ChannelState(
|
||||||
members: members,
|
members: members,
|
||||||
read: reads,
|
read: reads,
|
||||||
messages: messages,
|
messages: messages,
|
||||||
|
pinnedMessages: pinnedMessages,
|
||||||
channel: toChannelModel(createdBy: createdBy),
|
channel: toChannelModel(createdBy: createdBy),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,3 +5,4 @@ export 'event_mapper.dart';
|
|||||||
export 'member_mapper.dart';
|
export 'member_mapper.dart';
|
||||||
export 'read_mapper.dart';
|
export 'read_mapper.dart';
|
||||||
export 'message_mapper.dart';
|
export 'message_mapper.dart';
|
||||||
|
export 'pinned_message_mapper.dart';
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ extension MessageEntityX on MessageEntity {
|
|||||||
/// Maps a [MessageEntity] into [Message]
|
/// Maps a [MessageEntity] into [Message]
|
||||||
Message toMessage({
|
Message toMessage({
|
||||||
User user,
|
User user,
|
||||||
|
User pinnedBy,
|
||||||
List<Reaction> latestReactions,
|
List<Reaction> latestReactions,
|
||||||
List<Reaction> ownReactions,
|
List<Reaction> ownReactions,
|
||||||
Message quotedMessage,
|
Message quotedMessage,
|
||||||
@@ -37,6 +38,10 @@ extension MessageEntityX on MessageEntity {
|
|||||||
text: messageText,
|
text: messageText,
|
||||||
user: user,
|
user: user,
|
||||||
deletedAt: deletedAt,
|
deletedAt: deletedAt,
|
||||||
|
pinned: pinned,
|
||||||
|
pinnedAt: pinnedAt,
|
||||||
|
pinExpires: pinExpires,
|
||||||
|
pinnedBy: pinnedBy,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -67,6 +72,10 @@ extension MessageX on Message {
|
|||||||
userId: user?.id,
|
userId: user?.id,
|
||||||
deletedAt: deletedAt,
|
deletedAt: deletedAt,
|
||||||
messageText: text,
|
messageText: text,
|
||||||
|
pinned: pinned,
|
||||||
|
pinnedAt: pinnedAt,
|
||||||
|
pinExpires: pinExpires,
|
||||||
|
pinnedByUserId: pinnedBy?.id,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,81 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:stream_chat/stream_chat.dart';
|
||||||
|
import 'package:stream_chat_persistence/src/db/moor_chat_database.dart';
|
||||||
|
|
||||||
|
/// Useful mapping functions for [PinnedMessageEntity]
|
||||||
|
extension PinnedMessageEntityX on PinnedMessageEntity {
|
||||||
|
/// Maps a [PinnedMessageEntity] into [Message]
|
||||||
|
Message toMessage({
|
||||||
|
User user,
|
||||||
|
User pinnedBy,
|
||||||
|
List<Reaction> latestReactions,
|
||||||
|
List<Reaction> ownReactions,
|
||||||
|
Message quotedMessage,
|
||||||
|
}) {
|
||||||
|
return Message(
|
||||||
|
shadowed: shadowed,
|
||||||
|
latestReactions: latestReactions,
|
||||||
|
ownReactions: ownReactions,
|
||||||
|
attachments: attachments?.map((it) {
|
||||||
|
final json = jsonDecode(it);
|
||||||
|
return Attachment.fromData(json);
|
||||||
|
})?.toList(),
|
||||||
|
createdAt: createdAt,
|
||||||
|
extraData: extraData,
|
||||||
|
updatedAt: updatedAt,
|
||||||
|
id: id,
|
||||||
|
type: type,
|
||||||
|
status: status,
|
||||||
|
command: command,
|
||||||
|
parentId: parentId,
|
||||||
|
quotedMessageId: quotedMessageId,
|
||||||
|
quotedMessage: quotedMessage,
|
||||||
|
reactionCounts: reactionCounts,
|
||||||
|
reactionScores: reactionScores,
|
||||||
|
replyCount: replyCount,
|
||||||
|
showInChannel: showInChannel,
|
||||||
|
text: messageText,
|
||||||
|
user: user,
|
||||||
|
deletedAt: deletedAt,
|
||||||
|
pinned: pinned,
|
||||||
|
pinnedAt: pinnedAt,
|
||||||
|
pinExpires: pinExpires,
|
||||||
|
pinnedBy: pinnedBy,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Useful mapping functions for [Message]
|
||||||
|
extension PMessageX on Message {
|
||||||
|
/// Maps a [Message] into [PinnedMessageEntity]
|
||||||
|
PinnedMessageEntity toPinnedEntity({String cid}) {
|
||||||
|
return PinnedMessageEntity(
|
||||||
|
id: id,
|
||||||
|
attachments: attachments?.map((it) {
|
||||||
|
return jsonEncode(it.toData());
|
||||||
|
})?.toList(),
|
||||||
|
channelCid: cid,
|
||||||
|
type: type,
|
||||||
|
parentId: parentId,
|
||||||
|
quotedMessageId: quotedMessageId,
|
||||||
|
command: command,
|
||||||
|
createdAt: createdAt,
|
||||||
|
shadowed: shadowed,
|
||||||
|
showInChannel: showInChannel,
|
||||||
|
replyCount: replyCount,
|
||||||
|
reactionScores: reactionScores,
|
||||||
|
reactionCounts: reactionCounts,
|
||||||
|
status: status,
|
||||||
|
updatedAt: updatedAt,
|
||||||
|
extraData: extraData,
|
||||||
|
userId: user?.id,
|
||||||
|
deletedAt: deletedAt,
|
||||||
|
messageText: text,
|
||||||
|
pinned: pinned,
|
||||||
|
pinnedAt: pinnedAt,
|
||||||
|
pinExpires: pinExpires,
|
||||||
|
pinnedByUserId: pinnedBy?.id,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -81,11 +81,21 @@ class StreamChatPersistenceClient extends ChatPersistenceClient {
|
|||||||
return _db.messageDao.deleteMessageByIds(messageIds);
|
return _db.messageDao.deleteMessageByIds(messageIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> deletePinnedMessageByIds(List<String> messageIds) {
|
||||||
|
return _db.pinnedMessageDao.deleteMessageByIds(messageIds);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> deleteMessageByCids(List<String> cids) {
|
Future<void> deleteMessageByCids(List<String> cids) {
|
||||||
return _db.messageDao.deleteMessageByCids(cids);
|
return _db.messageDao.deleteMessageByCids(cids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> deletePinnedMessageByCids(List<String> cids) {
|
||||||
|
return _db.pinnedMessageDao.deleteMessageByCids(cids);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<Member>> getMembersByCid(String cid) {
|
Future<List<Member>> getMembersByCid(String cid) {
|
||||||
return _db.memberDao.getMembersByCid(cid);
|
return _db.memberDao.getMembersByCid(cid);
|
||||||
@@ -107,6 +117,17 @@ class StreamChatPersistenceClient extends ChatPersistenceClient {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<List<Message>> getPinnedMessagesByCid(
|
||||||
|
String cid, {
|
||||||
|
PaginationParams messagePagination,
|
||||||
|
}) {
|
||||||
|
return _db.pinnedMessageDao.getMessagesByCid(
|
||||||
|
cid,
|
||||||
|
messagePagination: messagePagination,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<Read>> getReadsByCid(String cid) {
|
Future<List<Read>> getReadsByCid(String cid) {
|
||||||
return _db.readDao.getReadsByCid(cid);
|
return _db.readDao.getReadsByCid(cid);
|
||||||
@@ -178,6 +199,11 @@ class StreamChatPersistenceClient extends ChatPersistenceClient {
|
|||||||
return _db.messageDao.updateMessages(cid, messages);
|
return _db.messageDao.updateMessages(cid, messages);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> updatePinnedMessages(String cid, List<Message> messages) {
|
||||||
|
return _db.pinnedMessageDao.updateMessages(cid, messages);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> updateReactions(List<Reaction> reactions) {
|
Future<void> updateReactions(List<Reaction> reactions) {
|
||||||
return _db.reactionDao.updateReactions(reactions);
|
return _db.reactionDao.updateReactions(reactions);
|
||||||
|
|||||||
@@ -13,7 +13,8 @@ dependencies:
|
|||||||
path: ^1.7.0
|
path: ^1.7.0
|
||||||
path_provider: ^1.6.27
|
path_provider: ^1.6.27
|
||||||
sqlite3_flutter_libs: ^0.4.0+1
|
sqlite3_flutter_libs: ^0.4.0+1
|
||||||
stream_chat: ^1.2.0-beta
|
stream_chat:
|
||||||
|
path: ../stream_chat
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
test: ^1.15.7
|
test: ^1.15.7
|
||||||
|
|||||||
Reference in New Issue
Block a user