97 lines
3.7 KiB
Python
97 lines
3.7 KiB
Python
import asyncio
|
|
import discord
|
|
from redbot.core.utils.chat_formatting import box
|
|
from .menu import MenuCheck
|
|
|
|
|
|
class Inventory:
|
|
def __init__(self, ctx, data):
|
|
self.ctx = ctx
|
|
self.data = data
|
|
|
|
async def display(self):
|
|
msg, groups = await self.setup()
|
|
try:
|
|
return await self.inv_loop(groups, msg)
|
|
except asyncio.TimeoutError:
|
|
await msg.delete()
|
|
await self.ctx.send("Menu timed out.")
|
|
raise RuntimeError
|
|
except ExitMenu:
|
|
await self.ctx.send("Exited inventory.")
|
|
raise RuntimeError
|
|
|
|
async def setup(self, groups=None, page=0, msg=None):
|
|
if not groups:
|
|
groups = self.splitter()
|
|
options = self.update(groups, page)
|
|
embed = self.build_embed(options, page, groups)
|
|
if msg:
|
|
await msg.edit(embed=embed)
|
|
else:
|
|
msg = await self.ctx.send(embed=embed)
|
|
return msg, groups
|
|
|
|
async def inv_loop(self, groups, msg):
|
|
page = 0
|
|
maximum = len(groups) - 1
|
|
while True:
|
|
check = MenuCheck(self.ctx, groups, page, maximum)
|
|
choice = await self.ctx.bot.wait_for("message", timeout=35.0, check=check.predicate)
|
|
if choice.content.isdigit() and int(choice.content) in range(1, len(groups[page]) + 1):
|
|
try:
|
|
await choice.delete()
|
|
await msg.delete()
|
|
except (discord.NotFound, discord.Forbidden):
|
|
pass
|
|
return groups[page][int(choice.content) - 1][0]
|
|
elif choice.content.lower() in (">", "n", "next"):
|
|
page += 1
|
|
elif choice.content.lower() in ("b", "<", "back"):
|
|
page -= 1
|
|
elif choice.content.lower() in ("e", "x", "exit"):
|
|
try:
|
|
await choice.delete()
|
|
await msg.delete()
|
|
except (discord.NotFound, discord.Forbidden):
|
|
pass
|
|
raise ExitMenu
|
|
elif choice.content.lower() in ("p", "prev"):
|
|
continue
|
|
else:
|
|
msg, _ = await self.setup(groups=groups, page=page, msg=msg)
|
|
await msg.edit(embed=msg)
|
|
msg, _ = await self.setup(groups=groups, page=page, msg=msg)
|
|
|
|
def splitter(self):
|
|
return [self.data[i : i + 5] if len(self.data) > 5 else self.data for i in range(0, len(self.data), 5)]
|
|
|
|
def update(self, groups, page=0):
|
|
header = f"{'#':<3} {'Items':<29} {'Qty':<7} {'Type':<8}\n{'--':<3} {'-'*29:<29} {'-'*4:<7} {'-'*8:<8}"
|
|
fmt = [header]
|
|
for idx, x in enumerate(groups[page], 1):
|
|
line_one = f"{f'{idx}.': <{3}} {x[0]: <{28}s} {x[1]['Qty']: < {9}}{x[1]['Type']: <{7}s}"
|
|
fmt.append(line_one)
|
|
fmt.append(f'< {x[1]["Info"][:50]} >' if len(x[1]["Info"]) < 50 else f'< {x[1]["Info"][:47]}... >')
|
|
fmt.append("",)
|
|
return box("\n".join(fmt), lang="md")
|
|
|
|
def build_embed(self, options, page, groups):
|
|
title = "{}'s Inventory".format(self.ctx.author.name)
|
|
footer = "You are viewing page {} of {}.".format(page + 1 if page > 0 else 1, len(groups))
|
|
instructions = (
|
|
"Type the number for your selection or one of the words below "
|
|
"for page navigation if there are multiple pages available.\n"
|
|
"Next page: Type n, next, or >\n"
|
|
"Previous page: Type b, back, or <\n"
|
|
"Exit menu system: Type e, x, or exit"
|
|
)
|
|
embed = discord.Embed(color=0x5EC6FF)
|
|
embed.add_field(name=title, value=options, inline=False)
|
|
embed.set_footer(text="\n".join((instructions, footer)))
|
|
|
|
return embed
|
|
|
|
|
|
class ExitMenu(Exception):
|
|
pass
|