From 3686f60305e773f91c61e7c49a67d2d1f2d5c28a Mon Sep 17 00:00:00 2001 From: shtlrs Date: Sat, 26 Nov 2022 18:58:11 +0100 Subject: add the roles channel to the config --- bot/constants.py | 2 ++ config-default.yml | 3 +++ 2 files changed, 5 insertions(+) diff --git a/bot/constants.py b/bot/constants.py index 24862059e..90527d66a 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -465,6 +465,8 @@ class Channels(metaclass=YAMLGetter): big_brother_logs: int + roles: int + class Webhooks(metaclass=YAMLGetter): section = "guild" diff --git a/config-default.yml b/config-default.yml index c9d043ff7..9a3f35008 100644 --- a/config-default.yml +++ b/config-default.yml @@ -235,6 +235,9 @@ guild: # Watch big_brother_logs: &BB_LOGS 468507907357409333 + # Roles + roles: 851270062434156586 + moderation_categories: - *MODS_CATEGORY - *MODMAIL -- cgit v1.2.3 From 579514077f9b3307dc4717af94d1f8cda595c74d Mon Sep 17 00:00:00 2001 From: shtlrs Date: Sat, 26 Nov 2022 19:02:06 +0100 Subject: add the AllSelfAssignableRolesView and its corresponding ClaimAllSelfAssignableRolesButton button Note that these are still dummy views & have no behavior --- bot/exts/info/subscribe.py | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/bot/exts/info/subscribe.py b/bot/exts/info/subscribe.py index 36304539f..4991f4a96 100644 --- a/bot/exts/info/subscribe.py +++ b/bot/exts/info/subscribe.py @@ -59,6 +59,27 @@ DELETE_MESSAGE_AFTER = 300 # Seconds log = get_logger(__name__) +class AllSelfAssignableRolesView(discord.ui.View): + """A view that'll hold one button allowing interactors to get all available self-assignable roles.""" + + def __init__(self): + super(AllSelfAssignableRolesView, self).__init__(timeout=None) + + +class ClaimAllSelfAssignableRolesButton(discord.ui.Button): + """A button that adds all self assignable roles to the interactor.""" + + CUSTOM_ID = "gotta-claim-them-all" + + def __init__(self): + super().__init__( + style=discord.ButtonStyle.success, + label="Assign me a", + custom_id=self.CUSTOM_ID, + row=1 + ) + + class RoleButtonView(discord.ui.View): """A list of SingleRoleButtons to show to the member.""" @@ -150,7 +171,6 @@ class Subscribe(commands.Cog): async def cog_load(self) -> None: """Initialise the cog by resolving the role IDs in ASSIGNABLE_ROLES to role names.""" await self.bot.wait_until_guild_available() - self.guild = self.bot.get_guild(constants.Guild.id) for role in ASSIGNABLE_ROLES: -- cgit v1.2.3 From 6ab9f9cf2a5889f3f6999117458e75140a40533b Mon Sep 17 00:00:00 2001 From: shtlrs Date: Sat, 26 Nov 2022 19:17:26 +0100 Subject: add the logic for attaching the persistent view This comes with another dependency to try to locate the message that needs to hold the view. If that message is not found, a new one will be created & sent. --- bot/exts/info/subscribe.py | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/bot/exts/info/subscribe.py b/bot/exts/info/subscribe.py index 4991f4a96..c8886c4f7 100644 --- a/bot/exts/info/subscribe.py +++ b/bot/exts/info/subscribe.py @@ -13,6 +13,7 @@ from bot import constants from bot.bot import Bot from bot.decorators import redirect_output from bot.log import get_logger +from bot.utils.channel import get_or_fetch_channel @dataclass(frozen=True) @@ -74,7 +75,7 @@ class ClaimAllSelfAssignableRolesButton(discord.ui.Button): def __init__(self): super().__init__( style=discord.ButtonStyle.success, - label="Assign me a", + label="Claim all available roles", custom_id=self.CUSTOM_ID, row=1 ) @@ -163,6 +164,8 @@ class SingleRoleButton(discord.ui.Button): class Subscribe(commands.Cog): """Cog to allow user to self-assign & remove the roles present in ASSIGNABLE_ROLES.""" + SELF_ASSIGNABLE_ROLES_MESSAGE = "Click on this button to earn all the currently available server roles" + def __init__(self, bot: Bot): self.bot = bot self.assignable_roles: list[AssignableRole] = [] @@ -190,6 +193,9 @@ class Subscribe(commands.Cog): self.assignable_roles.sort(key=operator.attrgetter("name")) self.assignable_roles.sort(key=operator.methodcaller("is_currently_available"), reverse=True) + initial_self_assignable_roles_message = await self.__search_for_self_assignable_roles_message() + self.__attach_view_to_initial_self_assignable_roles_message(initial_self_assignable_roles_message) + @commands.cooldown(1, 10, commands.BucketType.member) @commands.command(name="subscribe", aliases=("unsubscribe",)) @redirect_output( @@ -210,6 +216,35 @@ class Subscribe(commands.Cog): delete_after=DELETE_MESSAGE_AFTER, ) + async def __search_for_self_assignable_roles_message(self) -> discord.Message: + """ + Searches for the message that holds the self assignable roles view. + + If the initial message isn't found, a new one will be created. + This message will always be needed to attach the persistent view to it + """ + roles_channel = await get_or_fetch_channel(constants.Channels.roles) + + async for message in roles_channel.history(limit=30): + if message.content == self.SELF_ASSIGNABLE_ROLES_MESSAGE: + log.debug(f"Found self assignable roles view message: {message.id}") + return message + + log.debug("Self assignable roles view message hasn't been found, creating a new one.") + view = AllSelfAssignableRolesView() + view.add_item(ClaimAllSelfAssignableRolesButton()) + return await roles_channel.send(self.SELF_ASSIGNABLE_ROLES_MESSAGE, view=view) + + def __attach_view_to_initial_self_assignable_roles_message(self, message: discord.Message) -> None: + """ + Attaches the persistent self assignable roles view. + + The message is searched for/created upon loading the Cog. + """ + view = AllSelfAssignableRolesView() + view.add_item(ClaimAllSelfAssignableRolesButton()) + self.bot.add_view(view, message_id=message.id) + async def setup(bot: Bot) -> None: """Load the Subscribe cog.""" -- cgit v1.2.3 From b25ad801bd99bd7055fcb5a49e13b5ff339a515b Mon Sep 17 00:00:00 2001 From: shtlrs Date: Sat, 26 Nov 2022 19:41:39 +0100 Subject: add assignable_roles as a property to the ClaimAllSelfAssignableRoles button --- bot/exts/info/subscribe.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/bot/exts/info/subscribe.py b/bot/exts/info/subscribe.py index c8886c4f7..4f4f5df58 100644 --- a/bot/exts/info/subscribe.py +++ b/bot/exts/info/subscribe.py @@ -72,13 +72,14 @@ class ClaimAllSelfAssignableRolesButton(discord.ui.Button): CUSTOM_ID = "gotta-claim-them-all" - def __init__(self): + def __init__(self, assignable_roles: list[AssignableRole]): super().__init__( style=discord.ButtonStyle.success, label="Claim all available roles", custom_id=self.CUSTOM_ID, row=1 ) + self.assignable_roles = assignable_roles class RoleButtonView(discord.ui.View): @@ -232,7 +233,7 @@ class Subscribe(commands.Cog): log.debug("Self assignable roles view message hasn't been found, creating a new one.") view = AllSelfAssignableRolesView() - view.add_item(ClaimAllSelfAssignableRolesButton()) + view.add_item(ClaimAllSelfAssignableRolesButton(self.assignable_roles)) return await roles_channel.send(self.SELF_ASSIGNABLE_ROLES_MESSAGE, view=view) def __attach_view_to_initial_self_assignable_roles_message(self, message: discord.Message) -> None: @@ -242,7 +243,7 @@ class Subscribe(commands.Cog): The message is searched for/created upon loading the Cog. """ view = AllSelfAssignableRolesView() - view.add_item(ClaimAllSelfAssignableRolesButton()) + view.add_item(ClaimAllSelfAssignableRolesButton(self.assignable_roles)) self.bot.add_view(view, message_id=message.id) -- cgit v1.2.3 From 1d604034caf476a900882502b15e47a222a8dd0c Mon Sep 17 00:00:00 2001 From: shtlrs Date: Sat, 26 Nov 2022 19:44:16 +0100 Subject: add implementation of the button's callback that'll handle assigning the appropriate roles --- bot/exts/info/subscribe.py | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/bot/exts/info/subscribe.py b/bot/exts/info/subscribe.py index 4f4f5df58..1aec0e3a0 100644 --- a/bot/exts/info/subscribe.py +++ b/bot/exts/info/subscribe.py @@ -81,6 +81,40 @@ class ClaimAllSelfAssignableRolesButton(discord.ui.Button): ) self.assignable_roles = assignable_roles + async def callback(self, interaction: Interaction) -> t.Any: + """Assigns all missing available roles to the interactor.""" + await interaction.response.defer() + + if isinstance(interaction.user, discord.User): + log.trace("User %s is not a member", interaction.user) + await interaction.message.delete() + self.view.stop() + return + + author_roles = [role.id for role in interaction.user.roles] + assigned_roles = [] + + for role in self.assignable_roles: + if role.role_id in author_roles: + continue + if not role.is_currently_available(): + continue + + log.debug(f"Assigning role {role.name} to {interaction.user.display_name}") + await members.handle_role_change( + interaction.user, + interaction.user.add_roles, + discord.Object(role.role_id), + ) + + assigned_roles.append(role.name) + + if assigned_roles: + await interaction.followup.send( + f"The following roles have been assigned to you: {', '.join(assigned_roles)}", + ephemeral=True, + ) + class RoleButtonView(discord.ui.View): """A list of SingleRoleButtons to show to the member.""" -- cgit v1.2.3 From af588147589c17718dbcaa9c407c2368418f7f4b Mon Sep 17 00:00:00 2001 From: shtlrs Date: Sun, 27 Nov 2022 15:52:51 +0100 Subject: rely on original_message to delete view once it times out --- bot/exts/info/subscribe.py | 128 ++++++++++++++++++++++----------------------- 1 file changed, 62 insertions(+), 66 deletions(-) diff --git a/bot/exts/info/subscribe.py b/bot/exts/info/subscribe.py index 1aec0e3a0..333f33b50 100644 --- a/bot/exts/info/subscribe.py +++ b/bot/exts/info/subscribe.py @@ -55,72 +55,18 @@ ASSIGNABLE_ROLES = ( ) ITEMS_PER_ROW = 3 -DELETE_MESSAGE_AFTER = 300 # Seconds +DELETE_MESSAGE_AFTER = 20 # Seconds log = get_logger(__name__) -class AllSelfAssignableRolesView(discord.ui.View): - """A view that'll hold one button allowing interactors to get all available self-assignable roles.""" - - def __init__(self): - super(AllSelfAssignableRolesView, self).__init__(timeout=None) - - -class ClaimAllSelfAssignableRolesButton(discord.ui.Button): - """A button that adds all self assignable roles to the interactor.""" - - CUSTOM_ID = "gotta-claim-them-all" - - def __init__(self, assignable_roles: list[AssignableRole]): - super().__init__( - style=discord.ButtonStyle.success, - label="Claim all available roles", - custom_id=self.CUSTOM_ID, - row=1 - ) - self.assignable_roles = assignable_roles - - async def callback(self, interaction: Interaction) -> t.Any: - """Assigns all missing available roles to the interactor.""" - await interaction.response.defer() - - if isinstance(interaction.user, discord.User): - log.trace("User %s is not a member", interaction.user) - await interaction.message.delete() - self.view.stop() - return - - author_roles = [role.id for role in interaction.user.roles] - assigned_roles = [] - - for role in self.assignable_roles: - if role.role_id in author_roles: - continue - if not role.is_currently_available(): - continue - - log.debug(f"Assigning role {role.name} to {interaction.user.display_name}") - await members.handle_role_change( - interaction.user, - interaction.user.add_roles, - discord.Object(role.role_id), - ) - - assigned_roles.append(role.name) - - if assigned_roles: - await interaction.followup.send( - f"The following roles have been assigned to you: {', '.join(assigned_roles)}", - ephemeral=True, - ) - - class RoleButtonView(discord.ui.View): """A list of SingleRoleButtons to show to the member.""" def __init__(self, member: discord.Member): - super().__init__() + super().__init__(timeout=DELETE_MESSAGE_AFTER) + # We can't obtain the reference to the message before the view is sent + self.original_message = None self.interaction_owner = member async def interaction_check(self, interaction: Interaction) -> bool: @@ -133,6 +79,10 @@ class RoleButtonView(discord.ui.View): return False return True + async def on_timeout(self) -> None: + """Delete the original message that the view was sent along with.""" + await self.original_message.delete() + class SingleRoleButton(discord.ui.Button): """A button that adds or removes a role from the member depending on it's current state.""" @@ -196,6 +146,38 @@ class SingleRoleButton(discord.ui.Button): self.view.stop() +class AllSelfAssignableRolesView(discord.ui.View): + """A view that'll hold one button allowing interactors to get all available self-assignable roles.""" + + def __init__(self): + super(AllSelfAssignableRolesView, self).__init__(timeout=None) + + +class ClaimAllSelfAssignableRolesButton(discord.ui.Button): + """A button that adds all self assignable roles to the interactor.""" + + CUSTOM_ID = "gotta-claim-them-all" + + def __init__(self, assignable_roles: list[AssignableRole]): + super().__init__( + style=discord.ButtonStyle.success, + label="Claim all available roles", + custom_id=self.CUSTOM_ID, + row=1 + ) + self.assignable_roles = assignable_roles + + async def callback(self, interaction: Interaction) -> t.Any: + """Assigns all missing available roles to the interactor.""" + await interaction.response.defer() + view = prepare_available_role_subscription_view(interaction, self.assignable_roles) + message = await interaction.followup.send( + view=view, + ) + # Keep reference of the message that contains the view to be deleted + view.original_message = message + + class Subscribe(commands.Cog): """Cog to allow user to self-assign & remove the roles present in ASSIGNABLE_ROLES.""" @@ -239,17 +221,14 @@ class Subscribe(commands.Cog): ) async def subscribe_command(self, ctx: commands.Context, *_) -> None: # We don't actually care about the args """Display the member's current state for each role, and allow them to add/remove the roles.""" - button_view = RoleButtonView(ctx.author) - author_roles = [role.id for role in ctx.author.roles] - for index, role in enumerate(self.assignable_roles): - row = index // ITEMS_PER_ROW - button_view.add_item(SingleRoleButton(role, role.role_id in author_roles, row)) + view = prepare_available_role_subscription_view(ctx, self.assignable_roles) - await ctx.send( + message = await ctx.send( "Click the buttons below to add or remove your roles!", - view=button_view, - delete_after=DELETE_MESSAGE_AFTER, + view=view, ) + # Keep reference of the message that contains the view to be deleted + view.original_message = message async def __search_for_self_assignable_roles_message(self) -> discord.Message: """ @@ -281,6 +260,23 @@ class Subscribe(commands.Cog): self.bot.add_view(view, message_id=message.id) +def prepare_available_role_subscription_view( + trigger_action: commands.Context | Interaction, + assignable_roles: list[AssignableRole] +) -> discord.ui.View: + """Prepares the view containing the self assignable roles before its sent.""" + author = trigger_action.author if isinstance(trigger_action, commands.Context) else trigger_action.user + author_roles = [role.id for role in author.roles] + button_view = RoleButtonView(member=author) + button_view.original_message = trigger_action.message + + for index, role in enumerate(assignable_roles): + row = index // ITEMS_PER_ROW + button_view.add_item(SingleRoleButton(role, role.role_id in author_roles, row)) + + return button_view + + async def setup(bot: Bot) -> None: """Load the Subscribe cog.""" if len(ASSIGNABLE_ROLES) > ITEMS_PER_ROW*5: # Discord limits views to 5 rows of buttons. -- cgit v1.2.3 From 3cedc99e7fcf342aad8b0217e42d38aad78bb419 Mon Sep 17 00:00:00 2001 From: shtlrs Date: Sun, 27 Nov 2022 16:02:12 +0100 Subject: restore original value of DELETE_MESSAGE_AFTER --- bot/exts/info/subscribe.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/exts/info/subscribe.py b/bot/exts/info/subscribe.py index 333f33b50..dd676080b 100644 --- a/bot/exts/info/subscribe.py +++ b/bot/exts/info/subscribe.py @@ -55,7 +55,7 @@ ASSIGNABLE_ROLES = ( ) ITEMS_PER_ROW = 3 -DELETE_MESSAGE_AFTER = 20 # Seconds +DELETE_MESSAGE_AFTER = 300 # Seconds log = get_logger(__name__) -- cgit v1.2.3 From 6c61d34ff6ded0a744d4d6304ae0fc8a41ec204c Mon Sep 17 00:00:00 2001 From: shtlrs Date: Sun, 27 Nov 2022 17:43:13 +0100 Subject: rename ClaimAllSelfAssignableRolesButton to ShowAllSelfAssignableRolesButton --- bot/exts/info/subscribe.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/bot/exts/info/subscribe.py b/bot/exts/info/subscribe.py index dd676080b..c68207e1c 100644 --- a/bot/exts/info/subscribe.py +++ b/bot/exts/info/subscribe.py @@ -153,15 +153,15 @@ class AllSelfAssignableRolesView(discord.ui.View): super(AllSelfAssignableRolesView, self).__init__(timeout=None) -class ClaimAllSelfAssignableRolesButton(discord.ui.Button): - """A button that adds all self assignable roles to the interactor.""" +class ShowAllSelfAssignableRolesButton(discord.ui.Button): + """A button that sends a view containing all the different roles a user can self assign at that time.""" CUSTOM_ID = "gotta-claim-them-all" def __init__(self, assignable_roles: list[AssignableRole]): super().__init__( style=discord.ButtonStyle.success, - label="Claim all available roles", + label="Show available roles", custom_id=self.CUSTOM_ID, row=1 ) @@ -246,7 +246,7 @@ class Subscribe(commands.Cog): log.debug("Self assignable roles view message hasn't been found, creating a new one.") view = AllSelfAssignableRolesView() - view.add_item(ClaimAllSelfAssignableRolesButton(self.assignable_roles)) + view.add_item(ShowAllSelfAssignableRolesButton(self.assignable_roles)) return await roles_channel.send(self.SELF_ASSIGNABLE_ROLES_MESSAGE, view=view) def __attach_view_to_initial_self_assignable_roles_message(self, message: discord.Message) -> None: @@ -256,7 +256,7 @@ class Subscribe(commands.Cog): The message is searched for/created upon loading the Cog. """ view = AllSelfAssignableRolesView() - view.add_item(ClaimAllSelfAssignableRolesButton(self.assignable_roles)) + view.add_item(ShowAllSelfAssignableRolesButton(self.assignable_roles)) self.bot.add_view(view, message_id=message.id) -- cgit v1.2.3 From bde96fd65a7d30592f65a31eaa07dfa8ed404f68 Mon Sep 17 00:00:00 2001 From: shtlrs Date: Sun, 27 Nov 2022 17:50:27 +0100 Subject: update message content of the persistent view The messages were intended for a button that will automatically assign all availables roles to the interactor This changes since it's not the intended behavior --- bot/exts/info/subscribe.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bot/exts/info/subscribe.py b/bot/exts/info/subscribe.py index c68207e1c..8f46fde61 100644 --- a/bot/exts/info/subscribe.py +++ b/bot/exts/info/subscribe.py @@ -161,7 +161,7 @@ class ShowAllSelfAssignableRolesButton(discord.ui.Button): def __init__(self, assignable_roles: list[AssignableRole]): super().__init__( style=discord.ButtonStyle.success, - label="Show available roles", + label="Show all self assignable roles", custom_id=self.CUSTOM_ID, row=1 ) @@ -181,7 +181,7 @@ class ShowAllSelfAssignableRolesButton(discord.ui.Button): class Subscribe(commands.Cog): """Cog to allow user to self-assign & remove the roles present in ASSIGNABLE_ROLES.""" - SELF_ASSIGNABLE_ROLES_MESSAGE = "Click on this button to earn all the currently available server roles" + SELF_ASSIGNABLE_ROLES_MESSAGE = "Click on this button to show all self assignable roles" def __init__(self, bot: Bot): self.bot = bot -- cgit v1.2.3 From dd4903c6654e471156f984d3f38b1207909529b0 Mon Sep 17 00:00:00 2001 From: shtlrs Date: Sun, 27 Nov 2022 17:51:27 +0100 Subject: fix docstrings of the ShowAllSelfAssignableRolesButton's callback function --- bot/exts/info/subscribe.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/exts/info/subscribe.py b/bot/exts/info/subscribe.py index 8f46fde61..a2ce4beb7 100644 --- a/bot/exts/info/subscribe.py +++ b/bot/exts/info/subscribe.py @@ -168,7 +168,7 @@ class ShowAllSelfAssignableRolesButton(discord.ui.Button): self.assignable_roles = assignable_roles async def callback(self, interaction: Interaction) -> t.Any: - """Assigns all missing available roles to the interactor.""" + """Sends the original subscription view containing the available self assignable roles.""" await interaction.response.defer() view = prepare_available_role_subscription_view(interaction, self.assignable_roles) message = await interaction.followup.send( -- cgit v1.2.3 From bd4b0b47e045145f03baddb35523615a42eb204e Mon Sep 17 00:00:00 2001 From: shtlrs Date: Sun, 27 Nov 2022 17:57:07 +0100 Subject: rename prepare_available_role_subscription_view to prepare_self_assignable_roles_view --- bot/exts/info/subscribe.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bot/exts/info/subscribe.py b/bot/exts/info/subscribe.py index a2ce4beb7..fe54a3dbe 100644 --- a/bot/exts/info/subscribe.py +++ b/bot/exts/info/subscribe.py @@ -170,7 +170,7 @@ class ShowAllSelfAssignableRolesButton(discord.ui.Button): async def callback(self, interaction: Interaction) -> t.Any: """Sends the original subscription view containing the available self assignable roles.""" await interaction.response.defer() - view = prepare_available_role_subscription_view(interaction, self.assignable_roles) + view = prepare_self_assignable_roles_view(interaction, self.assignable_roles) message = await interaction.followup.send( view=view, ) @@ -221,7 +221,7 @@ class Subscribe(commands.Cog): ) async def subscribe_command(self, ctx: commands.Context, *_) -> None: # We don't actually care about the args """Display the member's current state for each role, and allow them to add/remove the roles.""" - view = prepare_available_role_subscription_view(ctx, self.assignable_roles) + view = prepare_self_assignable_roles_view(ctx, self.assignable_roles) message = await ctx.send( "Click the buttons below to add or remove your roles!", @@ -260,7 +260,7 @@ class Subscribe(commands.Cog): self.bot.add_view(view, message_id=message.id) -def prepare_available_role_subscription_view( +def prepare_self_assignable_roles_view( trigger_action: commands.Context | Interaction, assignable_roles: list[AssignableRole] ) -> discord.ui.View: -- cgit v1.2.3 From 54dfcf9ad4e764c6c7de9862d0b5641f7d31ef61 Mon Sep 17 00:00:00 2001 From: shtlrs Date: Sun, 27 Nov 2022 22:31:37 +0100 Subject: update docs for the newly added view & button --- bot/exts/info/subscribe.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bot/exts/info/subscribe.py b/bot/exts/info/subscribe.py index fe54a3dbe..ab1c3cf7e 100644 --- a/bot/exts/info/subscribe.py +++ b/bot/exts/info/subscribe.py @@ -147,14 +147,14 @@ class SingleRoleButton(discord.ui.Button): class AllSelfAssignableRolesView(discord.ui.View): - """A view that'll hold one button allowing interactors to get all available self-assignable roles.""" + """A persistent view that'll hold one button allowing interactors to toggle all available self-assignable roles.""" def __init__(self): super(AllSelfAssignableRolesView, self).__init__(timeout=None) class ShowAllSelfAssignableRolesButton(discord.ui.Button): - """A button that sends a view containing all the different roles a user can self assign at that time.""" + """A button that, when clicked, sends a view a user can interact with to assign one or all the available roles.""" CUSTOM_ID = "gotta-claim-them-all" -- cgit v1.2.3 From 28c733cc61f449fa5143242e231a1557d5533d9e Mon Sep 17 00:00:00 2001 From: shtlrs Date: Sun, 27 Nov 2022 22:40:39 +0100 Subject: rename the method that attaches the persistent view This also enhances the docstrings for a better clarification of its purpose --- bot/exts/info/subscribe.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/bot/exts/info/subscribe.py b/bot/exts/info/subscribe.py index ab1c3cf7e..dba36edac 100644 --- a/bot/exts/info/subscribe.py +++ b/bot/exts/info/subscribe.py @@ -211,7 +211,7 @@ class Subscribe(commands.Cog): self.assignable_roles.sort(key=operator.methodcaller("is_currently_available"), reverse=True) initial_self_assignable_roles_message = await self.__search_for_self_assignable_roles_message() - self.__attach_view_to_initial_self_assignable_roles_message(initial_self_assignable_roles_message) + self.__attach_persistent_roles_view(initial_self_assignable_roles_message) @commands.cooldown(1, 10, commands.BucketType.member) @commands.command(name="subscribe", aliases=("unsubscribe",)) @@ -249,15 +249,23 @@ class Subscribe(commands.Cog): view.add_item(ShowAllSelfAssignableRolesButton(self.assignable_roles)) return await roles_channel.send(self.SELF_ASSIGNABLE_ROLES_MESSAGE, view=view) - def __attach_view_to_initial_self_assignable_roles_message(self, message: discord.Message) -> None: + def __attach_persistent_roles_view( + self, + placeholder_message: discord.Message + ) -> None: """ - Attaches the persistent self assignable roles view. + Attaches the persistent view that toggles self assignable roles to its placeholder message. The message is searched for/created upon loading the Cog. + + Parameters + __________ + :param placeholder_message: The message that will hold the persistent view allowing + users to toggle the RoleButtonView """ view = AllSelfAssignableRolesView() view.add_item(ShowAllSelfAssignableRolesButton(self.assignable_roles)) - self.bot.add_view(view, message_id=message.id) + self.bot.add_view(view, message_id=placeholder_message.id) def prepare_self_assignable_roles_view( -- cgit v1.2.3 From c62872260bf79e03318828c3fa333bc3b4c78171 Mon Sep 17 00:00:00 2001 From: shtlrs Date: Sun, 27 Nov 2022 22:41:29 +0100 Subject: remove waring in setup docstrings --- bot/exts/info/subscribe.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/exts/info/subscribe.py b/bot/exts/info/subscribe.py index dba36edac..204efb340 100644 --- a/bot/exts/info/subscribe.py +++ b/bot/exts/info/subscribe.py @@ -286,7 +286,7 @@ def prepare_self_assignable_roles_view( async def setup(bot: Bot) -> None: - """Load the Subscribe cog.""" + """Load the 'Subscribe' cog.""" if len(ASSIGNABLE_ROLES) > ITEMS_PER_ROW*5: # Discord limits views to 5 rows of buttons. log.error("Too many roles for 5 rows, not loading the Subscribe cog.") else: -- cgit v1.2.3 From f748ceb5c2a432cde383488e74325dcdd364f452 Mon Sep 17 00:00:00 2001 From: shtlrs Date: Sun, 27 Nov 2022 22:45:31 +0100 Subject: misc style & doc improvements --- bot/exts/info/subscribe.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bot/exts/info/subscribe.py b/bot/exts/info/subscribe.py index 204efb340..573d015b0 100644 --- a/bot/exts/info/subscribe.py +++ b/bot/exts/info/subscribe.py @@ -85,7 +85,7 @@ class RoleButtonView(discord.ui.View): class SingleRoleButton(discord.ui.Button): - """A button that adds or removes a role from the member depending on it's current state.""" + """A button that adds or removes a role from the member depending on its current state.""" ADD_STYLE = discord.ButtonStyle.success REMOVE_STYLE = discord.ButtonStyle.red @@ -237,7 +237,7 @@ class Subscribe(commands.Cog): If the initial message isn't found, a new one will be created. This message will always be needed to attach the persistent view to it """ - roles_channel = await get_or_fetch_channel(constants.Channels.roles) + roles_channel: discord.TextChannel = await get_or_fetch_channel(constants.Channels.roles) async for message in roles_channel.history(limit=30): if message.content == self.SELF_ASSIGNABLE_ROLES_MESSAGE: @@ -287,7 +287,7 @@ def prepare_self_assignable_roles_view( async def setup(bot: Bot) -> None: """Load the 'Subscribe' cog.""" - if len(ASSIGNABLE_ROLES) > ITEMS_PER_ROW*5: # Discord limits views to 5 rows of buttons. + if len(ASSIGNABLE_ROLES) > ITEMS_PER_ROW * 5: # Discord limits views to 5 rows of buttons. log.error("Too many roles for 5 rows, not loading the Subscribe cog.") else: await bot.add_cog(Subscribe(bot)) -- cgit v1.2.3 From c14e75afc290a7520851758368acb24c74ba54ba Mon Sep 17 00:00:00 2001 From: shtlrs Date: Sun, 27 Nov 2022 22:50:46 +0100 Subject: add docstrings to RoleButtonView This documents the attributes the class has, which gives better context for future readers/contributors --- bot/exts/info/subscribe.py | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/bot/exts/info/subscribe.py b/bot/exts/info/subscribe.py index 573d015b0..4a34077f3 100644 --- a/bot/exts/info/subscribe.py +++ b/bot/exts/info/subscribe.py @@ -61,12 +61,23 @@ log = get_logger(__name__) class RoleButtonView(discord.ui.View): - """A list of SingleRoleButtons to show to the member.""" + """ + A view that holds the list of SingleRoleButtons to show to the member. + + Attributes + __________ + anchor_message : discord.Message + The message to which this view will be attached + interaction_owner: discord.Member + The member that initiated the interaction + """ + + anchor_message: discord.Message def __init__(self, member: discord.Member): super().__init__(timeout=DELETE_MESSAGE_AFTER) # We can't obtain the reference to the message before the view is sent - self.original_message = None + self.anchor_message = None self.interaction_owner = member async def interaction_check(self, interaction: Interaction) -> bool: @@ -81,7 +92,7 @@ class RoleButtonView(discord.ui.View): async def on_timeout(self) -> None: """Delete the original message that the view was sent along with.""" - await self.original_message.delete() + await self.anchor_message.delete() class SingleRoleButton(discord.ui.Button): @@ -175,7 +186,7 @@ class ShowAllSelfAssignableRolesButton(discord.ui.Button): view=view, ) # Keep reference of the message that contains the view to be deleted - view.original_message = message + view.anchor_message = message class Subscribe(commands.Cog): @@ -228,7 +239,7 @@ class Subscribe(commands.Cog): view=view, ) # Keep reference of the message that contains the view to be deleted - view.original_message = message + view.anchor_message = message async def __search_for_self_assignable_roles_message(self) -> discord.Message: """ @@ -276,7 +287,7 @@ def prepare_self_assignable_roles_view( author = trigger_action.author if isinstance(trigger_action, commands.Context) else trigger_action.user author_roles = [role.id for role in author.roles] button_view = RoleButtonView(member=author) - button_view.original_message = trigger_action.message + button_view.anchor_message = trigger_action.message for index, role in enumerate(assignable_roles): row = index // ITEMS_PER_ROW -- cgit v1.2.3 From e7d0987a62ecb532a68839d8e98d33f2ddf0912f Mon Sep 17 00:00:00 2001 From: shtlrs Date: Sun, 27 Nov 2022 22:58:54 +0100 Subject: make the roles view ephemeral when sent in roles channel --- bot/exts/info/subscribe.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bot/exts/info/subscribe.py b/bot/exts/info/subscribe.py index 4a34077f3..63a23346f 100644 --- a/bot/exts/info/subscribe.py +++ b/bot/exts/info/subscribe.py @@ -151,7 +151,7 @@ class SingleRoleButton(discord.ui.Button): self.style = self.REMOVE_STYLE if self.assigned else self.ADD_STYLE self.label = self.LABEL_FORMAT.format(action="Remove" if self.assigned else "Add", role_name=self.role.name) try: - await interaction.message.edit(view=self.view) + await self.view.anchor_message.edit(view=self.view) except discord.NotFound: log.debug("Subscribe message for %s removed before buttons could be updated", interaction.user) self.view.stop() @@ -184,6 +184,7 @@ class ShowAllSelfAssignableRolesButton(discord.ui.Button): view = prepare_self_assignable_roles_view(interaction, self.assignable_roles) message = await interaction.followup.send( view=view, + ephemeral=True ) # Keep reference of the message that contains the view to be deleted view.anchor_message = message -- cgit v1.2.3 From 0a60b5d4200219233ad5164da3ae73c5f43955e7 Mon Sep 17 00:00:00 2001 From: shtlrs Date: Sat, 3 Dec 2022 23:37:22 +0100 Subject: do not use name mangling This also renames to method to align more with our fetch or {action} pattern --- bot/exts/info/subscribe.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bot/exts/info/subscribe.py b/bot/exts/info/subscribe.py index 63a23346f..15e7ba347 100644 --- a/bot/exts/info/subscribe.py +++ b/bot/exts/info/subscribe.py @@ -222,7 +222,7 @@ class Subscribe(commands.Cog): self.assignable_roles.sort(key=operator.attrgetter("name")) self.assignable_roles.sort(key=operator.methodcaller("is_currently_available"), reverse=True) - initial_self_assignable_roles_message = await self.__search_for_self_assignable_roles_message() + initial_self_assignable_roles_message = await self._fetch_or_create_self_assignable_roles_message() self.__attach_persistent_roles_view(initial_self_assignable_roles_message) @commands.cooldown(1, 10, commands.BucketType.member) @@ -242,9 +242,9 @@ class Subscribe(commands.Cog): # Keep reference of the message that contains the view to be deleted view.anchor_message = message - async def __search_for_self_assignable_roles_message(self) -> discord.Message: + async def _fetch_or_create_self_assignable_roles_message(self) -> discord.Message: """ - Searches for the message that holds the self assignable roles view. + Fetches the message that holds the self assignable roles view. If the initial message isn't found, a new one will be created. This message will always be needed to attach the persistent view to it -- cgit v1.2.3 From 28dac62fb325e0f09404945645589a89af19bfdd Mon Sep 17 00:00:00 2001 From: shtlrs Date: Sat, 3 Dec 2022 23:39:57 +0100 Subject: call super without referencing the current class --- bot/exts/info/subscribe.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/exts/info/subscribe.py b/bot/exts/info/subscribe.py index 15e7ba347..92d7d23b2 100644 --- a/bot/exts/info/subscribe.py +++ b/bot/exts/info/subscribe.py @@ -161,7 +161,7 @@ class AllSelfAssignableRolesView(discord.ui.View): """A persistent view that'll hold one button allowing interactors to toggle all available self-assignable roles.""" def __init__(self): - super(AllSelfAssignableRolesView, self).__init__(timeout=None) + super().__init__(timeout=None) class ShowAllSelfAssignableRolesButton(discord.ui.Button): -- cgit v1.2.3 From 72b2f803a6bb915c4bb07d3a0cd3f4d141d46431 Mon Sep 17 00:00:00 2001 From: shtlrs Date: Sat, 3 Dec 2022 23:41:28 +0100 Subject: rename #Roles section to #Information --- config-default.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config-default.yml b/config-default.yml index 86474c204..ac76a670a 100644 --- a/config-default.yml +++ b/config-default.yml @@ -235,7 +235,7 @@ guild: # Watch big_brother_logs: &BB_LOGS 468507907357409333 - # Roles + # Information roles: 851270062434156586 moderation_categories: -- cgit v1.2.3 From 24c36e5bcc8f87c045242c88b6b5baa8d12110c0 Mon Sep 17 00:00:00 2001 From: shtlrs Date: Sun, 4 Dec 2022 11:10:53 +0100 Subject: use button decorator instead of subclassing discord.ui.Button This will help clarify the relationship between the button & the viw since it'll only be used there --- bot/exts/info/subscribe.py | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/bot/exts/info/subscribe.py b/bot/exts/info/subscribe.py index 92d7d23b2..55ee3d855 100644 --- a/bot/exts/info/subscribe.py +++ b/bot/exts/info/subscribe.py @@ -160,25 +160,17 @@ class SingleRoleButton(discord.ui.Button): class AllSelfAssignableRolesView(discord.ui.View): """A persistent view that'll hold one button allowing interactors to toggle all available self-assignable roles.""" - def __init__(self): - super().__init__(timeout=None) - - -class ShowAllSelfAssignableRolesButton(discord.ui.Button): - """A button that, when clicked, sends a view a user can interact with to assign one or all the available roles.""" - - CUSTOM_ID = "gotta-claim-them-all" - def __init__(self, assignable_roles: list[AssignableRole]): - super().__init__( - style=discord.ButtonStyle.success, - label="Show all self assignable roles", - custom_id=self.CUSTOM_ID, - row=1 - ) + super().__init__(timeout=None) self.assignable_roles = assignable_roles - async def callback(self, interaction: Interaction) -> t.Any: + @discord.ui.button( + style=discord.ButtonStyle.success, + label="Show all self assignable roles", + custom_id="gotta-claim-them-all", + row=1 + ) + async def show_all_self_assignable_roles(self, interaction: Interaction, button: discord.ui.Button) -> None: """Sends the original subscription view containing the available self assignable roles.""" await interaction.response.defer() view = prepare_self_assignable_roles_view(interaction, self.assignable_roles) @@ -257,8 +249,7 @@ class Subscribe(commands.Cog): return message log.debug("Self assignable roles view message hasn't been found, creating a new one.") - view = AllSelfAssignableRolesView() - view.add_item(ShowAllSelfAssignableRolesButton(self.assignable_roles)) + view = AllSelfAssignableRolesView(self.assignable_roles) return await roles_channel.send(self.SELF_ASSIGNABLE_ROLES_MESSAGE, view=view) def __attach_persistent_roles_view( @@ -275,8 +266,7 @@ class Subscribe(commands.Cog): :param placeholder_message: The message that will hold the persistent view allowing users to toggle the RoleButtonView """ - view = AllSelfAssignableRolesView() - view.add_item(ShowAllSelfAssignableRolesButton(self.assignable_roles)) + view = AllSelfAssignableRolesView(self.assignable_roles) self.bot.add_view(view, message_id=placeholder_message.id) -- cgit v1.2.3 From a6fa4b1b7ce4dcff8c0ecfc4459df471ec97cde9 Mon Sep 17 00:00:00 2001 From: shtlrs Date: Sun, 4 Dec 2022 11:12:57 +0100 Subject: update custom id of the AllSelfAssignableRolesView's button --- bot/exts/info/subscribe.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/exts/info/subscribe.py b/bot/exts/info/subscribe.py index 55ee3d855..8eeb852b8 100644 --- a/bot/exts/info/subscribe.py +++ b/bot/exts/info/subscribe.py @@ -167,7 +167,7 @@ class AllSelfAssignableRolesView(discord.ui.View): @discord.ui.button( style=discord.ButtonStyle.success, label="Show all self assignable roles", - custom_id="gotta-claim-them-all", + custom_id="toggle-available-roles-button", row=1 ) async def show_all_self_assignable_roles(self, interaction: Interaction, button: discord.ui.Button) -> None: -- cgit v1.2.3 From c630e1b9c2ca624dd272d634cd24704c11bea953 Mon Sep 17 00:00:00 2001 From: shtlrs Date: Sun, 4 Dec 2022 11:19:28 +0100 Subject: make SELF_ASSIGNABLE_ROLES_MESSAGE more inviting for people to interact with --- bot/exts/info/subscribe.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bot/exts/info/subscribe.py b/bot/exts/info/subscribe.py index 8eeb852b8..b77dcd8b0 100644 --- a/bot/exts/info/subscribe.py +++ b/bot/exts/info/subscribe.py @@ -185,7 +185,11 @@ class AllSelfAssignableRolesView(discord.ui.View): class Subscribe(commands.Cog): """Cog to allow user to self-assign & remove the roles present in ASSIGNABLE_ROLES.""" - SELF_ASSIGNABLE_ROLES_MESSAGE = "Click on this button to show all self assignable roles" + GREETING_EMOJI = ":wave:" + + SELF_ASSIGNABLE_ROLES_MESSAGE = f"Hi there {GREETING_EMOJI}," \ + "\nDid you know we had various self-assignable roles for server updates an events?"\ + "\nClick the button below to toggle them." def __init__(self, bot: Bot): self.bot = bot -- cgit v1.2.3 From 37b43a6c04af0498d96bd28ec544973d2e653941 Mon Sep 17 00:00:00 2001 From: shtlrs Date: Sun, 4 Dec 2022 11:31:52 +0100 Subject: ditch prepare_self_assignable_roles_view by constructing the buttons inside the view itself --- bot/exts/info/subscribe.py | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/bot/exts/info/subscribe.py b/bot/exts/info/subscribe.py index b77dcd8b0..0c12da37d 100644 --- a/bot/exts/info/subscribe.py +++ b/bot/exts/info/subscribe.py @@ -74,12 +74,18 @@ class RoleButtonView(discord.ui.View): anchor_message: discord.Message - def __init__(self, member: discord.Member): + def __init__(self, member: discord.Member, assignable_roles: list[AssignableRole]): super().__init__(timeout=DELETE_MESSAGE_AFTER) # We can't obtain the reference to the message before the view is sent self.anchor_message = None self.interaction_owner = member + author_roles = [role.id for role in member.roles] + + for index, role in enumerate(assignable_roles): + row = index // ITEMS_PER_ROW + self.add_item(SingleRoleButton(role, role.role_id in author_roles, row)) + async def interaction_check(self, interaction: Interaction) -> bool: """Ensure that the user clicking the button is the member who invoked the command.""" if interaction.user != self.interaction_owner: @@ -173,7 +179,7 @@ class AllSelfAssignableRolesView(discord.ui.View): async def show_all_self_assignable_roles(self, interaction: Interaction, button: discord.ui.Button) -> None: """Sends the original subscription view containing the available self assignable roles.""" await interaction.response.defer() - view = prepare_self_assignable_roles_view(interaction, self.assignable_roles) + view = RoleButtonView(interaction.user, self.assignable_roles) message = await interaction.followup.send( view=view, ephemeral=True @@ -229,8 +235,7 @@ class Subscribe(commands.Cog): ) async def subscribe_command(self, ctx: commands.Context, *_) -> None: # We don't actually care about the args """Display the member's current state for each role, and allow them to add/remove the roles.""" - view = prepare_self_assignable_roles_view(ctx, self.assignable_roles) - + view = RoleButtonView(ctx.author, self.assignable_roles) message = await ctx.send( "Click the buttons below to add or remove your roles!", view=view, @@ -274,23 +279,6 @@ class Subscribe(commands.Cog): self.bot.add_view(view, message_id=placeholder_message.id) -def prepare_self_assignable_roles_view( - trigger_action: commands.Context | Interaction, - assignable_roles: list[AssignableRole] -) -> discord.ui.View: - """Prepares the view containing the self assignable roles before its sent.""" - author = trigger_action.author if isinstance(trigger_action, commands.Context) else trigger_action.user - author_roles = [role.id for role in author.roles] - button_view = RoleButtonView(member=author) - button_view.anchor_message = trigger_action.message - - for index, role in enumerate(assignable_roles): - row = index // ITEMS_PER_ROW - button_view.add_item(SingleRoleButton(role, role.role_id in author_roles, row)) - - return button_view - - async def setup(bot: Bot) -> None: """Load the 'Subscribe' cog.""" if len(ASSIGNABLE_ROLES) > ITEMS_PER_ROW * 5: # Discord limits views to 5 rows of buttons. -- cgit v1.2.3 From 6c6b2bc358228404978c855d18c788e85fb4433a Mon Sep 17 00:00:00 2001 From: shtlrs Date: Sun, 4 Dec 2022 13:25:13 +0100 Subject: relay the newly created view to __attach_persistent_roles_view --- bot/exts/info/subscribe.py | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/bot/exts/info/subscribe.py b/bot/exts/info/subscribe.py index 0c12da37d..cdf0bc86b 100644 --- a/bot/exts/info/subscribe.py +++ b/bot/exts/info/subscribe.py @@ -224,8 +224,9 @@ class Subscribe(commands.Cog): self.assignable_roles.sort(key=operator.attrgetter("name")) self.assignable_roles.sort(key=operator.methodcaller("is_currently_available"), reverse=True) - initial_self_assignable_roles_message = await self._fetch_or_create_self_assignable_roles_message() - self.__attach_persistent_roles_view(initial_self_assignable_roles_message) + placeholder_message_view_tuple = await self._fetch_or_create_self_assignable_roles_message() + self_assignable_roles_message, self_assignable_roles_view = placeholder_message_view_tuple + self.__attach_persistent_roles_view(self_assignable_roles_message, self_assignable_roles_view) @commands.cooldown(1, 10, commands.BucketType.member) @commands.command(name="subscribe", aliases=("unsubscribe",)) @@ -243,7 +244,7 @@ class Subscribe(commands.Cog): # Keep reference of the message that contains the view to be deleted view.anchor_message = message - async def _fetch_or_create_self_assignable_roles_message(self) -> discord.Message: + async def _fetch_or_create_self_assignable_roles_message(self) -> tuple[discord.Message, discord.ui.View | None]: """ Fetches the message that holds the self assignable roles view. @@ -255,15 +256,17 @@ class Subscribe(commands.Cog): async for message in roles_channel.history(limit=30): if message.content == self.SELF_ASSIGNABLE_ROLES_MESSAGE: log.debug(f"Found self assignable roles view message: {message.id}") - return message + return message, None log.debug("Self assignable roles view message hasn't been found, creating a new one.") view = AllSelfAssignableRolesView(self.assignable_roles) - return await roles_channel.send(self.SELF_ASSIGNABLE_ROLES_MESSAGE, view=view) + placeholder_message = await roles_channel.send(self.SELF_ASSIGNABLE_ROLES_MESSAGE, view=view) + return placeholder_message, view def __attach_persistent_roles_view( self, - placeholder_message: discord.Message + placeholder_message: discord.Message, + persistent_roles_view: discord.ui.View | None = None ) -> None: """ Attaches the persistent view that toggles self assignable roles to its placeholder message. @@ -274,9 +277,13 @@ class Subscribe(commands.Cog): __________ :param placeholder_message: The message that will hold the persistent view allowing users to toggle the RoleButtonView + :param persistent_roles_view: The view attached to the placeholder_message + If none, a new view will be created """ - view = AllSelfAssignableRolesView(self.assignable_roles) - self.bot.add_view(view, message_id=placeholder_message.id) + if not persistent_roles_view: + persistent_roles_view = AllSelfAssignableRolesView(self.assignable_roles) + + self.bot.add_view(persistent_roles_view, message_id=placeholder_message.id) async def setup(bot: Bot) -> None: -- cgit v1.2.3 From 7118c51b9b62b2a5ce0e745e4832b17f52901235 Mon Sep 17 00:00:00 2001 From: shtlrs Date: Sun, 4 Dec 2022 13:53:34 +0100 Subject: edit view through interaction.response.edit_message --- bot/exts/info/subscribe.py | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/bot/exts/info/subscribe.py b/bot/exts/info/subscribe.py index cdf0bc86b..d52836cfd 100644 --- a/bot/exts/info/subscribe.py +++ b/bot/exts/info/subscribe.py @@ -66,20 +66,15 @@ class RoleButtonView(discord.ui.View): Attributes __________ - anchor_message : discord.Message - The message to which this view will be attached interaction_owner: discord.Member The member that initiated the interaction """ - anchor_message: discord.Message + interaction_owner: discord.Member def __init__(self, member: discord.Member, assignable_roles: list[AssignableRole]): super().__init__(timeout=DELETE_MESSAGE_AFTER) - # We can't obtain the reference to the message before the view is sent - self.anchor_message = None self.interaction_owner = member - author_roles = [role.id for role in member.roles] for index, role in enumerate(assignable_roles): @@ -96,10 +91,6 @@ class RoleButtonView(discord.ui.View): return False return True - async def on_timeout(self) -> None: - """Delete the original message that the view was sent along with.""" - await self.anchor_message.delete() - class SingleRoleButton(discord.ui.Button): """A button that adds or removes a role from the member depending on its current state.""" @@ -157,7 +148,7 @@ class SingleRoleButton(discord.ui.Button): self.style = self.REMOVE_STYLE if self.assigned else self.ADD_STYLE self.label = self.LABEL_FORMAT.format(action="Remove" if self.assigned else "Add", role_name=self.role.name) try: - await self.view.anchor_message.edit(view=self.view) + await interaction.response.edit_message(view=self.view) except discord.NotFound: log.debug("Subscribe message for %s removed before buttons could be updated", interaction.user) self.view.stop() @@ -178,14 +169,11 @@ class AllSelfAssignableRolesView(discord.ui.View): ) async def show_all_self_assignable_roles(self, interaction: Interaction, button: discord.ui.Button) -> None: """Sends the original subscription view containing the available self assignable roles.""" - await interaction.response.defer() view = RoleButtonView(interaction.user, self.assignable_roles) - message = await interaction.followup.send( + await interaction.response.send_message( view=view, ephemeral=True ) - # Keep reference of the message that contains the view to be deleted - view.anchor_message = message class Subscribe(commands.Cog): @@ -237,12 +225,11 @@ class Subscribe(commands.Cog): async def subscribe_command(self, ctx: commands.Context, *_) -> None: # We don't actually care about the args """Display the member's current state for each role, and allow them to add/remove the roles.""" view = RoleButtonView(ctx.author, self.assignable_roles) - message = await ctx.send( + await ctx.send( "Click the buttons below to add or remove your roles!", view=view, + delete_after=DELETE_MESSAGE_AFTER ) - # Keep reference of the message that contains the view to be deleted - view.anchor_message = message async def _fetch_or_create_self_assignable_roles_message(self) -> tuple[discord.Message, discord.ui.View | None]: """ -- cgit v1.2.3 From 7976bc2af0fe49ddaebc63242b581b9eecb66132 Mon Sep 17 00:00:00 2001 From: shtlrs Date: Sun, 4 Dec 2022 14:00:22 +0100 Subject: use follow.send to send the role update message --- bot/exts/info/subscribe.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/exts/info/subscribe.py b/bot/exts/info/subscribe.py index d52836cfd..aa48be13c 100644 --- a/bot/exts/info/subscribe.py +++ b/bot/exts/info/subscribe.py @@ -138,7 +138,7 @@ class SingleRoleButton(discord.ui.Button): self.assigned = not self.assigned await self.update_view(interaction) - await interaction.response.send_message( + await interaction.followup.send( self.LABEL_FORMAT.format(action="Added" if self.assigned else "Removed", role_name=self.role.name), ephemeral=True, ) -- cgit v1.2.3 From 91a869e4a23fdee8c6407678ca178e324d6184f3 Mon Sep 17 00:00:00 2001 From: shtlrs Date: Sun, 4 Dec 2022 15:51:00 +0100 Subject: do not use name mangling in _attach_persistent_roles_view --- bot/exts/info/subscribe.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bot/exts/info/subscribe.py b/bot/exts/info/subscribe.py index aa48be13c..f3f6e71f6 100644 --- a/bot/exts/info/subscribe.py +++ b/bot/exts/info/subscribe.py @@ -214,7 +214,7 @@ class Subscribe(commands.Cog): placeholder_message_view_tuple = await self._fetch_or_create_self_assignable_roles_message() self_assignable_roles_message, self_assignable_roles_view = placeholder_message_view_tuple - self.__attach_persistent_roles_view(self_assignable_roles_message, self_assignable_roles_view) + self._attach_persistent_roles_view(self_assignable_roles_message, self_assignable_roles_view) @commands.cooldown(1, 10, commands.BucketType.member) @commands.command(name="subscribe", aliases=("unsubscribe",)) @@ -250,7 +250,7 @@ class Subscribe(commands.Cog): placeholder_message = await roles_channel.send(self.SELF_ASSIGNABLE_ROLES_MESSAGE, view=view) return placeholder_message, view - def __attach_persistent_roles_view( + def _attach_persistent_roles_view( self, placeholder_message: discord.Message, persistent_roles_view: discord.ui.View | None = None -- cgit v1.2.3 From c55b9ffb4ef4eb245eff2fd256c42c16976a3467 Mon Sep 17 00:00:00 2001 From: shtlrs Date: Sun, 18 Dec 2022 08:47:14 +0100 Subject: fix Zig's nit comments --- bot/exts/info/subscribe.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/bot/exts/info/subscribe.py b/bot/exts/info/subscribe.py index f3f6e71f6..082f8438b 100644 --- a/bot/exts/info/subscribe.py +++ b/bot/exts/info/subscribe.py @@ -98,7 +98,7 @@ class SingleRoleButton(discord.ui.Button): ADD_STYLE = discord.ButtonStyle.success REMOVE_STYLE = discord.ButtonStyle.red UNAVAILABLE_STYLE = discord.ButtonStyle.secondary - LABEL_FORMAT = "{action} role {role_name}." + LABEL_FORMAT = "{action} role {role_name}" CUSTOM_ID_FORMAT = "subscribe-{role_id}" def __init__(self, role: AssignableRole, assigned: bool, row: int): @@ -181,9 +181,11 @@ class Subscribe(commands.Cog): GREETING_EMOJI = ":wave:" - SELF_ASSIGNABLE_ROLES_MESSAGE = f"Hi there {GREETING_EMOJI}," \ - "\nDid you know we had various self-assignable roles for server updates an events?"\ - "\nClick the button below to toggle them." + SELF_ASSIGNABLE_ROLES_MESSAGE = ( + f"Hi there {GREETING_EMOJI}," + "\nWe have self-assignable roles for server updates an events!" + "\nClick the button below to toggle them:" + ) def __init__(self, bot: Bot): self.bot = bot -- cgit v1.2.3 From 52d69dee620d2cb659b1fee288ed6360bded83d7 Mon Sep 17 00:00:00 2001 From: shtlrs Date: Sat, 14 Jan 2023 10:56:09 +0100 Subject: fix typos in the SELF_ASSIGNABLE_ROLES_MESSAGE --- bot/exts/info/subscribe.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/exts/info/subscribe.py b/bot/exts/info/subscribe.py index 082f8438b..86a209214 100644 --- a/bot/exts/info/subscribe.py +++ b/bot/exts/info/subscribe.py @@ -183,7 +183,7 @@ class Subscribe(commands.Cog): SELF_ASSIGNABLE_ROLES_MESSAGE = ( f"Hi there {GREETING_EMOJI}," - "\nWe have self-assignable roles for server updates an events!" + "\nWe have self-assignable roles for server updates and events!" "\nClick the button below to toggle them:" ) -- cgit v1.2.3