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 {
const blockingQuery = this.blockingsRepository.createQueryBuilder('blocking')
.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 {
const blockingQuery = this.blockingsRepository.createQueryBuilder('blocking')
.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')
.select('blocking.blockerId')

View File

@ -3,15 +3,21 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { Inject, Injectable, OnModuleInit } from '@nestjs/common';
import { ModuleRef } from '@nestjs/core';
import { IdService } from '@/core/IdService.js';
import type { MiUser } from '@/models/User.js';
import type { MiBlocking } from '@/models/Blocking.js';
import { QueueService } from '@/core/QueueService.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
import { DI } from '@/di-symbols.js';
import type { FollowRequestsRepository, BlockingsRepository, UserListsRepository, UserListMembershipsRepository } from '@/models/_.js';
import {Inject, Injectable, OnModuleInit} from '@nestjs/common';
import {ModuleRef} from '@nestjs/core';
import {IdService} from '@/core/IdService.js';
import type {MiUser} from '@/models/User.js';
import type {MiBlocking} from '@/models/Blocking.js';
import {MiBlockingType} from '@/models/Blocking.js';
import {QueueService} from '@/core/QueueService.js';
import {GlobalEventService} from '@/core/GlobalEventService.js';
import {DI} from '@/di-symbols.js';
import type {
BlockingsRepository,
FollowRequestsRepository,
UserListMembershipsRepository,
UserListsRepository,
} from '@/models/_.js';
import Logger from '@/logger.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js';
import { ApRendererService } from '@/core/activitypub/ApRendererService.js';
@ -20,6 +26,7 @@ import { UserWebhookService } from '@/core/UserWebhookService.js';
import { bindThis } from '@/decorators.js';
import { CacheService } from '@/core/CacheService.js';
import { UserFollowingService } from '@/core/UserFollowingService.js';
import { UserReactionBlockingService } from '@/core/UserReactionBlockingService.js';
@Injectable()
export class UserBlockingService implements OnModuleInit {
@ -43,6 +50,7 @@ export class UserBlockingService implements OnModuleInit {
private cacheService: CacheService,
private userEntityService: UserEntityService,
private userReactionBlockingService: UserReactionBlockingService,
private idService: IdService,
private queueService: QueueService,
private globalEventService: GlobalEventService,
@ -67,15 +75,27 @@ export class UserBlockingService implements OnModuleInit {
this.removeFromList(blockee, blocker),
]);
const blocking = {
const blocking = await this.blockingsRepository.findOneBy({
blockerId: blocker.id,
blockeeId: blockee.id,
}).then(blocking => {
if (blocking) {
return blocking;
}
return {
id: this.idService.gen(),
blocker,
blockerId: blocker.id,
blockee,
blockeeId: blockee.id,
isReactionBlock: false,
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);
this.cacheService.userBlockingCache.refresh(blocker.id);
@ -161,7 +181,7 @@ export class UserBlockingService implements OnModuleInit {
const blocking = await this.blockingsRepository.findOneBy({
blockerId: blocker.id,
blockeeId: blockee.id,
isReactionBlock: false,
blockType: MiBlockingType.User,
});
if (blocking == null) {
@ -177,17 +197,23 @@ export class UserBlockingService implements OnModuleInit {
await this.blockingsRepository.delete(blocking.id);
this.cacheService.userReactionBlockedCache.refresh(blocker.id);
this.cacheService.userReactionBlockedCache.refresh(blockee.id);
this.cacheService.userBlockingCache.refresh(blocker.id);
this.cacheService.userBlockedCache.refresh(blockee.id);
this.globalEventService.publishInternalEvent('blockingReactionDeleted', {
this.globalEventService.publishInternalEvent('blockingDeleted', {
blockerId: blocker.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
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 { CacheService } from '@/core/CacheService.js';
import { UserFollowingService } from '@/core/UserFollowingService.js';
import {MiBlockingType} from "@/models/Blocking.js";
import {UserBlockingService} from "@/core/UserBlockingService.js";
@Injectable()
export class UserReactionBlockingService {
@ -37,6 +39,7 @@ export class UserReactionBlockingService {
private cacheService: CacheService,
private userEntityService: UserEntityService,
private userBlockingService: UserBlockingService,
private idService: IdService,
private queueService: QueueService,
private globalEventService: GlobalEventService,
@ -49,15 +52,27 @@ export class UserReactionBlockingService {
@bindThis
public async block(blocker: MiUser, blockee: MiUser, silent = false) {
const blocking = {
const blocking = await this.blockingsRepository.findOneBy({
blockerId: blocker.id,
blockeeId: blockee.id,
}).then(blocking => {
if (blocking) {
return blocking;
}
return {
id: this.idService.gen(),
blocker,
blockerId: blocker.id,
blockee,
blockeeId: blockee.id,
isReactionBlock: true,
} satisfies MiBlocking;
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);
this.cacheService.userReactionBlockingCache.refresh(blocker.id);
@ -74,7 +89,7 @@ export class UserReactionBlockingService {
const blocking = await this.blockingsRepository.findOneBy({
blockerId: blocker.id,
blockeeId: blockee.id,
isReactionBlock: true,
blockType: MiBlockingType.Reaction,
});
if (blocking == null) {
@ -89,23 +104,17 @@ export class UserReactionBlockingService {
await this.blockingsRepository.delete(blocking.id);
this.cacheService.userBlockingCache.refresh(blocker.id);
this.cacheService.userBlockedCache.refresh(blockee.id);
this.cacheService.userReactionBlockingCache.refresh(blocker.id);
this.cacheService.userReactionBlockedCache.refresh(blockee.id);
this.globalEventService.publishInternalEvent('blockingDeleted', {
this.globalEventService.publishInternalEvent('blockingReactionDeleted', {
blockerId: blocker.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
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,
FollowingsRepository,
FollowRequestsRepository,
MiBlockingType,
MiFollowing,
MiUserNotePining,
MiUserProfile,
@ -202,28 +203,28 @@ export class UserEntityService implements OnModuleInit {
where: {
blockerId: me,
blockeeId: target,
isReactionBlock: false,
blockType: MiBlockingType.User,
},
}),
this.blockingsRepository.exists({
where: {
blockerId: target,
blockeeId: me,
isReactionBlock: false,
blockType: MiBlockingType.User,
},
}),
this.blockingsRepository.exists({
where: {
blockerId: me,
blockeeId: target,
isReactionBlock: true,
blockType: MiBlockingType.Reaction,
},
}),
this.blockingsRepository.exists({
where: {
blockerId: target,
blockeeId: me,
isReactionBlock: true,
blockType: MiBlockingType.Reaction,
},
}),
this.mutingsRepository.exists({
@ -290,25 +291,25 @@ export class UserEntityService implements OnModuleInit {
this.blockingsRepository.createQueryBuilder('b')
.select('b.blockeeId')
.where('b.blockerId = :me', { me })
.andWhere('b.isReactionBlock = false')
.andWhere('b.blockType = "user"')
.getRawMany<{ b_blockeeId: string }>()
.then(it => it.map(it => it.b_blockeeId)),
this.blockingsRepository.createQueryBuilder('b')
.select('b.blockerId')
.where('b.blockeeId = :me', { me })
.andWhere('b.isReactionBlock = false')
.andWhere('b.blockType = "user"')
.getRawMany<{ b_blockerId: string }>()
.then(it => it.map(it => it.b_blockerId)),
this.blockingsRepository.createQueryBuilder('b')
.select('b.blockeeId')
.where('b.blockerId = :me', { me })
.andWhere('b.isReactionBlock = true')
.andWhere('b.blockType = "reaction"')
.getRawMany<{ b_blockeeId: string }>()
.then(it => it.map(it => it.b_blockeeId)),
this.blockingsRepository.createQueryBuilder('b')
.select('b.blockerId')
.where('b.blockeeId = :me', { me })
.andWhere('b.isReactionBlock = true')
.andWhere('b.blockType = "reaction"')
.getRawMany<{ b_blockerId: string }>()
.then(it => it.map(it => it.b_blockerId)),
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 { MiUser } from './User.js';
export enum MiBlockingType {
User = 'user',
Reaction = 'reaction',
}
@Entity('blocking')
@Index(['blockerId', 'blockeeId'], { unique: true })
export class MiBlocking {
@ -41,8 +46,8 @@ export class MiBlocking {
@Index()
@Column({
comment: 'Whether the blockee is a reaction block.',
default: false,
comment: 'Block type.',
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 { MiAvatarDecoration } from '@/models/AvatarDecoration.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 { MiChannelFavorite } from '@/models/ChannelFavorite.js';
import { MiClip } from '@/models/Clip.js';
@ -136,6 +136,7 @@ export {
MiAvatarDecoration,
MiAuthSession,
MiBlocking,
MiBlockingType,
MiChannelFollowing,
MiChannelFavorite,
MiClip,

View File

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

View File

@ -4,14 +4,15 @@
*/
import ms from 'ms';
import { Inject, Injectable } from '@nestjs/common';
import { Endpoint } from '@/server/api/endpoint-base.js';
import type { UsersRepository, BlockingsRepository } from '@/models/_.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js';
import { DI } from '@/di-symbols.js';
import { GetterService } from '@/server/api/GetterService.js';
import { ApiError } from '../../error.js';
import { UserReactionBlockingService } from '@/core/UserReactionBlockingService.js';
import {Inject, Injectable} from '@nestjs/common';
import {Endpoint} from '@/server/api/endpoint-base.js';
import type {BlockingsRepository, UsersRepository} from '@/models/_.js';
import {MiBlockingType} from "@/models/_.js";
import {UserEntityService} from '@/core/entities/UserEntityService.js';
import {DI} from '@/di-symbols.js';
import {GetterService} from '@/server/api/GetterService.js';
import {ApiError} from '../../error.js';
import {UserReactionBlockingService} from '@/core/UserReactionBlockingService.js';
export const meta = {
tags: ['account'],
@ -92,7 +93,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
where: {
blockerId: blocker.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 { GetterService } from '@/server/api/GetterService.js';
import { ApiError } from '../../error.js';
import {MiBlockingType} from "@/models/_.js";
export const meta = {
tags: ['account'],
@ -92,7 +93,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
where: {
blockerId: blocker.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) => {
const query = this.queryService.makePaginationQuery(this.blockingsRepository.createQueryBuilder('blocking'), ps.sinceId, ps.untilId)
.andWhere('blocking.blockerId = :meId', { meId: me.id })
.andWhere('blocking.isReactionBlock = true');
.andWhere('blocking.blockType = "reaction"');
const blockings = await query
.limit(ps.limit)

View File

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

View File

@ -4,14 +4,15 @@
*/
import ms from 'ms';
import { Inject, Injectable } from '@nestjs/common';
import { Endpoint } from '@/server/api/endpoint-base.js';
import type { UsersRepository, BlockingsRepository } from '@/models/_.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js';
import { UserBlockingService } from '@/core/UserBlockingService.js';
import { DI } from '@/di-symbols.js';
import { GetterService } from '@/server/api/GetterService.js';
import { ApiError } from '../../error.js';
import {Inject, Injectable} from '@nestjs/common';
import {Endpoint} from '@/server/api/endpoint-base.js';
import type {BlockingsRepository, UsersRepository} from '@/models/_.js';
import {MiBlockingType} from "@/models/_.js";
import {UserEntityService} from '@/core/entities/UserEntityService.js';
import {UserBlockingService} from '@/core/UserBlockingService.js';
import {DI} from '@/di-symbols.js';
import {GetterService} from '@/server/api/GetterService.js';
import {ApiError} from '../../error.js';
export const meta = {
tags: ['account'],
@ -92,6 +93,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
where: {
blockerId: blocker.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) => {
const query = this.queryService.makePaginationQuery(this.blockingsRepository.createQueryBuilder('blocking'), ps.sinceId, ps.untilId)
.andWhere('blocking.blockerId = :meId', { meId: me.id })
.andWhere('blocking.isReactionBlock = false');
.andWhere('blocking.blockType = "user"');
const blockings = await query
.limit(ps.limit)