diff --git a/modules/moderation/role.py b/modules/moderation/role.py index a97606b9..662f702c 100644 --- a/modules/moderation/role.py +++ b/modules/moderation/role.py @@ -9,7 +9,6 @@ from discord import app_commands import configuration -import ui from core import auxiliary, cogs if TYPE_CHECKING: @@ -182,7 +181,7 @@ async def role_command_base( return self.locked.add(identifier) - view = ui.SelectView(role_options) + view = RoleView(role_options) await interaction.response.send_message( content=f"Select what roles should be assigned to {member} below", ephemeral=True, @@ -190,6 +189,15 @@ async def role_command_base( ) await view.wait() + # If we cancelled, assign no roles and release the lock + if view.select.cancelled: + embed = auxiliary.prepare_deny_embed( + "You cancelled editing roles. No changes were made" + ) + await interaction.edit_original_response(embed=embed, view=None) + self.locked.remove(identifier) + return + # In the event of a timeout, do not remove any roles, and release the lock if view.select.timeout: embed = auxiliary.prepare_deny_embed("This menu timed out") @@ -312,3 +320,76 @@ async def modify_roles( if removed_roles: embed.add_field(name="Removed roles:", value="\n".join(removed_roles)) await interaction.edit_original_response(content=None, embed=embed, view=None) + + +class RoleSelectView(discord.ui.Select): + """This holds the select object for a list of roles + + Args: + role_list (list[str]): A list of SelectOption to be in the dropdown + """ + + def __init__(self: Self, role_list: list[str]) -> None: + super().__init__( + placeholder="Select roles...", + min_values=0, + max_values=len(role_list), + options=role_list, + row=0, + ) + self.timeout = True + self.cancelled = False + + async def callback(self: Self, interaction: discord.Interaction) -> None: + """What happens when the select menu has been used + + Args: + interaction (discord.Interaction): The interaction that called this select object + """ + self.timeout = False + self.view.stop() + + async def on_timeout(self: Self) -> None: + """What happens when the view timesout. This is to prevent all roles from being removed.""" + self.values = None + self.view.stop() + + +class RoleView(discord.ui.View): + """This is the view that will hold only the dropdown + Adds the dropdown and does nothing else + Args: + role_list (list[str]): The list of SelectOptions to add to the dropdown + """ + + def __init__(self: Self, role_list: list[str]) -> None: + super().__init__() + # Adds the dropdown to our view object. + self.select = RoleSelectView(role_list) + self.add_item(self.select) + + async def on_timeout(self: Self) -> None: + """What happens when the view times out.""" + self.select.values = None + self.stop() + + @discord.ui.button( + label="Cancel", + style=discord.ButtonStyle.secondary, + emoji="❌", + row=1, + ) + async def cancel_button( + self: Self, + interaction: discord.Interaction, + button: discord.ui.Button, + ) -> None: + """A button to instatly cancel the role assignment + + Args: + interaction (discord.Interaction): The interaction that pressed this button + button (discord.ui.Button): The button object + """ + + self.select.cancelled = True + self.stop() diff --git a/ui/__init__.py b/ui/__init__.py index 8d6e8d3e..ee6f70ec 100644 --- a/ui/__init__.py +++ b/ui/__init__.py @@ -5,5 +5,4 @@ from .confirm import * from .pagination import * from .persistent_voting import * -from .roleselect import * from .vote_creation import * diff --git a/ui/roleselect.py b/ui/roleselect.py deleted file mode 100644 index 22cbe954..00000000 --- a/ui/roleselect.py +++ /dev/null @@ -1,52 +0,0 @@ -"""This holds the UI view used by the role extension""" - -from __future__ import annotations - -from typing import Self - -import discord - - -class RoleSelect(discord.ui.Select): - """This holds the select object for a list of roles - - Args: - role_list (list[str]): A list of SelectOption to be in the dropdown - """ - - def __init__(self: Self, role_list: list[str]) -> None: - super().__init__( - placeholder="Select roles...", - min_values=0, - max_values=len(role_list), - options=role_list, - ) - self.timeout = True - - async def callback(self: Self, interaction: discord.Interaction) -> None: - """What happens when the select menu has been used - - Args: - interaction (discord.Interaction): The interaction that called this select object - """ - self.timeout = False - self.view.stop() - - async def on_timeout(self: Self) -> None: - """What happens when the view timesout. This is to prevent all roles from being removed.""" - self.values = None - self.view.stop() - - -class SelectView(discord.ui.View): - """This is the view that will hold only the dropdown - Adds the dropdown and does nothing else - Args: - role_list (list[str]): The list of SelectOptions to add to the dropdown - """ - - def __init__(self: Self, role_list: list[str]) -> None: - super().__init__() - # Adds the dropdown to our view object. - self.select = RoleSelect(role_list) - self.add_item(self.select)