Johann150
d292f035aa
Prospectively, the messaging messages will be removed as objects so it does not make sense to refactor this to match the remainder of refactoring away the user from deliver. It is just easier to remove this use of delivering something that is not an activity. Changelog: Removed
132 lines
4.1 KiB
TypeScript
132 lines
4.1 KiB
TypeScript
import { In } from 'typeorm';
|
|
import { publishMainStream, publishMessagingStream, publishMessagingIndexStream, publishGroupMessagingStream } from '@/services/stream.js';
|
|
import { pushNotification } from '@/services/push-notification.js';
|
|
import { User, IRemoteUser } from '@/models/entities/user.js';
|
|
import { MessagingMessage } from '@/models/entities/messaging-message.js';
|
|
import { MessagingMessages, UserGroupJoinings, Users } from '@/models/index.js';
|
|
import { IdentifiableError } from '@/misc/identifiable-error.js';
|
|
import { UserGroup } from '@/models/entities/user-group.js';
|
|
import { toArray } from '@/prelude/array.js';
|
|
|
|
/**
|
|
* Mark messages as read
|
|
*/
|
|
export async function readUserMessagingMessage(
|
|
userId: User['id'],
|
|
otherpartyId: User['id'],
|
|
messageIds: MessagingMessage['id'][],
|
|
) {
|
|
if (messageIds.length === 0) return;
|
|
|
|
const messages = await MessagingMessages.findBy({
|
|
id: In(messageIds),
|
|
});
|
|
|
|
for (const message of messages) {
|
|
if (message.recipientId !== userId) {
|
|
throw new IdentifiableError('e140a4bf-49ce-4fb6-b67c-b78dadf6b52f', 'Access denied (user).');
|
|
}
|
|
}
|
|
|
|
// Update documents
|
|
await MessagingMessages.update({
|
|
id: In(messageIds),
|
|
userId: otherpartyId,
|
|
recipientId: userId,
|
|
isRead: false,
|
|
}, {
|
|
isRead: true,
|
|
});
|
|
|
|
// Publish event
|
|
publishMessagingStream(otherpartyId, userId, 'read', messageIds);
|
|
publishMessagingIndexStream(userId, 'read', messageIds);
|
|
|
|
if (!await Users.getHasUnreadMessagingMessage(userId)) {
|
|
// 全ての(いままで未読だった)自分宛てのメッセージを(これで)読みましたよというイベントを発行
|
|
publishMainStream(userId, 'readAllMessagingMessages');
|
|
pushNotification(userId, 'readAllMessagingMessages', undefined);
|
|
} else {
|
|
// そのユーザーとのメッセージで未読がなければイベント発行
|
|
const count = await MessagingMessages.count({
|
|
where: {
|
|
userId: otherpartyId,
|
|
recipientId: userId,
|
|
isRead: false,
|
|
},
|
|
take: 1,
|
|
});
|
|
|
|
if (!count) {
|
|
pushNotification(userId, 'readAllMessagingMessagesOfARoom', { userId: otherpartyId });
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Mark messages as read
|
|
*/
|
|
export async function readGroupMessagingMessage(
|
|
userId: User['id'],
|
|
groupId: UserGroup['id'],
|
|
messageIds: MessagingMessage['id'][],
|
|
) {
|
|
if (messageIds.length === 0) return;
|
|
|
|
// check joined
|
|
const joining = await UserGroupJoinings.findOneBy({
|
|
userId,
|
|
userGroupId: groupId,
|
|
});
|
|
|
|
if (joining == null) {
|
|
throw new IdentifiableError('930a270c-714a-46b2-b776-ad27276dc569', 'Access denied (group).');
|
|
}
|
|
|
|
const messages = await MessagingMessages.findBy({
|
|
id: In(messageIds),
|
|
});
|
|
|
|
const reads: MessagingMessage['id'][] = [];
|
|
|
|
for (const message of messages) {
|
|
if (message.userId === userId) continue;
|
|
if (message.reads.includes(userId)) continue;
|
|
|
|
// Update document
|
|
await MessagingMessages.createQueryBuilder().update()
|
|
.set({
|
|
reads: (() => `array_append("reads", '${joining.userId}')`) as any,
|
|
})
|
|
.where('id = :id', { id: message.id })
|
|
.execute();
|
|
|
|
reads.push(message.id);
|
|
}
|
|
|
|
// Publish event
|
|
publishGroupMessagingStream(groupId, 'read', {
|
|
ids: reads,
|
|
userId,
|
|
});
|
|
publishMessagingIndexStream(userId, 'read', reads);
|
|
|
|
if (!await Users.getHasUnreadMessagingMessage(userId)) {
|
|
// 全ての(いままで未読だった)自分宛てのメッセージを(これで)読みましたよというイベントを発行
|
|
publishMainStream(userId, 'readAllMessagingMessages');
|
|
pushNotification(userId, 'readAllMessagingMessages', undefined);
|
|
} else {
|
|
// そのグループにおいて未読がなければイベント発行
|
|
const unreadExist = await MessagingMessages.createQueryBuilder('message')
|
|
.where('message.groupId = :groupId', { groupId })
|
|
.andWhere('message.userId != :userId', { userId })
|
|
.andWhere('NOT (:userId = ANY(message.reads))', { userId })
|
|
.andWhere('message.createdAt > :joinedAt', { joinedAt: joining.createdAt }) // 自分が加入する前の会話については、未読扱いしない
|
|
.getOne().then(x => x != null);
|
|
|
|
if (!unreadExist) {
|
|
pushNotification(userId, 'readAllMessagingMessagesOfARoom', { groupId });
|
|
}
|
|
}
|
|
}
|