generated from HoloTech/holotech-plugin-template
140 lines
4.6 KiB
Python
140 lines
4.6 KiB
Python
"""
|
|
Defines widgets for displaying a campaign
|
|
"""
|
|
|
|
from typing import Optional, TYPE_CHECKING
|
|
import asyncio
|
|
import datetime as dt
|
|
|
|
import discord
|
|
from discord.ui import Modal
|
|
from discord.ui.select import select, Select, SelectOption
|
|
from discord.ui.button import button, Button, ButtonStyle
|
|
from discord.ui.text_input import TextInput, TextStyle
|
|
|
|
from meta import LionBot
|
|
from meta.errors import UserInputError
|
|
from meta.config import conf
|
|
from utils.lib import tabulate, utc_now, MessageArgs, parse_duration
|
|
from utils.ui import MessageUI, AButton, AsComponents, ConfigEditor
|
|
from utils.ui.micros import FastModal
|
|
from utils.ui.pagers import BasePager, Pager
|
|
|
|
from ...campaign import RewardCampaign
|
|
from ...data import EarnedReward
|
|
from .. import logger
|
|
|
|
from .rewards import RewardList
|
|
|
|
|
|
class CampaignDashboard(MessageUI):
|
|
def __init__(self, bot: LionBot, campaign: RewardCampaign, **kwargs):
|
|
super().__init__(**kwargs)
|
|
|
|
self.bot = bot
|
|
self.campaign = campaign
|
|
|
|
# UI state
|
|
|
|
# ------ UI API -----
|
|
|
|
# ------ UI Components -----
|
|
# Button to open rewards list
|
|
|
|
@button(label="Rewards Earned")
|
|
async def rewards_list_button(self, press: discord.Interaction, pressed: Button):
|
|
await press.response.defer()
|
|
widget = RewardList(
|
|
bot=self.bot,
|
|
campaign=self.campaign,
|
|
callerid=self._callerid,
|
|
)
|
|
self._slaves.append(widget)
|
|
await widget.run(press)
|
|
await widget.wait()
|
|
self._slaves.remove(widget)
|
|
|
|
@button(emoji=conf.emojis.cancel, style=ButtonStyle.red)
|
|
async def quit_button(self, press: discord.Interaction, pressed: Button):
|
|
"""Close the UI and all children."""
|
|
await press.response.defer(thinking=False)
|
|
await self.quit()
|
|
|
|
@button(emoji=conf.emojis.refresh)
|
|
async def refresh_button(self, press: discord.Interaction, pressed: Button):
|
|
await press.response.defer()
|
|
await self.refresh()
|
|
|
|
# ------ UI Flow -----
|
|
|
|
async def refresh_layout(self):
|
|
# Nothing to refresh
|
|
pass
|
|
|
|
async def make_message(self) -> MessageArgs:
|
|
embed = discord.Embed(
|
|
title=f"{self.campaign.row.campaign_name} Campaign Dashboard"
|
|
)
|
|
# embed.set_footer with last update
|
|
|
|
# Don't show the webhook url since it contains secrets, just show whether it is set
|
|
# Hard-coded channel/timer URL for now
|
|
campaign = self.campaign
|
|
started_at = (
|
|
discord.utils.format_dt(campaign.row.started_at, "F")
|
|
if campaign.row.started_at
|
|
else "*Not Started*"
|
|
)
|
|
|
|
all_rewards = await campaign.get_rewards()
|
|
rewards_earned = len(all_rewards)
|
|
reward_cap = campaign.row.target_rewards
|
|
if reward_cap is not None:
|
|
rewards = f"{rewards_earned} out of {reward_cap}"
|
|
else:
|
|
rewards = f"{rewards_earned}"
|
|
|
|
description = (
|
|
f"Campaign running since {started_at} with {rewards} rewards given."
|
|
)
|
|
|
|
table = {
|
|
"Created at": discord.utils.format_dt(campaign.row.created_at, "F"),
|
|
"Started at": started_at,
|
|
"Moderator Role": f"<&@{campaign.row.moderator_role_id}>" if campaign.row.moderator_role_id else "*Not Set*",
|
|
"Logging webhook": "*Set Up*" if campaign.row.logging_webhook_url else "*Not Set*",
|
|
"Rewards Earned": str(rewards_earned),
|
|
"Rewards Cap": str(reward_cap),
|
|
}
|
|
if campaign.row.completed_at is not None:
|
|
table['Finished at'] = discord.utils.format_dt(campaign.row.completed_at, "F")
|
|
prop_table = '\n'.join(tabulate(*table.items()))
|
|
|
|
embed.description = f"{description}\n\n{prop_table}"
|
|
|
|
# Brief summary of rewards in columns. 12 per column. Empty titles?
|
|
rewardrows = []
|
|
for reward in all_rewards:
|
|
name = reward.twitch_user_name or str(reward.twitch_user_id) or str(reward.profileid)
|
|
fluffed = reward.fulfilled_at is not None
|
|
fluffed_emoji = '✅' if fluffed else '🔳'
|
|
rewardrows.append(f"{fluffed_emoji} {name}")
|
|
|
|
blocks = ['\n'.join(rewardrows[i:i+12]) for i in range(0, len(rewardrows), 12)]
|
|
|
|
embed.add_field(
|
|
name="Rewards Summary",
|
|
value=blocks[0] or 'No Rewards Earned',
|
|
inline=True
|
|
)
|
|
for block in blocks[1:]:
|
|
embed.add_field(
|
|
name="--",
|
|
value=block,
|
|
)
|
|
|
|
return MessageArgs(embed=embed)
|
|
|
|
async def reload(self):
|
|
await self.campaign.row.refresh()
|