diff --git a/packages/backend/src/core/FanoutTimelineService.ts b/packages/backend/src/core/FanoutTimelineService.ts index 654a035a5..9b2678fbc 100644 --- a/packages/backend/src/core/FanoutTimelineService.ts +++ b/packages/backend/src/core/FanoutTimelineService.ts @@ -17,6 +17,7 @@ export type FanoutTimelineName = | `localTimeline` // replies are not included | `localTimelineWithFiles` // only non-reply notes with files are included | `localTimelineWithReplies` // only replies are included + | `localTimelineWithReplyTo:${string}` // Only replies to specific local user are included. Parameter is reply user id. // antenna | `antennaTimeline:${string}` diff --git a/packages/backend/src/core/NoteCreateService.ts b/packages/backend/src/core/NoteCreateService.ts index 0110ebaf5..45dfbb87a 100644 --- a/packages/backend/src/core/NoteCreateService.ts +++ b/packages/backend/src/core/NoteCreateService.ts @@ -933,6 +933,9 @@ export class NoteCreateService implements OnApplicationShutdown { if (note.visibility === 'public' && note.userHost == null) { this.fanoutTimelineService.push('localTimelineWithReplies', note.id, 300, r); + if (note.replyUserHost == null) { + this.fanoutTimelineService.push(`localTimelineWithReplyTo:${note.replyUserId}`, note.id, 300 / 10, r); + } } } else { this.fanoutTimelineService.push(`userTimeline:${user.id}`, note.id, note.userHost == null ? meta.perLocalUserUserTimelineCacheMax : meta.perRemoteUserUserTimelineCacheMax, r); 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 e8ba39bbf..3fd4dc83f 100644 --- a/packages/backend/src/server/api/endpoints/notes/local-timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/local-timeline.ts @@ -42,7 +42,7 @@ export const meta = { bothWithRepliesAndWithFiles: { message: 'Specifying both withReplies and withFiles is not supported', code: 'BOTH_WITH_REPLIES_AND_WITH_FILES', - id: 'dd9c8400-1cb5-4eef-8a31-200c5f933793' + id: 'dd9c8400-1cb5-4eef-8a31-200c5f933793', }, }, } as const; @@ -116,9 +116,12 @@ export default class extends Endpoint { // eslint- allowPartial: ps.allowPartial, me, useDbFallback: serverSettings.enableFanoutTimelineDbFallback, - redisTimelines: ps.withFiles ? ['localTimelineWithFiles'] : ['localTimeline', 'localTimelineWithReplies'], + redisTimelines: + ps.withFiles ? ['localTimelineWithFiles'] + : ps.withReplies ? ['localTimeline', 'localTimelineWithReplies'] + : me ? ['localTimeline', `localTimelineWithReplyTo:${me.id}`] + : ['localTimeline'], alwaysIncludeMyNotes: true, - excludeReplies: !ps.withReplies, excludePureRenotes: !ps.withRenotes, dbFallback: async (untilId, sinceId, limit) => await this.getFromDb({ untilId,