fix (backend): fix scheduled reply/quote behavior

This commit is contained in:
naskya 2024-06-07 07:35:56 +09:00
parent d6bd3af8a9
commit 5daa113928
No known key found for this signature in database
GPG key ID: 712D413B3A9FED5C
2 changed files with 298 additions and 284 deletions

View file

@ -171,6 +171,9 @@ export default async (
const dontFederateInitially = const dontFederateInitially =
data.visibility?.startsWith("hidden") === true; data.visibility?.startsWith("hidden") === true;
// Whether this is a scheduled "draft" post (yet to be published)
const isDraft = data.scheduledAt != null;
// If you reply outside the channel, match the scope of the target. // If you reply outside the channel, match the scope of the target.
// TODO (I think it's a process that could be done on the client side, but it's server side for now.) // TODO (I think it's a process that could be done on the client side, but it's server side for now.)
if ( if (
@ -270,7 +273,7 @@ export default async (
data.text = data.text?.trim() ?? null; data.text = data.text?.trim() ?? null;
if (data.lang) { if (data.lang != null) {
if (!Object.keys(langmap).includes(data.lang.toLowerCase())) if (!Object.keys(langmap).includes(data.lang.toLowerCase()))
throw new Error("invalid param"); throw new Error("invalid param");
data.lang = data.lang.toLowerCase(); data.lang = data.lang.toLowerCase();
@ -314,7 +317,7 @@ export default async (
); );
} }
if (data.visibility === "specified") { if (!isDraft && data.visibility === "specified") {
if (data.visibleUsers == null) throw new Error("invalid param"); if (data.visibleUsers == null) throw new Error("invalid param");
for (const u of data.visibleUsers) { for (const u of data.visibleUsers) {
@ -352,6 +355,7 @@ export default async (
}); });
} }
if (!isDraft) {
// ハッシュタグ更新 // ハッシュタグ更新
if (data.visibility === "public" || data.visibility === "home") { if (data.visibility === "public" || data.visibility === "home") {
updateHashtags(user, tags); updateHashtags(user, tags);
@ -398,7 +402,7 @@ export default async (
} }
// Channel // Channel
if (note.channelId) { if (note.channelId != null) {
ChannelFollowings.findBy({ followeeId: note.channelId }).then( ChannelFollowings.findBy({ followeeId: note.channelId }).then(
(followings) => { (followings) => {
for (const following of followings) { for (const following of followings) {
@ -528,9 +532,11 @@ export default async (
await createMentionedEvents(mentionedUsers, note, nm); await createMentionedEvents(mentionedUsers, note, nm);
// If has in reply to note // If has in reply to note
if (data.reply) { if (data.reply != null) {
// Fetch watchers // Fetch watchers
nmRelatedPromises.push(notifyToWatchersOfReplyee(data.reply, user, nm)); nmRelatedPromises.push(
notifyToWatchersOfReplyee(data.reply, user, nm),
);
// 通知 // 通知
if (data.reply.userHost === null) { if (data.reply.userHost === null) {
@ -548,7 +554,8 @@ export default async (
publishMainStream(data.reply.userId, "reply", packedReply); publishMainStream(data.reply.userId, "reply", packedReply);
const webhooks = (await getActiveWebhooks()).filter( const webhooks = (await getActiveWebhooks()).filter(
(x) => x.userId === data.reply?.userId && x.on.includes("reply"), (x) =>
x.userId === data.reply?.userId && x.on.includes("reply"),
); );
for (const webhook of webhooks) { for (const webhook of webhooks) {
webhookDeliver(webhook, "reply", { webhookDeliver(webhook, "reply", {
@ -560,7 +567,7 @@ export default async (
} }
// If it is renote // If it is renote
if (data.renote) { if (data.renote != null) {
const type = data.text ? "quote" : "renote"; const type = data.text ? "quote" : "renote";
// Notify // Notify
@ -609,7 +616,9 @@ export default async (
const dm = new DeliverManager(user, noteActivity); const dm = new DeliverManager(user, noteActivity);
// メンションされたリモートユーザーに配送 // メンションされたリモートユーザーに配送
for (const u of mentionedUsers.filter((u) => Users.isRemoteUser(u))) { for (const u of mentionedUsers.filter((u) =>
Users.isRemoteUser(u),
)) {
dm.addDirectRecipe(u as IRemoteUser); dm.addDirectRecipe(u as IRemoteUser);
} }
@ -657,6 +666,7 @@ export default async (
} }
}); });
} }
}
}); });
async function renderNoteOrRenoteActivity(data: NoteLike, note: Note) { async function renderNoteOrRenoteActivity(data: NoteLike, note: Note) {

View file

@ -42,8 +42,12 @@ export default async function (
) { ) {
const deletedAt = new Date(); const deletedAt = new Date();
// Whether this is a scheduled "draft" post
const isDraft = note.scheduledAt != null;
// この投稿を除く指定したユーザーによる指定したノートのリノートが存在しないとき // この投稿を除く指定したユーザーによる指定したノートのリノートが存在しないとき
if ( if (
!isDraft &&
note.renoteId && note.renoteId &&
(await countSameRenotes(user.id, note.renoteId, note.id)) === 0 && (await countSameRenotes(user.id, note.renoteId, note.id)) === 0 &&
deleteFromDb deleteFromDb
@ -52,7 +56,7 @@ export default async function (
Notes.decrement({ id: note.renoteId }, "score", 1); Notes.decrement({ id: note.renoteId }, "score", 1);
} }
if (note.replyId && deleteFromDb) { if (!isDraft && note.replyId != null && deleteFromDb) {
await Notes.decrement({ id: note.replyId }, "repliesCount", 1); await Notes.decrement({ id: note.replyId }, "repliesCount", 1);
} }
@ -67,14 +71,14 @@ export default async function (
const instanceNotesCountDecreasement: Record<string, number> = {}; const instanceNotesCountDecreasement: Record<string, number> = {};
// Only broadcast "deleted" to local if the note is deleted from db // Only broadcast "deleted" to local if the note is deleted from db
if (deleteFromDb) { if (!isDraft && deleteFromDb) {
publishNoteStream(note.id, "deleted", { publishNoteStream(note.id, "deleted", {
deletedAt: deletedAt, deletedAt: deletedAt,
}); });
} }
//#region ローカルの投稿なら削除アクティビティを配送 //#region ローカルの投稿なら削除アクティビティを配送
if (Users.isLocalUser(user) && !note.localOnly) { if (!isDraft && Users.isLocalUser(user) && !note.localOnly) {
let renote: Note | null = null; let renote: Note | null = null;
// if deletd note is renote // if deletd note is renote