diff --git a/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts b/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts index 01adfec7d3..fab835fa74 100644 --- a/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts @@ -43,12 +43,6 @@ export const meta = { code: 'STL_DISABLED', id: '620763f4-f621-4533-ab33-0577a1a3c342', }, - - bothWithRepliesAndWithFiles: { - message: 'Specifying both withReplies and withFiles is not supported', - code: 'BOTH_WITH_REPLIES_AND_WITH_FILES', - id: 'dfaa3eb7-8002-4cb7-bcc4-1095df46656f' - }, }, } as const; @@ -99,8 +93,6 @@ export default class extends Endpoint { // eslint- throw new ApiError(meta.errors.stlDisabled); } - if (ps.withReplies && ps.withFiles) throw new ApiError(meta.errors.bothWithRepliesAndWithFiles); - const serverSettings = await this.metaService.fetch(); if (!serverSettings.enableFanoutTimeline) { @@ -123,23 +115,12 @@ export default class extends Endpoint { // eslint- } let timelineConfig: FanoutTimelineName[]; - if (ps.withFiles) { - timelineConfig = [ - `homeTimelineWithFiles:${me.id}`, - 'localTimelineWithFiles', - ]; + timelineConfig = [`homeTimelineWithFiles:${me.id}`, 'localTimelineWithFiles']; } else if (ps.withReplies) { - timelineConfig = [ - `homeTimeline:${me.id}`, - 'localTimeline', - 'localTimelineWithReplies', - ]; + timelineConfig = [`homeTimeline:${me.id}`, 'localTimeline', 'localTimelineWithReplies']; } else { - timelineConfig = [ - `homeTimeline:${me.id}`, - 'localTimeline', - ]; + timelineConfig = [`homeTimeline:${me.id}`, 'localTimeline']; } const redisTimeline = await this.fanoutTimelineEndpointService.timeline({ diff --git a/packages/backend/src/server/api/endpoints/notes/local-timeline.ts b/packages/backend/src/server/api/endpoints/notes/local-timeline.ts index 3fd4dc83fb..375917eb0a 100644 --- a/packages/backend/src/server/api/endpoints/notes/local-timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/local-timeline.ts @@ -18,6 +18,7 @@ import { MetaService } from '@/core/MetaService.js'; import { MiLocalUser } from '@/models/User.js'; import { FanoutTimelineEndpointService } from '@/core/FanoutTimelineEndpointService.js'; import { ApiError } from '../../error.js'; +import { FanoutTimelineName } from "@/core/FanoutTimelineService.js"; export const meta = { tags: ['notes'], @@ -38,12 +39,6 @@ export const meta = { code: 'LTL_DISABLED', id: '45a6eb02-7695-4393-b023-dd3be9aaaefd', }, - - bothWithRepliesAndWithFiles: { - message: 'Specifying both withReplies and withFiles is not supported', - code: 'BOTH_WITH_REPLIES_AND_WITH_FILES', - id: 'dd9c8400-1cb5-4eef-8a31-200c5f933793', - }, }, } as const; @@ -87,8 +82,6 @@ export default class extends Endpoint { // eslint- throw new ApiError(meta.errors.ltlDisabled); } - if (ps.withReplies && ps.withFiles) throw new ApiError(meta.errors.bothWithRepliesAndWithFiles); - const serverSettings = await this.metaService.fetch(); if (!serverSettings.enableFanoutTimeline) { @@ -109,6 +102,17 @@ export default class extends Endpoint { // eslint- return await this.noteEntityService.packMany(timeline, me); } + let timelineConfig: FanoutTimelineName[]; + if (ps.withFiles) { + timelineConfig = ['localTimelineWithFiles']; + } else if (ps.withReplies) { + timelineConfig = ['localTimeline', 'localTimelineWithReplies']; + } else if (me) { + timelineConfig = ['localTimeline', `localTimelineWithReplyTo:${me.id}`]; + } else { + timelineConfig = ['localTimeline']; + } + const timeline = await this.fanoutTimelineEndpointService.timeline({ untilId, sinceId, @@ -116,11 +120,7 @@ export default class extends Endpoint { // eslint- allowPartial: ps.allowPartial, me, useDbFallback: serverSettings.enableFanoutTimelineDbFallback, - redisTimelines: - ps.withFiles ? ['localTimelineWithFiles'] - : ps.withReplies ? ['localTimeline', 'localTimelineWithReplies'] - : me ? ['localTimeline', `localTimelineWithReplyTo:${me.id}`] - : ['localTimeline'], + redisTimelines: timelineConfig, alwaysIncludeMyNotes: true, excludePureRenotes: !ps.withRenotes, dbFallback: async (untilId, sinceId, limit) => await this.getFromDb({ diff --git a/packages/backend/src/server/api/endpoints/users/notes.ts b/packages/backend/src/server/api/endpoints/users/notes.ts index 0ed5959bf0..b9ecc0efa6 100644 --- a/packages/backend/src/server/api/endpoints/users/notes.ts +++ b/packages/backend/src/server/api/endpoints/users/notes.ts @@ -16,7 +16,6 @@ import { MetaService } from '@/core/MetaService.js'; import { MiLocalUser } from '@/models/User.js'; import { FanoutTimelineEndpointService } from '@/core/FanoutTimelineEndpointService.js'; import { FanoutTimelineName } from '@/core/FanoutTimelineService.js'; -import { ApiError } from '@/server/api/error.js'; export const meta = { tags: ['users', 'notes'], @@ -37,12 +36,6 @@ export const meta = { code: 'NO_SUCH_USER', id: '27e494ba-2ac2-48e8-893b-10d4d8c2387b', }, - - bothWithRepliesAndWithFiles: { - message: 'Specifying both withReplies and withFiles is not supported', - code: 'BOTH_WITH_REPLIES_AND_WITH_FILES', - id: '91c8cb9f-36ed-46e7-9ca2-7df96ed6e222', - }, }, } as const; @@ -84,8 +77,6 @@ export default class extends Endpoint { // eslint- const serverSettings = await this.metaService.fetch(); - if (ps.withReplies && ps.withFiles) throw new ApiError(meta.errors.bothWithRepliesAndWithFiles); - // early return if me is blocked by requesting user if (me != null) { const userIdsWhoBlockingMe = await this.cacheService.userBlockedCache.fetch(me.id); diff --git a/packages/backend/src/server/api/stream/channels/global-timeline.ts b/packages/backend/src/server/api/stream/channels/global-timeline.ts index ddc74566bb..fb43be412a 100644 --- a/packages/backend/src/server/api/stream/channels/global-timeline.ts +++ b/packages/backend/src/server/api/stream/channels/global-timeline.ts @@ -19,7 +19,6 @@ class GlobalTimelineChannel extends Channel { public static shouldShare = false; public static requireCredential = false as const; private withRenotes: boolean; - private withReplies: boolean; private withFiles: boolean; constructor( @@ -40,7 +39,6 @@ class GlobalTimelineChannel extends Channel { if (!policies.gtlAvailable) return; this.withRenotes = params.withRenotes ?? true; - this.withReplies = params.withReplies ?? false; this.withFiles = params.withFiles ?? false; // Subscribe events @@ -60,7 +58,7 @@ class GlobalTimelineChannel extends Channel { // 関係ない返信は除外 if (note.reply) { const reply = note.reply; - if ((this.following[note.userId]?.withReplies ?? false) || this.withReplies) { + if ((this.following[note.userId]?.withReplies ?? false)) { // 自分のフォローしていないユーザーの visibility: followers な投稿への返信は弾く if (reply.visibility === 'followers' && !Object.hasOwn(this.following, reply.userId)) return; // 自分の見ることができないユーザーの visibility: specified な投稿への返信は弾く