forked from FoundKeyGang/FoundKey
Compare commits
3 commits
Author | SHA1 | Date | |
---|---|---|---|
1d653fdb0b | |||
46629a9884 | |||
457bd5ee3f |
10 changed files with 64 additions and 21 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`);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
import config from '../built/config/index.js';
|
||||||
|
|
||||||
|
export class remoteThreadIds1667212446191 {
|
||||||
|
name = 'remoteThreadIds1667212446191';
|
||||||
|
|
||||||
|
async up(queryRunner) {
|
||||||
|
await Promise.all([
|
||||||
|
queryRunner.query(`UPDATE "note" SET "threadId" = '${config.url}/notes/' + "threadId"`),
|
||||||
|
queryRunner.query(`UPDATE "note_thread_muting" SET "threadId" = '${config.url}/notes/' + "threadId"`),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
async down() {
|
||||||
|
// cannot be undone:
|
||||||
|
// after this migration other instances threadIds may be stored in the database
|
||||||
|
}
|
||||||
|
}
|
|
@ -51,7 +51,7 @@ export class Note {
|
||||||
@Column('varchar', {
|
@Column('varchar', {
|
||||||
length: 256, nullable: true,
|
length: 256, nullable: true,
|
||||||
})
|
})
|
||||||
public threadId: string | null;
|
public threadId: string;
|
||||||
|
|
||||||
@Column('text', {
|
@Column('text', {
|
||||||
nullable: true,
|
nullable: true,
|
||||||
|
|
|
@ -131,6 +131,7 @@ export default async function renderNote(note: Note, dive = true, isTalk = false
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: `${config.url}/notes/${note.id}`,
|
id: `${config.url}/notes/${note.id}`,
|
||||||
|
context: note.threadId,
|
||||||
type: 'Note',
|
type: 'Note',
|
||||||
attributedTo,
|
attributedTo,
|
||||||
summary,
|
summary,
|
||||||
|
|
|
@ -7,11 +7,7 @@ export function generateMutedNoteThreadQuery(q: SelectQueryBuilder<any>, me: { i
|
||||||
.select('threadMuted.threadId')
|
.select('threadMuted.threadId')
|
||||||
.where('threadMuted.userId = :userId', { userId: me.id });
|
.where('threadMuted.userId = :userId', { userId: me.id });
|
||||||
|
|
||||||
q.andWhere(`note.id NOT IN (${ mutedQuery.getQuery() })`);
|
q.andWhere(`note.threadId NOT IN (${ mutedQuery.getQuery() })`);
|
||||||
q.andWhere(new Brackets(qb => { qb
|
|
||||||
.where('note.threadId IS NULL')
|
|
||||||
.orWhere(`note.threadId NOT IN (${ mutedQuery.getQuery() })`);
|
|
||||||
}));
|
|
||||||
|
|
||||||
q.setParameters(mutedQuery.getParameters());
|
q.setParameters(mutedQuery.getParameters());
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
NoteThreadMutings.count({
|
NoteThreadMutings.count({
|
||||||
where: {
|
where: {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
threadId: note.threadId || note.id,
|
threadId: note.threadId,
|
||||||
},
|
},
|
||||||
take: 1,
|
take: 1,
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -41,9 +41,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
|
|
||||||
const mutedNotes = await Notes.find({
|
const mutedNotes = await Notes.find({
|
||||||
where: [{
|
where: [{
|
||||||
id: note.threadId || note.id,
|
threadId: note.threadId,
|
||||||
}, {
|
|
||||||
threadId: note.threadId || note.id,
|
|
||||||
}],
|
}],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -52,7 +50,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
await NoteThreadMutings.insert({
|
await NoteThreadMutings.insert({
|
||||||
id: genId(),
|
id: genId(),
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
threadId: note.threadId || note.id,
|
threadId: note.threadId,
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
mutingNotificationTypes: ps.mutingNotificationTypes,
|
mutingNotificationTypes: ps.mutingNotificationTypes,
|
||||||
});
|
});
|
||||||
|
|
|
@ -29,7 +29,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
await NoteThreadMutings.delete({
|
await NoteThreadMutings.delete({
|
||||||
threadId: note.threadId || note.id,
|
threadId: note.threadId,
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -369,7 +369,7 @@ export default async (user: { id: User['id']; username: User['username']; host:
|
||||||
if (data.reply.userHost === null) {
|
if (data.reply.userHost === null) {
|
||||||
const threadMuted = await NoteThreadMutings.findOneBy({
|
const threadMuted = await NoteThreadMutings.findOneBy({
|
||||||
userId: data.reply.userId,
|
userId: data.reply.userId,
|
||||||
threadId: data.reply.threadId || data.reply.id,
|
threadId: data.reply.threadId,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!threadMuted) {
|
if (!threadMuted) {
|
||||||
|
@ -500,15 +500,16 @@ function incRenoteCount(renote: Note): void {
|
||||||
|
|
||||||
async function insertNote(user: { id: User['id']; host: User['host']; }, data: Option, tags: string[], emojis: string[], mentionedUsers: MinimumUser[]): Promise<Note> {
|
async function insertNote(user: { id: User['id']; host: User['host']; }, data: Option, tags: string[], emojis: string[], mentionedUsers: MinimumUser[]): Promise<Note> {
|
||||||
const createdAt = data.createdAt ?? new Date();
|
const createdAt = data.createdAt ?? new Date();
|
||||||
|
const id = genId(createdAt);
|
||||||
|
|
||||||
const insert = new Note({
|
const insert = new Note({
|
||||||
id: genId(createdAt),
|
id,
|
||||||
createdAt,
|
createdAt,
|
||||||
fileIds: data.files?.map(file => file.id) ?? [],
|
fileIds: data.files ? data.files.map(file => file.id) : [],
|
||||||
replyId: data.reply?.id ?? null,
|
replyId: data.reply ? data.reply.id : null,
|
||||||
renoteId: data.renote?.id ?? null,
|
renoteId: data.renote ? data.renote.id : null,
|
||||||
channelId: data.channel?.id ?? null,
|
channelId: data.channel ? data.channel.id : null,
|
||||||
threadId: data.reply?.threadId ?? data.reply?.id ?? null,
|
threadId: data.reply?.threadId ?? `${config.url}/notes/${id}`,
|
||||||
name: data.name,
|
name: data.name,
|
||||||
text: data.text,
|
text: data.text,
|
||||||
hasPoll: data.poll != null,
|
hasPoll: data.poll != null,
|
||||||
|
@ -616,7 +617,7 @@ async function createMentionedEvents(mentionedUsers: MinimumUser[], note: Note,
|
||||||
for (const u of mentionedUsers.filter(u => Users.isLocalUser(u))) {
|
for (const u of mentionedUsers.filter(u => Users.isLocalUser(u))) {
|
||||||
const threadMuted = await NoteThreadMutings.findOneBy({
|
const threadMuted = await NoteThreadMutings.findOneBy({
|
||||||
userId: u.id,
|
userId: u.id,
|
||||||
threadId: note.threadId || note.id,
|
threadId: note.threadId,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (threadMuted) {
|
if (threadMuted) {
|
||||||
|
|
|
@ -20,7 +20,7 @@ export async function insertNoteUnread(userId: User['id'], note: Note, params: {
|
||||||
// スレッドミュート
|
// スレッドミュート
|
||||||
const threadMute = await NoteThreadMutings.findOneBy({
|
const threadMute = await NoteThreadMutings.findOneBy({
|
||||||
userId,
|
userId,
|
||||||
threadId: note.threadId || note.id,
|
threadId: note.threadId,
|
||||||
});
|
});
|
||||||
if (threadMute) return;
|
if (threadMute) return;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue