diff options
author | 2022-08-30 16:45:33 +0400 | |
---|---|---|
committer | 2022-08-30 16:45:33 +0400 | |
commit | 0364a40dced5420d6002f84be43ecc2983eab92c (patch) | |
tree | 72f5240332f9fcb9d43d90b4101219e062b01e5b /bot/exts/utilities | |
parent | Merge pull request #1094 from python-discord/message-content-intent (diff) |
Use buttons for bookmark command
Diffstat (limited to 'bot/exts/utilities')
-rw-r--r-- | bot/exts/utilities/bookmark.py | 131 |
1 files changed, 77 insertions, 54 deletions
diff --git a/bot/exts/utilities/bookmark.py b/bot/exts/utilities/bookmark.py index 2e3458d8..3c57aa09 100644 --- a/bot/exts/utilities/bookmark.py +++ b/bot/exts/utilities/bookmark.py @@ -1,7 +1,6 @@ -import asyncio import logging import random -from typing import Optional +from typing import Callable, Optional import discord from discord.ext import commands @@ -15,7 +14,6 @@ log = logging.getLogger(__name__) # Number of seconds to wait for other users to bookmark the same message TIMEOUT = 120 -BOOKMARK_EMOJI = "📌" MESSAGE_NOT_FOUND_ERROR = ( "You must either provide a reference to a valid message, or reply to one." "\n\nThe lookup strategy for a message is as follows (in order):" @@ -25,6 +23,54 @@ MESSAGE_NOT_FOUND_ERROR = ( ) +class LinkTargetMessage(discord.ui.View): + """The button that relays the user to the bookmarked message.""" + + def __init__( + self, + target_message: discord.Message, + ): + super().__init__() + self.add_item(discord.ui.Button(label="View Message", url=target_message.jump_url)) + + +class SendBookmark(discord.ui.View): + """The button that sends the bookmark to other users.""" + + def __init__( + self, + bookmark_function: Callable[ + [discord.TextChannel, discord.Member, discord.Message, str], None + ], + author: discord.Member, + channel: discord.TextChannel, + target_message: discord.Message, + ): + super().__init__() + + self.bookmark_function = bookmark_function # The function is the 'action_bookmark' + self.clicked: list[int] = [author.id] + self.channel = channel + self.target_message = target_message + + + @discord.ui.button(label="Receive Bookmark", style=discord.ButtonStyle.green) + async def button_callback(self, button: discord.Button, interaction: discord.Interaction) -> None: + """The button callback.""" + if interaction.user.id in self.clicked: + return await interaction.response.send_message( + "You have already received a bookmark to that message.", ephemeral=True + ) + + await self.bookmark_function( + self.channel, interaction.user, self.target_message + ) + await interaction.response.send_message( + "You have received a bookmark to that message.", ephemeral=True + ) + self.clicked.append(interaction.user.id) + + class Bookmark(commands.Cog): """Creates personal bookmarks by relaying a message link to the user's DMs.""" @@ -35,17 +81,13 @@ class Bookmark(commands.Cog): def build_bookmark_dm(target_message: discord.Message, title: str) -> discord.Embed: """Build the embed to DM the bookmark requester.""" embed = discord.Embed( - title=title, - description=target_message.content, - colour=Colours.soft_green + title=title, description=target_message.content, colour=Colours.soft_green ) - embed.add_field( - name="Wanna give it a visit?", - value=f"[Visit original message]({target_message.jump_url})" + embed.set_author( + name=target_message.author, + icon_url=target_message.author.display_avatar.url, ) - embed.set_author(name=target_message.author, icon_url=target_message.author.display_avatar.url) embed.set_thumbnail(url=Icons.bookmark) - return embed @staticmethod @@ -57,6 +99,17 @@ class Bookmark(commands.Cog): colour=Colours.soft_red ) + @staticmethod + def create_button_embed(target_message: discord.Message) -> discord.Embed: + """Generates the embed which is sent with the button, so other users can receive the bookmark too.""" + return discord.Embed( + description=( + f"Click the button to be sent your very own bookmark to " + f"[this message]({target_message.jump_url})." + ), + colour=Colours.soft_green, + ) + async def action_bookmark( self, channel: discord.TextChannel, @@ -71,7 +124,7 @@ class Bookmark(commands.Cog): """ embed = self.build_bookmark_dm(target_message, title) try: - await member.send(embed=embed) + await member.send(embed=embed, view=LinkTargetMessage(target_message)) except discord.Forbidden: error_embed = self.build_error_embed(f"{member.mention}, please enable your DMs to receive the bookmark.") await channel.send(embed=error_embed) @@ -102,53 +155,23 @@ class Bookmark(commands.Cog): # Prevent users from bookmarking a message in a channel they don't have access to permissions = target_message.channel.permissions_for(ctx.author) if not permissions.read_messages: - log.info(f"{ctx.author} tried to bookmark a message in #{target_message.channel} but has no permissions.") - embed = self.build_error_embed(f"{ctx.author.mention} You don't have permission to view this channel.") + log.info( + f"{ctx.author} tried to bookmark a message in #{target_message.channel} but has no permissions." + ) + embed = discord.Embed( + title=random.choice(ERROR_REPLIES), + color=Colours.soft_red, + description="You don't have permission to view this channel.", + ) await ctx.send(embed=embed) return await self.action_bookmark(ctx.channel, ctx.author, target_message, title) - # Keep track of who has already bookmarked, so users can't spam reactions and cause loads of DMs - bookmarked_users = [ctx.author.id] - - reaction_embed = discord.Embed( - description=( - f"React with {BOOKMARK_EMOJI} to be sent your very own bookmark to " - f"[this message]({ctx.message.jump_url})." - ), - colour=Colours.soft_green - ) - reaction_message = await ctx.send(embed=reaction_embed) - await reaction_message.add_reaction(BOOKMARK_EMOJI) - - def event_check(reaction: discord.Reaction, user: discord.Member) -> bool: - """Make sure that this reaction is what we want to operate on.""" - return ( - # Conditions for a successful pagination: - all(( - # Reaction is on this message - reaction.message.id == reaction_message.id, - # User has not already bookmarked this message - user.id not in bookmarked_users, - # Reaction is the `BOOKMARK_EMOJI` emoji - str(reaction.emoji) == BOOKMARK_EMOJI, - # Reaction was not made by the Bot - user.id != self.bot.user.id - )) - ) - - while True: - try: - _, user = await self.bot.wait_for("reaction_add", timeout=TIMEOUT, check=event_check) - except asyncio.TimeoutError: - log.debug("Timed out waiting for a reaction") - break - log.trace(f"{user} has successfully bookmarked from a reaction, attempting to DM them.") - await self.action_bookmark(ctx.channel, user, target_message, title) - bookmarked_users.append(user.id) - - await reaction_message.delete() + view = SendBookmark(self.action_bookmark, ctx.author, ctx.channel, target_message) + + embed = self.create_button_embed(target_message) + await ctx.send(embed=embed, view=view) @bookmark.command(name="delete", aliases=("del", "rm"), root_aliases=("unbm", "unbookmark", "dmdelete", "dmdel")) @whitelist_override(bypass_defaults=True, allow_dm=True) |