diff --git a/packages/backend/src/core/ReactionService.ts b/packages/backend/src/core/ReactionService.ts
index 96e0b80987..36a0dd480f 100644
--- a/packages/backend/src/core/ReactionService.ts
+++ b/packages/backend/src/core/ReactionService.ts
@@ -160,33 +160,56 @@ export class ReactionService {
userId: user.id,
reaction,
};
+ if (user.host == null) {
+ const exists = await this.noteReactionsRepository.findOneBy({
+ noteId: note.id,
+ userId: user.id,
+ reaction: record.reaction,
+ });
- // Create reaction
- const exists = await this.noteReactionsRepository.findOneBy({
- noteId: note.id,
- userId: user.id,
- reaction: record.reaction,
- });
+ const count = await this.noteReactionsRepository.countBy({
+ noteId: note.id,
+ userId: user.id,
+ });
- const count = await this.noteReactionsRepository.countBy({
- noteId: note.id,
- userId: user.id,
- });
+ if (count > 3) {
+ throw new IdentifiableError('51c42bb4-931a-456b-bff7-e5a8a70dd298');
+ }
- if (count > 3) {
- throw new IdentifiableError('51c42bb4-931a-456b-bff7-e5a8a70dd298');
- }
-
- if (exists == null) {
- if (user.host == null) {
- await this.noteReactionsRepository.insert(record);
+ if (exists == null) {
+ if (user.host == null) {
+ await this.noteReactionsRepository.insert(record);
+ } else {
+ throw new IdentifiableError('51c42bb4-931a-456b-bff7-e5a8a70dd298');
+ }
} else {
+ // 同じリアクションがすでにされていたらエラー
throw new IdentifiableError('51c42bb4-931a-456b-bff7-e5a8a70dd298');
}
} else {
- // 同じリアクションがすでにされていたらエラー
- throw new IdentifiableError('51c42bb4-931a-456b-bff7-e5a8a70dd298');
+ try {
+ await this.noteReactionsRepository.insert(record);
+ } catch (e) {
+ if (isDuplicateKeyValueError(e)) {
+ const exists = await this.noteReactionsRepository.findOneByOrFail({
+ noteId: note.id,
+ userId: user.id,
+ });
+
+ if (exists.reaction !== reaction) {
+ // 別のリアクションがすでにされていたら置き換える
+ await this.delete(user, note);
+ await this.noteReactionsRepository.insert(record);
+ } else {
+ // 同じリアクションがすでにされていたらエラー
+ throw new IdentifiableError('51c42bb4-931a-456b-bff7-e5a8a70dd298');
+ }
+ } else {
+ throw e;
+ }
+ }
}
+ // Create reaction
// Increment reactions count
const sql = `jsonb_set("reactions", '{${reaction}}', (COALESCE("reactions"->>'${reaction}', '0')::int + 1)::text::jsonb)`;
diff --git a/packages/frontend/src/components/MkNoteDetailed.vue b/packages/frontend/src/components/MkNoteDetailed.vue
index 681e58c4b9..e1b6fb58bd 100644
--- a/packages/frontend/src/components/MkNoteDetailed.vue
+++ b/packages/frontend/src/components/MkNoteDetailed.vue
@@ -129,7 +129,7 @@ SPDX-License-Identifier: AGPL-3.0-only