Mod: isReactionBlockからenumに変更

This commit is contained in:
鴇峰 朔華 2024-11-18 21:03:33 +09:00
parent 202fceed22
commit 3ea69b6203
13 changed files with 132 additions and 81 deletions

View File

@ -72,7 +72,8 @@ export class QueryService {
public generateBlockedUserQuery(q: SelectQueryBuilder<any>, me: { id: MiUser['id'] }): void { public generateBlockedUserQuery(q: SelectQueryBuilder<any>, me: { id: MiUser['id'] }): void {
const blockingQuery = this.blockingsRepository.createQueryBuilder('blocking') const blockingQuery = this.blockingsRepository.createQueryBuilder('blocking')
.select('blocking.blockerId') .select('blocking.blockerId')
.where('blocking.blockeeId = :blockeeId', { blockeeId: me.id }); .where('blocking.blockeeId = :blockeeId', { blockeeId: me.id })
.andWhere('blocking.blockType = "user"');
// 投稿の作者にブロックされていない かつ // 投稿の作者にブロックされていない かつ
// 投稿の返信先の作者にブロックされていない かつ // 投稿の返信先の作者にブロックされていない かつ
@ -97,7 +98,8 @@ export class QueryService {
public generateBlockQueryForUsers(q: SelectQueryBuilder<any>, me: { id: MiUser['id'] }): void { public generateBlockQueryForUsers(q: SelectQueryBuilder<any>, me: { id: MiUser['id'] }): void {
const blockingQuery = this.blockingsRepository.createQueryBuilder('blocking') const blockingQuery = this.blockingsRepository.createQueryBuilder('blocking')
.select('blocking.blockeeId') .select('blocking.blockeeId')
.where('blocking.blockerId = :blockerId', { blockerId: me.id }); .where('blocking.blockerId = :blockerId', { blockerId: me.id })
.andWhere('blocking.blockType = "user"');
const blockedQuery = this.blockingsRepository.createQueryBuilder('blocking') const blockedQuery = this.blockingsRepository.createQueryBuilder('blocking')
.select('blocking.blockerId') .select('blocking.blockerId')

View File

@ -3,15 +3,21 @@
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
import { Inject, Injectable, OnModuleInit } from '@nestjs/common'; import {Inject, Injectable, OnModuleInit} from '@nestjs/common';
import { ModuleRef } from '@nestjs/core'; import {ModuleRef} from '@nestjs/core';
import { IdService } from '@/core/IdService.js'; import {IdService} from '@/core/IdService.js';
import type { MiUser } from '@/models/User.js'; import type {MiUser} from '@/models/User.js';
import type { MiBlocking } from '@/models/Blocking.js'; import type {MiBlocking} from '@/models/Blocking.js';
import { QueueService } from '@/core/QueueService.js'; import {MiBlockingType} from '@/models/Blocking.js';
import { GlobalEventService } from '@/core/GlobalEventService.js'; import {QueueService} from '@/core/QueueService.js';
import { DI } from '@/di-symbols.js'; import {GlobalEventService} from '@/core/GlobalEventService.js';
import type { FollowRequestsRepository, BlockingsRepository, UserListsRepository, UserListMembershipsRepository } from '@/models/_.js'; import {DI} from '@/di-symbols.js';
import type {
BlockingsRepository,
FollowRequestsRepository,
UserListMembershipsRepository,
UserListsRepository,
} from '@/models/_.js';
import Logger from '@/logger.js'; import Logger from '@/logger.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js';
import { ApRendererService } from '@/core/activitypub/ApRendererService.js'; import { ApRendererService } from '@/core/activitypub/ApRendererService.js';
@ -20,6 +26,7 @@ import { UserWebhookService } from '@/core/UserWebhookService.js';
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
import { CacheService } from '@/core/CacheService.js'; import { CacheService } from '@/core/CacheService.js';
import { UserFollowingService } from '@/core/UserFollowingService.js'; import { UserFollowingService } from '@/core/UserFollowingService.js';
import { UserReactionBlockingService } from '@/core/UserReactionBlockingService.js';
@Injectable() @Injectable()
export class UserBlockingService implements OnModuleInit { export class UserBlockingService implements OnModuleInit {
@ -43,6 +50,7 @@ export class UserBlockingService implements OnModuleInit {
private cacheService: CacheService, private cacheService: CacheService,
private userEntityService: UserEntityService, private userEntityService: UserEntityService,
private userReactionBlockingService: UserReactionBlockingService,
private idService: IdService, private idService: IdService,
private queueService: QueueService, private queueService: QueueService,
private globalEventService: GlobalEventService, private globalEventService: GlobalEventService,
@ -67,15 +75,27 @@ export class UserBlockingService implements OnModuleInit {
this.removeFromList(blockee, blocker), this.removeFromList(blockee, blocker),
]); ]);
const blocking = { const blocking = await this.blockingsRepository.findOneBy({
id: this.idService.gen(),
blocker,
blockerId: blocker.id, blockerId: blocker.id,
blockee,
blockeeId: blockee.id, blockeeId: blockee.id,
isReactionBlock: false, }).then(blocking => {
} as MiBlocking; if (blocking) {
return blocking;
}
return {
id: this.idService.gen(),
blocker,
blockerId: blocker.id,
blockee,
blockeeId: blockee.id,
blockType: MiBlockingType.User,
} as MiBlocking;
});
if (blocking.blockType === MiBlockingType.Reaction) {
await this.userReactionBlockingService.unblock(blocker, blockee);
}
blocking.blockType = MiBlockingType.User;
await this.blockingsRepository.insert(blocking); await this.blockingsRepository.insert(blocking);
this.cacheService.userBlockingCache.refresh(blocker.id); this.cacheService.userBlockingCache.refresh(blocker.id);
@ -161,7 +181,7 @@ export class UserBlockingService implements OnModuleInit {
const blocking = await this.blockingsRepository.findOneBy({ const blocking = await this.blockingsRepository.findOneBy({
blockerId: blocker.id, blockerId: blocker.id,
blockeeId: blockee.id, blockeeId: blockee.id,
isReactionBlock: false, blockType: MiBlockingType.User,
}); });
if (blocking == null) { if (blocking == null) {
@ -177,17 +197,23 @@ export class UserBlockingService implements OnModuleInit {
await this.blockingsRepository.delete(blocking.id); await this.blockingsRepository.delete(blocking.id);
this.cacheService.userReactionBlockedCache.refresh(blocker.id); this.cacheService.userBlockingCache.refresh(blocker.id);
this.cacheService.userReactionBlockedCache.refresh(blockee.id); this.cacheService.userBlockedCache.refresh(blockee.id);
this.globalEventService.publishInternalEvent('blockingReactionDeleted', { this.globalEventService.publishInternalEvent('blockingDeleted', {
blockerId: blocker.id, blockerId: blocker.id,
blockeeId: blockee.id, blockeeId: blockee.id,
}); });
// deliver if remote bloking
if (this.userEntityService.isLocalUser(blocker) && this.userEntityService.isRemoteUser(blockee)) {
const content = this.apRendererService.addContext(this.apRendererService.renderUndo(this.apRendererService.renderBlock(blocking), blocker));
this.queueService.deliver(blocker, content, blockee.inbox, false);
}
} }
@bindThis @bindThis
public async checkBlocked(blockerId: MiUser['id'], blockeeId: MiUser['id']): Promise<boolean> { public async checkBlocked(blockerId: MiUser['id'], blockeeId: MiUser['id']): Promise<boolean> {
return (await this.cacheService.userReactionBlockingCache.fetch(blockerId)).has(blockeeId); return (await this.cacheService.userBlockingCache.fetch(blockerId)).has(blockeeId);
} }
} }

View File

@ -20,6 +20,8 @@ import { UserWebhookService } from '@/core/UserWebhookService.js';
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
import { CacheService } from '@/core/CacheService.js'; import { CacheService } from '@/core/CacheService.js';
import { UserFollowingService } from '@/core/UserFollowingService.js'; import { UserFollowingService } from '@/core/UserFollowingService.js';
import {MiBlockingType} from "@/models/Blocking.js";
import {UserBlockingService} from "@/core/UserBlockingService.js";
@Injectable() @Injectable()
export class UserReactionBlockingService { export class UserReactionBlockingService {
@ -37,6 +39,7 @@ export class UserReactionBlockingService {
private cacheService: CacheService, private cacheService: CacheService,
private userEntityService: UserEntityService, private userEntityService: UserEntityService,
private userBlockingService: UserBlockingService,
private idService: IdService, private idService: IdService,
private queueService: QueueService, private queueService: QueueService,
private globalEventService: GlobalEventService, private globalEventService: GlobalEventService,
@ -49,15 +52,27 @@ export class UserReactionBlockingService {
@bindThis @bindThis
public async block(blocker: MiUser, blockee: MiUser, silent = false) { public async block(blocker: MiUser, blockee: MiUser, silent = false) {
const blocking = { const blocking = await this.blockingsRepository.findOneBy({
id: this.idService.gen(),
blocker,
blockerId: blocker.id, blockerId: blocker.id,
blockee,
blockeeId: blockee.id, blockeeId: blockee.id,
isReactionBlock: true, }).then(blocking => {
} satisfies MiBlocking; if (blocking) {
return blocking;
}
return {
id: this.idService.gen(),
blocker,
blockerId: blocker.id,
blockee,
blockeeId: blockee.id,
blockType: MiBlockingType.Reaction,
} as MiBlocking;
});
if (blocking.blockType === MiBlockingType.User) {
await this.userBlockingService.unblock(blocker, blockee);
}
blocking.blockType = MiBlockingType.Reaction;
await this.blockingsRepository.insert(blocking); await this.blockingsRepository.insert(blocking);
this.cacheService.userReactionBlockingCache.refresh(blocker.id); this.cacheService.userReactionBlockingCache.refresh(blocker.id);
@ -74,7 +89,7 @@ export class UserReactionBlockingService {
const blocking = await this.blockingsRepository.findOneBy({ const blocking = await this.blockingsRepository.findOneBy({
blockerId: blocker.id, blockerId: blocker.id,
blockeeId: blockee.id, blockeeId: blockee.id,
isReactionBlock: true, blockType: MiBlockingType.Reaction,
}); });
if (blocking == null) { if (blocking == null) {
@ -89,23 +104,17 @@ export class UserReactionBlockingService {
await this.blockingsRepository.delete(blocking.id); await this.blockingsRepository.delete(blocking.id);
this.cacheService.userBlockingCache.refresh(blocker.id); this.cacheService.userReactionBlockingCache.refresh(blocker.id);
this.cacheService.userBlockedCache.refresh(blockee.id); this.cacheService.userReactionBlockedCache.refresh(blockee.id);
this.globalEventService.publishInternalEvent('blockingDeleted', { this.globalEventService.publishInternalEvent('blockingReactionDeleted', {
blockerId: blocker.id, blockerId: blocker.id,
blockeeId: blockee.id, blockeeId: blockee.id,
}); });
// deliver if remote bloking
if (this.userEntityService.isLocalUser(blocker) && this.userEntityService.isRemoteUser(blockee)) {
const content = this.apRendererService.addContext(this.apRendererService.renderUndo(this.apRendererService.renderBlock(blocking), blocker));
this.queueService.deliver(blocker, content, blockee.inbox, false);
}
} }
@bindThis @bindThis
public async checkBlocked(blockerId: MiUser['id'], blockeeId: MiUser['id']): Promise<boolean> { public async checkBlocked(blockerId: MiUser['id'], blockeeId: MiUser['id']): Promise<boolean> {
return (await this.cacheService.userBlockingCache.fetch(blockerId)).has(blockeeId); return (await this.cacheService.userReactionBlockingCache.fetch(blockerId)).has(blockeeId);
} }
} }

View File

@ -27,6 +27,7 @@ import type {
BlockingsRepository, BlockingsRepository,
FollowingsRepository, FollowingsRepository,
FollowRequestsRepository, FollowRequestsRepository,
MiBlockingType,
MiFollowing, MiFollowing,
MiUserNotePining, MiUserNotePining,
MiUserProfile, MiUserProfile,
@ -202,28 +203,28 @@ export class UserEntityService implements OnModuleInit {
where: { where: {
blockerId: me, blockerId: me,
blockeeId: target, blockeeId: target,
isReactionBlock: false, blockType: MiBlockingType.User,
}, },
}), }),
this.blockingsRepository.exists({ this.blockingsRepository.exists({
where: { where: {
blockerId: target, blockerId: target,
blockeeId: me, blockeeId: me,
isReactionBlock: false, blockType: MiBlockingType.User,
}, },
}), }),
this.blockingsRepository.exists({ this.blockingsRepository.exists({
where: { where: {
blockerId: me, blockerId: me,
blockeeId: target, blockeeId: target,
isReactionBlock: true, blockType: MiBlockingType.Reaction,
}, },
}), }),
this.blockingsRepository.exists({ this.blockingsRepository.exists({
where: { where: {
blockerId: target, blockerId: target,
blockeeId: me, blockeeId: me,
isReactionBlock: true, blockType: MiBlockingType.Reaction,
}, },
}), }),
this.mutingsRepository.exists({ this.mutingsRepository.exists({
@ -290,25 +291,25 @@ export class UserEntityService implements OnModuleInit {
this.blockingsRepository.createQueryBuilder('b') this.blockingsRepository.createQueryBuilder('b')
.select('b.blockeeId') .select('b.blockeeId')
.where('b.blockerId = :me', { me }) .where('b.blockerId = :me', { me })
.andWhere('b.isReactionBlock = false') .andWhere('b.blockType = "user"')
.getRawMany<{ b_blockeeId: string }>() .getRawMany<{ b_blockeeId: string }>()
.then(it => it.map(it => it.b_blockeeId)), .then(it => it.map(it => it.b_blockeeId)),
this.blockingsRepository.createQueryBuilder('b') this.blockingsRepository.createQueryBuilder('b')
.select('b.blockerId') .select('b.blockerId')
.where('b.blockeeId = :me', { me }) .where('b.blockeeId = :me', { me })
.andWhere('b.isReactionBlock = false') .andWhere('b.blockType = "user"')
.getRawMany<{ b_blockerId: string }>() .getRawMany<{ b_blockerId: string }>()
.then(it => it.map(it => it.b_blockerId)), .then(it => it.map(it => it.b_blockerId)),
this.blockingsRepository.createQueryBuilder('b') this.blockingsRepository.createQueryBuilder('b')
.select('b.blockeeId') .select('b.blockeeId')
.where('b.blockerId = :me', { me }) .where('b.blockerId = :me', { me })
.andWhere('b.isReactionBlock = true') .andWhere('b.blockType = "reaction"')
.getRawMany<{ b_blockeeId: string }>() .getRawMany<{ b_blockeeId: string }>()
.then(it => it.map(it => it.b_blockeeId)), .then(it => it.map(it => it.b_blockeeId)),
this.blockingsRepository.createQueryBuilder('b') this.blockingsRepository.createQueryBuilder('b')
.select('b.blockerId') .select('b.blockerId')
.where('b.blockeeId = :me', { me }) .where('b.blockeeId = :me', { me })
.andWhere('b.isReactionBlock = true') .andWhere('b.blockType = "reaction"')
.getRawMany<{ b_blockerId: string }>() .getRawMany<{ b_blockerId: string }>()
.then(it => it.map(it => it.b_blockerId)), .then(it => it.map(it => it.b_blockerId)),
this.mutingsRepository.createQueryBuilder('m') this.mutingsRepository.createQueryBuilder('m')

View File

@ -7,6 +7,11 @@ import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typ
import { id } from './util/id.js'; import { id } from './util/id.js';
import { MiUser } from './User.js'; import { MiUser } from './User.js';
export enum MiBlockingType {
User = 'user',
Reaction = 'reaction',
}
@Entity('blocking') @Entity('blocking')
@Index(['blockerId', 'blockeeId'], { unique: true }) @Index(['blockerId', 'blockeeId'], { unique: true })
export class MiBlocking { export class MiBlocking {
@ -41,8 +46,8 @@ export class MiBlocking {
@Index() @Index()
@Column({ @Column({
comment: 'Whether the blockee is a reaction block.', comment: 'Block type.',
default: false, default: MiBlockingType.User,
}) })
public isReactionBlock: boolean; public blockType: MiBlockingType;
} }

View File

@ -20,7 +20,7 @@ import { MiAntenna } from '@/models/Antenna.js';
import { MiApp } from '@/models/App.js'; import { MiApp } from '@/models/App.js';
import { MiAvatarDecoration } from '@/models/AvatarDecoration.js'; import { MiAvatarDecoration } from '@/models/AvatarDecoration.js';
import { MiAuthSession } from '@/models/AuthSession.js'; import { MiAuthSession } from '@/models/AuthSession.js';
import { MiBlocking } from '@/models/Blocking.js'; import { MiBlocking, MiBlockingType } from '@/models/Blocking.js';
import { MiChannelFollowing } from '@/models/ChannelFollowing.js'; import { MiChannelFollowing } from '@/models/ChannelFollowing.js';
import { MiChannelFavorite } from '@/models/ChannelFavorite.js'; import { MiChannelFavorite } from '@/models/ChannelFavorite.js';
import { MiClip } from '@/models/Clip.js'; import { MiClip } from '@/models/Clip.js';
@ -136,6 +136,7 @@ export {
MiAvatarDecoration, MiAvatarDecoration,
MiAuthSession, MiAuthSession,
MiBlocking, MiBlocking,
MiBlockingType,
MiChannelFollowing, MiChannelFollowing,
MiChannelFavorite, MiChannelFavorite,
MiClip, MiClip,

View File

@ -27,9 +27,10 @@ export const packedBlockingSchema = {
optional: false, nullable: false, optional: false, nullable: false,
ref: 'UserDetailedNotMe', ref: 'UserDetailedNotMe',
}, },
isReactionBlock: { blockType: {
type: 'boolean', type: 'string',
optional: false, nullable: false, optional: false, nullable: false,
enum: ['user', 'reaction'],
}, },
}, },
} as const; } as const;

View File

@ -4,14 +4,15 @@
*/ */
import ms from 'ms'; import ms from 'ms';
import { Inject, Injectable } from '@nestjs/common'; import {Inject, Injectable} from '@nestjs/common';
import { Endpoint } from '@/server/api/endpoint-base.js'; import {Endpoint} from '@/server/api/endpoint-base.js';
import type { UsersRepository, BlockingsRepository } from '@/models/_.js'; import type {BlockingsRepository, UsersRepository} from '@/models/_.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js'; import {MiBlockingType} from "@/models/_.js";
import { DI } from '@/di-symbols.js'; import {UserEntityService} from '@/core/entities/UserEntityService.js';
import { GetterService } from '@/server/api/GetterService.js'; import {DI} from '@/di-symbols.js';
import { ApiError } from '../../error.js'; import {GetterService} from '@/server/api/GetterService.js';
import { UserReactionBlockingService } from '@/core/UserReactionBlockingService.js'; import {ApiError} from '../../error.js';
import {UserReactionBlockingService} from '@/core/UserReactionBlockingService.js';
export const meta = { export const meta = {
tags: ['account'], tags: ['account'],
@ -92,7 +93,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
where: { where: {
blockerId: blocker.id, blockerId: blocker.id,
blockeeId: blockee.id, blockeeId: blockee.id,
isReactionBlock: true, blockType: MiBlockingType.Reaction,
}, },
}); });

View File

@ -12,6 +12,7 @@ import { UserReactionBlockingService } from '@/core/UserReactionBlockingService.
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
import { GetterService } from '@/server/api/GetterService.js'; import { GetterService } from '@/server/api/GetterService.js';
import { ApiError } from '../../error.js'; import { ApiError } from '../../error.js';
import {MiBlockingType} from "@/models/_.js";
export const meta = { export const meta = {
tags: ['account'], tags: ['account'],
@ -92,7 +93,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
where: { where: {
blockerId: blocker.id, blockerId: blocker.id,
blockeeId: blockee.id, blockeeId: blockee.id,
isReactionBlock: true, blockType: MiBlockingType.Reaction,
}, },
}); });

View File

@ -50,7 +50,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
super(meta, paramDef, async (ps, me) => { super(meta, paramDef, async (ps, me) => {
const query = this.queryService.makePaginationQuery(this.blockingsRepository.createQueryBuilder('blocking'), ps.sinceId, ps.untilId) const query = this.queryService.makePaginationQuery(this.blockingsRepository.createQueryBuilder('blocking'), ps.sinceId, ps.untilId)
.andWhere('blocking.blockerId = :meId', { meId: me.id }) .andWhere('blocking.blockerId = :meId', { meId: me.id })
.andWhere('blocking.isReactionBlock = true'); .andWhere('blocking.blockType = "reaction"');
const blockings = await query const blockings = await query
.limit(ps.limit) .limit(ps.limit)

View File

@ -4,14 +4,15 @@
*/ */
import ms from 'ms'; import ms from 'ms';
import { Inject, Injectable } from '@nestjs/common'; import {Inject, Injectable} from '@nestjs/common';
import { Endpoint } from '@/server/api/endpoint-base.js'; import {Endpoint} from '@/server/api/endpoint-base.js';
import type { UsersRepository, BlockingsRepository } from '@/models/_.js'; import type {BlockingsRepository, UsersRepository} from '@/models/_.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js'; import {MiBlockingType} from "@/models/_.js";
import { UserBlockingService } from '@/core/UserBlockingService.js'; import {UserEntityService} from '@/core/entities/UserEntityService.js';
import { DI } from '@/di-symbols.js'; import {UserBlockingService} from '@/core/UserBlockingService.js';
import { GetterService } from '@/server/api/GetterService.js'; import {DI} from '@/di-symbols.js';
import { ApiError } from '../../error.js'; import {GetterService} from '@/server/api/GetterService.js';
import {ApiError} from '../../error.js';
export const meta = { export const meta = {
tags: ['account'], tags: ['account'],
@ -92,6 +93,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
where: { where: {
blockerId: blocker.id, blockerId: blocker.id,
blockeeId: blockee.id, blockeeId: blockee.id,
blockType: MiBlockingType.User,
}, },
}); });

View File

@ -4,14 +4,15 @@
*/ */
import ms from 'ms'; import ms from 'ms';
import { Inject, Injectable } from '@nestjs/common'; import {Inject, Injectable} from '@nestjs/common';
import { Endpoint } from '@/server/api/endpoint-base.js'; import {Endpoint} from '@/server/api/endpoint-base.js';
import type { UsersRepository, BlockingsRepository } from '@/models/_.js'; import type {BlockingsRepository, UsersRepository} from '@/models/_.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js'; import {MiBlockingType} from "@/models/_.js";
import { UserBlockingService } from '@/core/UserBlockingService.js'; import {UserEntityService} from '@/core/entities/UserEntityService.js';
import { DI } from '@/di-symbols.js'; import {UserBlockingService} from '@/core/UserBlockingService.js';
import { GetterService } from '@/server/api/GetterService.js'; import {DI} from '@/di-symbols.js';
import { ApiError } from '../../error.js'; import {GetterService} from '@/server/api/GetterService.js';
import {ApiError} from '../../error.js';
export const meta = { export const meta = {
tags: ['account'], tags: ['account'],
@ -92,6 +93,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
where: { where: {
blockerId: blocker.id, blockerId: blocker.id,
blockeeId: blockee.id, blockeeId: blockee.id,
blockType: MiBlockingType.User,
}, },
}); });

View File

@ -50,7 +50,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
super(meta, paramDef, async (ps, me) => { super(meta, paramDef, async (ps, me) => {
const query = this.queryService.makePaginationQuery(this.blockingsRepository.createQueryBuilder('blocking'), ps.sinceId, ps.untilId) const query = this.queryService.makePaginationQuery(this.blockingsRepository.createQueryBuilder('blocking'), ps.sinceId, ps.untilId)
.andWhere('blocking.blockerId = :meId', { meId: me.id }) .andWhere('blocking.blockerId = :meId', { meId: me.id })
.andWhere('blocking.isReactionBlock = false'); .andWhere('blocking.blockType = "user"');
const blockings = await query const blockings = await query
.limit(ps.limit) .limit(ps.limit)