generated from HoloTech/holotech-plugin-template
(discord): Fill in discord interfaces
This commit is contained in:
@@ -1 +1,2 @@
|
||||
from .rewards import RewardList, RewardEditor
|
||||
from .campaign import CampaignDashboard
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
"""
|
||||
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()
|
||||
|
||||
@@ -16,9 +16,8 @@ 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 import MessageUI
|
||||
from utils.ui.micros import FastModal
|
||||
from utils.ui.pagers import BasePager, Pager
|
||||
|
||||
from ...campaign import RewardCampaign
|
||||
from ...data import EarnedReward
|
||||
@@ -134,7 +133,38 @@ class RewardList(MessageUI):
|
||||
value = int(selected.values[0])
|
||||
reward = next(r for r in self._rewards if r.earned_id == value)
|
||||
modal = RewardEditor.from_reward(reward)
|
||||
|
||||
currently_fluffed = (reward.fulfilled_at is not None)
|
||||
|
||||
@modal.submit_callback()
|
||||
async def on_editor_submit(interaction: discord.Interaction):
|
||||
update_args = {}
|
||||
|
||||
if modal.flufbox.component.value and not currently_fluffed:
|
||||
# Reward has been fluffed
|
||||
update_args['fulfilled_at'] = utc_now()
|
||||
elif currently_fluffed and not modal.flufbox.component.value:
|
||||
# Reward has been unfluffed
|
||||
update_args['fulfilled_at'] = None
|
||||
|
||||
new_ref_value = modal.reference.value or None
|
||||
if new_ref_value != reward.reference:
|
||||
update_args['reference'] = new_ref_value
|
||||
|
||||
new_notes_value = modal.notes.value or None
|
||||
if new_notes_value != reward.modnote:
|
||||
update_args['modnote'] = new_notes_value
|
||||
|
||||
if update_args:
|
||||
await interaction.response.defer(thinking=True, ephemeral=True)
|
||||
await self.campaign.update_reward(reward.earned_id, **update_args)
|
||||
await self.refresh(thinking=interaction)
|
||||
else:
|
||||
await interaction.response.defer(thinking=False)
|
||||
|
||||
|
||||
await selection.response.send_modal(modal)
|
||||
|
||||
await self.refresh()
|
||||
else:
|
||||
await selection.response.defer()
|
||||
@@ -200,7 +230,7 @@ class RewardList(MessageUI):
|
||||
'Earned At': discord.utils.format_dt(reward.earned_at, 'F'),
|
||||
'Earned From': reward.earned_from,
|
||||
'Fulfilled At': fluf,
|
||||
'Reference': "*No reference set*",
|
||||
'Reference': reward.reference or "*No reference set*",
|
||||
'Further notes': reward.modnote or "*No notes*",
|
||||
}
|
||||
prop_table = '\n'.join(tabulate(*table.items()))
|
||||
|
||||
Reference in New Issue
Block a user