288 lines
9.4 KiB
Python
288 lines
9.4 KiB
Python
import discord
|
|
|
|
from settings import ModelData
|
|
from settings.groups import SettingGroup, ModelConfig, SettingDotDict
|
|
from settings.setting_types import (
|
|
RoleSetting, BoolSetting, StringSetting, DurationSetting, EmojiSetting
|
|
)
|
|
from core.setting_types import CoinSetting
|
|
from utils.ui import AButton, AsComponents
|
|
from meta.errors import UserInputError
|
|
from babel.translator import ctx_translator
|
|
|
|
from .data import RoleMenuData
|
|
from . import babel
|
|
|
|
_p = babel._p
|
|
|
|
|
|
class RoleMenuRoleConfig(ModelConfig):
|
|
settings = SettingDotDict()
|
|
_model_settings = set()
|
|
model = RoleMenuData.RoleMenuRole
|
|
|
|
@property
|
|
def role(self):
|
|
return self.get(RoleMenuRoleOptions.Role.setting_id)
|
|
|
|
@property
|
|
def label(self):
|
|
return self.get(RoleMenuRoleOptions.Label.setting_id)
|
|
|
|
@property
|
|
def emoji(self):
|
|
return self.get(RoleMenuRoleOptions.Emoji.setting_id)
|
|
|
|
@property
|
|
def description(self):
|
|
return self.get(RoleMenuRoleOptions.Description.setting_id)
|
|
|
|
@property
|
|
def price(self):
|
|
return self.get(RoleMenuRoleOptions.Price.setting_id)
|
|
|
|
@property
|
|
def duration(self):
|
|
return self.get(RoleMenuRoleOptions.Duration.setting_id)
|
|
|
|
|
|
class RoleMenuRoleOptions(SettingGroup):
|
|
@RoleMenuRoleConfig.register_model_setting
|
|
class Role(ModelData, RoleSetting):
|
|
setting_id = 'role'
|
|
|
|
_display_name = _p('roleset:role', "role")
|
|
_desc = _p(
|
|
'roleset:role|desc',
|
|
"The role associated to this menu item."
|
|
)
|
|
_long_desc = _p(
|
|
'roleset:role|long_desc',
|
|
"The role given when this menu item is selected in the role menu."
|
|
)
|
|
|
|
_model = RoleMenuData.RoleMenuRole
|
|
_column = RoleMenuData.RoleMenuRole.roleid.name
|
|
|
|
@property
|
|
def update_message(self) -> str:
|
|
t = ctx_translator.get().t
|
|
value = self.value
|
|
if value:
|
|
resp = t(_p(
|
|
'roleset:role|set_response:set',
|
|
"This menu item will now give the role {role}."
|
|
)).format(role=self.formatted)
|
|
return resp
|
|
|
|
@RoleMenuRoleConfig.register_model_setting
|
|
class Label(ModelData, StringSetting):
|
|
setting_id = 'label'
|
|
|
|
_display_name = _p('roleset:label', "label")
|
|
_desc = _p(
|
|
'roleset:label|desc',
|
|
"A short button label for this role."
|
|
)
|
|
_accepts = _desc
|
|
_long_desc = _p(
|
|
'roleset:label|long_desc',
|
|
"A short name for this role, to be displayed in button labels, dropdown titles, and some menu layouts. "
|
|
"By default uses the Discord role name."
|
|
)
|
|
|
|
_quote = False
|
|
|
|
_model = RoleMenuData.RoleMenuRole
|
|
_column = RoleMenuData.RoleMenuRole.label.name
|
|
|
|
@property
|
|
def update_message(self) -> str:
|
|
t = ctx_translator.get().t
|
|
resp = t(_p(
|
|
'roleset:role|set_response',
|
|
"This menu role is now called `{value}`."
|
|
)).format(value=self.data)
|
|
return resp
|
|
|
|
@RoleMenuRoleConfig.register_model_setting
|
|
class Emoji(ModelData, EmojiSetting):
|
|
setting_id = 'emoji'
|
|
|
|
_display_name = _p('roleset:emoji', "emoji")
|
|
_desc = _p(
|
|
'roleset:emoji|desc',
|
|
"The emoji associated with this role."
|
|
)
|
|
_long_desc = _p(
|
|
'roleset:emoji|long_desc',
|
|
"The role emoji is used for the reaction (in reaction role menus), "
|
|
"and otherwise appears next to the role label in the button and dropdown styles. "
|
|
"The emoji is also displayed next to the role in most menu templates."
|
|
)
|
|
|
|
_model = RoleMenuData.RoleMenuRole
|
|
_column = RoleMenuData.RoleMenuRole.emoji.name
|
|
|
|
@property
|
|
def test_button(self):
|
|
if self.data:
|
|
button = AButton(emoji=self.data)
|
|
button.disabled = True
|
|
|
|
@button
|
|
async def emoji_test_callback(press, butt):
|
|
await press.response.defer()
|
|
else:
|
|
button = None
|
|
return button
|
|
|
|
@classmethod
|
|
async def _parse_string(cls, parent_id, string: str, interaction: discord.Interaction = None, **kwargs):
|
|
emojistr = await super()._parse_string(parent_id, string, interaction=interaction, **kwargs)
|
|
if emojistr and interaction is not None:
|
|
# Use the interaction to test
|
|
button = AButton(emoji=emojistr)
|
|
button.disabled = True
|
|
view = AsComponents(button)
|
|
try:
|
|
await interaction.edit_original_response(
|
|
content=f"Testing Emoji {emojistr}",
|
|
view=view,
|
|
)
|
|
except discord.HTTPException:
|
|
t = interaction.client.translator.t
|
|
raise UserInputError(t(_p(
|
|
'roleset:emoji|error:test_emoji',
|
|
"The selected emoji `{emoji}` is invalid or has been deleted."
|
|
)).format(emoji=emojistr))
|
|
return emojistr
|
|
|
|
@property
|
|
def update_message(self) -> str:
|
|
t = ctx_translator.get().t
|
|
value = self.value
|
|
if value:
|
|
resp = t(_p(
|
|
'roleset:emoji|set_response:set',
|
|
"The menu role emoji is now {emoji}."
|
|
)).format(emoji=self.as_partial)
|
|
else:
|
|
resp = t(_p(
|
|
'roleset:emoji|set_response:unset',
|
|
"The menu role emoji has been removed."
|
|
))
|
|
return resp
|
|
|
|
@RoleMenuRoleConfig.register_model_setting
|
|
class Description(ModelData, StringSetting):
|
|
setting_id = 'description'
|
|
|
|
_display_name = _p('roleset:description', "description")
|
|
_desc = _p(
|
|
'roleset:description|desc',
|
|
"A longer description of this role."
|
|
)
|
|
_accepts = _desc
|
|
_long_desc = _p(
|
|
'roleset:description|long_desc',
|
|
"The description is displayed under the role label in dropdown style menus. "
|
|
"It may also be used as a substitution key in custom role selection responses."
|
|
)
|
|
|
|
_quote = False
|
|
|
|
_model = RoleMenuData.RoleMenuRole
|
|
_column = RoleMenuData.RoleMenuRole.description.name
|
|
|
|
@property
|
|
def update_message(self) -> str:
|
|
t = ctx_translator.get().t
|
|
value = self.value
|
|
if value:
|
|
resp = t(_p(
|
|
'roleset:description|set_response:set',
|
|
"The role description has been set."
|
|
))
|
|
else:
|
|
resp = t(_p(
|
|
'roleset:description|set_response:unset',
|
|
"The role description has been removed."
|
|
))
|
|
return resp
|
|
|
|
@RoleMenuRoleConfig.register_model_setting
|
|
class Price(ModelData, CoinSetting):
|
|
setting_id = 'price'
|
|
|
|
_display_name = _p('roleset:price', "price")
|
|
_desc = _p(
|
|
'roleset:price|desc',
|
|
"Price of the role, in LionCoins."
|
|
)
|
|
_long_desc = _p(
|
|
'roleset:price|long_desc',
|
|
"How much the role costs when selected, in LionCoins."
|
|
)
|
|
_accepts = _p(
|
|
'roleset:price|accepts',
|
|
"Amount of coins that the role costs."
|
|
)
|
|
_default = 0
|
|
_model = RoleMenuData.RoleMenuRole
|
|
_column = RoleMenuData.RoleMenuRole.price.name
|
|
|
|
@property
|
|
def update_message(self) -> str:
|
|
t = ctx_translator.get().t
|
|
value = self.value
|
|
if value:
|
|
resp = t(_p(
|
|
'roleset:price|set_response:set',
|
|
"This role will now cost {price} to equip."
|
|
)).format(price=self.formatted)
|
|
else:
|
|
resp = t(_p(
|
|
'roleset:price|set_response:unset',
|
|
"This role will now be free to equip from this role menu."
|
|
))
|
|
return resp
|
|
|
|
@RoleMenuRoleConfig.register_model_setting
|
|
class Duration(ModelData, DurationSetting):
|
|
setting_id = 'duration'
|
|
|
|
_display_name = _p('roleset:duration', "duration")
|
|
_desc = _p(
|
|
'roleset:duration|desc',
|
|
"Lifetime of the role after selection"
|
|
)
|
|
_long_desc = _p(
|
|
'roleset:duration|long_desc',
|
|
"Allows creation of 'temporary roles' which expire a given time after being equipped. "
|
|
"Refunds will not be given upon expiry."
|
|
)
|
|
_notset_str = _p(
|
|
'roleset:duration|notset',
|
|
"Forever."
|
|
)
|
|
|
|
_model = RoleMenuData.RoleMenuRole
|
|
_column = RoleMenuData.RoleMenuRole.duration.name
|
|
|
|
@property
|
|
def update_message(self) -> str:
|
|
t = ctx_translator.get().t
|
|
value = self.value
|
|
if value:
|
|
resp = t(_p(
|
|
'roleset:duration|set_response:set',
|
|
"This role will now expire after {duration}."
|
|
)).format(duration=self.formatted)
|
|
else:
|
|
resp = t(_p(
|
|
'roleset:duration|set_response:unset',
|
|
"This role will no longer expire after being selected."
|
|
))
|
|
return resp
|