feat(premium): Implement gem API and admin.
This commit is contained in:
198
src/modules/premium/ui/transactions.py
Normal file
198
src/modules/premium/ui/transactions.py
Normal file
@@ -0,0 +1,198 @@
|
||||
from typing import Optional
|
||||
import asyncio
|
||||
import datetime as dt
|
||||
|
||||
import discord
|
||||
from discord.ui.button import button, Button, ButtonStyle
|
||||
|
||||
from meta import LionBot, conf
|
||||
from data import ORDER
|
||||
|
||||
from utils.ui import MessageUI, input
|
||||
from utils.lib import MessageArgs, tabulate
|
||||
|
||||
from .. import babel, logger
|
||||
from ..data import PremiumData
|
||||
|
||||
_p = babel._p
|
||||
|
||||
|
||||
class TransactionList(MessageUI):
|
||||
block_len = 5
|
||||
|
||||
def __init__(self, bot: LionBot, userid: int, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
self.bot = bot
|
||||
self.userid = userid
|
||||
|
||||
self._pagen = 0
|
||||
self.blocks: list[list[PremiumData.GemTransaction]] = [[]]
|
||||
|
||||
@property
|
||||
def page_count(self):
|
||||
return len(self.blocks)
|
||||
|
||||
@property
|
||||
def pagen(self):
|
||||
self._pagen = self._pagen % self.page_count
|
||||
return self._pagen
|
||||
|
||||
@pagen.setter
|
||||
def pagen(self, value):
|
||||
self._pagen = value % self.page_count
|
||||
|
||||
@property
|
||||
def current_page(self):
|
||||
return self.blocks[self.pagen]
|
||||
|
||||
# ----- UI Components -----
|
||||
|
||||
# Backwards
|
||||
@button(emoji=conf.emojis.backward, style=ButtonStyle.grey)
|
||||
async def prev_button(self, press: discord.Interaction, pressed: Button):
|
||||
await press.response.defer(thinking=True, ephemeral=True)
|
||||
self.pagen -= 1
|
||||
await self.refresh(thinking=press)
|
||||
|
||||
# Jump to page
|
||||
@button(label="JUMP_PLACEHOLDER", style=ButtonStyle.blurple)
|
||||
async def jump_button(self, press: discord.Interaction, pressed: Button):
|
||||
"""
|
||||
Jump-to-page button.
|
||||
Loads a page-switch dialogue.
|
||||
"""
|
||||
t = self.bot.translator.t
|
||||
try:
|
||||
interaction, value = await input(
|
||||
press,
|
||||
title=t(_p(
|
||||
'ui:transactions|button:jump|input:title',
|
||||
"Jump to page"
|
||||
)),
|
||||
question=t(_p(
|
||||
'ui:transactions|button:jump|input:question',
|
||||
"Page number to jump to"
|
||||
))
|
||||
)
|
||||
value = value.strip()
|
||||
except asyncio.TimeoutError:
|
||||
return
|
||||
|
||||
if not value.lstrip('- ').isdigit():
|
||||
error_embed = discord.Embed(
|
||||
title=t(_p(
|
||||
'ui:transactions|button:jump|error:invalid_page',
|
||||
"Invalid page number, please try again!"
|
||||
)),
|
||||
colour=discord.Colour.brand_red()
|
||||
)
|
||||
await interaction.response.send_message(embed=error_embed, ephemeral=True)
|
||||
else:
|
||||
await interaction.response.defer(thinking=True)
|
||||
pagen = int(value.lstrip('- '))
|
||||
if value.startswith('-'):
|
||||
pagen = -1 * pagen
|
||||
elif pagen > 0:
|
||||
pagen = pagen - 1
|
||||
self.pagen = pagen
|
||||
await self.refresh(thinking=interaction)
|
||||
|
||||
async def jump_button_refresh(self):
|
||||
component = self.jump_button
|
||||
component.label = f"{self.pagen + 1}/{self.page_count}"
|
||||
component.disabled = (self.page_count <= 1)
|
||||
|
||||
# Forward
|
||||
@button(emoji=conf.emojis.forward, style=ButtonStyle.grey)
|
||||
async def next_button(self, press: discord.Interaction, pressed: Button):
|
||||
await press.response.defer(thinking=True)
|
||||
self.pagen += 1
|
||||
await self.refresh(thinking=press)
|
||||
|
||||
# Quit
|
||||
@button(emoji=conf.emojis.cancel, style=ButtonStyle.red)
|
||||
async def quit_button(self, press: discord.Interaction, pressed: Button):
|
||||
"""
|
||||
Quit the UI.
|
||||
"""
|
||||
await press.response.defer()
|
||||
await self.quit()
|
||||
|
||||
# ----- UI Flow -----
|
||||
async def make_message(self) -> MessageArgs:
|
||||
t = self.bot.translator.t
|
||||
|
||||
title = t(_p(
|
||||
'ui:transactions|embed|title',
|
||||
"Gem Transactions for user `{userid}`"
|
||||
)).format(userid=self.userid)
|
||||
|
||||
rows = self.current_page
|
||||
if rows:
|
||||
embed = discord.Embed(
|
||||
colour=discord.Colour.orange(),
|
||||
title=title,
|
||||
description=t(_p(
|
||||
'ui:transactions|embed|desc:balance',
|
||||
"User {target} has a LionGem balance of {gem}**{balance}**"
|
||||
)).format(
|
||||
gem=self.bot.config.emojis.gem,
|
||||
target=f"<@{self.userid}>",
|
||||
balance=await (self.bot.get_cog('PremiumCog')).get_gem_balance(self.userid),
|
||||
)
|
||||
)
|
||||
for row in rows:
|
||||
name = f"Transaction #{row.transactionid}"
|
||||
table_rows = (
|
||||
('timestamp', discord.utils.format_dt(row._timestamp)),
|
||||
('type', row.transaction_type.name),
|
||||
('amount', str(row.amount)),
|
||||
('actor', f"<@{row.actorid}>"),
|
||||
('from', f"`{row.from_account}`" if row.from_account else 'None'),
|
||||
('to', f"`{row.to_account}`" if row.to_account else 'None'),
|
||||
('reference', str(row.reference)),
|
||||
)
|
||||
table = '\n'.join(tabulate(*table_rows))
|
||||
embed.add_field(
|
||||
name=name,
|
||||
value=f"{row.description}\n{table}",
|
||||
inline=False
|
||||
)
|
||||
else:
|
||||
embed = discord.Embed(
|
||||
colour=discord.Colour.brand_red(),
|
||||
description = t(_p(
|
||||
'ui:transactions|embed|desc:no_transactions',
|
||||
"This user has no related gem transactions!"
|
||||
))
|
||||
)
|
||||
return MessageArgs(embed=embed)
|
||||
|
||||
async def refresh_layout(self):
|
||||
to_refresh = (
|
||||
self.jump_button_refresh(),
|
||||
)
|
||||
await asyncio.gather(*to_refresh)
|
||||
|
||||
if self.page_count > 1:
|
||||
self.set_layout(
|
||||
(self.prev_button, self.jump_button, self.quit_button, self.next_button),
|
||||
)
|
||||
else:
|
||||
self.set_layout(
|
||||
(self.quit_button,)
|
||||
)
|
||||
|
||||
async def reload(self):
|
||||
model = PremiumData.GemTransaction
|
||||
|
||||
rows = await model.fetch_where(
|
||||
(model.from_account == self.userid) | (model.to_account == self.userid)
|
||||
).order_by('_timestamp', ORDER.DESC)
|
||||
|
||||
blocks = [
|
||||
rows[i:i+self.block_len]
|
||||
for i in range(0, len(rows), self.block_len)
|
||||
]
|
||||
self.blocks = blocks or [[]]
|
||||
Reference in New Issue
Block a user