[Persistence] Add support for pinned messages
Signed-off-by: Sahil Kumar <[email protected]>
This commit is contained in:
@@ -101,12 +101,14 @@ class ChannelQueryDao extends DatabaseAccessor<MoorChatDatabase>
|
||||
final members = await _db.memberDao.getMembersByCid(cid);
|
||||
final reads = await _db.readDao.getReadsByCid(cid);
|
||||
final messages = await _db.messageDao.getMessagesByCid(cid);
|
||||
final pinnedMessages = await _db.pinnedMessageDao.getMessagesByCid(cid);
|
||||
|
||||
return channelEntity.toChannelState(
|
||||
createdBy: userEntity?.toUser(),
|
||||
members: members,
|
||||
reads: reads,
|
||||
messages: messages,
|
||||
pinnedMessages: pinnedMessages,
|
||||
);
|
||||
}).get();
|
||||
}));
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
export 'user_dao.dart';
|
||||
export 'channel_dao.dart';
|
||||
export 'message_dao.dart';
|
||||
export 'pinned_message_dao.dart';
|
||||
export 'member_dao.dart';
|
||||
export 'connection_event_dao.dart';
|
||||
export 'reaction_dao.dart';
|
||||
|
||||
@@ -17,6 +17,10 @@ class MessageDao extends DatabaseAccessor<MoorChatDatabase>
|
||||
|
||||
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]
|
||||
///
|
||||
/// This will automatically delete the following linked records
|
||||
@@ -34,7 +38,8 @@ class MessageDao extends DatabaseAccessor<MoorChatDatabase>
|
||||
}
|
||||
|
||||
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 latestReactions = await _db.reactionDao.getReactions(msgEntity.id);
|
||||
final ownReactions = await _db.reactionDao.getReactionsByUserId(
|
||||
@@ -47,6 +52,7 @@ class MessageDao extends DatabaseAccessor<MoorChatDatabase>
|
||||
}
|
||||
return msgEntity.toMessage(
|
||||
user: userEntity?.toUser(),
|
||||
pinnedBy: pinnedByEntity?.toUser(),
|
||||
latestReactions: latestReactions,
|
||||
ownReactions: ownReactions,
|
||||
quotedMessage: quotedMessage,
|
||||
@@ -56,7 +62,9 @@ class MessageDao extends DatabaseAccessor<MoorChatDatabase>
|
||||
/// Returns a single message by matching the [Messages.id] with [id]
|
||||
Future<Message> getMessageById(String id) async {
|
||||
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)))
|
||||
.map(_messageFromJoinRow)
|
||||
@@ -67,7 +75,9 @@ class MessageDao extends DatabaseAccessor<MoorChatDatabase>
|
||||
/// [Messages.channelCid] with [cid]
|
||||
Future<List<Message>> getThreadMessages(String cid) async {
|
||||
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(isNotNull(messages.parentId))
|
||||
@@ -83,7 +93,9 @@ class MessageDao extends DatabaseAccessor<MoorChatDatabase>
|
||||
PaginationParams options,
|
||||
}) async {
|
||||
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))
|
||||
..orderBy([OrderingTerm.asc(messages.createdAt)]))
|
||||
@@ -104,7 +116,9 @@ class MessageDao extends DatabaseAccessor<MoorChatDatabase>
|
||||
PaginationParams messagePagination,
|
||||
}) async {
|
||||
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(
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user