Compare commits
2 commits
Author | SHA1 | Date | |
---|---|---|---|
1dd0b6aece | |||
9384ce8cf5 |
9 changed files with 44 additions and 20 deletions
30
packages/backend/migration/1659446758000-fix-thread-id.js
Normal file
30
packages/backend/migration/1659446758000-fix-thread-id.js
Normal file
|
@ -0,0 +1,30 @@
|
|||
export class fixThreadId1659446758000 {
|
||||
name = 'fixThreadId1659446758000'
|
||||
|
||||
async up(queryRunner) {
|
||||
await Promise.all([
|
||||
queryRunner.query(`UPDATE "note" SET "threadId" = "id" WHERE "replyId" IS NULL`),
|
||||
queryRunner.query(`WITH "threads" ("noteId", "thread") AS (
|
||||
SELECT "id" as "noteId", "parent" as "thread" FROM (
|
||||
WITH RECURSIVE "parents" ("id", "parent", "height") AS (
|
||||
SELECT "id", "replyId", 0 FROM "note" WHERE "replyId" IS NOT NULL AND "threadId" IS NULL
|
||||
UNION ALL
|
||||
SELECT "parents"."id", "note"."replyId", "parents"."height" + 1
|
||||
FROM "parents"
|
||||
JOIN "note" ON "parents"."parent" = "note"."id"
|
||||
WHERE "note"."replyId" IS NOT NULL
|
||||
) SELECT *, MAX("height") OVER (PARTITION BY "id") AS "maxheight" FROM "parents"
|
||||
) AS "x"
|
||||
WHERE "height" = "maxheight"
|
||||
) UPDATE "note" SET "threadId" = "threads"."thread" FROM "threads" WHERE "id" = "threads"."noteId"`),
|
||||
]);
|
||||
await queryRunner.query(`ALTER TABLE "note" ALTER COLUMN "threadId" SET NOT NULL`);
|
||||
}
|
||||
|
||||
async down(queryRunner) {
|
||||
await queryRunner.query(`ALTER TABLE "note" ALTER COLUMN "threaadId" DROP NOT NULL`);
|
||||
// Cannot un-fix thread id's for ones that just were not migrated (2nd query above)
|
||||
// but can remove the thread ids for the root notes of each thread.
|
||||
await queryRunner.query(`UPDATE "note" SET "threadId" = NULL WHERE "replyId" IS NULL`);
|
||||
}
|
||||
}
|
|
@ -51,7 +51,7 @@ export class Note {
|
|||
@Column('varchar', {
|
||||
length: 256, nullable: true,
|
||||
})
|
||||
public threadId: string | null;
|
||||
public threadId: string;
|
||||
|
||||
@Column('text', {
|
||||
nullable: true,
|
||||
|
|
|
@ -132,6 +132,7 @@ export default async function renderNote(note: Note, dive = true, isTalk = false
|
|||
|
||||
return {
|
||||
id: `${config.url}/notes/${note.id}`,
|
||||
context: `${config.url}/notes/${note.threadId}`,
|
||||
type: 'Note',
|
||||
attributedTo,
|
||||
summary,
|
||||
|
|
|
@ -8,10 +8,7 @@ export function generateMutedNoteThreadQuery(q: SelectQueryBuilder<any>, me: { i
|
|||
.where('threadMuted.userId = :userId', { userId: me.id });
|
||||
|
||||
q.andWhere(`note.id NOT IN (${ mutedQuery.getQuery() })`);
|
||||
q.andWhere(new Brackets(qb => { qb
|
||||
.where(`note.threadId IS NULL`)
|
||||
.orWhere(`note.threadId NOT IN (${ mutedQuery.getQuery() })`);
|
||||
}));
|
||||
q.andWhere(`note.threadId NOT IN (${ mutedQuery.getQuery() })`);
|
||||
|
||||
q.setParameters(mutedQuery.getParameters());
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
NoteThreadMutings.count({
|
||||
where: {
|
||||
userId: user.id,
|
||||
threadId: note.threadId || note.id,
|
||||
threadId: note.threadId,
|
||||
},
|
||||
take: 1,
|
||||
}),
|
||||
|
|
|
@ -38,9 +38,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
|
||||
const mutedNotes = await Notes.find({
|
||||
where: [{
|
||||
id: note.threadId || note.id,
|
||||
}, {
|
||||
threadId: note.threadId || note.id,
|
||||
threadId: note.threadId,
|
||||
}],
|
||||
});
|
||||
|
||||
|
@ -49,7 +47,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
await NoteThreadMutings.insert({
|
||||
id: genId(),
|
||||
createdAt: new Date(),
|
||||
threadId: note.threadId || note.id,
|
||||
threadId: note.threadId,
|
||||
userId: user.id,
|
||||
});
|
||||
});
|
||||
|
|
|
@ -35,7 +35,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
});
|
||||
|
||||
await NoteThreadMutings.delete({
|
||||
threadId: note.threadId || note.id,
|
||||
threadId: note.threadId,
|
||||
userId: user.id,
|
||||
});
|
||||
});
|
||||
|
|
|
@ -364,7 +364,7 @@ export default async (user: { id: User['id']; username: User['username']; host:
|
|||
if (data.reply.userHost === null) {
|
||||
const threadMuted = await NoteThreadMutings.findOneBy({
|
||||
userId: data.reply.userId,
|
||||
threadId: data.reply.threadId || data.reply.id,
|
||||
threadId: data.reply.threadId,
|
||||
});
|
||||
|
||||
if (!threadMuted) {
|
||||
|
@ -494,18 +494,16 @@ function incRenoteCount(renote: Note) {
|
|||
}
|
||||
|
||||
async function insertNote(user: { id: User['id']; host: User['host']; }, data: Option, tags: string[], emojis: string[], mentionedUsers: MinimumUser[]) {
|
||||
const id = genId(data.createdAt!);
|
||||
|
||||
const insert = new Note({
|
||||
id: genId(data.createdAt!),
|
||||
id,
|
||||
createdAt: data.createdAt!,
|
||||
fileIds: data.files ? data.files.map(file => file.id) : [],
|
||||
replyId: data.reply ? data.reply.id : null,
|
||||
renoteId: data.renote ? data.renote.id : null,
|
||||
channelId: data.channel ? data.channel.id : null,
|
||||
threadId: data.reply
|
||||
? data.reply.threadId
|
||||
? data.reply.threadId
|
||||
: data.reply.id
|
||||
: null,
|
||||
threadId: data.reply?.threadId ?? id,
|
||||
name: data.name,
|
||||
text: data.text,
|
||||
hasPoll: data.poll != null,
|
||||
|
@ -628,7 +626,7 @@ async function createMentionedEvents(mentionedUsers: MinimumUser[], note: Note,
|
|||
for (const u of mentionedUsers.filter(u => Users.isLocalUser(u))) {
|
||||
const threadMuted = await NoteThreadMutings.findOneBy({
|
||||
userId: u.id,
|
||||
threadId: note.threadId || note.id,
|
||||
threadId: note.threadId,
|
||||
});
|
||||
|
||||
if (threadMuted) {
|
||||
|
|
|
@ -20,7 +20,7 @@ export async function insertNoteUnread(userId: User['id'], note: Note, params: {
|
|||
// スレッドミュート
|
||||
const threadMute = await NoteThreadMutings.findOneBy({
|
||||
userId: userId,
|
||||
threadId: note.threadId || note.id,
|
||||
threadId: note.threadId,
|
||||
});
|
||||
if (threadMute) return;
|
||||
|
||||
|
|
Loading…
Reference in a new issue