280 lines
10 KiB
Python
280 lines
10 KiB
Python
import itertools
|
|
import asyncio
|
|
|
|
import discord
|
|
from discord.ui.button import button, Button, ButtonStyle
|
|
from discord.ui.select import select, ChannelSelect, RoleSelect
|
|
|
|
from meta import LionBot
|
|
|
|
from utils.ui import ConfigUI, DashboardSection
|
|
from utils.lib import MessageArgs
|
|
|
|
from ..settings import ScheduleSettings
|
|
from .. import babel
|
|
|
|
_p = babel._p
|
|
|
|
|
|
class ScheduleSettingUI(ConfigUI):
|
|
pages = [
|
|
(
|
|
ScheduleSettings.SessionLobby,
|
|
ScheduleSettings.SessionRoom,
|
|
ScheduleSettings.SessionChannels,
|
|
), (
|
|
ScheduleSettings.ScheduleCost,
|
|
ScheduleSettings.AttendanceReward,
|
|
ScheduleSettings.AttendanceBonus,
|
|
ScheduleSettings.MinAttendance,
|
|
), (
|
|
ScheduleSettings.BlacklistRole,
|
|
ScheduleSettings.BlacklistAfter,
|
|
)
|
|
]
|
|
setting_classes = list(itertools.chain(*pages))
|
|
|
|
def _init_children(self):
|
|
# HACK to stop ViewWeights complaining that this UI has too many children
|
|
# Children will be correctly initialised after parent init.
|
|
return []
|
|
|
|
def __init__(self, bot: LionBot, guildid: int, channelid: int, **kwargs):
|
|
self.settings = bot.get_cog('ScheduleCog').settings
|
|
super().__init__(bot, guildid, channelid, **kwargs)
|
|
self._children = super()._init_children()
|
|
self.page_num = 0
|
|
|
|
def get_instance(self, setting):
|
|
return next(instance for instance in self.instances if instance.setting_id == setting.setting_id)
|
|
|
|
@property
|
|
def page_instances(self):
|
|
start = sum(len(page) for page in self.pages[:self.page_num])
|
|
end = start + len(self.pages[self.page_num])
|
|
return self.instances[start:end]
|
|
|
|
# ----- UI Components -----
|
|
# Page 0 button
|
|
@button(label="PAGE0_BUTTON_PLACEHOLDER", style=ButtonStyle.grey)
|
|
async def page0_button(self, press: discord.Interaction, pressed: Button):
|
|
await press.response.defer(thinking=True, ephemeral=True)
|
|
self.page_num = 0
|
|
await self.refresh(thinking=press)
|
|
|
|
async def page0_button_refresh(self):
|
|
t = self.bot.translator.t
|
|
self.page0_button.label = t(_p(
|
|
'ui:schedule_config|button:page0|label',
|
|
"Page 1"
|
|
))
|
|
self.page0_button.disabled = (self.page_num == 0)
|
|
|
|
# Lobby channel selector
|
|
@select(cls=ChannelSelect, channel_types=[discord.ChannelType.text, discord.ChannelType.voice],
|
|
min_values=0, max_values=1,
|
|
placeholder='LOBBY_PLACEHOLDER')
|
|
async def lobby_menu(self, selection: discord.Interaction, selected: ChannelSelect):
|
|
# TODO: Setting value checks
|
|
await selection.response.defer()
|
|
setting = self.get_instance(ScheduleSettings.SessionLobby)
|
|
await setting.interaction_check(setting.parent_id, selection)
|
|
setting.value = selected.values[0] if selected.values else None
|
|
await setting.write()
|
|
|
|
async def lobby_menu_refresh(self):
|
|
t = self.bot.translator.t
|
|
self.lobby_menu.placeholder = t(_p(
|
|
'ui:schedule_config|menu:lobby|placeholder',
|
|
"Select Lobby Channel"
|
|
))
|
|
|
|
# Room channel selector
|
|
@select(cls=ChannelSelect, channel_types=[discord.ChannelType.category, discord.ChannelType.voice],
|
|
min_values=0, max_values=1,
|
|
placeholder='ROOM_PLACEHOLDER')
|
|
async def room_menu(self, selection: discord.Interaction, selected: ChannelSelect):
|
|
await selection.response.defer()
|
|
setting = self.get_instance(ScheduleSettings.SessionRoom)
|
|
await setting.interaction_check(setting.parent_id, selection)
|
|
setting.value = selected.values[0] if selected.values else None
|
|
await setting.write()
|
|
|
|
async def room_menu_refresh(self):
|
|
t = self.bot.translator.t
|
|
self.room_menu.placeholder = t(_p(
|
|
'ui:schedule_config|menu:room|placeholder',
|
|
"Select Session Room"
|
|
))
|
|
|
|
# Session channels selector
|
|
@select(cls=ChannelSelect, channel_types=[discord.ChannelType.category, discord.ChannelType.voice],
|
|
min_values=0, max_values=25,
|
|
placeholder='CHANNELS_PLACEHOLDER')
|
|
async def channels_menu(self, selection: discord.Interaction, selected: ChannelSelect):
|
|
# TODO: Consider XORing input
|
|
await selection.response.defer()
|
|
setting = self.get_instance(ScheduleSettings.SessionChannels)
|
|
await setting.interaction_check(setting.parent_id, selection)
|
|
setting.value = selected.values
|
|
await setting.write()
|
|
|
|
async def channels_menu_refresh(self):
|
|
t = self.bot.translator.t
|
|
self.channels_menu.placeholder = t(_p(
|
|
'ui:schedule_config|menu:channels|placeholder',
|
|
"Select Session Channels"
|
|
))
|
|
|
|
# Page 1 button
|
|
@button(label="PAGE1_BUTTON_PLACEHOLDER", style=ButtonStyle.grey)
|
|
async def page1_button(self, press: discord.Interaction, pressed: Button):
|
|
await press.response.defer(thinking=True, ephemeral=True)
|
|
self.page_num = 1
|
|
await self.refresh(thinking=press)
|
|
|
|
async def page1_button_refresh(self):
|
|
t = self.bot.translator.t
|
|
self.page1_button.label = t(_p(
|
|
'ui:schedule_config|button:page1|label',
|
|
"Page 2"
|
|
))
|
|
self.page1_button.disabled = (self.page_num == 1)
|
|
|
|
# Page 3 button
|
|
@button(label="PAGE2_BUTTON_PLACEHOLDER", style=ButtonStyle.grey)
|
|
async def page2_button(self, press: discord.Interaction, pressed: Button):
|
|
await press.response.defer(thinking=True, ephemeral=True)
|
|
self.page_num = 2
|
|
await self.refresh(thinking=press)
|
|
|
|
async def page2_button_refresh(self):
|
|
t = self.bot.translator.t
|
|
self.page2_button.label = t(_p(
|
|
'ui:schedule_config|button:page2|label',
|
|
"Page 3"
|
|
))
|
|
self.page2_button.disabled = (self.page_num == 3)
|
|
|
|
# Blacklist role selector
|
|
@select(cls=RoleSelect, min_values=0, max_values=1, placeholder="BLACKLIST_ROLE_PLACEHOLDER")
|
|
async def blacklist_role_menu(self, selection: discord.Interaction, selected: RoleSelect):
|
|
await selection.response.defer()
|
|
setting = self.get_instance(ScheduleSettings.BlacklistRole)
|
|
await setting.interaction_check(setting.parent_id, selection)
|
|
setting.value = selected.values[0] if selected.values else None
|
|
# TODO: Warning for insufficient permissions?
|
|
await setting.write()
|
|
|
|
async def blacklist_role_menu_refresh(self):
|
|
t = self.bot.translator.t
|
|
self.blacklist_role_menu.placeholder = t(_p(
|
|
'ui:schedule_config|menu:blacklist_role|placeholder',
|
|
"Select Blacklist Role"
|
|
))
|
|
|
|
# ----- UI Flow -----
|
|
async def make_message(self) -> MessageArgs:
|
|
t = self.bot.translator.t
|
|
title = t(_p(
|
|
'ui:schedule_config|embed|title',
|
|
"Scheduled Session Configuration Panel"
|
|
))
|
|
embed = discord.Embed(
|
|
colour=discord.Colour.orange(),
|
|
title=title
|
|
)
|
|
for setting in self.page_instances:
|
|
embed.add_field(**setting.embed_field, inline=False)
|
|
|
|
args = MessageArgs(embed=embed)
|
|
return args
|
|
|
|
async def refresh_components(self):
|
|
await asyncio.gather(
|
|
self.page0_button_refresh(),
|
|
self.page1_button_refresh(),
|
|
self.page2_button_refresh(),
|
|
self.edit_button_refresh(),
|
|
self.reset_button_refresh(),
|
|
self.close_button_refresh(),
|
|
)
|
|
if self.page_num == 0:
|
|
await asyncio.gather(
|
|
self.lobby_menu_refresh(),
|
|
self.room_menu_refresh(),
|
|
self.channels_menu_refresh(),
|
|
)
|
|
self.set_layout(
|
|
(self.page0_button, self.page1_button, self.page2_button),
|
|
(self.lobby_menu,),
|
|
(self.room_menu,),
|
|
(self.channels_menu,),
|
|
(self.edit_button, self.reset_button, self.close_button),
|
|
)
|
|
elif self.page_num == 1:
|
|
self.set_layout(
|
|
(self.page0_button, self.page1_button, self.page2_button),
|
|
(self.edit_button, self.reset_button, self.close_button),
|
|
)
|
|
elif self.page_num == 2:
|
|
await asyncio.gather(
|
|
self.blacklist_role_menu_refresh()
|
|
)
|
|
self.set_layout(
|
|
(self.page0_button, self.page1_button, self.page2_button),
|
|
(self.blacklist_role_menu,),
|
|
(self.edit_button, self.reset_button, self.close_button),
|
|
)
|
|
|
|
|
|
class ScheduleDashboard(DashboardSection):
|
|
section_name = _p(
|
|
'dash:schedule|title',
|
|
"Scheduled Session Configuration ({commands[admin config schedule]})"
|
|
)
|
|
_option_name = _p(
|
|
"dash:schedule|dropdown|placeholder",
|
|
"Scheduled Sessions Panel"
|
|
)
|
|
configui = ScheduleSettingUI
|
|
setting_classes = ScheduleSettingUI.setting_classes
|
|
|
|
def apply_to(self, page: discord.Embed):
|
|
t = self.bot.translator.t
|
|
pages = [
|
|
self.instances[0:3],
|
|
self.instances[3:7],
|
|
self.instances[7:]
|
|
]
|
|
# Schedule Channels
|
|
table = self._make_table(pages[0])
|
|
page.add_field(
|
|
name=t(_p(
|
|
'dash:schedule|section:schedule_channels|name',
|
|
"Scheduled Session Channels ({commands[admin config schedule]})",
|
|
)).format(commands=self.bot.core.mention_cache),
|
|
value=table,
|
|
inline=False
|
|
)
|
|
# Schedule Rewards
|
|
table = self._make_table(pages[1])
|
|
page.add_field(
|
|
name=t(_p(
|
|
'dash:schedule|section:schedule_rewards|name',
|
|
"Scheduled Session Rewards ({commands[admin config schedule]})",
|
|
)).format(commands=self.bot.core.mention_cache),
|
|
value=table,
|
|
inline=False
|
|
)
|
|
# Schedule Blacklist
|
|
table = self._make_table(pages[2])
|
|
page.add_field(
|
|
name=t(_p(
|
|
'dash:schedule|section:schedule_blacklist|name',
|
|
"Scheduled Session Blacklist ({commands[admin config schedule]})",
|
|
)).format(commands=self.bot.core.mention_cache),
|
|
value=table,
|
|
inline=False
|
|
)
|