diff options
| -rw-r--r-- | bot/exts/utilities/bookmark.py | 100 |
1 files changed, 85 insertions, 15 deletions
diff --git a/bot/exts/utilities/bookmark.py b/bot/exts/utilities/bookmark.py index 138284c2..e2988dca 100644 --- a/bot/exts/utilities/bookmark.py +++ b/bot/exts/utilities/bookmark.py @@ -23,6 +23,39 @@ MESSAGE_NOT_FOUND_ERROR = ( ) +class BookmarkTitleSelectionForm(discord.ui.Modal): + """ + The form where a user can fill in a custom title for their bookmark & submit it. + + This form is only available when the command is invoked from a context menu. + """ + + bookmark_title = discord.ui.TextInput( + label="Choose a title for you bookmark (optional)", + placeholder="Type your bookmark title here", + default="Bookmark", + max_length=50, + min_length=0, + required=False + ) + + def __init__( + self, + message: discord.Message, + action_bookmark_function: Callable[[discord.TextChannel, discord.Member, discord.Message, str], None], + ): + super().__init__(timeout=1000, title="Name your bookmark") + self.message = message + self.action_bookmark = action_bookmark_function + + async def on_submit(self, interaction: discord.Interaction) -> None: + """Sends the bookmark embed to the user with the newly chosen title.""" + title = self.bookmark_title.value or self.bookmark_title.default + await self.action_bookmark(interaction.channel, interaction.user, self.message, title) + embed = Bookmark.build_ephemeral_bookmark_embed(self.message) + await interaction.response.send_message(embed=embed, ephemeral=True) + + class LinkTargetMessage(discord.ui.View): """The button that relays the user to the bookmarked message.""" @@ -71,6 +104,33 @@ class Bookmark(commands.Cog): def __init__(self, bot: Bot): self.bot = bot + self.book_mark_context_menu = discord.app_commands.ContextMenu( + name="Bookmark", + callback=self._bookmark_context_menu_callback + ) + self.bot.tree.add_command(self.book_mark_context_menu) + + @staticmethod + def build_bookmark_embed(target_message: discord.Message) -> discord.Embed: + """Build the channel embed to the bookmark requester.""" + 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, + ) + + @staticmethod + def build_ephemeral_bookmark_embed(target_message: discord.Message) -> discord.Embed: + """Build the ephemeral embed to the bookmark requester.""" + return discord.Embed( + description=( + f"A bookmark for [this message]({target_message.jump_url}) " + f"has been successfully sent your way.\n" + ), + colour=Colours.soft_green, + ) @staticmethod def build_bookmark_dm(target_message: discord.Message, title: str) -> discord.Embed: @@ -117,6 +177,27 @@ class Bookmark(commands.Cog): else: log.info(f"{member} bookmarked {target_message.jump_url} with title '{title}'") + async def _bookmark_context_menu_callback(self, interaction: discord.Interaction, message: discord.Message) -> None: + """The callback that will be invoked upon using the bookmark's context menu command.""" + permissions = interaction.channel.permissions_for(interaction.user) + if not interaction.channel.guild: + embed = Bookmark.build_error_embed("This command cannot be used in DMs.") + await interaction.response.send_message(embed=embed) + return + + if not permissions.read_messages: + log.info(f"{interaction.user} tried to bookmark a message in #{interaction.channel}" + f"but has no permissions.") + embed = Bookmark.build_error_embed("You don't have permission to view this channel.") + await interaction.response.send_message(embed=embed) + return + + bookmark_title_form = BookmarkTitleSelectionForm( + message=message, + action_bookmark_function=self.action_bookmark + ) + await interaction.response.send_modal(bookmark_title_form) + @commands.group(name="bookmark", aliases=("bm", "pin"), invoke_without_command=True) @commands.guild_only() @whitelist_override(roles=(Roles.everyone,)) @@ -138,29 +219,18 @@ class Bookmark(commands.Cog): if target_message is None: raise commands.UserInputError(MESSAGE_NOT_FOUND_ERROR) - # Prevent users from bookmarking a message in a channel they don't have access to - permissions = target_message.channel.permissions_for(ctx.author) + permissions = ctx.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 = discord.Embed( - title=random.choice(ERROR_REPLIES), - color=Colours.soft_red, - description="You don't have permission to view this channel.", - ) + log.info(f"{ctx.author} tried to bookmark a message in #{ctx.channel} but has no permissions.") + embed = Bookmark.build_error_embed("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) view = SendBookmark(self.action_bookmark, ctx.author, ctx.channel, target_message, title) + embed = self.build_bookmark_embed(target_message) - embed = 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, - ) await ctx.send(embed=embed, view=view) @bookmark.command(name="delete", aliases=("del", "rm"), root_aliases=("unbm", "unbookmark", "dmdelete", "dmdel")) |