From d76fceae855385ee2a9394ab69058efab169eab1 Mon Sep 17 00:00:00 2001 From: syuilo Date: Thu, 13 Feb 2020 22:13:24 +0900 Subject: [PATCH] Fix #5935 --- CHANGELOG.md | 1 + src/server/api/endpoints/notes/global-timeline.ts | 13 +++++++++++++ src/server/api/endpoints/notes/hybrid-timeline.ts | 12 ++++++++++++ src/server/api/endpoints/notes/local-timeline.ts | 12 ++++++++++++ src/server/api/endpoints/notes/timeline.ts | 12 ++++++++++++ src/server/api/stream/channels/global-timeline.ts | 6 ++++++ src/server/api/stream/channels/home-timeline.ts | 6 ++++++ src/server/api/stream/channels/hybrid-timeline.ts | 6 ++++++ src/server/api/stream/channels/local-timeline.ts | 6 ++++++ 9 files changed, 74 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 79fd22722..157c89507 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ChangeLog unreleased ------------------- ### 🐛Fixes +* タイムラインに自分の返信と自分への返信と投稿者自身への返信以外の返信が含まれている問題を修正 * グループがない状態でグループチャットを開始しようとするとフリーズする問題を修正 12.8.0 (2020/02/13) diff --git a/src/server/api/endpoints/notes/global-timeline.ts b/src/server/api/endpoints/notes/global-timeline.ts index 8654cf889..15f495576 100644 --- a/src/server/api/endpoints/notes/global-timeline.ts +++ b/src/server/api/endpoints/notes/global-timeline.ts @@ -7,6 +7,7 @@ import { makePaginationQuery } from '../../common/make-pagination-query'; import { Notes } from '../../../../models'; import { generateMuteQuery } from '../../common/generate-mute-query'; import { activeUsersChart } from '../../../../services/chart'; +import { Brackets } from 'typeorm'; export const meta = { desc: { @@ -77,6 +78,18 @@ export default define(meta, async (ps, user) => { ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('note.visibility = \'public\'') .andWhere('note.replyId IS NULL') + .andWhere(new Brackets(qb => { qb + .where(`note.replyId IS NULL`) // 返信ではない + .orWhere('note.replyUserId = :meId', { meId: user.id }) // 返信だけど自分のノートへの返信 + .orWhere(new Brackets(qb => { qb // 返信だけど自分の行った返信 + .where(`note.replyId IS NOT NULL`) + .andWhere('note.userId = :meId', { meId: user.id }); + })) + .orWhere(new Brackets(qb => { qb // 返信だけど投稿者自身への返信 + .where(`note.replyId IS NOT NULL`) + .andWhere('note.replyUserId = note.userId', { meId: user.id }); + })); + })) .leftJoinAndSelect('note.user', 'user'); if (user) generateMuteQuery(query, user); diff --git a/src/server/api/endpoints/notes/hybrid-timeline.ts b/src/server/api/endpoints/notes/hybrid-timeline.ts index 4d0ac2fed..4ff8e65e3 100644 --- a/src/server/api/endpoints/notes/hybrid-timeline.ts +++ b/src/server/api/endpoints/notes/hybrid-timeline.ts @@ -124,6 +124,18 @@ export default define(meta, async (ps, user) => { qb.where(`((note.userId IN (${ followingQuery.getQuery() })) OR (note.userId = :meId))`, { meId: user.id }) .orWhere('(note.visibility = \'public\') AND (note.userHost IS NULL)'); })) + .andWhere(new Brackets(qb => { qb + .where(`note.replyId IS NULL`) // 返信ではない + .orWhere('note.replyUserId = :meId', { meId: user.id }) // 返信だけど自分のノートへの返信 + .orWhere(new Brackets(qb => { qb // 返信だけど自分の行った返信 + .where(`note.replyId IS NOT NULL`) + .andWhere('note.userId = :meId', { meId: user.id }); + })) + .orWhere(new Brackets(qb => { qb // 返信だけど投稿者自身への返信 + .where(`note.replyId IS NOT NULL`) + .andWhere('note.replyUserId = note.userId', { meId: user.id }); + })); + })) .leftJoinAndSelect('note.user', 'user') .setParameters(followingQuery.getParameters()); diff --git a/src/server/api/endpoints/notes/local-timeline.ts b/src/server/api/endpoints/notes/local-timeline.ts index 9fae40ecb..71ebceb0e 100644 --- a/src/server/api/endpoints/notes/local-timeline.ts +++ b/src/server/api/endpoints/notes/local-timeline.ts @@ -93,6 +93,18 @@ export default define(meta, async (ps, user) => { const query = makePaginationQuery(Notes.createQueryBuilder('note'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('(note.visibility = \'public\') AND (note.userHost IS NULL)') + .andWhere(new Brackets(qb => { qb + .where(`note.replyId IS NULL`) // 返信ではない + .orWhere('note.replyUserId = :meId', { meId: user.id }) // 返信だけど自分のノートへの返信 + .orWhere(new Brackets(qb => { qb // 返信だけど自分の行った返信 + .where(`note.replyId IS NOT NULL`) + .andWhere('note.userId = :meId', { meId: user.id }); + })) + .orWhere(new Brackets(qb => { qb // 返信だけど投稿者自身への返信 + .where(`note.replyId IS NOT NULL`) + .andWhere('note.replyUserId = note.userId', { meId: user.id }); + })); + })) .leftJoinAndSelect('note.user', 'user'); generateVisibilityQuery(query, user); diff --git a/src/server/api/endpoints/notes/timeline.ts b/src/server/api/endpoints/notes/timeline.ts index b2fb250c5..1cf8cc4d1 100644 --- a/src/server/api/endpoints/notes/timeline.ts +++ b/src/server/api/endpoints/notes/timeline.ts @@ -110,6 +110,18 @@ export default define(meta, async (ps, user) => { .where(`note.userId IN (${ followingQuery.getQuery() })`) .orWhere('note.userId = :meId', { meId: user.id }); })) + .andWhere(new Brackets(qb => { qb + .where(`note.replyId IS NULL`) // 返信ではない + .orWhere('note.replyUserId = :meId', { meId: user.id }) // 返信だけど自分のノートへの返信 + .orWhere(new Brackets(qb => { qb // 返信だけど自分の行った返信 + .where(`note.replyId IS NOT NULL`) + .andWhere('note.userId = :meId', { meId: user.id }); + })) + .orWhere(new Brackets(qb => { qb // 返信だけど投稿者自身への返信 + .where(`note.replyId IS NOT NULL`) + .andWhere('note.replyUserId = note.userId', { meId: user.id }); + })); + })) .leftJoinAndSelect('note.user', 'user') .setParameters(followingQuery.getParameters()); diff --git a/src/server/api/stream/channels/global-timeline.ts b/src/server/api/stream/channels/global-timeline.ts index 1271aae3a..a3ecf8e70 100644 --- a/src/server/api/stream/channels/global-timeline.ts +++ b/src/server/api/stream/channels/global-timeline.ts @@ -38,6 +38,12 @@ export default class extends Channel { }); } + // 関係ない返信は除外 + if (note.reply) { + // 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合 + if (note.reply.userId !== this.user!.id && note.userId !== this.user!.id && note.reply.userId !== note.userId) return; + } + // 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する if (shouldMuteThisNote(note, this.muting)) return; diff --git a/src/server/api/stream/channels/home-timeline.ts b/src/server/api/stream/channels/home-timeline.ts index 9aa4dc1c0..3cf57c294 100644 --- a/src/server/api/stream/channels/home-timeline.ts +++ b/src/server/api/stream/channels/home-timeline.ts @@ -43,6 +43,12 @@ export default class extends Channel { } } + // 関係ない返信は除外 + if (note.reply) { + // 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合 + if (note.reply.userId !== this.user!.id && note.userId !== this.user!.id && note.reply.userId !== note.userId) return; + } + // 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する if (shouldMuteThisNote(note, this.muting)) return; diff --git a/src/server/api/stream/channels/hybrid-timeline.ts b/src/server/api/stream/channels/hybrid-timeline.ts index e32f4111c..40686f4b2 100644 --- a/src/server/api/stream/channels/hybrid-timeline.ts +++ b/src/server/api/stream/channels/hybrid-timeline.ts @@ -52,6 +52,12 @@ export default class extends Channel { } } + // 関係ない返信は除外 + if (note.reply) { + // 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合 + if (note.reply.userId !== this.user!.id && note.userId !== this.user!.id && note.reply.userId !== note.userId) return; + } + // 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する if (shouldMuteThisNote(note, this.muting)) return; diff --git a/src/server/api/stream/channels/local-timeline.ts b/src/server/api/stream/channels/local-timeline.ts index e31e5c59c..4b7f74e4f 100644 --- a/src/server/api/stream/channels/local-timeline.ts +++ b/src/server/api/stream/channels/local-timeline.ts @@ -40,6 +40,12 @@ export default class extends Channel { }); } + // 関係ない返信は除外 + if (note.reply) { + // 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合 + if (note.reply.userId !== this.user!.id && note.userId !== this.user!.id && note.reply.userId !== note.userId) return; + } + // 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する if (shouldMuteThisNote(note, this.muting)) return;