93 lines
2.4 KiB
Python
93 lines
2.4 KiB
Python
import discord
|
|
from discord.ext import commands
|
|
from abc import ABC, abstractmethod
|
|
import asyncio
|
|
|
|
class InteractiveEmbed(ABC):
|
|
"""
|
|
This abstract base class can be used to create interactive embeds
|
|
"""
|
|
def __init__(self, bot, ctx, timeout):
|
|
"""
|
|
Sets up the embed with needed parameters
|
|
bot: The bot hosting this embed
|
|
ctx: The context that caused this embed
|
|
timeuout: The time until the embed times out (in seconds)
|
|
"""
|
|
self.bot = bot
|
|
self.ctx = ctx
|
|
self.message = None
|
|
self.timeout = timeout
|
|
|
|
@abstractmethod
|
|
async def on_reaction(self, reaction, user):
|
|
"""
|
|
Gets called when the user interacted with the embed
|
|
"""
|
|
pass
|
|
|
|
@abstractmethod
|
|
def make_embed(self):
|
|
"""
|
|
Creates and returns a new embed
|
|
"""
|
|
pass
|
|
|
|
@abstractmethod
|
|
async def add_navigation(self, message):
|
|
"""
|
|
Adds the navigational emotes to the embed
|
|
"""
|
|
pass
|
|
|
|
async def on_close(self):
|
|
"""
|
|
Can be overridden. Gets called when the embed is closed
|
|
"""
|
|
pass
|
|
|
|
def additional_checks(self, reaction, user):
|
|
"""
|
|
Can be overridden. Additional checks to do before calling on_reaction()
|
|
"""
|
|
return True
|
|
|
|
async def show_embed(self):
|
|
"""
|
|
Displays an embed / Creates an embed
|
|
"""
|
|
if self.message is None:
|
|
self.message = await self.ctx.send(embed=self.make_embed())
|
|
await self.add_navigation(self.message)
|
|
|
|
else:
|
|
await self.message.edit(embed=self.make_embed())
|
|
|
|
def check(reaction, user):
|
|
if self.message is None:
|
|
return False
|
|
|
|
if user.id != self.ctx.author.id:
|
|
return False
|
|
|
|
if reaction.message.id != self.message.id:
|
|
return False
|
|
|
|
if not reaction.me:
|
|
return False
|
|
|
|
return self.additional_checks(reaction, user)
|
|
|
|
try:
|
|
reaction, user = await self.bot.wait_for("reaction_add", check=check, timeout=self.timeout)
|
|
await self.on_reaction(reaction, user)
|
|
await self.show_embed()
|
|
except asyncio.TimeoutError:
|
|
await self.close_embed()
|
|
|
|
async def close_embed(self):
|
|
"""
|
|
Close this embed
|
|
"""
|
|
await self.message.clear_reactions()
|
|
await self.on_close() |