mirror of
https://github.com/artiemis/artemis.git
synced 2026-02-14 08:31:55 +00:00
183 lines
6.3 KiB
Python
183 lines
6.3 KiB
Python
from typing import Any, List
|
|
|
|
import discord
|
|
from discord.ext import commands
|
|
|
|
from utils.common import trim
|
|
|
|
|
|
class BaseView(discord.ui.View):
|
|
def __init__(self, ctx: commands.Context, timeout: int = 180):
|
|
super().__init__(timeout=timeout)
|
|
self.ctx = ctx
|
|
|
|
async def interaction_check(self, interaction):
|
|
if interaction.user == self.ctx.author:
|
|
return True
|
|
await interaction.response.send_message(
|
|
"This interaction cannot be controlled by you, sorry!", ephemeral=True
|
|
)
|
|
|
|
|
|
class ConfirmView(BaseView):
|
|
def __init__(self, ctx: commands.Context):
|
|
super().__init__(ctx, timeout=60)
|
|
self.result = None
|
|
|
|
@discord.ui.button(label="Yes", style=discord.ButtonStyle.green)
|
|
async def yes(self, interaction, button):
|
|
self.result = True
|
|
self.stop()
|
|
await self.message.delete()
|
|
|
|
@discord.ui.button(label="No", style=discord.ButtonStyle.red)
|
|
async def no(self, interaction, button):
|
|
self.result = False
|
|
self.stop()
|
|
await self.message.delete()
|
|
|
|
async def prompt(self, message="Are you sure?", timeout_msg="You took too long!"):
|
|
self.message = await self.ctx.send(message, view=self)
|
|
if await self.wait():
|
|
await self.message.edit(content=timeout_msg, view=None)
|
|
return None
|
|
return self.result
|
|
|
|
|
|
class ViewPages(BaseView):
|
|
def __init__(self, ctx: commands.Context, items: List[Any], timeout: int = 180):
|
|
super().__init__(ctx=ctx, timeout=timeout)
|
|
self.items = items
|
|
self.current_page = 0
|
|
self.pages = len(self.items)
|
|
self.use_last_and_first = self.pages > 2
|
|
|
|
def get_kwargs(self, item: discord.Embed | str):
|
|
if isinstance(item, discord.Embed):
|
|
return {"embed": item}
|
|
elif isinstance(item, str):
|
|
return {"content": item}
|
|
|
|
async def start(self):
|
|
start_page = self.items[0]
|
|
kwargs = self.get_kwargs(start_page)
|
|
|
|
if self.pages == 1:
|
|
return await self.ctx.send(**kwargs)
|
|
elif not self.use_last_and_first:
|
|
self.remove_item(self.first_page)
|
|
self.remove_item(self.last_page)
|
|
|
|
self.update_labels()
|
|
self.message = await self.ctx.send(**kwargs, view=self)
|
|
|
|
async def update_view(self, interaction: discord.Interaction):
|
|
item = self.items[self.current_page]
|
|
kwargs = self.get_kwargs(item)
|
|
self.update_labels()
|
|
|
|
if interaction.response.is_done():
|
|
if self.message:
|
|
await self.message.edit(**kwargs, view=self)
|
|
else:
|
|
await interaction.response.edit_message(**kwargs, view=self)
|
|
|
|
def update_labels(self):
|
|
self.current_page_display.label = f"{self.current_page + 1}/{self.pages}"
|
|
if self.use_last_and_first:
|
|
self.first_page.disabled = self.current_page == 0
|
|
self.last_page.disabled = (self.current_page + 1) >= self.pages
|
|
self.next_page.disabled = False
|
|
self.previous_page.disabled = False
|
|
|
|
if (self.current_page + 1) >= self.pages:
|
|
self.next_page.disabled = True
|
|
elif self.current_page == 0:
|
|
self.previous_page.disabled = True
|
|
|
|
@discord.ui.button(label="◀◀", style=discord.ButtonStyle.blurple)
|
|
async def first_page(self, interaction, button):
|
|
self.current_page = 0
|
|
await self.update_view(interaction)
|
|
|
|
@discord.ui.button(label="◀", style=discord.ButtonStyle.blurple)
|
|
async def previous_page(self, interaction, button):
|
|
if self.current_page != 0:
|
|
self.current_page -= 1
|
|
await self.update_view(interaction)
|
|
|
|
@discord.ui.button(label="PH", style=discord.ButtonStyle.gray, disabled=True)
|
|
async def current_page_display(self, interaction, button):
|
|
pass
|
|
|
|
@discord.ui.button(label="▶", style=discord.ButtonStyle.blurple)
|
|
async def next_page(self, interaction, button):
|
|
if not (self.current_page + 1) >= self.pages:
|
|
self.current_page += 1
|
|
await self.update_view(interaction)
|
|
|
|
@discord.ui.button(label="▶▶", style=discord.ButtonStyle.blurple)
|
|
async def last_page(self, interaction, button):
|
|
self.current_page = self.pages - 1
|
|
await self.update_view(interaction)
|
|
|
|
async def on_timeout(self):
|
|
if self.message:
|
|
await self.message.edit(view=None)
|
|
|
|
|
|
class BaseDropdown(discord.ui.Select):
|
|
def __init__(self, items: list, label_key, description_key, placeholder: str, max_values: int):
|
|
self.items = items
|
|
|
|
options = []
|
|
for i, item in enumerate(self.items[:25]):
|
|
options.append(
|
|
discord.SelectOption(
|
|
label=trim(label_key(item), 100),
|
|
description=trim(description_key(item), 100) if description_key else None,
|
|
value=str(i),
|
|
)
|
|
)
|
|
super().__init__(placeholder=placeholder, options=options, max_values=max_values)
|
|
|
|
async def callback(self, interaction: discord.Interaction):
|
|
if self.max_values > 1:
|
|
self.view.result = [self.items[int(i)] for i in self.values]
|
|
else:
|
|
result_idx = int(self.values[0])
|
|
self.view.result = self.items[result_idx]
|
|
self.view.stop()
|
|
await self.view.message.delete()
|
|
|
|
|
|
class DropdownView(BaseView):
|
|
def __init__(
|
|
self,
|
|
ctx,
|
|
items,
|
|
label_key,
|
|
description_key=None,
|
|
placeholder="Choose one...",
|
|
max_values=1,
|
|
chunk: bool = False,
|
|
):
|
|
super().__init__(ctx, timeout=60)
|
|
if chunk:
|
|
items = items[: 5 * 25]
|
|
for i in range(0, len(items), 25):
|
|
chunk = items[i : i + 25]
|
|
self.add_item(
|
|
BaseDropdown(chunk, label_key, description_key, placeholder, len(chunk))
|
|
)
|
|
else:
|
|
self.add_item(BaseDropdown(items, label_key, description_key, placeholder, max_values))
|
|
self.result = None
|
|
|
|
async def prompt(self, message="Which one?", timeout_msg="You took too long!"):
|
|
self.message = await self.ctx.send(message, view=self)
|
|
if await self.wait():
|
|
await self.message.edit(content=timeout_msg, view=None)
|
|
return None
|
|
return self.result
|