Files

151 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
from utils.ui.micros import FastModal
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)
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] if blocks else "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()