69b56f6658
* wip * wip * wip * ✌️ * add main stream * packedNotificationSchemaを更新 * read:gallery, write:gallery, read:gallery-likes, write:gallery-likesに翻訳を追加 * fix * ok * add header, choice, invitation * add header, choice, invitation * test * fix * fix * yatta * remove no longer needed "as PackedUser/PackedNote" * clean up * add simple-schema * fix lint * fix lint * wip * wip! * wip * fix * wip * wip * ✌️ * 送信側に型エラーがないことを3回確認した * ✌️ * wip * update typescript * define items in full Schema * edit comment * edit comment * edit comment * Update src/prelude/types.ts Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com> * https://github.com/misskey-dev/misskey/pull/7769#discussion_r703058458 * user packとnote packの型不整合を修正 * revert https://github.com/misskey-dev/misskey/pull/7772#discussion_r706627736 * revert https://github.com/misskey-dev/misskey/pull/7772#discussion_r706627736 * user packとnote packの型不整合を修正 * add prelude/types.ts * emoji * signin * game * matching * clean up * ev => data * refactor * clean up * add type * antenna * channel * fix * add Packed type * add PackedRef * fix lint * add emoji schema * add reversiGame * add reversiMatching * remove signin schema (use Signin entity) * add schemas refs, fix Packed type * wip PackedHoge => Packed<'Hoge'> * add Packed type * note-reaction * user * user-group * user-list * note * app, messaging-message * notification * drive-file * drive-folder * following * muting * blocking * hashtag * page * app (with modifying schema) * import user? * channel * antenna * clip * gallery-post * emoji * Packed * reversi-matching * update stream.ts * https://github.com/misskey-dev/misskey/pull/7769#issuecomment-917542339 * fix lint * clean up? * add changelog * add changelog * add changelog * fix: アンテナが既読にならないのを修正 * revert fix * https://github.com/misskey-dev/misskey/pull/7769#discussion_r711474875 * spec => payload * edit commetn Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com>
122 lines
3.8 KiB
TypeScript
122 lines
3.8 KiB
TypeScript
import { publishMainStream, publishGroupMessagingStream } from '@/services/stream';
|
|
import { publishMessagingStream } from '@/services/stream';
|
|
import { publishMessagingIndexStream } from '@/services/stream';
|
|
import { User, IRemoteUser } from '@/models/entities/user';
|
|
import { MessagingMessage } from '@/models/entities/messaging-message';
|
|
import { MessagingMessages, UserGroupJoinings, Users } from '@/models/index';
|
|
import { In } from 'typeorm';
|
|
import { IdentifiableError } from '@/misc/identifiable-error';
|
|
import { UserGroup } from '@/models/entities/user-group';
|
|
import { toArray } from '@/prelude/array';
|
|
import { renderReadActivity } from '@/remote/activitypub/renderer/read';
|
|
import { renderActivity } from '@/remote/activitypub/renderer/index';
|
|
import { deliver } from '@/queue/index';
|
|
import orderedCollection from '@/remote/activitypub/renderer/ordered-collection';
|
|
|
|
/**
|
|
* 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.find({
|
|
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');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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.findOne({
|
|
userId: userId,
|
|
userGroupId: groupId
|
|
});
|
|
|
|
if (joining == null) {
|
|
throw new IdentifiableError('930a270c-714a-46b2-b776-ad27276dc569', 'Access denied (group).');
|
|
}
|
|
|
|
const messages = await MessagingMessages.find({
|
|
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: userId
|
|
});
|
|
publishMessagingIndexStream(userId, 'read', reads);
|
|
|
|
if (!await Users.getHasUnreadMessagingMessage(userId)) {
|
|
// 全ての(いままで未読だった)自分宛てのメッセージを(これで)読みましたよというイベントを発行
|
|
publishMainStream(userId, 'readAllMessagingMessages');
|
|
}
|
|
}
|
|
|
|
export async function deliverReadActivity(user: { id: User['id']; host: null; }, recipient: IRemoteUser, messages: MessagingMessage | MessagingMessage[]) {
|
|
messages = toArray(messages).filter(x => x.uri);
|
|
const contents = messages.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);
|
|
}
|
|
}
|
|
}
|