rewrite (babel): Complete configuration UI.
This commit is contained in:
264
src/babel/cog.py
264
src/babel/cog.py
@@ -8,138 +8,23 @@ from typing import Optional
|
|||||||
import discord
|
import discord
|
||||||
from discord.ext import commands as cmds
|
from discord.ext import commands as cmds
|
||||||
from discord import app_commands as appcmds
|
from discord import app_commands as appcmds
|
||||||
|
from discord.ui.button import ButtonStyle
|
||||||
|
|
||||||
from meta import LionBot, LionCog, LionContext
|
from meta import LionBot, LionCog, LionContext
|
||||||
from meta.errors import UserInputError
|
from meta.errors import UserInputError
|
||||||
|
from utils.ui import AButton, AsComponents
|
||||||
from wards import low_management
|
from wards import low_management
|
||||||
|
|
||||||
from settings import ModelData
|
from .translator import ctx_locale, ctx_translator, SOURCE_LOCALE
|
||||||
from settings.setting_types import StringSetting, BoolSetting
|
|
||||||
from settings.groups import SettingGroup
|
|
||||||
|
|
||||||
from core.data import CoreData
|
|
||||||
|
|
||||||
from .translator import ctx_locale, ctx_translator, LocalBabel, SOURCE_LOCALE
|
|
||||||
from . import babel
|
from . import babel
|
||||||
|
from .enums import locale_names
|
||||||
|
from .settings import LocaleSettings
|
||||||
|
from .settingui import LocaleSettingUI
|
||||||
|
|
||||||
_ = babel._
|
_ = babel._
|
||||||
_p = babel._p
|
_p = babel._p
|
||||||
|
|
||||||
|
|
||||||
class LocaleSettings(SettingGroup):
|
|
||||||
class UserLocale(ModelData, StringSetting):
|
|
||||||
"""
|
|
||||||
User-configured locale.
|
|
||||||
|
|
||||||
Exposed via dedicated setting command.
|
|
||||||
"""
|
|
||||||
setting_id = 'user_locale'
|
|
||||||
|
|
||||||
_display_name = _p('userset:locale', 'language')
|
|
||||||
_desc = _p('userset:locale|desc', "Your preferred language for interacting with me.")
|
|
||||||
|
|
||||||
_model = CoreData.User
|
|
||||||
_column = CoreData.User.locale.name
|
|
||||||
|
|
||||||
@property
|
|
||||||
def update_message(self):
|
|
||||||
t = ctx_translator.get().t
|
|
||||||
if self.data is None:
|
|
||||||
return t(_p('userset:locale|response', "You have unset your language."))
|
|
||||||
else:
|
|
||||||
return t(_p('userset:locale|response', "You have set your language to `{lang}`.")).format(
|
|
||||||
lang=self.data
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
async def _parse_string(cls, parent_id, string, **kwargs):
|
|
||||||
translator = ctx_translator.get()
|
|
||||||
if string not in translator.supported_locales:
|
|
||||||
lang = string[:20]
|
|
||||||
raise UserInputError(
|
|
||||||
translator.t(
|
|
||||||
_p('userset:locale|error', "Sorry, we do not support the `{lang}` language at this time!")
|
|
||||||
).format(lang=lang)
|
|
||||||
)
|
|
||||||
return string
|
|
||||||
|
|
||||||
class ForceLocale(ModelData, BoolSetting):
|
|
||||||
"""
|
|
||||||
Guild configuration for whether to force usage of the guild locale.
|
|
||||||
|
|
||||||
Exposed via `/configure language` command and standard configuration interface.
|
|
||||||
"""
|
|
||||||
setting_id = 'force_locale'
|
|
||||||
|
|
||||||
_display_name = _p('guildset:force_locale', 'force_language')
|
|
||||||
_desc = _p('guildset:force_locale|desc',
|
|
||||||
"Whether to force all members to use the configured guild language when interacting with me.")
|
|
||||||
long_desc = _p(
|
|
||||||
'guildset:force_locale|long_desc',
|
|
||||||
"When enabled, commands in this guild will always use the configured guild language, "
|
|
||||||
"regardless of the member's personally configured language."
|
|
||||||
)
|
|
||||||
_outputs = {
|
|
||||||
True: _p('guildset:force_locale|output', 'Enabled (members will be forced to use the server language)'),
|
|
||||||
False: _p('guildset:force_locale|output', 'Disabled (members may set their own language)'),
|
|
||||||
None: 'Not Set' # This should be impossible, since we have a default
|
|
||||||
}
|
|
||||||
_default = False
|
|
||||||
|
|
||||||
_model = CoreData.Guild
|
|
||||||
_column = CoreData.Guild.force_locale.name
|
|
||||||
|
|
||||||
@property
|
|
||||||
def update_message(self):
|
|
||||||
t = ctx_translator.get().t
|
|
||||||
if self.data:
|
|
||||||
return t(_p(
|
|
||||||
'guildset:force_locale|response',
|
|
||||||
"I will always use the set language in this server."
|
|
||||||
))
|
|
||||||
else:
|
|
||||||
return t(_p(
|
|
||||||
'guildset:force_locale|response',
|
|
||||||
"I will now allow the members to set their own language here."
|
|
||||||
))
|
|
||||||
|
|
||||||
class GuildLocale(ModelData, StringSetting):
|
|
||||||
"""
|
|
||||||
Guild-configured locale.
|
|
||||||
|
|
||||||
Exposed via `/configure language` command, and standard configuration interface.
|
|
||||||
"""
|
|
||||||
setting_id = 'guild_locale'
|
|
||||||
|
|
||||||
_display_name = _p('guildset:locale', 'language')
|
|
||||||
_desc = _p('guildset:locale|desc', "Your preferred language for interacting with me.")
|
|
||||||
|
|
||||||
_model = CoreData.Guild
|
|
||||||
_column = CoreData.Guild.locale.name
|
|
||||||
|
|
||||||
@property
|
|
||||||
def update_message(self):
|
|
||||||
t = ctx_translator.get().t
|
|
||||||
if self.data is None:
|
|
||||||
return t(_p('guildset:locale|response', "You have reset the guild language."))
|
|
||||||
else:
|
|
||||||
return t(_p('guildset:locale|response', "You have set the guild language to `{lang}`.")).format(
|
|
||||||
lang=self.data
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
async def _parse_string(cls, parent_id, string, **kwargs):
|
|
||||||
translator = ctx_translator.get()
|
|
||||||
if string not in translator.supported_locales:
|
|
||||||
lang = string[:20]
|
|
||||||
raise UserInputError(
|
|
||||||
translator.t(
|
|
||||||
_p('guildset:locale|error', "Sorry, we do not support the `{lang}` language at this time!")
|
|
||||||
).format(lang=lang)
|
|
||||||
)
|
|
||||||
return string
|
|
||||||
|
|
||||||
|
|
||||||
class BabelCog(LionCog):
|
class BabelCog(LionCog):
|
||||||
depends = {'CoreCog'}
|
depends = {'CoreCog'}
|
||||||
|
|
||||||
@@ -158,6 +43,9 @@ class BabelCog(LionCog):
|
|||||||
configcog = self.bot.get_cog('ConfigCog')
|
configcog = self.bot.get_cog('ConfigCog')
|
||||||
self.crossload_group(self.configure_group, configcog.configure_group)
|
self.crossload_group(self.configure_group, configcog.configure_group)
|
||||||
|
|
||||||
|
userconfigcog = self.bot.get_cog('UserConfigCog')
|
||||||
|
self.crossload_group(self.userconfig_group, userconfigcog.userconfig_group)
|
||||||
|
|
||||||
async def cog_unload(self):
|
async def cog_unload(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -201,22 +89,6 @@ class BabelCog(LionCog):
|
|||||||
ctx_translator.set(self.bot.translator)
|
ctx_translator.set(self.bot.translator)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@cmds.hybrid_command(
|
|
||||||
name=LocaleSettings.UserLocale._display_name,
|
|
||||||
description=LocaleSettings.UserLocale._desc
|
|
||||||
)
|
|
||||||
async def cmd_language(self, ctx: LionContext, language: str):
|
|
||||||
"""
|
|
||||||
Dedicated user setting command for the `locale` setting.
|
|
||||||
"""
|
|
||||||
if not ctx.interaction:
|
|
||||||
# This command is not available as a text command
|
|
||||||
return
|
|
||||||
|
|
||||||
setting = await self.settings.UserLocale.get(ctx.author.id)
|
|
||||||
new_data = await setting._parse_string(ctx.author.id, language)
|
|
||||||
await setting.interactive_set(new_data, ctx.interaction)
|
|
||||||
|
|
||||||
@LionCog.placeholder_group
|
@LionCog.placeholder_group
|
||||||
@cmds.hybrid_group('configure', with_app_command=False)
|
@cmds.hybrid_group('configure', with_app_command=False)
|
||||||
async def configure_group(self, ctx: LionContext):
|
async def configure_group(self, ctx: LionContext):
|
||||||
@@ -244,9 +116,9 @@ class BabelCog(LionCog):
|
|||||||
)
|
)
|
||||||
@appcmds.guild_only() # Can be removed when attached as a subcommand
|
@appcmds.guild_only() # Can be removed when attached as a subcommand
|
||||||
@cmds.check(low_management)
|
@cmds.check(low_management)
|
||||||
async def cmd_configure_language(
|
async def cmd_configure_language(self, ctx: LionContext,
|
||||||
self, ctx: LionContext, language: Optional[str] = None, force_language: Optional[appcmds.Choice[int]] = None
|
language: Optional[str] = None,
|
||||||
):
|
force_language: Optional[appcmds.Choice[int]] = None):
|
||||||
if not ctx.interaction:
|
if not ctx.interaction:
|
||||||
# This command is not available as a text command
|
# This command is not available as a text command
|
||||||
return
|
return
|
||||||
@@ -284,10 +156,10 @@ class BabelCog(LionCog):
|
|||||||
force_setting.data = force_data
|
force_setting.data = force_data
|
||||||
await force_setting.write()
|
await force_setting.write()
|
||||||
lines.append(force_setting.update_message)
|
lines.append(force_setting.update_message)
|
||||||
|
if lines:
|
||||||
result = '\n'.join(
|
result = '\n'.join(
|
||||||
f"{self.bot.config.emojis.tick} {line}" for line in lines
|
f"{self.bot.config.emojis.tick} {line}" for line in lines
|
||||||
)
|
)
|
||||||
# TODO: Setting group widget
|
|
||||||
await ctx.reply(
|
await ctx.reply(
|
||||||
embed=discord.Embed(
|
embed=discord.Embed(
|
||||||
colour=discord.Colour.green(),
|
colour=discord.Colour.green(),
|
||||||
@@ -296,24 +168,100 @@ class BabelCog(LionCog):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@cmd_configure_language.autocomplete('language')
|
if ctx.channel.id not in LocaleSettingUI._listening or not lines:
|
||||||
async def cmd_configure_language_acmpl_language(self, interaction: discord.Interaction, partial: str):
|
ui = LocaleSettingUI(self.bot, ctx.guild.id, ctx.channel.id)
|
||||||
# TODO: More friendly language names
|
await ui.run(ctx.interaction)
|
||||||
supported = self.bot.translator.supported_locales
|
await ui.wait()
|
||||||
matching = [lang for lang in supported if partial.lower() in lang]
|
|
||||||
t = self.t
|
@LionCog.placeholder_group
|
||||||
if not matching:
|
@cmds.hybrid_group(name='my')
|
||||||
return [
|
async def userconfig_group(self, ctx: LionContext):
|
||||||
appcmds.Choice(
|
pass
|
||||||
name=t(_p(
|
|
||||||
'cmd:configure_language|acmpl:language',
|
@userconfig_group.command(
|
||||||
"No supported languages matching {partial}"
|
name=_p('cmd:userconfig_language', "language"),
|
||||||
)).format(partial=partial),
|
description=_p(
|
||||||
value='None'
|
'cmd:userconfig_language|desc',
|
||||||
|
"Set your preferred interaction language."
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
@appcmds.rename(
|
||||||
|
language=_p('cmd:userconfig_language|param:language', "language")
|
||||||
|
)
|
||||||
|
@appcmds.describe(
|
||||||
|
language=_p(
|
||||||
|
'cmd:userconfig_language|param:language|desc',
|
||||||
|
"Which language do you want me to respond in?"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
async def userconfig_language_cmd(self, ctx: LionContext, language: Optional[str] = None):
|
||||||
|
if not ctx.interaction:
|
||||||
|
return
|
||||||
|
t = self.bot.translator.t
|
||||||
|
|
||||||
|
setting = await self.settings.UserLocale.get(ctx.author.id)
|
||||||
|
if language:
|
||||||
|
new_data = await setting._parse_string(ctx.author.id, language)
|
||||||
|
await setting.interactive_set(new_data, ctx.interaction, ephemeral=True)
|
||||||
|
else:
|
||||||
|
if setting.value:
|
||||||
|
desc = t(_p(
|
||||||
|
'cmd:userconfig_language|response:set',
|
||||||
|
"Your preferred language is currently set to {language}"
|
||||||
|
)).format(language=setting.formatted)
|
||||||
|
|
||||||
|
@AButton(
|
||||||
|
label=t(_p('cmd:userconfig_language|button:reset|label', "Reset")),
|
||||||
|
style=ButtonStyle.red
|
||||||
|
)
|
||||||
|
async def reset_button(_press: discord.Interaction, pressed):
|
||||||
|
await _press.response.defer()
|
||||||
|
await setting.interactive_set(None, ctx.interaction, view=None)
|
||||||
|
|
||||||
|
view = AsComponents(reset_button)
|
||||||
|
else:
|
||||||
|
desc = t(_p(
|
||||||
|
'cmd:userconfig_language|response:unset',
|
||||||
|
"You have not set a preferred language!"
|
||||||
|
))
|
||||||
|
view = None
|
||||||
|
embed = discord.Embed(
|
||||||
|
colour=discord.Colour.orange(),
|
||||||
|
description=desc
|
||||||
|
)
|
||||||
|
await ctx.reply(embed=embed, ephemeral=True, view=view)
|
||||||
|
|
||||||
|
@userconfig_language_cmd.autocomplete('language')
|
||||||
|
@cmd_configure_language.autocomplete('language')
|
||||||
|
async def acmpl_language(self, interaction: discord.Interaction, partial: str):
|
||||||
|
"""
|
||||||
|
Shared autocomplete for language options.
|
||||||
|
"""
|
||||||
|
t = self.bot.translator.t
|
||||||
|
supported = self.bot.translator.supported_locales
|
||||||
|
formatted = []
|
||||||
|
for locale in supported:
|
||||||
|
name = locale_names.get(locale, None)
|
||||||
|
if name:
|
||||||
|
localestr = f"{locale} ({t(name)})"
|
||||||
|
else:
|
||||||
|
localestr = locale
|
||||||
|
formatted.append((locale, localestr))
|
||||||
|
|
||||||
|
matching = {item for item in formatted if partial in item[1]}
|
||||||
|
if matching:
|
||||||
|
choices = [
|
||||||
|
appcmds.Choice(name=localestr, value=locale)
|
||||||
|
for locale, localestr in matching
|
||||||
]
|
]
|
||||||
else:
|
else:
|
||||||
return [
|
choices = [
|
||||||
appcmds.Choice(name=lang, value=lang)
|
appcmds.Choice(
|
||||||
for lang in matching
|
name=t(_p(
|
||||||
|
'acmpl:language|no_match',
|
||||||
|
"No supported languages matching {partial}"
|
||||||
|
)).format(partial=partial),
|
||||||
|
value=partial
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
return choices
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
from . import babel
|
||||||
|
|
||||||
|
_p = babel._p
|
||||||
|
|
||||||
|
|
||||||
class LocaleMap(Enum):
|
class LocaleMap(Enum):
|
||||||
@@ -32,3 +35,37 @@ class LocaleMap(Enum):
|
|||||||
turkish = 'tr'
|
turkish = 'tr'
|
||||||
ukrainian = 'uk'
|
ukrainian = 'uk'
|
||||||
vietnamese = 'vi'
|
vietnamese = 'vi'
|
||||||
|
|
||||||
|
|
||||||
|
locale_names = {
|
||||||
|
'en-US': _p('localenames|locale:en-US', "American English"),
|
||||||
|
'en-GB': _p('localenames|locale:en-GB', "British English"),
|
||||||
|
'bg': _p('localenames|locale:bg', "Bulgarian"),
|
||||||
|
'zh-CN': _p('localenames|locale:zh-CN', "Chinese"),
|
||||||
|
'zh-TW': _p('localenames|locale:zh-TW', "Taiwan Chinese"),
|
||||||
|
'hr': _p('localenames|locale:hr', "Croatian"),
|
||||||
|
'cs': _p('localenames|locale:cs', "Czech"),
|
||||||
|
'da': _p('localenames|locale:da', "Danish"),
|
||||||
|
'nl': _p('localenames|locale:nl', "Dutch"),
|
||||||
|
'fi': _p('localenames|locale:fi', "Finnish"),
|
||||||
|
'fr': _p('localenames|locale:fr', "French"),
|
||||||
|
'de': _p('localenames|locale:de', "German"),
|
||||||
|
'el': _p('localenames|locale:el', "Greek"),
|
||||||
|
'hi': _p('localenames|locale:hi', "Hindi"),
|
||||||
|
'hu': _p('localenames|locale:hu', "Hungarian"),
|
||||||
|
'it': _p('localenames|locale:it', "Italian"),
|
||||||
|
'ja': _p('localenames|locale:ja', "Japanese"),
|
||||||
|
'ko': _p('localenames|locale:ko', "Korean"),
|
||||||
|
'lt': _p('localenames|locale:lt', "Lithuanian"),
|
||||||
|
'no': _p('localenames|locale:no', "Norwegian"),
|
||||||
|
'pl': _p('localenames|locale:pl', "Polish"),
|
||||||
|
'pt-BR': _p('localenames|locale:pt-BR', "Brazil Portuguese"),
|
||||||
|
'ro': _p('localenames|locale:ro', "Romanian"),
|
||||||
|
'ru': _p('localenames|locale:ru', "Russian"),
|
||||||
|
'es-ES': _p('localenames|locale:es-ES', "Spain Spanish"),
|
||||||
|
'sv-SE': _p('localenames|locale:sv-SE', "Swedish"),
|
||||||
|
'th': _p('localenames|locale:th', "Thai"),
|
||||||
|
'tr': _p('localenames|locale:tr', "Turkish"),
|
||||||
|
'uk': _p('localenames|locale:uk', "Ukrainian"),
|
||||||
|
'vi': _p('localenames|locale:vi', "Vietnamese"),
|
||||||
|
}
|
||||||
|
|||||||
144
src/babel/settings.py
Normal file
144
src/babel/settings.py
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
|
||||||
|
from settings import ModelData
|
||||||
|
from settings.setting_types import StringSetting, BoolSetting
|
||||||
|
from settings.groups import SettingGroup
|
||||||
|
|
||||||
|
from meta.errors import UserInputError
|
||||||
|
from core.data import CoreData
|
||||||
|
|
||||||
|
from .translator import ctx_translator
|
||||||
|
from . import babel
|
||||||
|
from .enums import locale_names
|
||||||
|
|
||||||
|
_p = babel._p
|
||||||
|
|
||||||
|
|
||||||
|
class LocaleSetting(StringSetting):
|
||||||
|
"""
|
||||||
|
Base class describing a LocaleSetting.
|
||||||
|
"""
|
||||||
|
@classmethod
|
||||||
|
def _format_data(cls, parent_id, data, **kwargs):
|
||||||
|
t = ctx_translator.get().t
|
||||||
|
if data is None:
|
||||||
|
formatted = t(_p('set_type:locale|formatted:unset', "Unset"))
|
||||||
|
else:
|
||||||
|
name = locale_names.get(data, None)
|
||||||
|
if name:
|
||||||
|
formatted = f"`{data} ({t(name)})`"
|
||||||
|
else:
|
||||||
|
formatted = f"`{data}`"
|
||||||
|
return formatted
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def _parse_string(cls, parent_id, string, **kwargs):
|
||||||
|
translator = ctx_translator.get()
|
||||||
|
if string not in translator.supported_locales:
|
||||||
|
lang = string[:20]
|
||||||
|
raise UserInputError(
|
||||||
|
translator.t(
|
||||||
|
_p('set_type:locale|error', "Sorry, we do not support the language `{lang}` at this time!")
|
||||||
|
).format(lang=lang)
|
||||||
|
)
|
||||||
|
return string
|
||||||
|
|
||||||
|
|
||||||
|
class LocaleSettings(SettingGroup):
|
||||||
|
class UserLocale(ModelData, LocaleSetting):
|
||||||
|
"""
|
||||||
|
User-configured locale.
|
||||||
|
|
||||||
|
Exposed via dedicated setting command.
|
||||||
|
"""
|
||||||
|
setting_id = 'user_locale'
|
||||||
|
|
||||||
|
_display_name = _p('userset:locale', 'language')
|
||||||
|
_desc = _p('userset:locale|desc', "Your preferred language for interacting with me.")
|
||||||
|
|
||||||
|
_model = CoreData.User
|
||||||
|
_column = CoreData.User.locale.name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def update_message(self):
|
||||||
|
t = ctx_translator.get().t
|
||||||
|
if self.data is None:
|
||||||
|
return t(_p('userset:locale|response', "You have unset your language."))
|
||||||
|
else:
|
||||||
|
return t(_p('userset:locale|response', "You have set your language to {lang}.")).format(
|
||||||
|
lang=self.formatted
|
||||||
|
)
|
||||||
|
|
||||||
|
class ForceLocale(ModelData, BoolSetting):
|
||||||
|
"""
|
||||||
|
Guild configuration for whether to force usage of the guild locale.
|
||||||
|
|
||||||
|
Exposed via `/configure language` command and standard configuration interface.
|
||||||
|
"""
|
||||||
|
setting_id = 'force_locale'
|
||||||
|
|
||||||
|
_display_name = _p('guildset:force_locale', 'force_language')
|
||||||
|
_desc = _p('guildset:force_locale|desc',
|
||||||
|
"Whether to force all members to use the configured guild language when interacting with me.")
|
||||||
|
_long_desc = _p(
|
||||||
|
'guildset:force_locale|long_desc',
|
||||||
|
"When enabled, commands in this guild will always use the configured guild language, "
|
||||||
|
"regardless of the member's personally configured language."
|
||||||
|
)
|
||||||
|
_outputs = {
|
||||||
|
True: _p('guildset:force_locale|output', 'Enabled (members will be forced to use the server language)'),
|
||||||
|
False: _p('guildset:force_locale|output', 'Disabled (members may set their own language)'),
|
||||||
|
None: 'Not Set' # This should be impossible, since we have a default
|
||||||
|
}
|
||||||
|
_default = False
|
||||||
|
|
||||||
|
_model = CoreData.Guild
|
||||||
|
_column = CoreData.Guild.force_locale.name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def update_message(self):
|
||||||
|
t = ctx_translator.get().t
|
||||||
|
if self.data:
|
||||||
|
return t(_p(
|
||||||
|
'guildset:force_locale|response',
|
||||||
|
"I will always use the set language in this server."
|
||||||
|
))
|
||||||
|
else:
|
||||||
|
return t(_p(
|
||||||
|
'guildset:force_locale|response',
|
||||||
|
"I will now allow the members to set their own language here."
|
||||||
|
))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _format_data(cls, parent_id, data, **kwargs):
|
||||||
|
t = ctx_translator.get().t
|
||||||
|
return t(cls._outputs[data])
|
||||||
|
|
||||||
|
class GuildLocale(ModelData, LocaleSetting):
|
||||||
|
"""
|
||||||
|
Guild-configured locale.
|
||||||
|
|
||||||
|
Exposed via `/configure language` command, and standard configuration interface.
|
||||||
|
"""
|
||||||
|
setting_id = 'guild_locale'
|
||||||
|
|
||||||
|
_display_name = _p('guildset:locale', 'language')
|
||||||
|
_desc = _p('guildset:locale|desc', "Your preferred language for interacting with me.")
|
||||||
|
_long_desc = _p(
|
||||||
|
'guildset:locale|long_desc',
|
||||||
|
"The default language to use for responses and interactions in this server. "
|
||||||
|
"Member's own configured language will override this for their commands "
|
||||||
|
"unless `force_language` is enabled."
|
||||||
|
)
|
||||||
|
|
||||||
|
_model = CoreData.Guild
|
||||||
|
_column = CoreData.Guild.locale.name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def update_message(self):
|
||||||
|
t = ctx_translator.get().t
|
||||||
|
if self.data is None:
|
||||||
|
return t(_p('guildset:locale|response', "You have unset the guild language."))
|
||||||
|
else:
|
||||||
|
return t(_p('guildset:locale|response', "You have set the guild language to {lang}.")).format(
|
||||||
|
lang=self.formatted
|
||||||
|
)
|
||||||
86
src/babel/settingui.py
Normal file
86
src/babel/settingui.py
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
import asyncio
|
||||||
|
|
||||||
|
import discord
|
||||||
|
from discord.ui.button import button, Button, ButtonStyle
|
||||||
|
|
||||||
|
from meta import LionBot
|
||||||
|
|
||||||
|
from utils.ui import ConfigUI, MessageUI, DashboardSection
|
||||||
|
from utils.lib import MessageArgs
|
||||||
|
|
||||||
|
from .settings import LocaleSettings
|
||||||
|
from . import babel
|
||||||
|
|
||||||
|
_p = babel._p
|
||||||
|
|
||||||
|
|
||||||
|
class LocaleSettingUI(ConfigUI):
|
||||||
|
setting_classes = [
|
||||||
|
LocaleSettings.GuildLocale,
|
||||||
|
LocaleSettings.ForceLocale,
|
||||||
|
]
|
||||||
|
|
||||||
|
def __init__(self, bot: LionBot, guildid: int, channelid: int, **kwargs):
|
||||||
|
self.settings = bot.get_cog('BabelCog').settings
|
||||||
|
super().__init__(bot, guildid, channelid, **kwargs)
|
||||||
|
|
||||||
|
# ----- UI Components -----
|
||||||
|
@button(label="FORCE_BUTTON_PLACEHOLDER", style=ButtonStyle.grey)
|
||||||
|
async def force_button(self, press: discord.Interaction, pressed: Button):
|
||||||
|
await press.response.defer()
|
||||||
|
setting = next(inst for inst in self.instances if inst.setting_id == LocaleSettings.ForceLocale.setting_id)
|
||||||
|
setting.value = not setting.value
|
||||||
|
await setting.write()
|
||||||
|
|
||||||
|
async def force_button_refresh(self):
|
||||||
|
button = self.force_button
|
||||||
|
setting = next(inst for inst in self.instances if inst.setting_id == LocaleSettings.ForceLocale.setting_id)
|
||||||
|
button.label = self.bot.translator.t(_p(
|
||||||
|
'ui:locale_config|button:force|label',
|
||||||
|
"Toggle Force"
|
||||||
|
))
|
||||||
|
button.style = ButtonStyle.green if setting.value else ButtonStyle.grey
|
||||||
|
|
||||||
|
# ----- UI Flow -----
|
||||||
|
async def make_message(self) -> MessageArgs:
|
||||||
|
t = self.bot.translator.t
|
||||||
|
title = t(_p(
|
||||||
|
'ui:locale_config|embed|title',
|
||||||
|
"Language Configuration Panel"
|
||||||
|
))
|
||||||
|
embed = discord.Embed(
|
||||||
|
colour=discord.Colour.orange(),
|
||||||
|
title=title
|
||||||
|
)
|
||||||
|
for setting in self.instances:
|
||||||
|
embed.add_field(**setting.embed_field, inline=False)
|
||||||
|
|
||||||
|
args = MessageArgs(embed=embed)
|
||||||
|
return args
|
||||||
|
|
||||||
|
async def reload(self):
|
||||||
|
lguild = await self.bot.core.lions.fetch_guild(self.guildid)
|
||||||
|
self.instances = tuple(
|
||||||
|
lguild.config.get(setting.setting_id)
|
||||||
|
for setting in self.setting_classes
|
||||||
|
)
|
||||||
|
|
||||||
|
async def refresh_components(self):
|
||||||
|
await asyncio.gather(
|
||||||
|
self.force_button_refresh(),
|
||||||
|
self.edit_button_refresh(),
|
||||||
|
self.close_button_refresh(),
|
||||||
|
self.reset_button_refresh(),
|
||||||
|
)
|
||||||
|
self.set_layout(
|
||||||
|
(self.force_button, self.edit_button, self.reset_button, self.close_button)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class LocaleDashboard(DashboardSection):
|
||||||
|
section_name = _p(
|
||||||
|
'dash:locale|title',
|
||||||
|
"Server Language Configuration"
|
||||||
|
)
|
||||||
|
configui = LocaleSettingUI
|
||||||
|
setting_classes = LocaleSettingUI.setting_classes
|
||||||
@@ -33,6 +33,7 @@ class LeoBabel(Translator):
|
|||||||
locales = conf.babel.get('locales', '')
|
locales = conf.babel.get('locales', '')
|
||||||
stripped = (loc.strip(', ') for loc in locales.split(','))
|
stripped = (loc.strip(', ') for loc in locales.split(','))
|
||||||
self.supported_locales = {loc for loc in stripped if loc}
|
self.supported_locales = {loc for loc in stripped if loc}
|
||||||
|
self.supported_locales.add(SOURCE_LOCALE)
|
||||||
|
|
||||||
domains = conf.babel.get('domains', '')
|
domains = conf.babel.get('domains', '')
|
||||||
stripped = (dom.strip(', ') for dom in domains.split(','))
|
stripped = (dom.strip(', ') for dom in domains.split(','))
|
||||||
|
|||||||
@@ -53,8 +53,9 @@ async def main():
|
|||||||
db=db,
|
db=db,
|
||||||
config=conf,
|
config=conf,
|
||||||
initial_extensions=[
|
initial_extensions=[
|
||||||
'utils', 'core', 'analytics', 'babel',
|
'utils', 'core', 'analytics',
|
||||||
'modules',
|
'modules',
|
||||||
|
'babel',
|
||||||
'tracking.voice', 'tracking.text',
|
'tracking.voice', 'tracking.text',
|
||||||
],
|
],
|
||||||
web_client=session,
|
web_client=session,
|
||||||
@@ -62,6 +63,7 @@ async def main():
|
|||||||
testing_guilds=conf.bot.getintlist('admin_guilds'),
|
testing_guilds=conf.bot.getintlist('admin_guilds'),
|
||||||
shard_id=sharding.shard_number,
|
shard_id=sharding.shard_number,
|
||||||
shard_count=sharding.shard_count,
|
shard_count=sharding.shard_count,
|
||||||
|
help_command=None,
|
||||||
translator=translator
|
translator=translator
|
||||||
) as lionbot:
|
) as lionbot:
|
||||||
ctx_bot.set(lionbot)
|
ctx_bot.set(lionbot)
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ from tracking.text.ui import TextTrackerDashboard
|
|||||||
from modules.ranks.ui.config import RankDashboard
|
from modules.ranks.ui.config import RankDashboard
|
||||||
from modules.pomodoro.settingui import TimerDashboard
|
from modules.pomodoro.settingui import TimerDashboard
|
||||||
from modules.rooms.settingui import RoomDashboard
|
from modules.rooms.settingui import RoomDashboard
|
||||||
|
from babel.settingui import LocaleDashboard
|
||||||
# from modules.statistics.settings import StatisticsConfigUI
|
# from modules.statistics.settings import StatisticsConfigUI
|
||||||
|
|
||||||
from . import babel, logger
|
from . import babel, logger
|
||||||
@@ -28,7 +29,7 @@ class GuildDashboard(BasePager):
|
|||||||
Paged UI providing an overview of the guild configuration.
|
Paged UI providing an overview of the guild configuration.
|
||||||
"""
|
"""
|
||||||
pages = [
|
pages = [
|
||||||
(EconomyDashboard, TasklistDashboard),
|
(LocaleDashboard, EconomyDashboard, TasklistDashboard),
|
||||||
(VoiceTrackerDashboard, TextTrackerDashboard, ),
|
(VoiceTrackerDashboard, TextTrackerDashboard, ),
|
||||||
(RankDashboard, TimerDashboard, RoomDashboard, )
|
(RankDashboard, TimerDashboard, RoomDashboard, )
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -176,3 +176,11 @@ class UserConfigCog(LionCog):
|
|||||||
)
|
)
|
||||||
choices.append(choice)
|
choices.append(choice)
|
||||||
return choices
|
return choices
|
||||||
|
|
||||||
|
@cmds.hybrid_group(
|
||||||
|
name=_p('cmd:userconfig', "my"),
|
||||||
|
description=_p('cmd:userconfig|desc', "User configuration commands.")
|
||||||
|
)
|
||||||
|
async def userconfig_group(self, ctx: LionContext):
|
||||||
|
# Group base command, no function.
|
||||||
|
pass
|
||||||
|
|||||||
Reference in New Issue
Block a user