summaryrefslogtreecommitdiff
path: root/packages/backend/src
diff options
context:
space:
mode:
authorsyuilo <Syuilotan@yahoo.co.jp>2023-10-12 09:21:04 +0900
committerGitHub <noreply@github.com>2023-10-12 09:21:04 +0900
commit7e7138c0eb980d7cb9cb0a68e4f07eb2f0d0daeb (patch)
tree4b8e58dcd39d113313866c6b66ecb82c65bb7880 /packages/backend/src
parentMerge pull request #11963 from misskey-dev/develop (diff)
parentMerge branch 'develop' of https://github.com/misskey-dev/misskey into develop (diff)
downloadmisskey-7e7138c0eb980d7cb9cb0a68e4f07eb2f0d0daeb.tar.gz
misskey-7e7138c0eb980d7cb9cb0a68e4f07eb2f0d0daeb.tar.bz2
misskey-7e7138c0eb980d7cb9cb0a68e4f07eb2f0d0daeb.zip
Merge pull request #12011 from misskey-dev/develop
Release: 2023.10.1
Diffstat (limited to 'packages/backend/src')
-rw-r--r--packages/backend/src/core/NoteCreateService.ts12
-rw-r--r--packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts28
-rw-r--r--packages/backend/src/server/api/endpoints/notes/local-timeline.ts16
-rw-r--r--packages/backend/src/server/api/endpoints/users/notes.ts4
-rw-r--r--packages/backend/src/server/api/stream/channels/hybrid-timeline.ts4
-rw-r--r--packages/backend/src/server/api/stream/channels/local-timeline.ts4
6 files changed, 55 insertions, 13 deletions
diff --git a/packages/backend/src/core/NoteCreateService.ts b/packages/backend/src/core/NoteCreateService.ts
index 2a73467122..64d2880ba1 100644
--- a/packages/backend/src/core/NoteCreateService.ts
+++ b/packages/backend/src/core/NoteCreateService.ts
@@ -868,8 +868,8 @@ export class NoteCreateService implements OnApplicationShutdown {
// 基本的にvisibleUserIdsには自身のidが含まれている前提であること
if (note.visibility === 'specified' && !note.visibleUserIds.some(v => v === following.followerId)) continue;
- // 自分自身以外への返信
- if (note.replyId && note.replyUserId !== note.userId) {
+ // 「自分自身への返信 or そのフォロワーへの返信」のどちらでもない場合
+ if (note.replyId && !(note.replyUserId === note.userId || note.replyUserId === following.followerId)) {
if (!following.withReplies) continue;
}
@@ -886,8 +886,8 @@ export class NoteCreateService implements OnApplicationShutdown {
!note.visibleUserIds.some(v => v === userListMembership.userListUserId)
) continue;
- // 自分自身以外への返信
- if (note.replyId && note.replyUserId !== note.userId) {
+ // 「自分自身への返信 or そのリストの作成者への返信」のどちらでもない場合
+ if (note.replyId && !(note.replyUserId === note.userId || note.replyUserId === userListMembership.userListUserId)) {
if (!userListMembership.withReplies) continue;
}
@@ -907,6 +907,10 @@ export class NoteCreateService implements OnApplicationShutdown {
// 自分自身以外への返信
if (note.replyId && note.replyUserId !== note.userId) {
this.redisTimelineService.push(`userTimelineWithReplies:${user.id}`, note.id, note.userHost == null ? meta.perLocalUserUserTimelineCacheMax : meta.perRemoteUserUserTimelineCacheMax, r);
+
+ if (note.visibility === 'public' && note.userHost == null) {
+ this.redisTimelineService.push('localTimelineWithReplies', note.id, 300, r);
+ }
} else {
this.redisTimelineService.push(`userTimeline:${user.id}`, note.id, note.userHost == null ? meta.perLocalUserUserTimelineCacheMax : meta.perRemoteUserUserTimelineCacheMax, r);
if (note.fileIds.length > 0) {
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 1b77285d47..8ac5f1b038 100644
--- a/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts
+++ b/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts
@@ -55,6 +55,7 @@ export const paramDef = {
includeLocalRenotes: { type: 'boolean', default: true },
withFiles: { type: 'boolean', default: false },
withRenotes: { type: 'boolean', default: true },
+ withReplies: { type: 'boolean', default: false },
},
required: [],
} as const;
@@ -94,12 +95,29 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
this.cacheService.userBlockedCache.fetch(me.id),
]);
- const [htlNoteIds, ltlNoteIds] = await this.redisTimelineService.getMulti([
- ps.withFiles ? `homeTimelineWithFiles:${me.id}` : `homeTimeline:${me.id}`,
- ps.withFiles ? 'localTimelineWithFiles' : 'localTimeline',
- ], untilId, sinceId);
+ let noteIds: string[];
+
+ if (ps.withFiles) {
+ const [htlNoteIds, ltlNoteIds] = await this.redisTimelineService.getMulti([
+ `homeTimelineWithFiles:${me.id}`,
+ 'localTimelineWithFiles',
+ ], untilId, sinceId);
+ noteIds = Array.from(new Set([...htlNoteIds, ...ltlNoteIds]));
+ } else if (ps.withReplies) {
+ const [htlNoteIds, ltlNoteIds, ltlReplyNoteIds] = await this.redisTimelineService.getMulti([
+ `homeTimeline:${me.id}`,
+ 'localTimeline',
+ 'localTimelineWithReplies',
+ ], untilId, sinceId);
+ noteIds = Array.from(new Set([...htlNoteIds, ...ltlNoteIds, ...ltlReplyNoteIds]));
+ } else {
+ const [htlNoteIds, ltlNoteIds] = await this.redisTimelineService.getMulti([
+ `homeTimeline:${me.id}`,
+ 'localTimeline',
+ ], untilId, sinceId);
+ noteIds = Array.from(new Set([...htlNoteIds, ...ltlNoteIds]));
+ }
- let noteIds = Array.from(new Set([...htlNoteIds, ...ltlNoteIds]));
noteIds.sort((a, b) => a > b ? -1 : 1);
noteIds = noteIds.slice(0, ps.limit);
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 2357f32d5e..d10c3bedbf 100644
--- a/packages/backend/src/server/api/endpoints/notes/local-timeline.ts
+++ b/packages/backend/src/server/api/endpoints/notes/local-timeline.ts
@@ -45,6 +45,7 @@ export const paramDef = {
properties: {
withFiles: { type: 'boolean', default: false },
withRenotes: { type: 'boolean', default: true },
+ withReplies: { type: 'boolean', default: false },
excludeNsfw: { type: 'boolean', default: false },
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
sinceId: { type: 'string', format: 'misskey:id' },
@@ -90,7 +91,19 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
this.cacheService.userBlockedCache.fetch(me.id),
]) : [new Set<string>(), new Set<string>(), new Set<string>()];
- let noteIds = await this.redisTimelineService.get(ps.withFiles ? 'localTimelineWithFiles' : 'localTimeline', untilId, sinceId);
+ let noteIds: string[];
+
+ if (ps.withFiles) {
+ noteIds = await this.redisTimelineService.get('localTimelineWithFiles', untilId, sinceId);
+ } else {
+ const [nonReplyNoteIds, replyNoteIds] = await this.redisTimelineService.getMulti([
+ 'localTimeline',
+ 'localTimelineWithReplies',
+ ], untilId, sinceId);
+ noteIds = Array.from(new Set([...nonReplyNoteIds, ...replyNoteIds]));
+ noteIds.sort((a, b) => a > b ? -1 : 1);
+ }
+
noteIds = noteIds.slice(0, ps.limit);
if (noteIds.length === 0) {
@@ -112,6 +125,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
if (me && (note.userId === me.id)) {
return true;
}
+ if (!ps.withReplies && note.replyId && (me == null || note.replyUserId !== me.id)) return false;
if (me && isUserRelated(note, userIdsWhoBlockingMe)) return false;
if (me && isUserRelated(note, userIdsWhoMeMuting)) return false;
if (note.renoteId) {
diff --git a/packages/backend/src/server/api/endpoints/users/notes.ts b/packages/backend/src/server/api/endpoints/users/notes.ts
index dfef35986e..df0951ce74 100644
--- a/packages/backend/src/server/api/endpoints/users/notes.ts
+++ b/packages/backend/src/server/api/endpoints/users/notes.ts
@@ -150,7 +150,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
.leftJoinAndSelect('reply.user', 'replyUser')
.leftJoinAndSelect('renote.user', 'renoteUser');
- if (!ps.withChannelNotes) {
+ if (ps.withChannelNotes) {
+ if (!isSelf) query.andWhere('channel.isSensitive = false');
+ } else {
query.andWhere('note.channelId IS NULL');
}
diff --git a/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts b/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts
index d5f5d54e46..adedca5152 100644
--- a/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts
+++ b/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts
@@ -19,6 +19,7 @@ class HybridTimelineChannel extends Channel {
public static shouldShare = false;
public static requireCredential = true;
private withRenotes: boolean;
+ private withReplies: boolean;
private withFiles: boolean;
constructor(
@@ -39,6 +40,7 @@ class HybridTimelineChannel extends Channel {
if (!policies.ltlAvailable) return;
this.withRenotes = params.withRenotes ?? true;
+ this.withReplies = params.withReplies ?? false;
this.withFiles = params.withFiles ?? false;
// Subscribe events
@@ -87,7 +89,7 @@ class HybridTimelineChannel extends Channel {
if (isInstanceMuted(note, new Set<string>(this.userProfile!.mutedInstances ?? []))) return;
// 関係ない返信は除外
- if (note.reply && !this.following[note.userId]?.withReplies) {
+ if (note.reply && !this.following[note.userId]?.withReplies && !this.withReplies) {
const reply = note.reply;
// 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合
if (reply.userId !== this.user!.id && note.userId !== this.user!.id && reply.userId !== note.userId) return;
diff --git a/packages/backend/src/server/api/stream/channels/local-timeline.ts b/packages/backend/src/server/api/stream/channels/local-timeline.ts
index 94c22f8915..69aa366f00 100644
--- a/packages/backend/src/server/api/stream/channels/local-timeline.ts
+++ b/packages/backend/src/server/api/stream/channels/local-timeline.ts
@@ -18,6 +18,7 @@ class LocalTimelineChannel extends Channel {
public static shouldShare = false;
public static requireCredential = false;
private withRenotes: boolean;
+ private withReplies: boolean;
private withFiles: boolean;
constructor(
@@ -38,6 +39,7 @@ class LocalTimelineChannel extends Channel {
if (!policies.ltlAvailable) return;
this.withRenotes = params.withRenotes ?? true;
+ this.withReplies = params.withReplies ?? false;
this.withFiles = params.withFiles ?? false;
// Subscribe events
@@ -66,7 +68,7 @@ class LocalTimelineChannel extends Channel {
}
// 関係ない返信は除外
- if (note.reply && this.user && !this.following[note.userId]?.withReplies) {
+ if (note.reply && this.user && !this.following[note.userId]?.withReplies && !this.withReplies) {
const reply = note.reply;
// 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合
if (reply.userId !== this.user.id && note.userId !== this.user.id && reply.userId !== note.userId) return;