From d2a6cb1684cfb070cf40e165ad4c0d863099aacb Mon Sep 17 00:00:00 2001 From: Dragory <2606411+Dragory@users.noreply.github.com> Date: Sat, 30 Nov 2019 23:39:29 +0200 Subject: [PATCH] Add --exclusive/-e to !reaction_roles When reaction roles are set as exclusive, a user can only have 1 reaction role from that message. Others are removed automatically when picking a role if needed. --- backend/src/data/GuildReactionRoles.ts | 3 ++- backend/src/data/entities/ReactionRole.ts | 2 ++ ...145703039-AddIsExclusiveToReactionRoles.ts | 19 ++++++++++++++++ backend/src/plugins/ReactionRoles.ts | 22 ++++++++++++++++--- 4 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 backend/src/migrations/1575145703039-AddIsExclusiveToReactionRoles.ts diff --git a/backend/src/data/GuildReactionRoles.ts b/backend/src/data/GuildReactionRoles.ts index 0f7196c2..c197bc1d 100644 --- a/backend/src/data/GuildReactionRoles.ts +++ b/backend/src/data/GuildReactionRoles.ts @@ -50,13 +50,14 @@ export class GuildReactionRoles extends BaseGuildRepository { await this.reactionRoles.delete(criteria); } - async add(channelId: string, messageId: string, emoji: string, roleId: string) { + async add(channelId: string, messageId: string, emoji: string, roleId: string, exclusive?: boolean) { await this.reactionRoles.insert({ guild_id: this.guildId, channel_id: channelId, message_id: messageId, emoji, role_id: roleId, + is_exclusive: Boolean(exclusive), }); } } diff --git a/backend/src/data/entities/ReactionRole.ts b/backend/src/data/entities/ReactionRole.ts index ebefd1a0..38cb256d 100644 --- a/backend/src/data/entities/ReactionRole.ts +++ b/backend/src/data/entities/ReactionRole.ts @@ -19,4 +19,6 @@ export class ReactionRole { emoji: string; @Column() role_id: string; + + @Column() is_exclusive: boolean; } diff --git a/backend/src/migrations/1575145703039-AddIsExclusiveToReactionRoles.ts b/backend/src/migrations/1575145703039-AddIsExclusiveToReactionRoles.ts new file mode 100644 index 00000000..141aeef3 --- /dev/null +++ b/backend/src/migrations/1575145703039-AddIsExclusiveToReactionRoles.ts @@ -0,0 +1,19 @@ +import { MigrationInterface, QueryRunner, TableColumn } from "typeorm"; + +export class AddIsExclusiveToReactionRoles1575145703039 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.addColumn( + "reaction_roles", + new TableColumn({ + name: "is_exclusive", + type: "tinyint", + unsigned: true, + default: 0, + }), + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropColumn("reaction_roles", "is_exclusive"); + } +} diff --git a/backend/src/plugins/ReactionRoles.ts b/backend/src/plugins/ReactionRoles.ts index 5bdc4c51..b07609d9 100644 --- a/backend/src/plugins/ReactionRoles.ts +++ b/backend/src/plugins/ReactionRoles.ts @@ -268,9 +268,17 @@ export class ReactionRolesPlugin extends ZeppelinPlugin { * :zep_twitch: = 473086848831455234 * :zep_ps4: = 543184300250759188 */ - @d.command("reaction_roles", " ") + @d.command("reaction_roles", " ", { + options: [ + { + name: "exclusive", + shortcut: "e", + isSwitch: true, + }, + ], + }) @d.permission("can_manage") - async reactionRolesCmd(msg: Message, args: { messageId: string; reactionRolePairs: string }) { + async reactionRolesCmd(msg: Message, args: { messageId: string; reactionRolePairs: string; exclusive?: boolean }) { const savedMessage = await this.savedMessages.find(args.messageId); if (!savedMessage) { msg.channel.createMessage(errorMessage("Unknown message")); @@ -331,7 +339,7 @@ export class ReactionRolesPlugin extends ZeppelinPlugin { // Save the new reaction roles to the database for (const pair of emojiRolePairs) { - await this.reactionRoles.add(channel.id, targetMessage.id, pair[0], pair[1]); + await this.reactionRoles.add(channel.id, targetMessage.id, pair[0], pair[1], args.exclusive); } // Apply the reactions themselves @@ -370,6 +378,14 @@ export class ReactionRolesPlugin extends ZeppelinPlugin { const matchingReactionRole = await this.reactionRoles.getByMessageAndEmoji(msg.id, emoji.id || emoji.name); if (!matchingReactionRole) return; + // If the reaction role is exclusive, remove any other roles in the message first + if (matchingReactionRole.is_exclusive) { + const messageReactionRoles = await this.reactionRoles.getForMessage(msg.id); + for (const reactionRole of messageReactionRoles) { + this.addMemberPendingRoleChange(userId, "-", reactionRole.role_id); + } + } + this.addMemberPendingRoleChange(userId, "+", matchingReactionRole.role_id); }