From 4d17115c091855824116f6d9a1247458a975ec5b Mon Sep 17 00:00:00 2001 From: Zevaryx Date: Sun, 28 Aug 2022 19:10:21 -0600 Subject: [PATCH] Add delete button to all embeds, change how reminders work a little --- jarvis/client.py | 69 ++++++++++++++- jarvis/cogs/botutil.py | 23 ++++- jarvis/cogs/dev.py | 17 +++- jarvis/cogs/image.py | 8 +- jarvis/cogs/remindme.py | 181 ++++++++++++++++----------------------- jarvis/cogs/rolegiver.py | 15 ++-- jarvis/cogs/starboard.py | 9 +- jarvis/cogs/tags.py | 26 ++++-- jarvis/cogs/temprole.py | 8 +- jarvis/cogs/util.py | 40 ++++++--- 10 files changed, 251 insertions(+), 145 deletions(-) diff --git a/jarvis/client.py b/jarvis/client.py index b37dda6..cc4b9c3 100644 --- a/jarvis/client.py +++ b/jarvis/client.py @@ -14,8 +14,10 @@ from jarvis_core.db.models import ( Autoreact, Modlog, Note, + Reminder, Roleping, Setting, + Star, Warning, ) from jarvis_core.filters import invites, url @@ -154,6 +156,9 @@ class Jarvis(StatsClient): "{}&permissions=8&scope=bot%20applications.commands".format(self.user.id) ) + self.logger.debug("Hitting Reminders for faster loads") + _ = await Reminder.find().to_list(None) + async def on_error(self, source: str, error: Exception, *args, **kwargs) -> None: """NAFF on_error override.""" if isinstance(error, HTTPException): @@ -841,13 +846,11 @@ class Jarvis(StatsClient): f"Failed to process edit {message.guild.id}/{message.channel.id}/{message.id}: {e}" ) - @listen() - async def on_button(self, event: Button) -> None: - """Process button events.""" + async def _handle_modcase_button(self, event: Button) -> None: context = event.context if not context.custom_id.startswith("modcase|"): - return # await super().on_button(event) + return # Failsafe if not context.deferred and not context.responded: await context.defer(ephemeral=True) @@ -917,3 +920,61 @@ class Jarvis(StatsClient): await context.send(msg) await self.redis.delete(user_key) await self.redis.delete(action_key) + + async def _handle_delete_button(self, event: Button) -> None: + context = event.context + + if not context.custom_id.startswith("delete|"): + return # Failsafe + + if not context.deferred and not context.responded: + await context.defer(ephemeral=True) + + uid = context.custom_id.split("|")[1] + + if ( + not context.author.has_permission(Permissions.MANAGE_MESSAGES) + and not context.author.has_permission(Permissions.ADMINISTRATOR) + and not str(context.author) == uid + ): + await context.send("I'm afraid I can't let you do that", ephemeral=True) + return # User does not have perms to delete + + if star := await Star.find_one(q(star=context.message.id, guild=context.guild.id)): + await star.delete() + + await context.message.delete() + await context.send("Message deleted", ephemeral=True) + + async def _handle_copy_button(self, event: Button) -> None: + context = event.context + + if not context.custom_id.startswith("copy|"): + return + + if not context.deferred and not context.responded: + await context.defer(ephemeral=True) + + what, rid = context.custom_id.split("|")[1:] + if what == "rme": + reminder = await Reminder.find_one(q(_id=rid)) + if reminder: + new_reminder = Reminder( + user=context.author.id, + channel=context.channel.id, + guild=context.guild.id, + message=reminder.message, + remind_at=reminder.remind_at, + private=reminder.private, + active=reminder.active, + ) + await new_reminder.commit() + + await context.send("Reminder copied!", ephemeral=True) + + @listen() + async def on_button(self, event: Button) -> None: + """Process button events.""" + await self._handle_modcase_button(event) + await self._handle_delete_button(event) + await self._handle_copy_button(event) diff --git a/jarvis/cogs/botutil.py b/jarvis/cogs/botutil.py index 8cd9d26..9f9ae83 100644 --- a/jarvis/cogs/botutil.py +++ b/jarvis/cogs/botutil.py @@ -7,7 +7,9 @@ from io import BytesIO import psutil from aiofile import AIOFile, LineReader from naff import Client, Extension, PrefixedContext, prefixed_command +from naff.models.discord.components import Button from naff.models.discord.embed import EmbedField +from naff.models.discord.enums import ButtonStyles from naff.models.discord.file import File from rich.console import Console @@ -78,7 +80,10 @@ class BotutilCog(Extension): ) embed = build_embed(title="System Info", description="", fields=fields) embed.set_image(url=self.bot.user.avatar.url) - await ctx.send(embeds=embed) + components = Button( + style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}" + ) + await ctx.send(embeds=embed, components=components) @prefixed_command(name="update") async def _update(self, ctx: PrefixedContext) -> None: @@ -111,15 +116,25 @@ class BotutilCog(Extension): self.logger.info("Updates applied") content = f"```ansi\n{capture.get()}\n```" + components = Button( + style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}" + ) if len(content) < 3000: - await ctx.reply(content, embeds=embed) + await ctx.reply(content, embeds=embed, components=components) else: - await ctx.reply(f"Total Changes: {status.lines['total_lines']}", embeds=embed) + await ctx.reply( + f"Total Changes: {status.lines['total_lines']}", + embeds=embed, + components=components, + ) else: embed = build_embed(title="Update Status", description="No changes applied", fields=[]) embed.set_thumbnail(url="https://dev.zevaryx.com/git.png") - await ctx.reply(embeds=embed) + components = Button( + style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}" + ) + await ctx.reply(embeds=embed, components=components) def setup(bot: Client) -> None: diff --git a/jarvis/cogs/dev.py b/jarvis/cogs/dev.py index 49091b0..cad6dab 100644 --- a/jarvis/cogs/dev.py +++ b/jarvis/cogs/dev.py @@ -16,7 +16,9 @@ from jarvis_core.filters import invites, url from jarvis_core.util import convert_bytesize, hash from jarvis_core.util.http import get_size from naff import Client, Extension, InteractionContext +from naff.models.discord.components import Button from naff.models.discord.embed import EmbedField +from naff.models.discord.enums import ButtonStyles from naff.models.discord.file import File from naff.models.discord.message import Attachment from naff.models.naff.application_commands import ( @@ -119,7 +121,10 @@ class DevCog(Extension): ] embed = build_embed(title=title, description=description, fields=fields) - await ctx.send(embeds=embed) + components = Button( + style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}" + ) + await ctx.send(embeds=embed, components=components) @slash_command(name="uuid", description="Generate a UUID") @slash_option( @@ -235,7 +240,10 @@ class DevCog(Extension): EmbedField(name=mstr, value=f"`{encoded}`", inline=False), ] embed = build_embed(title="Decoded Data", description="", fields=fields) - await ctx.send(embeds=embed) + components = Button( + style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}" + ) + await ctx.send(embeds=embed, components=components) @slash_command(name="decode", description="Decode some data") @slash_option( @@ -270,7 +278,10 @@ class DevCog(Extension): EmbedField(name=mstr, value=f"`{decoded}`", inline=False), ] embed = build_embed(title="Decoded Data", description="", fields=fields) - await ctx.send(embeds=embed) + components = Button( + style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}" + ) + await ctx.send(embeds=embed, components=components) @slash_command(name="cloc", description="Get JARVIS lines of code") @cooldown(bucket=Buckets.CHANNEL, rate=1, interval=30) diff --git a/jarvis/cogs/image.py b/jarvis/cogs/image.py index 10d9b01..93f7a12 100644 --- a/jarvis/cogs/image.py +++ b/jarvis/cogs/image.py @@ -8,7 +8,9 @@ import cv2 import numpy as np from jarvis_core.util import convert_bytesize, unconvert_bytesize from naff import Client, Extension, InteractionContext +from naff.models.discord.components import Button from naff.models.discord.embed import EmbedField +from naff.models.discord.enums import ButtonStyles from naff.models.discord.file import File from naff.models.discord.message import Attachment from naff.models.naff.application_commands import ( @@ -147,9 +149,11 @@ class ImageCog(Extension): ] embed = build_embed(title=filename, description="", fields=fields) embed.set_image(url="attachment://resized.png") + components = Button( + style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}" + ) await ctx.send( - embeds=embed, - file=File(file=bufio, file_name="resized.png"), + embeds=embed, file=File(file=bufio, file_name="resized.png"), components=components ) diff --git a/jarvis/cogs/remindme.py b/jarvis/cogs/remindme.py index a9aa431..a18dfb6 100644 --- a/jarvis/cogs/remindme.py +++ b/jarvis/cogs/remindme.py @@ -5,16 +5,15 @@ import re from datetime import datetime, timezone from typing import List -from bson import ObjectId from dateparser import parse from dateparser_data.settings import default_parsers from jarvis_core.db import q from jarvis_core.db.models import Reminder -from naff import Client, Extension, InteractionContext -from naff.client.utils.misc_utils import get +from naff import AutocompleteContext, Client, Extension, InteractionContext from naff.models.discord.channel import GuildChannel -from naff.models.discord.components import ActionRow, Select, SelectOption +from naff.models.discord.components import ActionRow, Button from naff.models.discord.embed import Embed, EmbedField +from naff.models.discord.enums import ButtonStyles from naff.models.discord.modal import InputText, Modal, TextStyles from naff.models.naff.application_commands import ( OptionTypes, @@ -22,6 +21,7 @@ from naff.models.naff.application_commands import ( slash_command, slash_option, ) +from thefuzz import process from jarvis.utils import build_embed @@ -52,16 +52,8 @@ class RemindmeCog(Extension): ctx: InteractionContext, private: bool = None, ) -> None: - if private is None: + if private is None and ctx.guild: private = ctx.guild.member_count >= 5000 - reminders = len([x async for x in Reminder.find(q(user=ctx.author.id, active=True))]) - if reminders >= 5: - await ctx.send( - "You already have 5 (or more) active reminders. " - "Please either remove an old one, or wait for one to pass", - ephemeral=True, - ) - return modal = Modal( title="Set your reminder!", components=[ @@ -145,7 +137,7 @@ class RemindmeCog(Extension): r = Reminder( user=ctx.author.id, channel=ctx.channel.id, - guild=ctx.guild.id, + guild=ctx.guild.id if ctx.guild else ctx.author.id, message=message, remind_at=remind_at, private=private, @@ -173,7 +165,13 @@ class RemindmeCog(Extension): ) embed.set_thumbnail(url=ctx.author.display_avatar.url) - await response.send(embeds=embed, ephemeral=private) + delete_button = Button( + style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}" + ) + copy_button = Button(style=ButtonStyles.GREEN, emoji="📋", custom_id=f"copy|rme|{r.id}") + components = [ActionRow(delete_button, copy_button)] + private = private if private is not None else False + await response.send(embeds=embed, components=components, ephemeral=private) async def get_reminders_embed( self, ctx: InteractionContext, reminders: List[Reminder] @@ -222,126 +220,99 @@ class RemindmeCog(Extension): return embed = await self.get_reminders_embed(ctx, reminders) - - await ctx.send(embeds=embed) + components = Button( + style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}" + ) + await ctx.send(embeds=embed, components=components) @reminders.subcommand(sub_cmd_name="delete", sub_cmd_description="Delete a reminder") - async def _delete(self, ctx: InteractionContext) -> None: - reminders = await Reminder.find(q(user=ctx.author.id, active=True)).to_list(None) - if not reminders: - await ctx.send("You have no reminders set", ephemeral=True) + @slash_option( + name="content", + description="Content of the reminder", + opt_type=OptionTypes.STRING, + required=True, + autocomplete=True, + ) + async def _delete(self, ctx: InteractionContext, content: str) -> None: + reminder = await Reminder.find_one(q(_id=content)) + if not reminder: + await ctx.send(f"Reminder `{content}` does not exist", ephemeral=True) return - options = [] - for reminder in reminders: - option = SelectOption( - label=f"{reminder.remind_at}", - value=str(reminder.id), - emoji="⏰", - ) - options.append(option) + ts = int(reminder.remind_at.timestamp()) - select = Select( - options=options, - custom_id="to_delete", - placeholder="Select reminders to delete", - min_values=1, - max_values=len(reminders), + fields = [EmbedField(name=f"", value=reminder.message, inline=False)] + + embed = build_embed( + title="Deleted Reminder(s)", + description="", + fields=fields, ) - components = [ActionRow(select)] - embed = await self.get_reminders_embed(ctx, reminders) - message = await ctx.send( - content=f"You have {len(reminders)} reminder(s) set:", - embeds=embed, - components=components, + embed.set_author( + name=ctx.author.display_name + "#" + ctx.author.discriminator, + icon_url=ctx.author.display_avatar.url, ) + embed.set_thumbnail(url=ctx.author.display_avatar.url) + components = Button( + style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}" + ) try: - context = await self.bot.wait_for_component( - check=lambda x: ctx.author.id == x.context.author.id, - messages=message, - timeout=60 * 5, - ) - - fields = [] - for to_delete in context.context.values: - reminder = get(reminders, user=ctx.author.id, id=ObjectId(to_delete)) - if reminder.private and isinstance(ctx.channel, GuildChannel): - fields.append( - EmbedField( - name=f"", - value="Private reminder", - inline=False, - ) - ) - else: - fields.append( - EmbedField( - name=f"", - value=reminder.message, - inline=False, - ) - ) - try: - await reminder.delete() - except Exception: - self.logger.debug("Ignoring deletion error") - - for row in components: - for component in row.components: - component.disabled = True - - embed = build_embed( - title="Deleted Reminder(s)", - description="", - fields=fields, - ) - - embed.set_author( - name=ctx.author.display_name + "#" + ctx.author.discriminator, - icon_url=ctx.author.display_avatar.url, - ) - embed.set_thumbnail(url=ctx.author.display_avatar.url) - - await context.context.edit_origin( - content=f"Deleted {len(context.context.values)} reminder(s)", - components=components, - embeds=embed, - ) - except asyncio.TimeoutError: - for row in components: - for component in row.components: - component.disabled = True - await message.edit(components=components) + await reminder.delete() + except Exception: + self.logger.debug("Ignoring deletion error") + await ctx.send(embeds=embed, ephemeral=reminder.private, components=components) @reminders.subcommand( sub_cmd_name="fetch", sub_cmd_description="Fetch a reminder that failed to send", ) @slash_option( - name="id", description="ID of the reminder", opt_type=OptionTypes.STRING, required=True + name="content", + description="Content of the reminder", + opt_type=OptionTypes.STRING, + required=True, + autocomplete=True, ) - async def _fetch(self, ctx: InteractionContext, id: str) -> None: - reminder = await Reminder.find_one(q(id=id)) + async def _fetch(self, ctx: InteractionContext, content: str) -> None: + reminder = await Reminder.find_one(q(_id=content)) if not reminder: - await ctx.send(f"Reminder `{id}` does not exist", ephemeral=True) + await ctx.send(f"Reminder `{content}` does not exist", ephemeral=True) return - embed = build_embed(title="You have a reminder!", description=reminder.message, fields=[]) + ts = int(reminder.remind_at.timestamp()) + + fields = [EmbedField(name="Remind At", value=f" ()")] + + embed = build_embed( + title="You have a reminder!", description=reminder.message, fields=fields + ) embed.set_author( name=ctx.author.display_name + "#" + ctx.author.discriminator, - icon_url=ctx.author.display_avatar, + icon_url=ctx.author.display_avatar.url, ) - embed.set_thumbnail(url=ctx.author.display_avatar) - await ctx.send(embeds=embed, ephemeral=reminder.private) + embed.set_thumbnail(url=ctx.author.display_avatar.url) + components = Button( + style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}" + ) + await ctx.send(embeds=embed, ephemeral=reminder.private, components=components) if reminder.remind_at <= datetime.now(tz=timezone.utc) and not reminder.active: try: await reminder.delete() except Exception: self.logger.debug("Ignoring deletion error") + @_fetch.autocomplete("content") + @_delete.autocomplete("content") + async def _search_reminders(self, ctx: AutocompleteContext, content: str) -> None: + reminders = await Reminder.find(q(user=ctx.author.id)).to_list(None) + lookup = {r.message: str(r.id) for r in reminders} + results = process.extract(content, list(lookup.keys()), limit=5) + choices = [{"name": r[0], "value": lookup[r[0]]} for r in results] + await ctx.send(choices=choices) + def setup(bot: Client) -> None: """Add RemindmeCog to JARVIS""" diff --git a/jarvis/cogs/rolegiver.py b/jarvis/cogs/rolegiver.py index cf818ed..6627a39 100644 --- a/jarvis/cogs/rolegiver.py +++ b/jarvis/cogs/rolegiver.py @@ -6,8 +6,9 @@ from jarvis_core.db import q from jarvis_core.db.models import Rolegiver from naff import Client, Extension, InteractionContext, Permissions from naff.client.utils.misc_utils import get -from naff.models.discord.components import ActionRow, Select, SelectOption +from naff.models.discord.components import ActionRow, Button, Select, SelectOption from naff.models.discord.embed import EmbedField +from naff.models.discord.enums import ButtonStyles from naff.models.discord.role import Role from naff.models.naff.application_commands import ( OptionTypes, @@ -92,8 +93,10 @@ class RolegiverCog(Extension): embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.display_avatar.url) embed.set_footer(text=f"{ctx.author.username}#{ctx.author.discriminator} | {ctx.author.id}") - - await ctx.send(embeds=embed) + components = Button( + style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}" + ) + await ctx.send(embeds=embed, components=components) @rolegiver.subcommand(sub_cmd_name="remove", sub_cmd_description="Remove a role from rolegiver") @check(admin_or_permissions(Permissions.MANAGE_GUILD)) @@ -210,8 +213,10 @@ class RolegiverCog(Extension): ) embed.set_footer(text=f"{ctx.author.username}#{ctx.author.discriminator} | {ctx.author.id}") - - await ctx.send(embeds=embed) + components = Button( + style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}" + ) + await ctx.send(embeds=embed, components=components) role = SlashCommand(name="role", description="Get/Remove Rolegiver roles") diff --git a/jarvis/cogs/starboard.py b/jarvis/cogs/starboard.py index 868ece6..7e62058 100644 --- a/jarvis/cogs/starboard.py +++ b/jarvis/cogs/starboard.py @@ -7,7 +7,8 @@ from jarvis_core.db.models import Star, Starboard from naff import Client, Extension, InteractionContext, Permissions from naff.client import errors from naff.models.discord.channel import GuildText -from naff.models.discord.components import ActionRow, Select, SelectOption +from naff.models.discord.components import ActionRow, Button, Select, SelectOption +from naff.models.discord.enums import ButtonStyles from naff.models.discord.message import Message from naff.models.naff.application_commands import ( CommandTypes, @@ -231,8 +232,10 @@ class StarboardCog(Extension): embed.set_footer(text=ctx.guild.name + " | " + channel.name) if image_url: embed.set_image(url=image_url) - - star = await starboard.send(embeds=embed) + star_components = Button( + style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}" + ) + star = await starboard.send(embeds=embed, components=star_components) await Star( index=count, diff --git a/jarvis/cogs/tags.py b/jarvis/cogs/tags.py index d476244..43f9f8b 100644 --- a/jarvis/cogs/tags.py +++ b/jarvis/cogs/tags.py @@ -7,8 +7,9 @@ from typing import Dict, List from jarvis_core.db import q from jarvis_core.db.models import Setting, Tag from naff import AutocompleteContext, Client, Extension, InteractionContext +from naff.models.discord.components import Button from naff.models.discord.embed import EmbedField -from naff.models.discord.enums import Permissions +from naff.models.discord.enums import ButtonStyles, Permissions from naff.models.discord.modal import InputText, Modal, TextStyles from naff.models.naff.application_commands import ( OptionTypes, @@ -128,7 +129,11 @@ class TagCog(Extension): icon_url=ctx.author.display_avatar.url, ) - await response.send(embeds=embed) + components = Button( + style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}" + ) + + await response.send(embeds=embed, components=components) if ctx.guild.id not in self.cache: self.cache[ctx.guild.id] = [] self.cache[ctx.guild.id].append(tag.name) @@ -230,8 +235,10 @@ class TagCog(Extension): name=ctx.author.username + "#" + ctx.author.discriminator, icon_url=ctx.author.display_avatar.url, ) - - await response.send(embeds=embed) + components = Button( + style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}" + ) + await response.send(embeds=embed, components=components) if tag.name not in self.cache[ctx.guild.id]: self.cache[ctx.guild.id].remove(old_name) self.cache[ctx.guild.id].append(tag.name) @@ -309,15 +316,20 @@ class TagCog(Extension): name=f"{username}#{discrim}" if username else "Unknown User", icon_url=url, ) - - await ctx.send(embeds=embed) + components = Button( + style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}" + ) + await ctx.send(embeds=embed, components=components) @tag.subcommand(sub_cmd_name="list", sub_cmd_description="List tag names") async def _list(self, ctx: InteractionContext) -> None: tags = await Tag.find(q(guild=ctx.guild.id)).to_list(None) names = "\n".join(f"`{t.name}`" for t in tags) embed = build_embed(title="All Tags", description=names, fields=[]) - await ctx.send(embeds=embed) + components = Button( + style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}" + ) + await ctx.send(embeds=embed, components=components) @_get.autocomplete("name") @_edit.autocomplete("name") diff --git a/jarvis/cogs/temprole.py b/jarvis/cogs/temprole.py index d2a89a3..679394e 100644 --- a/jarvis/cogs/temprole.py +++ b/jarvis/cogs/temprole.py @@ -6,7 +6,9 @@ from dateparser import parse from dateparser_data.settings import default_parsers from jarvis_core.db.models import Temprole from naff import Client, Extension, InteractionContext, Permissions +from naff.models.discord.components import Button from naff.models.discord.embed import EmbedField +from naff.models.discord.enums import ButtonStyles from naff.models.discord.role import Role from naff.models.discord.user import Member from naff.models.naff.application_commands import ( @@ -117,8 +119,10 @@ class TemproleCog(Extension): embed.set_author( name=f"{user.username}#{user.discriminator}", icon_url=user.display_avatar.url ) - - await ctx.send(embeds=embed) + components = Button( + style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}" + ) + await ctx.send(embeds=embed, components=components) def setup(bot: Client) -> None: diff --git a/jarvis/cogs/util.py b/jarvis/cogs/util.py index a9f91d4..1134a81 100644 --- a/jarvis/cogs/util.py +++ b/jarvis/cogs/util.py @@ -10,7 +10,9 @@ import numpy as np from dateparser import parse from naff import Client, Extension, InteractionContext, const from naff.models.discord.channel import GuildCategory, GuildText, GuildVoice +from naff.models.discord.components import Button from naff.models.discord.embed import EmbedField +from naff.models.discord.enums import ButtonStyles from naff.models.discord.file import File from naff.models.discord.guild import Guild from naff.models.discord.role import Role @@ -67,7 +69,10 @@ class UtilCog(Extension): ) ) embed = build_embed(title=title, description=desc, fields=fields, color=color) - await ctx.send(embeds=embed) + components = Button( + style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}" + ) + await ctx.send(embeds=embed, components=components) @slash_command( name="logo", @@ -79,7 +84,10 @@ class UtilCog(Extension): JARVIS_LOGO.save(image_bytes, "PNG") image_bytes.seek(0) logo = File(image_bytes, file_name="logo.png") - await ctx.send(file=logo) + components = Button( + style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}" + ) + await ctx.send(file=logo, components=components) @slash_command(name="rchk", description="Robot Camo HK416") async def _rchk(self, ctx: InteractionContext) -> None: @@ -130,7 +138,10 @@ class UtilCog(Extension): embed = build_embed(title="Avatar", description="", fields=[], color="#00FFEE") embed.set_image(url=avatar) embed.set_author(name=f"{user.username}#{user.discriminator}", icon_url=avatar) - await ctx.send(embeds=embed) + components = Button( + style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}" + ) + await ctx.send(embeds=embed, components=components) @slash_command( name="roleinfo", @@ -177,8 +188,10 @@ class UtilCog(Extension): im.save(image_bytes, "PNG") image_bytes.seek(0) color_show = File(image_bytes, file_name="color_show.png") - - await ctx.send(embeds=embed, file=color_show) + components = Button( + style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}" + ) + await ctx.send(embeds=embed, file=color_show, components=components) async def _userinfo(self, ctx: InteractionContext, user: User = None) -> None: await ctx.defer() @@ -224,8 +237,10 @@ class UtilCog(Extension): ) embed.set_thumbnail(url=user.display_avatar.url) embed.set_footer(text=f"ID: {user.id}") - - await ctx.send(embeds=embed) + components = Button( + style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}" + ) + await ctx.send(embeds=embed, components=components) @slash_command( name="userinfo", @@ -279,8 +294,10 @@ class UtilCog(Extension): embed.set_author(name=guild.name, icon_url=guild.icon.url) embed.set_thumbnail(url=guild.icon.url) embed.set_footer(text=f"ID: {guild.id} | Server Created") - - await ctx.send(embeds=embed) + components = Button( + style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}" + ) + await ctx.send(embeds=embed, components=components) @slash_command( name="pw", @@ -375,7 +392,10 @@ class UtilCog(Extension): EmbedField(name="ISO8601", value=timestamp.isoformat()), ] embed = build_embed(title="Converted Time", description=f"`{string}`", fields=fields) - await ctx.send(embeds=embed, ephemeral=private) + components = Button( + style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}" + ) + await ctx.send(embeds=embed, ephemeral=private, components=components) @slash_command(name="support", description="Got issues?") async def _support(self, ctx: InteractionContext) -> None: