fix(backend): 「ファイル付きのみ」のTLでファイル無しの新着ノートが表示される

Fix #11939
This commit is contained in:
syuilo 2023-10-09 17:48:09 +09:00
parent 7066d61730
commit 6ff98846e6
7 changed files with 22 additions and 3 deletions

View file

@ -53,6 +53,7 @@
- Fix: nodeinfoにおいてCORS用のヘッダーが設定されていないのを修正 - Fix: nodeinfoにおいてCORS用のヘッダーが設定されていないのを修正
- Fix: 同じ種類のTLのストリーミングを複数接続できない問題を修正 - Fix: 同じ種類のTLのストリーミングを複数接続できない問題を修正
- Fix: アンテナTLを途中までしかページネーションできなくなることがある問題を修正 - Fix: アンテナTLを途中までしかページネーションできなくなることがある問題を修正
- Fix: 「ファイル付きのみ」のTLでファイル無しの新着ートが流れる問題を修正
## 2023.9.3 ## 2023.9.3
### General ### General

View file

@ -19,6 +19,7 @@ class GlobalTimelineChannel extends Channel {
public static shouldShare = false; public static shouldShare = false;
public static requireCredential = false; public static requireCredential = false;
private withRenotes: boolean; private withRenotes: boolean;
private withFiles: boolean;
constructor( constructor(
private metaService: MetaService, private metaService: MetaService,
@ -38,6 +39,7 @@ class GlobalTimelineChannel extends Channel {
if (!policies.gtlAvailable) return; if (!policies.gtlAvailable) return;
this.withRenotes = params.withRenotes ?? true; this.withRenotes = params.withRenotes ?? true;
this.withFiles = params.withFiles ?? false;
// Subscribe events // Subscribe events
this.subscriber.on('notesStream', this.onNote); this.subscriber.on('notesStream', this.onNote);
@ -45,6 +47,8 @@ class GlobalTimelineChannel extends Channel {
@bindThis @bindThis
private async onNote(note: Packed<'Note'>) { private async onNote(note: Packed<'Note'>) {
if (this.withFiles && (note.fileIds == null || note.fileIds.length === 0)) return;
if (note.visibility !== 'public') return; if (note.visibility !== 'public') return;
if (note.channelId != null) return; if (note.channelId != null) return;

View file

@ -17,6 +17,7 @@ class HomeTimelineChannel extends Channel {
public static shouldShare = false; public static shouldShare = false;
public static requireCredential = true; public static requireCredential = true;
private withRenotes: boolean; private withRenotes: boolean;
private withFiles: boolean;
constructor( constructor(
private noteEntityService: NoteEntityService, private noteEntityService: NoteEntityService,
@ -31,12 +32,15 @@ class HomeTimelineChannel extends Channel {
@bindThis @bindThis
public async init(params: any) { public async init(params: any) {
this.withRenotes = params.withRenotes ?? true; this.withRenotes = params.withRenotes ?? true;
this.withFiles = params.withFiles ?? false;
this.subscriber.on('notesStream', this.onNote); this.subscriber.on('notesStream', this.onNote);
} }
@bindThis @bindThis
private async onNote(note: Packed<'Note'>) { private async onNote(note: Packed<'Note'>) {
if (this.withFiles && (note.fileIds == null || note.fileIds.length === 0)) return;
if (note.channelId) { if (note.channelId) {
if (!this.followingChannels.has(note.channelId)) return; if (!this.followingChannels.has(note.channelId)) return;
} else { } else {

View file

@ -19,6 +19,7 @@ class HybridTimelineChannel extends Channel {
public static shouldShare = false; public static shouldShare = false;
public static requireCredential = true; public static requireCredential = true;
private withRenotes: boolean; private withRenotes: boolean;
private withFiles: boolean;
constructor( constructor(
private metaService: MetaService, private metaService: MetaService,
@ -38,6 +39,7 @@ class HybridTimelineChannel extends Channel {
if (!policies.ltlAvailable) return; if (!policies.ltlAvailable) return;
this.withRenotes = params.withRenotes ?? true; this.withRenotes = params.withRenotes ?? true;
this.withFiles = params.withFiles ?? false;
// Subscribe events // Subscribe events
this.subscriber.on('notesStream', this.onNote); this.subscriber.on('notesStream', this.onNote);
@ -45,6 +47,8 @@ class HybridTimelineChannel extends Channel {
@bindThis @bindThis
private async onNote(note: Packed<'Note'>) { private async onNote(note: Packed<'Note'>) {
if (this.withFiles && (note.fileIds == null || note.fileIds.length === 0)) return;
// チャンネルの投稿ではなく、自分自身の投稿 または // チャンネルの投稿ではなく、自分自身の投稿 または
// チャンネルの投稿ではなく、その投稿のユーザーをフォローしている または // チャンネルの投稿ではなく、その投稿のユーザーをフォローしている または
// チャンネルの投稿ではなく、全体公開のローカルの投稿 または // チャンネルの投稿ではなく、全体公開のローカルの投稿 または

View file

@ -18,6 +18,7 @@ class LocalTimelineChannel extends Channel {
public static shouldShare = false; public static shouldShare = false;
public static requireCredential = false; public static requireCredential = false;
private withRenotes: boolean; private withRenotes: boolean;
private withFiles: boolean;
constructor( constructor(
private metaService: MetaService, private metaService: MetaService,
@ -37,6 +38,7 @@ class LocalTimelineChannel extends Channel {
if (!policies.ltlAvailable) return; if (!policies.ltlAvailable) return;
this.withRenotes = params.withRenotes ?? true; this.withRenotes = params.withRenotes ?? true;
this.withFiles = params.withFiles ?? false;
// Subscribe events // Subscribe events
this.subscriber.on('notesStream', this.onNote); this.subscriber.on('notesStream', this.onNote);
@ -44,6 +46,8 @@ class LocalTimelineChannel extends Channel {
@bindThis @bindThis
private async onNote(note: Packed<'Note'>) { private async onNote(note: Packed<'Note'>) {
if (this.withFiles && (note.fileIds == null || note.fileIds.length === 0)) return;
if (note.user.host !== null) return; if (note.user.host !== null) return;
if (note.visibility !== 'public') return; if (note.visibility !== 'public') return;
if (note.channelId != null && !this.followingChannels.has(note.channelId)) return; if (note.channelId != null && !this.followingChannels.has(note.channelId)) return;

View file

@ -18,8 +18,9 @@ class UserListChannel extends Channel {
public static shouldShare = false; public static shouldShare = false;
public static requireCredential = false; public static requireCredential = false;
private listId: string; private listId: string;
public membershipsMap: Record<string, Pick<MiUserListMembership, 'withReplies'> | undefined> = {}; private membershipsMap: Record<string, Pick<MiUserListMembership, 'withReplies'> | undefined> = {};
private listUsersClock: NodeJS.Timeout; private listUsersClock: NodeJS.Timeout;
private withFiles: boolean;
constructor( constructor(
private userListsRepository: UserListsRepository, private userListsRepository: UserListsRepository,
@ -37,6 +38,7 @@ class UserListChannel extends Channel {
@bindThis @bindThis
public async init(params: any) { public async init(params: any) {
this.listId = params.listId as string; this.listId = params.listId as string;
this.withFiles = params.withFiles ?? false;
// Check existence and owner // Check existence and owner
const listExist = await this.userListsRepository.exist({ const listExist = await this.userListsRepository.exist({
@ -76,6 +78,8 @@ class UserListChannel extends Channel {
@bindThis @bindThis
private async onNote(note: Packed<'Note'>) { private async onNote(note: Packed<'Note'>) {
if (this.withFiles && (note.fileIds == null || note.fileIds.length === 0)) return;
if (!Object.hasOwn(this.membershipsMap, note.userId)) return; if (!Object.hasOwn(this.membershipsMap, note.userId)) return;
if (['followers', 'specified'].includes(note.visibility)) { if (['followers', 'specified'].includes(note.visibility)) {

View file

@ -138,12 +138,10 @@ if (props.src === 'antenna') {
} else if (props.src === 'list') { } else if (props.src === 'list') {
endpoint = 'notes/user-list-timeline'; endpoint = 'notes/user-list-timeline';
query = { query = {
withRenotes: props.withRenotes,
withFiles: props.onlyFiles ? true : undefined, withFiles: props.onlyFiles ? true : undefined,
listId: props.list, listId: props.list,
}; };
connection = stream.useChannel('userList', { connection = stream.useChannel('userList', {
withRenotes: props.withRenotes,
withFiles: props.onlyFiles ? true : undefined, withFiles: props.onlyFiles ? true : undefined,
listId: props.list, listId: props.list,
}); });