summaryrefslogtreecommitdiff
path: root/packages/backend/src/server/api/stream
diff options
context:
space:
mode:
authorMar0xy <marie@kaifa.ch>2023-10-31 19:33:24 +0100
committerMar0xy <marie@kaifa.ch>2023-10-31 19:33:24 +0100
commit4dd23a37931e6e2dc5935b2aa47a1fe51f1a9fc4 (patch)
tree6df74a71fb0cdd479edc1ad1e510a1729e402c0b /packages/backend/src/server/api/stream
parentmerge: fix file sorting on user notes (#122) (diff)
parentMerge branch 'develop' of https://github.com/misskey-dev/misskey into develop (diff)
downloadsharkey-4dd23a37931e6e2dc5935b2aa47a1fe51f1a9fc4.tar.gz
sharkey-4dd23a37931e6e2dc5935b2aa47a1fe51f1a9fc4.tar.bz2
sharkey-4dd23a37931e6e2dc5935b2aa47a1fe51f1a9fc4.zip
merge: upstream
Diffstat (limited to 'packages/backend/src/server/api/stream')
-rw-r--r--packages/backend/src/server/api/stream/Connection.ts4
-rw-r--r--packages/backend/src/server/api/stream/channel.ts2
-rw-r--r--packages/backend/src/server/api/stream/channels/channel.ts6
-rw-r--r--packages/backend/src/server/api/stream/channels/global-timeline.ts6
-rw-r--r--packages/backend/src/server/api/stream/channels/hashtag.ts6
-rw-r--r--packages/backend/src/server/api/stream/channels/home-timeline.ts26
-rw-r--r--packages/backend/src/server/api/stream/channels/hybrid-timeline.ts27
-rw-r--r--packages/backend/src/server/api/stream/channels/local-timeline.ts6
-rw-r--r--packages/backend/src/server/api/stream/channels/user-list.ts22
9 files changed, 71 insertions, 34 deletions
diff --git a/packages/backend/src/server/api/stream/Connection.ts b/packages/backend/src/server/api/stream/Connection.ts
index f981e63871..2d8fec30b1 100644
--- a/packages/backend/src/server/api/stream/Connection.ts
+++ b/packages/backend/src/server/api/stream/Connection.ts
@@ -13,6 +13,7 @@ import { bindThis } from '@/decorators.js';
import { CacheService } from '@/core/CacheService.js';
import { MiFollowing, MiUserProfile } from '@/models/_.js';
import type { StreamEventEmitter, GlobalEvents } from '@/core/GlobalEventService.js';
+import { ChannelFollowingService } from '@/core/ChannelFollowingService.js';
import type { ChannelsService } from './ChannelsService.js';
import type { EventEmitter } from 'events';
import type Channel from './channel.js';
@@ -42,6 +43,7 @@ export default class Connection {
private noteReadService: NoteReadService,
private notificationService: NotificationService,
private cacheService: CacheService,
+ private channelFollowingService: ChannelFollowingService,
user: MiUser | null | undefined,
token: MiAccessToken | null | undefined,
@@ -56,7 +58,7 @@ export default class Connection {
const [userProfile, following, followingChannels, userIdsWhoMeMuting, userIdsWhoBlockingMe, userIdsWhoMeMutingRenotes] = await Promise.all([
this.cacheService.userProfileCache.fetch(this.user.id),
this.cacheService.userFollowingsCache.fetch(this.user.id),
- this.cacheService.userFollowingChannelsCache.fetch(this.user.id),
+ this.channelFollowingService.userFollowingChannelsCache.fetch(this.user.id),
this.cacheService.userMutingsCache.fetch(this.user.id),
this.cacheService.userBlockedCache.fetch(this.user.id),
this.cacheService.renoteMutingsCache.fetch(this.user.id),
diff --git a/packages/backend/src/server/api/stream/channel.ts b/packages/backend/src/server/api/stream/channel.ts
index ad32d08fee..3aa0d69c0b 100644
--- a/packages/backend/src/server/api/stream/channel.ts
+++ b/packages/backend/src/server/api/stream/channel.ts
@@ -67,6 +67,8 @@ export default abstract class Channel {
}
public abstract init(params: any): void;
+
public dispose?(): void;
+
public onMessage?(type: string, body: any): void;
}
diff --git a/packages/backend/src/server/api/stream/channels/channel.ts b/packages/backend/src/server/api/stream/channels/channel.ts
index e4c34e00ce..57034231a3 100644
--- a/packages/backend/src/server/api/stream/channels/channel.ts
+++ b/packages/backend/src/server/api/stream/channels/channel.ts
@@ -46,8 +46,10 @@ class ChannelChannel extends Channel {
if (note.renote && !note.text && isUserRelated(note, this.userIdsWhoMeMutingRenotes)) return;
if (this.user && note.renoteId && !note.text) {
- const myRenoteReaction = await this.noteEntityService.populateMyReaction(note.renoteId, this.user.id);
- note.renote!.myReaction = myRenoteReaction;
+ if (note.renote && Object.keys(note.renote.reactions).length > 0) {
+ const myRenoteReaction = await this.noteEntityService.populateMyReaction(note.renote, this.user.id);
+ note.renote.myReaction = myRenoteReaction;
+ }
}
this.connection.cacheNote(note);
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 b39afbe361..fa0493854b 100644
--- a/packages/backend/src/server/api/stream/channels/global-timeline.ts
+++ b/packages/backend/src/server/api/stream/channels/global-timeline.ts
@@ -77,8 +77,10 @@ class GlobalTimelineChannel extends Channel {
if (note.renote && !note.text && isUserRelated(note, this.userIdsWhoMeMutingRenotes)) return;
if (this.user && note.renoteId && !note.text) {
- const myRenoteReaction = await this.noteEntityService.populateMyReaction(note.renoteId, this.user.id);
- note.renote!.myReaction = myRenoteReaction;
+ if (note.renote && Object.keys(note.renote.reactions).length > 0) {
+ const myRenoteReaction = await this.noteEntityService.populateMyReaction(note.renote, this.user.id);
+ note.renote.myReaction = myRenoteReaction;
+ }
}
this.connection.cacheNote(note);
diff --git a/packages/backend/src/server/api/stream/channels/hashtag.ts b/packages/backend/src/server/api/stream/channels/hashtag.ts
index 2cfe9572d3..f30b29cfd6 100644
--- a/packages/backend/src/server/api/stream/channels/hashtag.ts
+++ b/packages/backend/src/server/api/stream/channels/hashtag.ts
@@ -51,8 +51,10 @@ class HashtagChannel extends Channel {
if (note.renote && !note.text && isUserRelated(note, this.userIdsWhoMeMutingRenotes)) return;
if (this.user && note.renoteId && !note.text) {
- const myRenoteReaction = await this.noteEntityService.populateMyReaction(note.renoteId, this.user.id);
- note.renote!.myReaction = myRenoteReaction;
+ if (note.renote && Object.keys(note.renote.reactions).length > 0) {
+ const myRenoteReaction = await this.noteEntityService.populateMyReaction(note.renote, this.user.id);
+ note.renote.myReaction = myRenoteReaction;
+ }
}
this.connection.cacheNote(note);
diff --git a/packages/backend/src/server/api/stream/channels/home-timeline.ts b/packages/backend/src/server/api/stream/channels/home-timeline.ts
index f5216bb4f6..32bb9fd984 100644
--- a/packages/backend/src/server/api/stream/channels/home-timeline.ts
+++ b/packages/backend/src/server/api/stream/channels/home-timeline.ts
@@ -39,29 +39,35 @@ class HomeTimelineChannel extends Channel {
@bindThis
private async onNote(note: Packed<'Note'>) {
+ const isMe = this.user!.id === note.userId;
+
if (this.withFiles && (note.fileIds == null || note.fileIds.length === 0)) return;
if (note.channelId) {
if (!this.followingChannels.has(note.channelId)) return;
} else {
// その投稿のユーザーをフォローしていなかったら弾く
- if ((this.user!.id !== note.userId) && !Object.hasOwn(this.following, note.userId)) return;
+ if (!isMe && !Object.hasOwn(this.following, note.userId)) return;
}
// Ignore notes from instances the user has muted
if (isInstanceMuted(note, new Set<string>(this.userProfile!.mutedInstances))) return;
if (note.visibility === 'followers') {
- if (!Object.hasOwn(this.following, note.userId)) return;
+ if (!isMe && !Object.hasOwn(this.following, note.userId)) return;
} else if (note.visibility === 'specified') {
- if (!note.visibleUserIds!.includes(this.user!.id)) return;
+ if (!isMe && !note.visibleUserIds!.includes(this.user!.id)) return;
}
- // 関係ない返信は除外
- if (note.reply && !this.following[note.userId]?.withReplies) {
+ if (note.reply) {
const reply = note.reply;
- // 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合
- if (reply.userId !== this.user!.id && note.userId !== this.user!.id && reply.userId !== note.userId) return;
+ if (this.following[note.userId]?.withReplies) {
+ // 自分のフォローしていないユーザーの visibility: followers な投稿への返信は弾く
+ if (reply.visibility === 'followers' && !Object.hasOwn(this.following, reply.userId)) return;
+ } else {
+ // 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合
+ if (reply.userId !== this.user!.id && !isMe && reply.userId !== note.userId) return;
+ }
}
if (note.user.isSilenced && !this.following[note.userId] && note.userId !== this.user!.id) return;
@@ -76,8 +82,10 @@ class HomeTimelineChannel extends Channel {
if (note.renote && !note.text && isUserRelated(note, this.userIdsWhoMeMutingRenotes)) return;
if (this.user && note.renoteId && !note.text) {
- const myRenoteReaction = await this.noteEntityService.populateMyReaction(note.renoteId, this.user.id);
- note.renote!.myReaction = myRenoteReaction;
+ if (note.renote && Object.keys(note.renote.reactions).length > 0) {
+ const myRenoteReaction = await this.noteEntityService.populateMyReaction(note.renote, this.user.id);
+ note.renote.myReaction = myRenoteReaction;
+ }
}
this.connection.cacheNote(note);
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 1a062f393b..cf904b475a 100644
--- a/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts
+++ b/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts
@@ -51,6 +51,8 @@ class HybridTimelineChannel extends Channel {
@bindThis
private async onNote(note: Packed<'Note'>) {
+ const isMe = this.user!.id === note.userId;
+
if (this.withFiles && (note.fileIds == null || note.fileIds.length === 0)) return;
if (!this.withBots && note.user.isBot) return;
@@ -59,26 +61,30 @@ class HybridTimelineChannel extends Channel {
// チャンネルの投稿ではなく、全体公開のローカルの投稿 または
// フォローしているチャンネルの投稿 の場合だけ
if (!(
- (note.channelId == null && this.user!.id === note.userId) ||
+ (note.channelId == null && isMe) ||
(note.channelId == null && Object.hasOwn(this.following, note.userId)) ||
(note.channelId == null && (note.user.host == null && note.visibility === 'public')) ||
(note.channelId != null && this.followingChannels.has(note.channelId))
)) return;
if (note.visibility === 'followers') {
- if (!Object.hasOwn(this.following, note.userId)) return;
+ if (!isMe && !Object.hasOwn(this.following, note.userId)) return;
} else if (note.visibility === 'specified') {
- if (!note.visibleUserIds!.includes(this.user!.id)) return;
+ if (!isMe && !note.visibleUserIds!.includes(this.user!.id)) return;
}
// Ignore notes from instances the user has muted
if (isInstanceMuted(note, new Set<string>(this.userProfile!.mutedInstances))) return;
- // 関係ない返信は除外
- if (note.reply && !this.following[note.userId]?.withReplies && !this.withReplies) {
+ if (note.reply) {
const reply = note.reply;
- // 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合
- if (reply.userId !== this.user!.id && note.userId !== this.user!.id && reply.userId !== note.userId) return;
+ if ((this.following[note.userId]?.withReplies ?? false) || this.withReplies) {
+ // 自分のフォローしていないユーザーの visibility: followers な投稿への返信は弾く
+ if (reply.visibility === 'followers' && !Object.hasOwn(this.following, reply.userId)) return;
+ } else {
+ // 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合
+ if (reply.userId !== this.user!.id && !isMe && reply.userId !== note.userId) return;
+ }
}
if (note.user.isSilenced && !this.following[note.userId] && note.userId !== this.user!.id) return;
@@ -93,8 +99,11 @@ class HybridTimelineChannel extends Channel {
if (note.renote && !note.text && isUserRelated(note, this.userIdsWhoMeMutingRenotes)) return;
if (this.user && note.renoteId && !note.text) {
- const myRenoteReaction = await this.noteEntityService.populateMyReaction(note.renoteId, this.user.id);
- note.renote!.myReaction = myRenoteReaction;
+ if (note.renote && Object.keys(note.renote.reactions).length > 0) {
+ console.log(note.renote.reactionAndUserPairCache);
+ const myRenoteReaction = await this.noteEntityService.populateMyReaction(note.renote, this.user.id);
+ note.renote.myReaction = myRenoteReaction;
+ }
}
this.connection.cacheNote(note);
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 738dbd80fc..388f4dc361 100644
--- a/packages/backend/src/server/api/stream/channels/local-timeline.ts
+++ b/packages/backend/src/server/api/stream/channels/local-timeline.ts
@@ -76,8 +76,10 @@ class LocalTimelineChannel extends Channel {
if (note.renote && !note.text && isUserRelated(note, this.userIdsWhoMeMutingRenotes)) return;
if (this.user && note.renoteId && !note.text) {
- const myRenoteReaction = await this.noteEntityService.populateMyReaction(note.renoteId, this.user.id);
- note.renote!.myReaction = myRenoteReaction;
+ if (note.renote && Object.keys(note.renote.reactions).length > 0) {
+ const myRenoteReaction = await this.noteEntityService.populateMyReaction(note.renote, this.user.id);
+ note.renote.myReaction = myRenoteReaction;
+ }
}
this.connection.cacheNote(note);
diff --git a/packages/backend/src/server/api/stream/channels/user-list.ts b/packages/backend/src/server/api/stream/channels/user-list.ts
index b73cedaa8b..4b6628df6f 100644
--- a/packages/backend/src/server/api/stream/channels/user-list.ts
+++ b/packages/backend/src/server/api/stream/channels/user-list.ts
@@ -78,21 +78,27 @@ class UserListChannel extends Channel {
@bindThis
private async onNote(note: Packed<'Note'>) {
+ const isMe = this.user!.id === note.userId;
+
if (this.withFiles && (note.fileIds == null || note.fileIds.length === 0)) return;
if (!Object.hasOwn(this.membershipsMap, note.userId)) return;
if (note.visibility === 'followers') {
- if (!Object.hasOwn(this.following, note.userId)) return;
+ if (!isMe && !Object.hasOwn(this.following, note.userId)) return;
} else if (note.visibility === 'specified') {
if (!note.visibleUserIds!.includes(this.user!.id)) return;
}
- // 関係ない返信は除外
- if (note.reply && !this.membershipsMap[note.userId]?.withReplies) {
+ if (note.reply) {
const reply = note.reply;
- // 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合
- if (reply.userId !== this.user!.id && note.userId !== this.user!.id && reply.userId !== note.userId) return;
+ if (this.membershipsMap[note.userId]?.withReplies) {
+ // 自分のフォローしていないユーザーの visibility: followers な投稿への返信は弾く
+ if (reply.visibility === 'followers' && !Object.hasOwn(this.following, reply.userId)) return;
+ } else {
+ // 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合
+ if (reply.userId !== this.user!.id && !isMe && reply.userId !== note.userId) return;
+ }
}
// 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する
@@ -103,8 +109,10 @@ class UserListChannel extends Channel {
if (note.renote && !note.text && isUserRelated(note, this.userIdsWhoMeMutingRenotes)) return;
if (this.user && note.renoteId && !note.text) {
- const myRenoteReaction = await this.noteEntityService.populateMyReaction(note.renoteId, this.user.id);
- note.renote!.myReaction = myRenoteReaction;
+ if (note.renote && Object.keys(note.renote.reactions).length > 0) {
+ const myRenoteReaction = await this.noteEntityService.populateMyReaction(note.renote, this.user.id);
+ note.renote.myReaction = myRenoteReaction;
+ }
}
this.connection.cacheNote(note);