-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat: 特定ユーザーからのリアクションをブロックする機能の追加 #14986
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/* | ||
* SPDX-FileCopyrightText: sakuhanight and misskey-project | ||
* SPDX-License-Identifier: AGPL-3.0-only | ||
*/ | ||
|
||
export class MakeNotesHiddenBefore1729486255072 { | ||
name = 'AddBlockingReactionUser1731566099974' | ||
async up(queryRunner) { | ||
await queryRunner.query(` | ||
CREATE TABLE "blocking_reaction_user"( | ||
id varchar(32) NULL, | ||
blockeeId varchar(32) NULL, | ||
blockerId varchar(32) NULL, | ||
CONSTRAINT "PK_blocking_reaction_user" PRIMARY KEY (id), | ||
CONSTRAINT "FK_blocking_reaction_user_blockeeid" FOREIGN KEY (blockeeid) REFERENCES "user" (id) ON DELETE CASCADE, | ||
CONSTRAINT "FK_blocking_reaction_user_blockerid" FOREIGN KEY (blockerid) REFERENCES "user" (id) ON DELETE CASCADE); | ||
`); | ||
await queryRunner.query(`CREATE INDEX "IDX_blocking_reaction_user_id" ON "blocking_reaction_user" (id);`); | ||
await queryRunner.query(`CREATE INDEX "IDX_blocking_reaction_user_blockeeid" ON "blocking_reaction_user" (blockeeid);`); | ||
await queryRunner.query(`CREATE INDEX "IDX_blocking_reaction_user_blockerid" ON "blocking_reaction_user" (blockerid);`); | ||
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_blocking_reaction_user_blockeeid_blockerid" ON "blocking_reaction_user" (blockeeid, blockerid);`); | ||
} | ||
|
||
async down(queryRunner) { | ||
await queryRunner.query(`DROP INDEX "IDX_blocking_reaction_user_blockeeid_blockerid";`); | ||
await queryRunner.query(`DROP INDEX "IDX_blocking_reaction_user_blockerid";`); | ||
await queryRunner.query(`DROP INDEX "IDX_blocking_reaction_user_blockeeid";`); | ||
await queryRunner.query(`DROP INDEX "IDX_blocking_reaction_user_id";`); | ||
await queryRunner.query(`ALTER TABLE "blocking_reaction_user" DROP CONSTRAINT "FK_blocking_reaction_user_blockerid";`); | ||
await queryRunner.query(`ALTER TABLE "blocking_reaction_user" DROP CONSTRAINT "FK_blocking_reaction_user_blockeeid";`); | ||
await queryRunner.query(`ALTER TABLE "blocking_reaction_user" DROP CONSTRAINT "PK_blocking_reaction_user";`); | ||
await queryRunner.query(`DROP TABLE "blocking_reaction_user";`); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,110 @@ | ||||||
/* | ||||||
* SPDX-FileCopyrightText: syuilo and misskey-project | ||||||
* 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 { QueueService } from '@/core/QueueService.js'; | ||||||
import { GlobalEventService } from '@/core/GlobalEventService.js'; | ||||||
import { DI } from '@/di-symbols.js'; | ||||||
import type { | ||||||
FollowRequestsRepository, | ||||||
BlockingsRepository, | ||||||
UserListsRepository, | ||||||
UserListMembershipsRepository, | ||||||
BlockingReactionUsersRepository | ||||||
} from '@/models/_.js'; | ||||||
import Logger from '@/logger.js'; | ||||||
import { UserEntityService } from '@/core/entities/UserEntityService.js'; | ||||||
import { ApRendererService } from '@/core/activitypub/ApRendererService.js'; | ||||||
import { LoggerService } from '@/core/LoggerService.js'; | ||||||
import { UserWebhookService } from '@/core/UserWebhookService.js'; | ||||||
import { bindThis } from '@/decorators.js'; | ||||||
import { CacheService } from '@/core/CacheService.js'; | ||||||
import {MiBlockingReactionUser} from "@/models/_.js"; | ||||||
Check failure on line 27 in packages/backend/src/core/BlockingReactionUserService.ts GitHub Actions / lint (backend)
|
||||||
|
||||||
@Injectable() | ||||||
export class BlockingReactionUserService implements OnModuleInit { | ||||||
private logger: Logger; | ||||||
|
||||||
constructor( | ||||||
private moduleRef: ModuleRef, | ||||||
|
||||||
@Inject(DI.blockingReactionUsersRepository) | ||||||
private blockingReactionUsersRepository: BlockingReactionUsersRepository, | ||||||
|
||||||
private cacheService: CacheService, | ||||||
private userEntityService: UserEntityService, | ||||||
private idService: IdService, | ||||||
private queueService: QueueService, | ||||||
private globalEventService: GlobalEventService, | ||||||
private webhookService: UserWebhookService, | ||||||
private apRendererService: ApRendererService, | ||||||
private loggerService: LoggerService, | ||||||
) { | ||||||
this.logger = this.loggerService.getLogger('user-block'); | ||||||
} | ||||||
|
||||||
onModuleInit() { | ||||||
} | ||||||
|
||||||
@bindThis | ||||||
public async block(blocker: MiUser, blockee: MiUser, silent = false) { | ||||||
await Promise.all([ | ||||||
]); | ||||||
|
||||||
const blocking = { | ||||||
id: this.idService.gen(), | ||||||
blocker, | ||||||
blockerId: blocker.id, | ||||||
blockee, | ||||||
blockeeId: blockee.id, | ||||||
} as MiBlockingReactionUser; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
await this.blockingReactionUsersRepository.insert(blocking); | ||||||
|
||||||
this.cacheService.blockingReactionUserCache.refresh(blocker.id); | ||||||
this.cacheService.blockedReactionUserCache.refresh(blockee.id); | ||||||
|
||||||
this.globalEventService.publishInternalEvent('blockingReactionUserCreated', { | ||||||
blockerId: blocker.id, | ||||||
blockeeId: blockee.id, | ||||||
}); | ||||||
} | ||||||
|
||||||
@bindThis | ||||||
public async unblock(blocker: MiUser, blockee: MiUser) { | ||||||
const blocking = await this.blockingReactionUsersRepository.findOneBy({ | ||||||
blockerId: blocker.id, | ||||||
blockeeId: blockee.id, | ||||||
}); | ||||||
|
||||||
if (blocking == null) { | ||||||
this.logger.warn('ブロック解除がリクエストされましたがブロックしていませんでした'); | ||||||
return; | ||||||
} | ||||||
|
||||||
// Since we already have the blocker and blockee, we do not need to fetch | ||||||
// them in the query above and can just manually insert them here. | ||||||
blocking.blocker = blocker; | ||||||
blocking.blockee = blockee; | ||||||
Comment on lines
+90
to
+93
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 上記の処理は不要に見受けられるのですが、いかがでしょうか。 |
||||||
|
||||||
await this.blockingReactionUsersRepository.delete(blocking.id); | ||||||
|
||||||
this.cacheService.blockingReactionUserCache.refresh(blocker.id); | ||||||
this.cacheService.blockedReactionUserCache.refresh(blockee.id); | ||||||
|
||||||
this.globalEventService.publishInternalEvent('blockingReactionUserDeleted', { | ||||||
blockerId: blocker.id, | ||||||
blockeeId: blockee.id, | ||||||
}); | ||||||
} | ||||||
|
||||||
@bindThis | ||||||
public async checkBlocked(blockerId: MiUser['id'], blockeeId: MiUser['id']): Promise<boolean> { | ||||||
return (await this.cacheService.blockingReactionUserCache.fetch(blockerId)).has(blockeeId); | ||||||
} | ||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lint / code style