302 lines
10 KiB
Python
302 lines
10 KiB
Python
import asyncio
|
|
|
|
import discord
|
|
from discord.ui.button import button, Button, ButtonStyle
|
|
from discord.ui.select import select, RoleSelect, ChannelSelect
|
|
|
|
from meta import LionBot
|
|
|
|
from utils.ui import ConfigUI, DashboardSection
|
|
from utils.lib import MessageArgs
|
|
from utils.ui.msgeditor import MsgEditor
|
|
from wards import equippable_role
|
|
|
|
from .settings import MemberAdminSettings as Settings
|
|
from . import babel
|
|
|
|
_p = babel._p
|
|
|
|
|
|
class MemberAdminUI(ConfigUI):
|
|
setting_classes = (
|
|
Settings.GreetingChannel,
|
|
Settings.GreetingMessage,
|
|
Settings.ReturningMessage,
|
|
Settings.Autoroles,
|
|
Settings.BotAutoroles,
|
|
Settings.RolePersistence,
|
|
)
|
|
|
|
def __init__(self, bot: LionBot, guildid: int, channelid: int, **kwargs):
|
|
self.settings = bot.get_cog('MemberAdminCog').settings
|
|
super().__init__(bot, guildid, channelid, **kwargs)
|
|
|
|
# ----- UI Components -----
|
|
# Greeting Channel
|
|
@select(
|
|
cls=ChannelSelect,
|
|
channel_types=[discord.ChannelType.voice, discord.ChannelType.text],
|
|
placeholder="GREETCH_MENU_PLACEHOLDER",
|
|
min_values=0, max_values=1
|
|
)
|
|
async def greetch_menu(self, selection: discord.Interaction, selected: ChannelSelect):
|
|
"""
|
|
Selector for the `greeting_channel` setting.
|
|
"""
|
|
await selection.response.defer(thinking=True, ephemeral=True)
|
|
setting = self.get_instance(Settings.GreetingChannel)
|
|
await setting.interaction_check(setting.parent_id, selection)
|
|
setting.value = selected.values[0] if selected.values else None
|
|
await setting.write()
|
|
await selection.delete_original_response()
|
|
|
|
async def greetch_menu_refresh(self):
|
|
menu = self.greetch_menu
|
|
t = self.bot.translator.t
|
|
menu.placeholder = t(_p(
|
|
'ui:memberadmin|menu:greetch|placeholder',
|
|
"Select Greeting Channel"
|
|
))
|
|
|
|
# Autoroles
|
|
@select(
|
|
cls=RoleSelect,
|
|
placeholder="AUTOROLES_MENU_PLACEHOLDER",
|
|
min_values=0, max_values=25
|
|
)
|
|
async def autoroles_menu(self, selection: discord.Interaction, selected: RoleSelect):
|
|
"""
|
|
Simple multi-role selector for the 'autoroles' setting.
|
|
"""
|
|
await selection.response.defer(thinking=True, ephemeral=True)
|
|
for role in selected.values:
|
|
# Check authority to set these roles (for author and client)
|
|
await equippable_role(self.bot, role, selection.user)
|
|
|
|
setting = self.get_instance(Settings.Autoroles)
|
|
await setting.interaction_check(setting.parent_id, selection)
|
|
setting.value = selected.values
|
|
await setting.write()
|
|
# Instance hooks will update the menu
|
|
await selection.delete_original_response()
|
|
|
|
async def autoroles_menu_refresh(self):
|
|
menu = self.autoroles_menu
|
|
t = self.bot.translator.t
|
|
menu.placeholder = t(_p(
|
|
'ui:memberadmin|menu:autoroles|placeholder',
|
|
"Select Autoroles"
|
|
))
|
|
|
|
# Bot autoroles
|
|
@select(
|
|
cls=RoleSelect,
|
|
placeholder="BOT_AUTOROLES_MENU_PLACEHOLDER",
|
|
min_values=0, max_values=25
|
|
)
|
|
async def bot_autoroles_menu(self, selection: discord.Interaction, selected: RoleSelect):
|
|
"""
|
|
Simple multi-role selector for the 'bot_autoroles' setting.
|
|
"""
|
|
await selection.response.defer(thinking=True, ephemeral=True)
|
|
for role in selected.values:
|
|
# Check authority to set these roles (for author and client)
|
|
await equippable_role(self.bot, role, selection.user)
|
|
|
|
setting = self.get_instance(Settings.BotAutoroles)
|
|
await setting.interaction_check(setting.parent_id, selection)
|
|
setting.value = selected.values
|
|
await setting.write()
|
|
# Instance hooks will update the menu
|
|
await selection.delete_original_response()
|
|
|
|
async def bot_autoroles_menu_refresh(self):
|
|
menu = self.bot_autoroles_menu
|
|
t = self.bot.translator.t
|
|
menu.placeholder = t(_p(
|
|
'ui:memberadmin|menu:bot_autoroles|placeholder',
|
|
"Select Bot Autoroles"
|
|
))
|
|
|
|
# Greeting Msg
|
|
@button(
|
|
label="GREET_MSG_BUTTON_PLACEHOLDER",
|
|
style=ButtonStyle.blurple
|
|
)
|
|
async def greet_msg_button(self, press: discord.Interaction, pressed: Button):
|
|
"""
|
|
Message Editor Button for the `greeting_message` setting.
|
|
|
|
This will open up a Message Editor with the current `greeting_message`,
|
|
if set, otherwise a default `greeting_message`.
|
|
This also generates a preview formatter using the calling user.
|
|
"""
|
|
await press.response.defer(thinking=True, ephemeral=True)
|
|
t = self.bot.translator.t
|
|
setting = self.get_instance(Settings.GreetingMessage)
|
|
await setting.interaction_check(setting.parent_id, press)
|
|
|
|
value = setting.value
|
|
if value is None:
|
|
value = setting._data_to_value(self.guildid, t(setting._soft_default))
|
|
setting.value = value
|
|
await setting.write()
|
|
|
|
editor = MsgEditor(
|
|
self.bot,
|
|
value,
|
|
callback=setting.editor_callback,
|
|
formatter=await setting.generate_formatter(self.bot, press.user),
|
|
callerid=press.user.id,
|
|
)
|
|
self._slaves.append(editor)
|
|
await editor.run(press)
|
|
|
|
async def greet_msg_button_refresh(self):
|
|
button = self.greet_msg_button
|
|
t = self.bot.translator.t
|
|
button.label = t(_p(
|
|
'ui:member_admin|button:greet_msg|label',
|
|
"Greeting Msg"
|
|
))
|
|
|
|
# Returning Msg
|
|
@button(
|
|
label="RETURN_MSG_BUTTON_PLACEHOLDER",
|
|
style=ButtonStyle.blurple
|
|
)
|
|
async def return_msg_button(self, press: discord.Interaction, pressed: Button):
|
|
"""
|
|
Message Editor Button for the `returning_message` setting.
|
|
|
|
Similar to the `greet_msg_button`, this opens a Message Editor
|
|
with the current `returning_message`.
|
|
If the setting is unset, will instead either use the current `greeting_message`,
|
|
or if that is also unset, use a default `returning_message`.
|
|
"""
|
|
await press.response.defer(thinking=True, ephemeral=True)
|
|
t = self.bot.translator.t
|
|
setting = self.get_instance(Settings.ReturningMessage)
|
|
await setting.interaction_check(setting.parent_id, press)
|
|
greeting = self.get_instance(Settings.GreetingMessage)
|
|
|
|
value = setting.value
|
|
if value is not None:
|
|
pass
|
|
elif greeting.value is not None:
|
|
value = greeting.value
|
|
else:
|
|
value = setting._data_to_value(self.guildid, t(setting._soft_default))
|
|
setting.value = value
|
|
await setting.write()
|
|
|
|
editor = MsgEditor(
|
|
self.bot,
|
|
value,
|
|
callback=setting.editor_callback,
|
|
formatter=await setting.generate_formatter(
|
|
self.bot, press.user, press.user.joined_at.timestamp()
|
|
),
|
|
callerid=press.user.id,
|
|
)
|
|
self._slaves.append(editor)
|
|
await editor.run(press)
|
|
|
|
async def return_msg_button_refresh(self):
|
|
button = self.return_msg_button
|
|
t = self.bot.translator.t
|
|
button.label = t(_p(
|
|
'ui:memberadmin|button:return_msg|label',
|
|
"Returning Msg"
|
|
))
|
|
|
|
# ----- UI Flow -----
|
|
async def make_message(self) -> MessageArgs:
|
|
t = self.bot.translator.t
|
|
title = t(_p(
|
|
'ui:memberadmin|embed|title',
|
|
"Greetings and Initial Roles Panel"
|
|
))
|
|
embed = discord.Embed(
|
|
title=title,
|
|
colour=discord.Colour.orange()
|
|
)
|
|
for setting in self.instances:
|
|
embed.add_field(**setting.embed_field, inline=False)
|
|
|
|
return MessageArgs(embed=embed)
|
|
|
|
async def reload(self):
|
|
# Re-fetch data for each instance
|
|
# This should generally hit cache
|
|
self.instances = [
|
|
await setting.get(self.guildid)
|
|
for setting in self.setting_classes
|
|
]
|
|
|
|
async def refresh_components(self):
|
|
component_refresh = (
|
|
self.edit_button_refresh(),
|
|
self.close_button_refresh(),
|
|
self.reset_button_refresh(),
|
|
self.greetch_menu_refresh(),
|
|
self.autoroles_menu_refresh(),
|
|
self.bot_autoroles_menu_refresh(),
|
|
self.greet_msg_button_refresh(),
|
|
self.return_msg_button_refresh(),
|
|
)
|
|
await asyncio.gather(*component_refresh)
|
|
|
|
self.set_layout(
|
|
(self.greetch_menu,),
|
|
(self.autoroles_menu,),
|
|
(self.bot_autoroles_menu,),
|
|
(self.greet_msg_button, self.return_msg_button,
|
|
self.edit_button, self.reset_button, self.close_button),
|
|
)
|
|
|
|
|
|
class MemberAdminDashboard(DashboardSection):
|
|
section_name = _p(
|
|
"dash:member_admin|title",
|
|
"Greetings and Initial Roles ({commands[config welcome]})"
|
|
)
|
|
_option_name = _p(
|
|
"dash:member_admin|dropdown|placeholder",
|
|
"Greetings and Initial Roles Panel"
|
|
)
|
|
configui = MemberAdminUI
|
|
setting_classes = MemberAdminUI.setting_classes
|
|
|
|
def apply_to(self, page: discord.Embed):
|
|
"""
|
|
Overriding DashboardSection apply_to to split into two sections.
|
|
"""
|
|
t = self.bot.translator.t
|
|
sections = [
|
|
self.instances[:3],
|
|
self.instances[3:]
|
|
]
|
|
|
|
# Greeting messages
|
|
table = self._make_table(sections[0])
|
|
page.add_field(
|
|
name=t(_p(
|
|
'dash:member_admin|section:greeting_messages|name',
|
|
"Greeting Messages ({commands[admin config welcome]})"
|
|
)).format(commands=self.bot.core.mention_cache),
|
|
value=table,
|
|
inline=False
|
|
)
|
|
|
|
# Initial Roles
|
|
table = self._make_table(sections[1])
|
|
page.add_field(
|
|
name=t(_p(
|
|
'dash:member_admin|section:initial_roles|name',
|
|
"Initial Roles ({commands[admin config welcome]})"
|
|
)).format(commands=self.bot.core.mention_cache),
|
|
value=table,
|
|
inline=False
|
|
)
|