FoundKey/packages/backend/src/server/api/common/read-messaging-message.ts
Johann150 6ce4b3fe2f
fix some lints
Many of these were fixed automatically with eslint --fix.

Some of them (e.g. adding return types to functions) were done manually.
2022-08-11 00:09:29 +02:00

151 lines
4.9 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';
import { renderReadActivity } from '@/remote/activitypub/renderer/read.js';
import { renderActivity } from '@/remote/activitypub/renderer/index.js';
import { deliver } from '@/queue/index.js';
import orderedCollection from '@/remote/activitypub/renderer/ordered-collection.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 });
}
}
}
export async function deliverReadActivity(user: { id: User['id']; host: null; }, recipient: IRemoteUser, messages: MessagingMessage | MessagingMessage[]) {
const contents = toArray(messages)
.filter(x => x.uri)
.map(x => renderReadActivity(user, x));
if (contents.length > 1) {
const collection = orderedCollection(null, contents.length, undefined, undefined, contents);
deliver(user, renderActivity(collection), recipient.inbox);
} else {
for (const content of contents) {
deliver(user, renderActivity(content), recipient.inbox);
}
}
}