実装忘れ対応
This commit is contained in:
parent
ac728dd3fb
commit
3514c9f68c
|
@ -15,6 +15,8 @@ import { CacheService } from '@/core/CacheService.js';
|
||||||
import { MetaService } from '@/core/MetaService.js';
|
import { MetaService } from '@/core/MetaService.js';
|
||||||
import { FanoutTimelineEndpointService } from '@/core/FanoutTimelineEndpointService.js';
|
import { FanoutTimelineEndpointService } from '@/core/FanoutTimelineEndpointService.js';
|
||||||
import { MiLocalUser } from '@/models/User.js';
|
import { MiLocalUser } from '@/models/User.js';
|
||||||
|
import { ChannelMutingService } from '@/core/ChannelMutingService.js';
|
||||||
|
import { isChannelRelated } from '@/misc/is-channel-related.js';
|
||||||
import { ApiError } from '../../error.js';
|
import { ApiError } from '../../error.js';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
|
@ -71,6 +73,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
private cacheService: CacheService,
|
private cacheService: CacheService,
|
||||||
private activeUsersChart: ActiveUsersChart,
|
private activeUsersChart: ActiveUsersChart,
|
||||||
private metaService: MetaService,
|
private metaService: MetaService,
|
||||||
|
private channelMutingService: ChannelMutingService,
|
||||||
) {
|
) {
|
||||||
super(meta, paramDef, async (ps, me) => {
|
super(meta, paramDef, async (ps, me) => {
|
||||||
const untilId = ps.untilId ?? (ps.untilDate ? this.idService.gen(ps.untilDate!) : null);
|
const untilId = ps.untilId ?? (ps.untilDate ? this.idService.gen(ps.untilDate!) : null);
|
||||||
|
@ -92,6 +95,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
return await this.noteEntityService.packMany(await this.getFromDb({ untilId, sinceId, limit: ps.limit, channelId: channel.id }, me), me);
|
return await this.noteEntityService.packMany(await this.getFromDb({ untilId, sinceId, limit: ps.limit, channelId: channel.id }, me), me);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const mutingChannelIds = me
|
||||||
|
? await this.channelMutingService.mutingChannelsCache.get(me.id) ?? new Set<string>()
|
||||||
|
: new Set<string>();
|
||||||
return await this.fanoutTimelineEndpointService.timeline({
|
return await this.fanoutTimelineEndpointService.timeline({
|
||||||
untilId,
|
untilId,
|
||||||
sinceId,
|
sinceId,
|
||||||
|
@ -101,6 +107,11 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
useDbFallback: true,
|
useDbFallback: true,
|
||||||
redisTimelines: [`channelTimeline:${channel.id}`],
|
redisTimelines: [`channelTimeline:${channel.id}`],
|
||||||
excludePureRenotes: false,
|
excludePureRenotes: false,
|
||||||
|
noteFilter: note => {
|
||||||
|
// 共通機能を使うと見ているチャンネルそのものもミュートしてしまうので閲覧中のチャンネル以外を除く形にする
|
||||||
|
if (note.channelId === channel.id) return true;
|
||||||
|
return !isChannelRelated(note, mutingChannelIds);
|
||||||
|
},
|
||||||
dbFallback: async (untilId, sinceId, limit) => {
|
dbFallback: async (untilId, sinceId, limit) => {
|
||||||
return await this.getFromDb({ untilId, sinceId, limit, channelId: channel.id }, me);
|
return await this.getFromDb({ untilId, sinceId, limit, channelId: channel.id }, me);
|
||||||
},
|
},
|
||||||
|
@ -125,6 +136,14 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
.leftJoinAndSelect('note.channel', 'channel');
|
.leftJoinAndSelect('note.channel', 'channel');
|
||||||
|
|
||||||
if (me) {
|
if (me) {
|
||||||
|
const mutingChannelIds = await this.channelMutingService
|
||||||
|
.list({ requestUserId: me.id }, { idOnly: true })
|
||||||
|
.then(x => x.map(x => x.id).filter(x => x !== ps.channelId));
|
||||||
|
if (mutingChannelIds.length > 0) {
|
||||||
|
query.andWhere('note.channelId NOT IN (:...mutingChannelIds)', { mutingChannelIds });
|
||||||
|
query.andWhere('note.renoteChannelId NOT IN (:...mutingChannelIds)', { mutingChannelIds });
|
||||||
|
}
|
||||||
|
|
||||||
this.queryService.generateMutedUserQuery(query, me);
|
this.queryService.generateMutedUserQuery(query, me);
|
||||||
this.queryService.generateBlockedUserQuery(query, me);
|
this.queryService.generateBlockedUserQuery(query, me);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { isInstanceMuted } from '@/misc/is-instance-muted.js';
|
||||||
import { isUserRelated } from '@/misc/is-user-related.js';
|
import { isUserRelated } from '@/misc/is-user-related.js';
|
||||||
import { isQuotePacked, isRenotePacked } from '@/misc/is-renote.js';
|
import { isQuotePacked, isRenotePacked } from '@/misc/is-renote.js';
|
||||||
import type { Packed } from '@/misc/json-schema.js';
|
import type { Packed } from '@/misc/json-schema.js';
|
||||||
|
import { isChannelRelated } from '@/misc/is-channel-related.js';
|
||||||
import type Connection from './Connection.js';
|
import type Connection from './Connection.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -77,6 +78,9 @@ export default abstract class Channel {
|
||||||
// 流れてきたNoteがリノートをミュートしてるユーザが行ったもの
|
// 流れてきたNoteがリノートをミュートしてるユーザが行ったもの
|
||||||
if (isRenotePacked(note) && !isQuotePacked(note) && this.userIdsWhoMeMutingRenotes.has(note.user.id)) return true;
|
if (isRenotePacked(note) && !isQuotePacked(note) && this.userIdsWhoMeMutingRenotes.has(note.user.id)) return true;
|
||||||
|
|
||||||
|
// 流れてきたNoteがミュートしているチャンネルと関わる
|
||||||
|
if (isChannelRelated(note, this.mutingChannels)) return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,9 @@ import { Injectable } from '@nestjs/common';
|
||||||
import type { Packed } from '@/misc/json-schema.js';
|
import type { Packed } from '@/misc/json-schema.js';
|
||||||
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
|
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import { isRenotePacked, isQuotePacked } from '@/misc/is-renote.js';
|
import { isQuotePacked, isRenotePacked } from '@/misc/is-renote.js';
|
||||||
|
import { isInstanceMuted } from '@/misc/is-instance-muted.js';
|
||||||
|
import { isUserRelated } from '@/misc/is-user-related.js';
|
||||||
import Channel, { type MiChannelService } from '../channel.js';
|
import Channel, { type MiChannelService } from '../channel.js';
|
||||||
|
|
||||||
class ChannelChannel extends Channel {
|
class ChannelChannel extends Channel {
|
||||||
|
@ -18,7 +20,6 @@ class ChannelChannel extends Channel {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private noteEntityService: NoteEntityService,
|
private noteEntityService: NoteEntityService,
|
||||||
|
|
||||||
id: string,
|
id: string,
|
||||||
connection: Channel['connection'],
|
connection: Channel['connection'],
|
||||||
) {
|
) {
|
||||||
|
@ -52,6 +53,35 @@ class ChannelChannel extends Channel {
|
||||||
this.send('note', note);
|
this.send('note', note);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ミュートとブロックされてるを処理する
|
||||||
|
*/
|
||||||
|
protected override isNoteMutedOrBlocked(note: Packed<'Note'>): boolean {
|
||||||
|
// 流れてきたNoteがインスタンスミュートしたインスタンスが関わる
|
||||||
|
if (isInstanceMuted(note, new Set<string>(this.userProfile?.mutedInstances ?? []))) return true;
|
||||||
|
|
||||||
|
// 流れてきたNoteがミュートしているユーザーが関わる
|
||||||
|
if (isUserRelated(note, this.userIdsWhoMeMuting)) return true;
|
||||||
|
// 流れてきたNoteがブロックされているユーザーが関わる
|
||||||
|
if (isUserRelated(note, this.userIdsWhoBlockingMe)) return true;
|
||||||
|
|
||||||
|
// 流れてきたNoteがリノートをミュートしてるユーザが行ったもの
|
||||||
|
if (isRenotePacked(note) && !isQuotePacked(note) && this.userIdsWhoMeMutingRenotes.has(note.user.id)) return true;
|
||||||
|
|
||||||
|
// このソケットで見ているチャンネルがミュートされていたとしても、チャンネルを直接見ている以上は流すようにしたい
|
||||||
|
// ただし、他のミュートしているチャンネルは流さないようにもしたい
|
||||||
|
// ノート自体のチャンネルIDはonNoteでチェックしているので、ここではリノートのチャンネルIDをチェックする
|
||||||
|
if (
|
||||||
|
(note.renote) &&
|
||||||
|
(note.renote.channelId !== this.channelId) &&
|
||||||
|
(note.renote.channelId && this.mutingChannels.has(note.renote.channelId))
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public dispose() {
|
public dispose() {
|
||||||
// Unsubscribe events
|
// Unsubscribe events
|
||||||
|
|
|
@ -44,8 +44,8 @@ class HomeTimelineChannel extends Channel {
|
||||||
if (this.withFiles && (note.fileIds == null || note.fileIds.length === 0)) return;
|
if (this.withFiles && (note.fileIds == null || note.fileIds.length === 0)) return;
|
||||||
|
|
||||||
if (note.channelId) {
|
if (note.channelId) {
|
||||||
// そのチャンネルをフォローしていない or そのチャンネル(リノート・引用リノート含む)はミュートしている
|
// そのチャンネルをフォローしていない
|
||||||
if (!this.followingChannels.has(note.channelId) || isChannelRelated(note, this.mutingChannels)) {
|
if (!this.followingChannels.has(note.channelId)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -67,11 +67,7 @@ class HybridTimelineChannel extends Channel {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 以下の条件に該当するノートのみ後続処理に通す(ので、以下のif文は該当しないノートをすべて弾くようにする)
|
// 以下の条件に該当するノートのみ後続処理に通す(ので、以下のif文は該当しないノートをすべて弾くようにする)
|
||||||
// - ミュートしていないチャンネルの投稿(リノート・引用リノートもチェック対象)
|
|
||||||
// - フォローしているチャンネルの投稿
|
// - フォローしているチャンネルの投稿
|
||||||
if (isChannelRelated(note, this.mutingChannels)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!this.followingChannels.has(note.channelId)) {
|
if (!this.followingChannels.has(note.channelId)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue