Add delete button to all embeds, change how reminders work a little

This commit is contained in:
Zeva Rose 2022-08-28 19:10:21 -06:00
parent b192de5222
commit 4d17115c09
10 changed files with 251 additions and 145 deletions

View file

@ -14,8 +14,10 @@ from jarvis_core.db.models import (
Autoreact, Autoreact,
Modlog, Modlog,
Note, Note,
Reminder,
Roleping, Roleping,
Setting, Setting,
Star,
Warning, Warning,
) )
from jarvis_core.filters import invites, url from jarvis_core.filters import invites, url
@ -154,6 +156,9 @@ class Jarvis(StatsClient):
"{}&permissions=8&scope=bot%20applications.commands".format(self.user.id) "{}&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: async def on_error(self, source: str, error: Exception, *args, **kwargs) -> None:
"""NAFF on_error override.""" """NAFF on_error override."""
if isinstance(error, HTTPException): 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}" f"Failed to process edit {message.guild.id}/{message.channel.id}/{message.id}: {e}"
) )
@listen() async def _handle_modcase_button(self, event: Button) -> None:
async def on_button(self, event: Button) -> None:
"""Process button events."""
context = event.context context = event.context
if not context.custom_id.startswith("modcase|"): if not context.custom_id.startswith("modcase|"):
return # await super().on_button(event) return # Failsafe
if not context.deferred and not context.responded: if not context.deferred and not context.responded:
await context.defer(ephemeral=True) await context.defer(ephemeral=True)
@ -917,3 +920,61 @@ class Jarvis(StatsClient):
await context.send(msg) await context.send(msg)
await self.redis.delete(user_key) await self.redis.delete(user_key)
await self.redis.delete(action_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)

View file

@ -7,7 +7,9 @@ from io import BytesIO
import psutil import psutil
from aiofile import AIOFile, LineReader from aiofile import AIOFile, LineReader
from naff import Client, Extension, PrefixedContext, prefixed_command 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.embed import EmbedField
from naff.models.discord.enums import ButtonStyles
from naff.models.discord.file import File from naff.models.discord.file import File
from rich.console import Console from rich.console import Console
@ -78,7 +80,10 @@ class BotutilCog(Extension):
) )
embed = build_embed(title="System Info", description="", fields=fields) embed = build_embed(title="System Info", description="", fields=fields)
embed.set_image(url=self.bot.user.avatar.url) 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") @prefixed_command(name="update")
async def _update(self, ctx: PrefixedContext) -> None: async def _update(self, ctx: PrefixedContext) -> None:
@ -111,15 +116,25 @@ class BotutilCog(Extension):
self.logger.info("Updates applied") self.logger.info("Updates applied")
content = f"```ansi\n{capture.get()}\n```" content = f"```ansi\n{capture.get()}\n```"
components = Button(
style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}"
)
if len(content) < 3000: if len(content) < 3000:
await ctx.reply(content, embeds=embed) await ctx.reply(content, embeds=embed, components=components)
else: 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: else:
embed = build_embed(title="Update Status", description="No changes applied", fields=[]) embed = build_embed(title="Update Status", description="No changes applied", fields=[])
embed.set_thumbnail(url="https://dev.zevaryx.com/git.png") 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: def setup(bot: Client) -> None:

View file

@ -16,7 +16,9 @@ from jarvis_core.filters import invites, url
from jarvis_core.util import convert_bytesize, hash from jarvis_core.util import convert_bytesize, hash
from jarvis_core.util.http import get_size from jarvis_core.util.http import get_size
from naff import Client, Extension, InteractionContext from naff import Client, Extension, InteractionContext
from naff.models.discord.components import Button
from naff.models.discord.embed import EmbedField 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.file import File
from naff.models.discord.message import Attachment from naff.models.discord.message import Attachment
from naff.models.naff.application_commands import ( from naff.models.naff.application_commands import (
@ -119,7 +121,10 @@ class DevCog(Extension):
] ]
embed = build_embed(title=title, description=description, fields=fields) 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_command(name="uuid", description="Generate a UUID")
@slash_option( @slash_option(
@ -235,7 +240,10 @@ class DevCog(Extension):
EmbedField(name=mstr, value=f"`{encoded}`", inline=False), EmbedField(name=mstr, value=f"`{encoded}`", inline=False),
] ]
embed = build_embed(title="Decoded Data", description="", fields=fields) 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_command(name="decode", description="Decode some data")
@slash_option( @slash_option(
@ -270,7 +278,10 @@ class DevCog(Extension):
EmbedField(name=mstr, value=f"`{decoded}`", inline=False), EmbedField(name=mstr, value=f"`{decoded}`", inline=False),
] ]
embed = build_embed(title="Decoded Data", description="", fields=fields) 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") @slash_command(name="cloc", description="Get JARVIS lines of code")
@cooldown(bucket=Buckets.CHANNEL, rate=1, interval=30) @cooldown(bucket=Buckets.CHANNEL, rate=1, interval=30)

View file

@ -8,7 +8,9 @@ import cv2
import numpy as np import numpy as np
from jarvis_core.util import convert_bytesize, unconvert_bytesize from jarvis_core.util import convert_bytesize, unconvert_bytesize
from naff import Client, Extension, InteractionContext from naff import Client, Extension, InteractionContext
from naff.models.discord.components import Button
from naff.models.discord.embed import EmbedField 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.file import File
from naff.models.discord.message import Attachment from naff.models.discord.message import Attachment
from naff.models.naff.application_commands import ( from naff.models.naff.application_commands import (
@ -147,9 +149,11 @@ class ImageCog(Extension):
] ]
embed = build_embed(title=filename, description="", fields=fields) embed = build_embed(title=filename, description="", fields=fields)
embed.set_image(url="attachment://resized.png") embed.set_image(url="attachment://resized.png")
components = Button(
style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}"
)
await ctx.send( await ctx.send(
embeds=embed, embeds=embed, file=File(file=bufio, file_name="resized.png"), components=components
file=File(file=bufio, file_name="resized.png"),
) )

View file

@ -5,16 +5,15 @@ import re
from datetime import datetime, timezone from datetime import datetime, timezone
from typing import List from typing import List
from bson import ObjectId
from dateparser import parse from dateparser import parse
from dateparser_data.settings import default_parsers from dateparser_data.settings import default_parsers
from jarvis_core.db import q from jarvis_core.db import q
from jarvis_core.db.models import Reminder from jarvis_core.db.models import Reminder
from naff import Client, Extension, InteractionContext from naff import AutocompleteContext, Client, Extension, InteractionContext
from naff.client.utils.misc_utils import get
from naff.models.discord.channel import GuildChannel 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.embed import Embed, EmbedField
from naff.models.discord.enums import ButtonStyles
from naff.models.discord.modal import InputText, Modal, TextStyles from naff.models.discord.modal import InputText, Modal, TextStyles
from naff.models.naff.application_commands import ( from naff.models.naff.application_commands import (
OptionTypes, OptionTypes,
@ -22,6 +21,7 @@ from naff.models.naff.application_commands import (
slash_command, slash_command,
slash_option, slash_option,
) )
from thefuzz import process
from jarvis.utils import build_embed from jarvis.utils import build_embed
@ -52,16 +52,8 @@ class RemindmeCog(Extension):
ctx: InteractionContext, ctx: InteractionContext,
private: bool = None, private: bool = None,
) -> None: ) -> None:
if private is None: if private is None and ctx.guild:
private = ctx.guild.member_count >= 5000 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( modal = Modal(
title="Set your reminder!", title="Set your reminder!",
components=[ components=[
@ -145,7 +137,7 @@ class RemindmeCog(Extension):
r = Reminder( r = Reminder(
user=ctx.author.id, user=ctx.author.id,
channel=ctx.channel.id, channel=ctx.channel.id,
guild=ctx.guild.id, guild=ctx.guild.id if ctx.guild else ctx.author.id,
message=message, message=message,
remind_at=remind_at, remind_at=remind_at,
private=private, private=private,
@ -173,7 +165,13 @@ class RemindmeCog(Extension):
) )
embed.set_thumbnail(url=ctx.author.display_avatar.url) 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( async def get_reminders_embed(
self, ctx: InteractionContext, reminders: List[Reminder] self, ctx: InteractionContext, reminders: List[Reminder]
@ -222,126 +220,99 @@ class RemindmeCog(Extension):
return return
embed = await self.get_reminders_embed(ctx, reminders) embed = await self.get_reminders_embed(ctx, reminders)
components = Button(
await ctx.send(embeds=embed) 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") @reminders.subcommand(sub_cmd_name="delete", sub_cmd_description="Delete a reminder")
async def _delete(self, ctx: InteractionContext) -> None: @slash_option(
reminders = await Reminder.find(q(user=ctx.author.id, active=True)).to_list(None) name="content",
if not reminders: description="Content of the reminder",
await ctx.send("You have no reminders set", ephemeral=True) 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 return
options = [] ts = int(reminder.remind_at.timestamp())
for reminder in reminders:
option = SelectOption(
label=f"{reminder.remind_at}",
value=str(reminder.id),
emoji="",
)
options.append(option)
select = Select( fields = [EmbedField(name=f"<t:{ts}:F>", value=reminder.message, inline=False)]
options=options,
custom_id="to_delete", embed = build_embed(
placeholder="Select reminders to delete", title="Deleted Reminder(s)",
min_values=1, description="",
max_values=len(reminders), fields=fields,
) )
components = [ActionRow(select)] embed.set_author(
embed = await self.get_reminders_embed(ctx, reminders) name=ctx.author.display_name + "#" + ctx.author.discriminator,
message = await ctx.send( icon_url=ctx.author.display_avatar.url,
content=f"You have {len(reminders)} reminder(s) set:",
embeds=embed,
components=components,
) )
embed.set_thumbnail(url=ctx.author.display_avatar.url)
components = Button(
style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}"
)
try: try:
context = await self.bot.wait_for_component( await reminder.delete()
check=lambda x: ctx.author.id == x.context.author.id, except Exception:
messages=message, self.logger.debug("Ignoring deletion error")
timeout=60 * 5, await ctx.send(embeds=embed, ephemeral=reminder.private, components=components)
)
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"<t:{int(reminder.remind_at.timestamp())}:F>",
value="Private reminder",
inline=False,
)
)
else:
fields.append(
EmbedField(
name=f"<t:{int(reminder.remind_at.timestamp())}: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)
@reminders.subcommand( @reminders.subcommand(
sub_cmd_name="fetch", sub_cmd_name="fetch",
sub_cmd_description="Fetch a reminder that failed to send", sub_cmd_description="Fetch a reminder that failed to send",
) )
@slash_option( @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: async def _fetch(self, ctx: InteractionContext, content: str) -> None:
reminder = await Reminder.find_one(q(id=id)) reminder = await Reminder.find_one(q(_id=content))
if not reminder: 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 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"<t:{ts}:F> (<t:{ts}:R>)")]
embed = build_embed(
title="You have a reminder!", description=reminder.message, fields=fields
)
embed.set_author( embed.set_author(
name=ctx.author.display_name + "#" + ctx.author.discriminator, 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) embed.set_thumbnail(url=ctx.author.display_avatar.url)
await ctx.send(embeds=embed, ephemeral=reminder.private) 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: if reminder.remind_at <= datetime.now(tz=timezone.utc) and not reminder.active:
try: try:
await reminder.delete() await reminder.delete()
except Exception: except Exception:
self.logger.debug("Ignoring deletion error") 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: def setup(bot: Client) -> None:
"""Add RemindmeCog to JARVIS""" """Add RemindmeCog to JARVIS"""

View file

@ -6,8 +6,9 @@ from jarvis_core.db import q
from jarvis_core.db.models import Rolegiver from jarvis_core.db.models import Rolegiver
from naff import Client, Extension, InteractionContext, Permissions from naff import Client, Extension, InteractionContext, Permissions
from naff.client.utils.misc_utils import get 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.embed import EmbedField
from naff.models.discord.enums import ButtonStyles
from naff.models.discord.role import Role from naff.models.discord.role import Role
from naff.models.naff.application_commands import ( from naff.models.naff.application_commands import (
OptionTypes, 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_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}") embed.set_footer(text=f"{ctx.author.username}#{ctx.author.discriminator} | {ctx.author.id}")
components = Button(
await ctx.send(embeds=embed) 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") @rolegiver.subcommand(sub_cmd_name="remove", sub_cmd_description="Remove a role from rolegiver")
@check(admin_or_permissions(Permissions.MANAGE_GUILD)) @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}") embed.set_footer(text=f"{ctx.author.username}#{ctx.author.discriminator} | {ctx.author.id}")
components = Button(
await ctx.send(embeds=embed) 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") role = SlashCommand(name="role", description="Get/Remove Rolegiver roles")

View file

@ -7,7 +7,8 @@ from jarvis_core.db.models import Star, Starboard
from naff import Client, Extension, InteractionContext, Permissions from naff import Client, Extension, InteractionContext, Permissions
from naff.client import errors from naff.client import errors
from naff.models.discord.channel import GuildText 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.discord.message import Message
from naff.models.naff.application_commands import ( from naff.models.naff.application_commands import (
CommandTypes, CommandTypes,
@ -231,8 +232,10 @@ class StarboardCog(Extension):
embed.set_footer(text=ctx.guild.name + " | " + channel.name) embed.set_footer(text=ctx.guild.name + " | " + channel.name)
if image_url: if image_url:
embed.set_image(url=image_url) embed.set_image(url=image_url)
star_components = Button(
star = await starboard.send(embeds=embed) style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}"
)
star = await starboard.send(embeds=embed, components=star_components)
await Star( await Star(
index=count, index=count,

View file

@ -7,8 +7,9 @@ from typing import Dict, List
from jarvis_core.db import q from jarvis_core.db import q
from jarvis_core.db.models import Setting, Tag from jarvis_core.db.models import Setting, Tag
from naff import AutocompleteContext, Client, Extension, InteractionContext 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.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.discord.modal import InputText, Modal, TextStyles
from naff.models.naff.application_commands import ( from naff.models.naff.application_commands import (
OptionTypes, OptionTypes,
@ -128,7 +129,11 @@ class TagCog(Extension):
icon_url=ctx.author.display_avatar.url, 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: if ctx.guild.id not in self.cache:
self.cache[ctx.guild.id] = [] self.cache[ctx.guild.id] = []
self.cache[ctx.guild.id].append(tag.name) self.cache[ctx.guild.id].append(tag.name)
@ -230,8 +235,10 @@ class TagCog(Extension):
name=ctx.author.username + "#" + ctx.author.discriminator, name=ctx.author.username + "#" + ctx.author.discriminator,
icon_url=ctx.author.display_avatar.url, icon_url=ctx.author.display_avatar.url,
) )
components = Button(
await response.send(embeds=embed) 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]: if tag.name not in self.cache[ctx.guild.id]:
self.cache[ctx.guild.id].remove(old_name) self.cache[ctx.guild.id].remove(old_name)
self.cache[ctx.guild.id].append(tag.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", name=f"{username}#{discrim}" if username else "Unknown User",
icon_url=url, icon_url=url,
) )
components = Button(
await ctx.send(embeds=embed) 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") @tag.subcommand(sub_cmd_name="list", sub_cmd_description="List tag names")
async def _list(self, ctx: InteractionContext) -> None: async def _list(self, ctx: InteractionContext) -> None:
tags = await Tag.find(q(guild=ctx.guild.id)).to_list(None) tags = await Tag.find(q(guild=ctx.guild.id)).to_list(None)
names = "\n".join(f"`{t.name}`" for t in tags) names = "\n".join(f"`{t.name}`" for t in tags)
embed = build_embed(title="All Tags", description=names, fields=[]) 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") @_get.autocomplete("name")
@_edit.autocomplete("name") @_edit.autocomplete("name")

View file

@ -6,7 +6,9 @@ from dateparser import parse
from dateparser_data.settings import default_parsers from dateparser_data.settings import default_parsers
from jarvis_core.db.models import Temprole from jarvis_core.db.models import Temprole
from naff import Client, Extension, InteractionContext, Permissions 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.embed import EmbedField
from naff.models.discord.enums import ButtonStyles
from naff.models.discord.role import Role from naff.models.discord.role import Role
from naff.models.discord.user import Member from naff.models.discord.user import Member
from naff.models.naff.application_commands import ( from naff.models.naff.application_commands import (
@ -117,8 +119,10 @@ class TemproleCog(Extension):
embed.set_author( embed.set_author(
name=f"{user.username}#{user.discriminator}", icon_url=user.display_avatar.url name=f"{user.username}#{user.discriminator}", icon_url=user.display_avatar.url
) )
components = Button(
await ctx.send(embeds=embed) style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}"
)
await ctx.send(embeds=embed, components=components)
def setup(bot: Client) -> None: def setup(bot: Client) -> None:

View file

@ -10,7 +10,9 @@ import numpy as np
from dateparser import parse from dateparser import parse
from naff import Client, Extension, InteractionContext, const from naff import Client, Extension, InteractionContext, const
from naff.models.discord.channel import GuildCategory, GuildText, GuildVoice 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.embed import EmbedField
from naff.models.discord.enums import ButtonStyles
from naff.models.discord.file import File from naff.models.discord.file import File
from naff.models.discord.guild import Guild from naff.models.discord.guild import Guild
from naff.models.discord.role import Role 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) 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( @slash_command(
name="logo", name="logo",
@ -79,7 +84,10 @@ class UtilCog(Extension):
JARVIS_LOGO.save(image_bytes, "PNG") JARVIS_LOGO.save(image_bytes, "PNG")
image_bytes.seek(0) image_bytes.seek(0)
logo = File(image_bytes, file_name="logo.png") 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") @slash_command(name="rchk", description="Robot Camo HK416")
async def _rchk(self, ctx: InteractionContext) -> None: async def _rchk(self, ctx: InteractionContext) -> None:
@ -130,7 +138,10 @@ class UtilCog(Extension):
embed = build_embed(title="Avatar", description="", fields=[], color="#00FFEE") embed = build_embed(title="Avatar", description="", fields=[], color="#00FFEE")
embed.set_image(url=avatar) embed.set_image(url=avatar)
embed.set_author(name=f"{user.username}#{user.discriminator}", icon_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( @slash_command(
name="roleinfo", name="roleinfo",
@ -177,8 +188,10 @@ class UtilCog(Extension):
im.save(image_bytes, "PNG") im.save(image_bytes, "PNG")
image_bytes.seek(0) image_bytes.seek(0)
color_show = File(image_bytes, file_name="color_show.png") color_show = File(image_bytes, file_name="color_show.png")
components = Button(
await ctx.send(embeds=embed, file=color_show) 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: async def _userinfo(self, ctx: InteractionContext, user: User = None) -> None:
await ctx.defer() await ctx.defer()
@ -224,8 +237,10 @@ class UtilCog(Extension):
) )
embed.set_thumbnail(url=user.display_avatar.url) embed.set_thumbnail(url=user.display_avatar.url)
embed.set_footer(text=f"ID: {user.id}") embed.set_footer(text=f"ID: {user.id}")
components = Button(
await ctx.send(embeds=embed) style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}"
)
await ctx.send(embeds=embed, components=components)
@slash_command( @slash_command(
name="userinfo", name="userinfo",
@ -279,8 +294,10 @@ class UtilCog(Extension):
embed.set_author(name=guild.name, icon_url=guild.icon.url) embed.set_author(name=guild.name, icon_url=guild.icon.url)
embed.set_thumbnail(url=guild.icon.url) embed.set_thumbnail(url=guild.icon.url)
embed.set_footer(text=f"ID: {guild.id} | Server Created") embed.set_footer(text=f"ID: {guild.id} | Server Created")
components = Button(
await ctx.send(embeds=embed) style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}"
)
await ctx.send(embeds=embed, components=components)
@slash_command( @slash_command(
name="pw", name="pw",
@ -375,7 +392,10 @@ class UtilCog(Extension):
EmbedField(name="ISO8601", value=timestamp.isoformat()), EmbedField(name="ISO8601", value=timestamp.isoformat()),
] ]
embed = build_embed(title="Converted Time", description=f"`{string}`", fields=fields) 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?") @slash_command(name="support", description="Got issues?")
async def _support(self, ctx: InteractionContext) -> None: async def _support(self, ctx: InteractionContext) -> None: