feat(skins): Implement CustomSkin editor.
This commit is contained in:
@@ -13,7 +13,7 @@ from aiohttp import ClientSession
|
||||
from data import Database
|
||||
from utils.lib import tabulate
|
||||
from gui.errors import RenderingException
|
||||
from babel.translator import ctx_locale
|
||||
from babel.translator import ctx_locale, LeoBabel
|
||||
|
||||
from .config import Conf
|
||||
from .logger import logging_context, log_context, log_action_stack, log_wrap, set_logging_context
|
||||
@@ -54,9 +54,9 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
class LionBot(Bot):
|
||||
def __init__(
|
||||
self, *args, appname: str, shardname: str, db: Database, config: Conf,
|
||||
self, *args, appname: str, shardname: str, db: Database, config: Conf, translator: LeoBabel,
|
||||
initial_extensions: List[str], web_client: ClientSession, app_ipc,
|
||||
testing_guilds: List[int] = [], translator=None, **kwargs
|
||||
testing_guilds: List[int] = [], **kwargs
|
||||
):
|
||||
kwargs.setdefault('tree_cls', LionTree)
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
@@ -10,6 +10,7 @@ from frozendict import frozendict
|
||||
|
||||
|
||||
from meta import LionCog, LionBot, LionContext
|
||||
from meta.errors import UserInputError
|
||||
from meta.logger import log_wrap
|
||||
from utils.lib import MISSING, utc_now
|
||||
from wards import sys_admin_ward, low_management_ward
|
||||
@@ -22,6 +23,7 @@ from .skinlib import appskin_as_choice, FrozenCustomSkin, CustomSkin
|
||||
from .settings import GlobalSkinSettings
|
||||
from .settingui import GlobalSkinSettingUI
|
||||
from .userskinui import UserSkinUI
|
||||
from .editor.skineditor import CustomSkinEditor
|
||||
|
||||
_p = babel._p
|
||||
|
||||
@@ -46,6 +48,8 @@ class CustomSkinCog(LionCog):
|
||||
# Cache of custom skin id -> frozen custom skin
|
||||
self.custom_skins: LRUCache[int, FrozenCustomSkin] = LRUCache(maxsize=1000)
|
||||
|
||||
self.current_default: Optional[str] = None
|
||||
|
||||
async def cog_load(self):
|
||||
await self.data.init()
|
||||
|
||||
@@ -61,6 +65,7 @@ class CustomSkinCog(LionCog):
|
||||
|
||||
await self._reload_appskins()
|
||||
await self._reload_property_map()
|
||||
await self.get_default_skin()
|
||||
|
||||
async def _reload_property_map(self):
|
||||
"""
|
||||
@@ -123,6 +128,7 @@ class CustomSkinCog(LionCog):
|
||||
"""
|
||||
setting = self.bot_settings.DefaultSkin
|
||||
instance = await setting.get(self.bot.appname)
|
||||
self.current_default = instance.value
|
||||
return instance.value
|
||||
|
||||
async def fetch_property_ids(self, *card_properties: tuple[str, str]) -> list[int]:
|
||||
@@ -203,7 +209,7 @@ class CustomSkinCog(LionCog):
|
||||
skin_args = await self.args_for_skin(skinid, card_id)
|
||||
args.update(skin_args)
|
||||
|
||||
default = await self.get_default_skin()
|
||||
default = self.current_default
|
||||
if default:
|
||||
args.setdefault("base_skin_id", default)
|
||||
|
||||
@@ -224,11 +230,20 @@ class CustomSkinCog(LionCog):
|
||||
Update cached args for given custom skin id.
|
||||
"""
|
||||
self.custom_skins.pop(skinid, None)
|
||||
custom_skin = await CustomSkin.fetch(skinid)
|
||||
custom_skin = await CustomSkin.fetch(self.bot, skinid)
|
||||
if custom_skin is not None:
|
||||
skin = custom_skin.freeze()
|
||||
self.custom_skins[skinid] = skin
|
||||
|
||||
@LionCog.listener('on_botset_skin')
|
||||
async def handle_botset_skin(self, appname, instance):
|
||||
await self.bot.global_dispatch('global_botset_skin', appname)
|
||||
|
||||
@LionCog.listener('on_global_botset_skin')
|
||||
async def refresh_default_skin(self, appname):
|
||||
await self.bot.core.data.BotConfig.fetch(appname, cached=False)
|
||||
await self.get_default_skin()
|
||||
|
||||
# ----- Userspace commands -----
|
||||
@LionCog.placeholder_group
|
||||
@cmds.hybrid_group("my", with_app_command=False)
|
||||
@@ -268,8 +283,40 @@ class CustomSkinCog(LionCog):
|
||||
return
|
||||
if not ctx.guild:
|
||||
return
|
||||
# TODO
|
||||
...
|
||||
t = self.bot.translator.t
|
||||
|
||||
# Check guild premium status
|
||||
premiumcog = self.bot.get_cog('PremiumCog')
|
||||
guild_row = await premiumcog.data.PremiumGuild.fetch(ctx.guild.id, cached=False)
|
||||
|
||||
if not guild_row:
|
||||
raise UserInputError(
|
||||
t(_p(
|
||||
'cmd:admin_brand|error:not_premium',
|
||||
"Only premium servers can modify their interface theme! "
|
||||
"Use the {premium} command to upgrade your server."
|
||||
)).format(premium=self.bot.core.mention_cmd('premium'))
|
||||
)
|
||||
|
||||
await ctx.interaction.response.defer(thinking=True, ephemeral=False)
|
||||
|
||||
if guild_row.custom_skin_id is None:
|
||||
# Create new custom skin
|
||||
skin_data = await self.data.CustomisedSkin.create(
|
||||
base_skin_id=self.appskin_names.inverse[self.current_default] if self.current_default else None
|
||||
)
|
||||
await guild_row.update(custom_skin_id=skin_data.custom_skin_id)
|
||||
|
||||
skinid = guild_row.custom_skin_id
|
||||
custom_skin = await CustomSkin.fetch(self.bot, skinid)
|
||||
if custom_skin is None:
|
||||
raise ValueError("Invalid custom skin id")
|
||||
|
||||
# Open the CustomSkinEditor with this skin
|
||||
ui = CustomSkinEditor(custom_skin, callerid=ctx.author.id)
|
||||
await ui.send(ctx.channel)
|
||||
await ctx.interaction.delete_original_response()
|
||||
await ui.wait()
|
||||
|
||||
# ----- Owner commands -----
|
||||
@LionCog.placeholder_group
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
from typing import Optional
|
||||
from dataclasses import dataclass, field
|
||||
|
||||
import uuid
|
||||
import discord
|
||||
from discord.components import SelectOption
|
||||
|
||||
from babel.translator import LazyStr
|
||||
from gui.base.Card import Card
|
||||
from utils.lib import EmbedField, tabulate
|
||||
|
||||
from .skinsetting import SettingInputType, Setting
|
||||
from ..skinlib import CustomSkin
|
||||
|
||||
|
||||
@dataclass
|
||||
class SettingGroup:
|
||||
"""
|
||||
Data class representing a collection of settings which are naturally
|
||||
grouped together at interface level.
|
||||
|
||||
Typically the settings in a single SettingGroup are displayed
|
||||
in the same embed field, the settings are edited with the same modal,
|
||||
and the group represents a single option in the "setting group menu".
|
||||
|
||||
Setting groups do not correspond to any grouping at the Card or Skin level,
|
||||
and may cross multiple cards.
|
||||
"""
|
||||
|
||||
# The name and description strings are shown in the embed field and menu option
|
||||
name: LazyStr
|
||||
|
||||
# Tuple of settings that are part of this setting group
|
||||
settings: tuple[Setting, ...]
|
||||
|
||||
description: Optional[LazyStr] = None
|
||||
|
||||
# Whether the group should be displayed in a group or not
|
||||
ungrouped: bool = False
|
||||
|
||||
# Whether the embed field should be inline
|
||||
inline: bool = True
|
||||
|
||||
# Component custom id to identify the editing component
|
||||
# Also used as the value of the select option
|
||||
custom_id: str = str(uuid.uuid4())
|
||||
|
||||
@property
|
||||
def editable_settings(self):
|
||||
return tuple(setting for setting in self.settings if setting.input_type is SettingInputType.ModalInput)
|
||||
|
||||
def embed_field_for(self, skin: CustomSkin) -> EmbedField:
|
||||
"""
|
||||
Tabulates the contained settings and builds an embed field for the editor UI.
|
||||
"""
|
||||
t = skin.bot.translator.t
|
||||
|
||||
rows: list[tuple[str, str]] = []
|
||||
for setting in self.settings:
|
||||
name = t(setting.display_name)
|
||||
value = setting.value_in(skin) or setting.default_value_in(skin)
|
||||
formatted = setting.format_value_in(skin, value)
|
||||
rows.append((name, formatted))
|
||||
|
||||
lines = tabulate(*rows)
|
||||
table = '\n'.join(lines)
|
||||
|
||||
description = f"*{t(self.description)}*" if self.description else ''
|
||||
|
||||
embed_field = EmbedField(
|
||||
name=t(self.name),
|
||||
value=f"{description}\n{table}",
|
||||
inline=self.inline,
|
||||
)
|
||||
return embed_field
|
||||
|
||||
def select_option_for(self, skin: CustomSkin) -> SelectOption:
|
||||
"""
|
||||
Makes a SelectOption referring to this setting group.
|
||||
"""
|
||||
t = skin.bot.translator.t
|
||||
option = SelectOption(
|
||||
label=t(self.name),
|
||||
description=t(self.description) if self.description else None,
|
||||
value=self.custom_id,
|
||||
)
|
||||
return option
|
||||
|
||||
|
||||
@dataclass
|
||||
class Page:
|
||||
"""
|
||||
Represents a page of skin settings for the skin editor UI.
|
||||
"""
|
||||
# Various string attributes of the page
|
||||
display_name: LazyStr
|
||||
editing_description: Optional[LazyStr] = None
|
||||
preview_description: Optional[LazyStr] = None
|
||||
|
||||
visible_in_preview: bool = True
|
||||
render_card: Optional[type[Card]] = None
|
||||
|
||||
groups: list[SettingGroup] = field(default_factory=list)
|
||||
|
||||
def make_embed_for(self, skin: CustomSkin) -> discord.Embed:
|
||||
t = skin.bot.translator.t
|
||||
|
||||
embed = discord.Embed(
|
||||
colour=discord.Colour.orange(),
|
||||
title=t(self.display_name),
|
||||
)
|
||||
|
||||
description_lines: list[str] = []
|
||||
field_counter = 0
|
||||
|
||||
for group in self.groups:
|
||||
field = group.embed_field_for(skin)
|
||||
if group.ungrouped:
|
||||
description_lines.append(field.value)
|
||||
else:
|
||||
embed.add_field(**field._asdict())
|
||||
if not (field_counter) % 3:
|
||||
embed.add_field(name='', value='')
|
||||
field_counter += 1
|
||||
field_counter += 1
|
||||
|
||||
if description_lines:
|
||||
embed.description = '\n'.join(description_lines)
|
||||
|
||||
if self.render_card is not None:
|
||||
embed.set_image(url='attachment://sample.png')
|
||||
|
||||
return embed
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
from .stats import stats_page
|
||||
from .profile import profile_page
|
||||
from .summary import summary_page
|
||||
from .weekly import weekly_page
|
||||
from .monthly import monthly_page
|
||||
from .weekly_goals import weekly_goal_page
|
||||
from .monthly_goals import monthly_goal_page
|
||||
from .leaderboard import leaderboard_page
|
||||
|
||||
|
||||
pages = [
|
||||
profile_page, stats_page,
|
||||
weekly_page, monthly_page,
|
||||
weekly_goal_page, monthly_goal_page,
|
||||
leaderboard_page,
|
||||
]
|
||||
|
||||
@@ -0,0 +1,294 @@
|
||||
from gui.cards import LeaderboardCard
|
||||
|
||||
from ... import babel
|
||||
from ..skinsetting import ColourSetting, SkinSetting, ColoursSetting
|
||||
from ..layout import Page, SettingGroup
|
||||
|
||||
_p = babel._p
|
||||
|
||||
"""
|
||||
top_position_colour
|
||||
top_name_colour
|
||||
top_hours_colour
|
||||
|
||||
entry_position_colour
|
||||
entry_position_highlight_colour
|
||||
entry_name_colour
|
||||
entry_hours_colour
|
||||
|
||||
header_text_colour
|
||||
[subheader_name_colour, subheader_value_colour]
|
||||
|
||||
entry_bg_colour
|
||||
entry_bg_highlight_colour
|
||||
"""
|
||||
|
||||
leaderboard_page = Page(
|
||||
display_name=_p('skinsettings|page:leaderboard|display_name', "Leaderboard"),
|
||||
editing_description=_p(
|
||||
'skinsettings|page:leaderboard|edit_desc',
|
||||
"Options for the Leaderboard pages."
|
||||
),
|
||||
preview_description=None,
|
||||
visible_in_preview=True,
|
||||
render_card=LeaderboardCard
|
||||
)
|
||||
|
||||
header_text_colour = ColourSetting(
|
||||
card=LeaderboardCard,
|
||||
property_name='header_text_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:leaderboard|set:header_text_colour|display_name',
|
||||
"Header"
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:leaderboard|set:header_text_colour|desc',
|
||||
"Text colour of the leaderboard header."
|
||||
)
|
||||
)
|
||||
|
||||
subheader_name_colour = ColourSetting(
|
||||
card=LeaderboardCard,
|
||||
property_name='subheader_name_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:leaderboard|set:subheader_name_colour|display_name',
|
||||
""
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:leaderboard|set:subheader_name_colour|desc',
|
||||
""
|
||||
)
|
||||
)
|
||||
|
||||
subheader_value_colour = ColourSetting(
|
||||
card=LeaderboardCard,
|
||||
property_name='subheader_value_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:leaderboard|set:subheader_value_colour|display_name',
|
||||
""
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:leaderboard|set:subheader_value_colour|desc',
|
||||
""
|
||||
)
|
||||
)
|
||||
|
||||
subheader_colour = ColoursSetting(
|
||||
subheader_value_colour,
|
||||
subheader_name_colour,
|
||||
display_name=_p(
|
||||
'skinsettings|page:leaderboard|set:subheader_colour|display_name',
|
||||
"Sub-Header"
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:leaderboard|set:subheader_colour|desc',
|
||||
"Text colour of the sub-header line."
|
||||
)
|
||||
)
|
||||
|
||||
top_position_colour = ColourSetting(
|
||||
card=LeaderboardCard,
|
||||
property_name='top_position_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:leaderboard|set:top_position_colour|display_name',
|
||||
"Position"
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:leaderboard|set:top_position_colour|desc',
|
||||
"Top 3 position colour."
|
||||
)
|
||||
)
|
||||
|
||||
top_name_colour = ColourSetting(
|
||||
card=LeaderboardCard,
|
||||
property_name='top_name_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:leaderboard|set:top_name_colour|display_name',
|
||||
"Name"
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:leaderboard|set:top_name_colour|desc',
|
||||
"Top 3 name colour."
|
||||
)
|
||||
)
|
||||
|
||||
top_hours_colour = ColourSetting(
|
||||
card=LeaderboardCard,
|
||||
property_name='top_hours_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:leaderboard|set:top_hours_colour|display_name',
|
||||
"Hours"
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:leaderboard|set:top_hours_colour|desc',
|
||||
"Top 3 hours colour."
|
||||
)
|
||||
)
|
||||
|
||||
entry_position_colour = ColourSetting(
|
||||
card=LeaderboardCard,
|
||||
property_name='entry_position_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:leaderboard|set:entry_position_colour|display_name',
|
||||
"Position"
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:leaderboard|set:entry_position_colour|desc',
|
||||
"Position text colour."
|
||||
)
|
||||
)
|
||||
|
||||
entry_position_highlight_colour = ColourSetting(
|
||||
card=LeaderboardCard,
|
||||
property_name='entry_position_highlight_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:leaderboard|set:entry_position_highlight_colour|display_name',
|
||||
"Position (HL)"
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:leaderboard|set:entry_position_highlight_colour|desc',
|
||||
"Highlighted position colour."
|
||||
)
|
||||
)
|
||||
|
||||
entry_name_colour = ColourSetting(
|
||||
card=LeaderboardCard,
|
||||
property_name='entry_name_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:leaderboard|set:entry_name_colour|display_name',
|
||||
"Name"
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:leaderboard|set:entry_name_colour|desc',
|
||||
"Entry name colour."
|
||||
)
|
||||
)
|
||||
|
||||
entry_hours_colour = ColourSetting(
|
||||
card=LeaderboardCard,
|
||||
property_name='entry_hours_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:leaderboard|set:entry_hours_colour|display_name',
|
||||
"Hours"
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:leaderboard|set:entry_hours_colour|desc',
|
||||
"Entry hours colour."
|
||||
)
|
||||
)
|
||||
|
||||
entry_bg_colour = ColourSetting(
|
||||
card=LeaderboardCard,
|
||||
property_name='entry_bg_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:leaderboard|set:entry_bg_colour|display_name',
|
||||
"Regular"
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:leaderboard|set:entry_bg_colour|desc',
|
||||
"Background colour of regular entries."
|
||||
)
|
||||
)
|
||||
|
||||
entry_bg_highlight_colour = ColourSetting(
|
||||
card=LeaderboardCard,
|
||||
property_name='entry_bg_highlight_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:leaderboard|set:entry_bg_highlight_colour|display_name',
|
||||
"Highlighted"
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:leaderboard|set:entry_bg_highlight_colour|desc',
|
||||
"Background colour of highlighted entries."
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
top_colour_group = SettingGroup(
|
||||
_p('skinsettings|page:leaderboard|grp:top_colour', "Top 3"),
|
||||
description=_p(
|
||||
'skinsettings|page:leaderboard|grp:top_colour|desc',
|
||||
"Customise the text colours for the top 3 positions."
|
||||
),
|
||||
custom_id='leaderboard-top',
|
||||
settings=(
|
||||
top_position_colour,
|
||||
top_name_colour,
|
||||
top_hours_colour
|
||||
)
|
||||
)
|
||||
|
||||
entry_text_group = SettingGroup(
|
||||
_p('skinsettings|page:leaderboard|grp:entry_text', "Entry Text"),
|
||||
description=_p(
|
||||
'skinsettings|page:leaderboard|grp:entry_text|desc',
|
||||
"Text colours of the leaderboard entries."
|
||||
),
|
||||
custom_id='leaderboard-text',
|
||||
settings=(
|
||||
entry_position_colour,
|
||||
entry_position_highlight_colour,
|
||||
entry_name_colour,
|
||||
entry_hours_colour
|
||||
)
|
||||
)
|
||||
|
||||
entry_bg_group = SettingGroup(
|
||||
_p('skinsettings|page:leaderboard|grp:entry_bg', "Entry Background"),
|
||||
description=_p(
|
||||
'skinsettings|page:leaderboard|grp:entry_bg|desc',
|
||||
"Background colours of the leaderboard entries."
|
||||
),
|
||||
custom_id='leaderboard-bg',
|
||||
settings=(
|
||||
entry_bg_colour,
|
||||
entry_bg_highlight_colour
|
||||
)
|
||||
)
|
||||
|
||||
misc_group = SettingGroup(
|
||||
_p('skinsettings|page:leaderboard|grp:misc', "Miscellaneous"),
|
||||
description=_p(
|
||||
'skinsettings|page:leaderboard|grp:misc|desc',
|
||||
"Other miscellaneous colour settings."
|
||||
),
|
||||
custom_id='leaderboard-misc',
|
||||
settings=(
|
||||
header_text_colour,
|
||||
subheader_colour
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
base_skin = SkinSetting(
|
||||
card=LeaderboardCard,
|
||||
property_name='base_skin_id',
|
||||
display_name=_p(
|
||||
'skinsettings|page:leaderboard|set:base_skin|display_name',
|
||||
'Skin'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:leaderboard|set:base_skin|desc',
|
||||
"Select a Skin Preset."
|
||||
)
|
||||
)
|
||||
|
||||
base_skin_group = SettingGroup(
|
||||
_p('skinsettings|page:leaderboard|grp:base_skin', "Leaderboard Skin"),
|
||||
description=_p(
|
||||
'skinsettings|page:leaderboard|grp:base_skin|desc',
|
||||
"Asset pack and default values for the Leaderboard."
|
||||
),
|
||||
custom_id='leaderboard-skin',
|
||||
settings=(base_skin,),
|
||||
ungrouped=True
|
||||
)
|
||||
|
||||
leaderboard_page.groups = [
|
||||
base_skin_group,
|
||||
top_colour_group,
|
||||
entry_text_group,
|
||||
entry_bg_group,
|
||||
misc_group
|
||||
]
|
||||
|
||||
|
||||
@@ -0,0 +1,376 @@
|
||||
from gui.cards import MonthlyStatsCard
|
||||
|
||||
from ... import babel
|
||||
from ..skinsetting import ColourSetting, SkinSetting, ColoursSetting
|
||||
from ..layout import Page, SettingGroup
|
||||
|
||||
_p = babel._p
|
||||
|
||||
""""
|
||||
title_colour
|
||||
[this_month_colour, last_month_colour]
|
||||
[stats_key_colour, stats_value_colour]
|
||||
footer_colour
|
||||
|
||||
top_hours_colour
|
||||
top_hours_bg_colour
|
||||
top_date_colour
|
||||
top_line_colour
|
||||
|
||||
top_this_colour
|
||||
top_this_hours_colour
|
||||
top_last_colour
|
||||
top_last_hours_colour
|
||||
|
||||
weekday_background_colour
|
||||
weekday_colour
|
||||
month_background_colour
|
||||
month_colour
|
||||
"""
|
||||
|
||||
monthly_page = Page(
|
||||
display_name=_p('skinsettings|page:monthly|display_name', "Monthly Statistics"),
|
||||
editing_description=_p(
|
||||
'skinsettings|page:monthly|edit_desc',
|
||||
"Options for the monthly statistis card."
|
||||
),
|
||||
preview_description=None,
|
||||
visible_in_preview=True,
|
||||
render_card=MonthlyStatsCard
|
||||
)
|
||||
|
||||
|
||||
title_colour = ColourSetting(
|
||||
card=MonthlyStatsCard,
|
||||
property_name='title_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly|set:title_colour|display_name',
|
||||
'Title'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly|set:title_colour|desc',
|
||||
"Colour of the card title."
|
||||
)
|
||||
)
|
||||
top_hours_colour = ColourSetting(
|
||||
card=MonthlyStatsCard,
|
||||
property_name='top_hours_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly|set:top_hours_colour|display_name',
|
||||
'Hours'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly|set:top_hours_colour|desc',
|
||||
"Hour axis labels."
|
||||
)
|
||||
)
|
||||
top_hours_bg_colour = ColourSetting(
|
||||
card=MonthlyStatsCard,
|
||||
property_name='top_hours_bg_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly|set:top_hours_bg_colour|display_name',
|
||||
'Hours Bg'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly|set:top_hours_bg_colour|desc',
|
||||
"Hour axis label background."
|
||||
)
|
||||
)
|
||||
top_line_colour = ColourSetting(
|
||||
card=MonthlyStatsCard,
|
||||
property_name='top_line_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly|set:top_line_colour|display_name',
|
||||
'Lines'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly|set:top_line_colour|desc',
|
||||
"Horizontal graph lines."
|
||||
)
|
||||
)
|
||||
top_date_colour = ColourSetting(
|
||||
card=MonthlyStatsCard,
|
||||
property_name='top_date_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly|set:top_date_colour|display_name',
|
||||
'Days'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly|set:top_date_colour|desc',
|
||||
"Day axis labels."
|
||||
)
|
||||
)
|
||||
top_this_colour = ColourSetting(
|
||||
card=MonthlyStatsCard,
|
||||
property_name='top_this_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly|set:top_this_colour|display_name',
|
||||
'This Month Bar'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly|set:top_this_colour|desc',
|
||||
"This month bar fill colour."
|
||||
)
|
||||
)
|
||||
top_last_colour = ColourSetting(
|
||||
card=MonthlyStatsCard,
|
||||
property_name='top_last_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly|set:top_last_colour|display_name',
|
||||
'Last Month Bar'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly|set:top_last_colour|desc',
|
||||
"Last month bar fill colour."
|
||||
)
|
||||
)
|
||||
top_this_hours_colour = ColourSetting(
|
||||
card=MonthlyStatsCard,
|
||||
property_name='top_this_hours_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly|set:top_this_hours_colour|display_name',
|
||||
'This Month Hours'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly|set:top_this_hours_colour|desc',
|
||||
"This month hour text."
|
||||
)
|
||||
)
|
||||
top_last_hours_colour = ColourSetting(
|
||||
card=MonthlyStatsCard,
|
||||
property_name='top_last_hours_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly|set:top_last_hours_colour|display_name',
|
||||
'Last Month Hours'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly|set:top_last_hours_colour|desc',
|
||||
"Last month hour text."
|
||||
)
|
||||
)
|
||||
this_month_colour = ColourSetting(
|
||||
card=MonthlyStatsCard,
|
||||
property_name='this_month_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly|set:this_month_colour|display_name',
|
||||
'This Month Legend'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly|set:this_month_colour|desc',
|
||||
"This month legend text."
|
||||
)
|
||||
)
|
||||
last_month_colour = ColourSetting(
|
||||
card=MonthlyStatsCard,
|
||||
property_name='last_month_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly|set:last_month_colour|display_name',
|
||||
'Last Month Legend'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly|set:last_month_colour|desc',
|
||||
"Last month legend text."
|
||||
)
|
||||
)
|
||||
legend_colour = ColoursSetting(
|
||||
this_month_colour,
|
||||
last_month_colour,
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly|set:legend_colour|display_name',
|
||||
'Legend'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly|set:legend_colour|desc',
|
||||
"Legend text colour."
|
||||
)
|
||||
)
|
||||
|
||||
weekday_background_colour = ColourSetting(
|
||||
card=MonthlyStatsCard,
|
||||
property_name='weekday_background_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly|set:weekday_background_colour|display_name',
|
||||
'Weekday Bg'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly|set:weekday_background_colour|desc',
|
||||
"Weekday axis background colour."
|
||||
)
|
||||
)
|
||||
weekday_colour = ColourSetting(
|
||||
card=MonthlyStatsCard,
|
||||
property_name='weekday_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly|set:weekday_colour|display_name',
|
||||
'Weekdays'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly|set:weekday_colour|desc',
|
||||
"Weekday axis labels."
|
||||
)
|
||||
)
|
||||
month_background_colour = ColourSetting(
|
||||
card=MonthlyStatsCard,
|
||||
property_name='month_background_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly|set:month_background_colour|display_name',
|
||||
'Month Bg'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly|set:month_background_colour|desc',
|
||||
"Month axis label backgrounds."
|
||||
)
|
||||
)
|
||||
month_colour = ColourSetting(
|
||||
card=MonthlyStatsCard,
|
||||
property_name='month_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly|set:month_colour|display_name',
|
||||
'Months'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly|set:month_colour|desc',
|
||||
"Month axis label text."
|
||||
)
|
||||
)
|
||||
stats_key_colour = ColourSetting(
|
||||
card=MonthlyStatsCard,
|
||||
property_name='stats_key_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly|set:stats_key_colour|display_name',
|
||||
'Stat Names'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly|set:stats_key_colour|desc',
|
||||
""
|
||||
)
|
||||
)
|
||||
stats_value_colour = ColourSetting(
|
||||
card=MonthlyStatsCard,
|
||||
property_name='stats_value_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly|set:stats_value_colour|display_name',
|
||||
'Stat Values'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly|set:stats_value_colour|desc',
|
||||
""
|
||||
)
|
||||
)
|
||||
statistics_colour = ColoursSetting(
|
||||
stats_key_colour,
|
||||
stats_value_colour,
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly|set:statistics_colour|display_name',
|
||||
'Statistics'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly|set:statistics_colour|desc',
|
||||
"Summary Statistics"
|
||||
)
|
||||
)
|
||||
footer_colour = ColourSetting(
|
||||
card=MonthlyStatsCard,
|
||||
property_name='footer_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly|set:footer_colour|display_name',
|
||||
'Footer'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly|set:footer_colour|desc',
|
||||
"Footer text colour."
|
||||
)
|
||||
)
|
||||
|
||||
top_graph_group = SettingGroup(
|
||||
_p('skinsettings|page:monthly|grp:top_graph', "Top Graph"),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly|grp:top_graph|desc',
|
||||
"Customise the axis and style of the top graph."
|
||||
),
|
||||
custom_id='monthly-top',
|
||||
settings=(
|
||||
top_hours_colour,
|
||||
top_hours_bg_colour,
|
||||
top_date_colour,
|
||||
top_line_colour
|
||||
)
|
||||
)
|
||||
|
||||
top_hours_group = SettingGroup(
|
||||
_p('skinsettings|page:monthly|grp:top_hours', "Hours"),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly|grp:top_hours|desc',
|
||||
"Customise the colour of this week and last week."
|
||||
),
|
||||
custom_id='monthly-hours',
|
||||
settings=(
|
||||
top_this_colour,
|
||||
top_this_hours_colour,
|
||||
top_last_colour,
|
||||
top_last_hours_colour
|
||||
)
|
||||
)
|
||||
|
||||
bottom_graph_group = SettingGroup(
|
||||
_p('skinsettings|page:monthly|grp:bottom_graph', "Heatmap"),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly|grp:bottom_graph|desc',
|
||||
"Customise the axis and style of the heatmap."
|
||||
),
|
||||
custom_id='monthly-heatmap',
|
||||
settings=(
|
||||
weekday_background_colour,
|
||||
weekday_colour,
|
||||
month_background_colour,
|
||||
month_colour
|
||||
)
|
||||
)
|
||||
|
||||
misc_group = SettingGroup(
|
||||
_p('skinsettings|page:monthly|grp:misc', "Miscellaneous"),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly|grp:misc|desc',
|
||||
"Miscellaneous colour options."
|
||||
),
|
||||
custom_id='monthly-misc',
|
||||
settings=(
|
||||
title_colour,
|
||||
legend_colour,
|
||||
statistics_colour,
|
||||
footer_colour
|
||||
)
|
||||
)
|
||||
|
||||
base_skin = SkinSetting(
|
||||
card=MonthlyStatsCard,
|
||||
property_name='base_skin_id',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly|set:base_skin|display_name',
|
||||
'Skin'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly|set:base_skin|desc',
|
||||
"Select a Skin Preset."
|
||||
)
|
||||
)
|
||||
|
||||
base_skin_group = SettingGroup(
|
||||
_p('skinsettings|page:monthly|grp:base_skin', "Monthly Stats Skin"),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly|grp:base_skin|desc',
|
||||
"Asset pack and default values for the Monthly Statistics."
|
||||
),
|
||||
custom_id='monthly-skin',
|
||||
settings=(base_skin,),
|
||||
ungrouped=True
|
||||
)
|
||||
|
||||
monthly_page.groups = [
|
||||
base_skin_group,
|
||||
top_graph_group,
|
||||
top_hours_group,
|
||||
bottom_graph_group,
|
||||
misc_group
|
||||
]
|
||||
|
||||
|
||||
@@ -0,0 +1,436 @@
|
||||
from gui.cards import MonthlyGoalCard
|
||||
|
||||
from ... import babel
|
||||
from ..skinsetting import ColourSetting, SkinSetting, ColoursSetting
|
||||
from ..layout import Page, SettingGroup
|
||||
|
||||
_p = babel._p
|
||||
|
||||
"""
|
||||
mini_profile_name_colour
|
||||
mini_profile_badge_colour
|
||||
mini_profile_badge_text_colour
|
||||
mini_profile_discrim_colour
|
||||
|
||||
title_colour
|
||||
footer_colour
|
||||
|
||||
progress_bg_colour
|
||||
progress_colour
|
||||
[attendance_rate_colour, task_count_colour, studied_hour_colour]
|
||||
[attendance_colour, task_done_colour, studied_text_colour, task_goal_colour]
|
||||
task_goal_number_colour
|
||||
|
||||
task_header_colour
|
||||
task_done_number_colour
|
||||
task_undone_number_colour
|
||||
task_done_text_colour
|
||||
task_undone_text_colour
|
||||
"""
|
||||
|
||||
monthly_goal_page = Page(
|
||||
display_name=_p('skinsettings|page:monthly_goal|display_name', "Monthly Goals"),
|
||||
editing_description=_p(
|
||||
'skinsettings|page:monthly_goal|edit_desc',
|
||||
"Options for the monthly goal card."
|
||||
),
|
||||
preview_description=None,
|
||||
visible_in_preview=True,
|
||||
render_card=MonthlyGoalCard
|
||||
)
|
||||
|
||||
title_colour = ColourSetting(
|
||||
card=MonthlyGoalCard,
|
||||
property_name='title_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly_goal|set:title_colour|display_name',
|
||||
"Title"
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly_goal|set:title_colour|desc',
|
||||
""
|
||||
)
|
||||
)
|
||||
|
||||
progress_bg_colour = ColourSetting(
|
||||
card=MonthlyGoalCard,
|
||||
property_name='progress_bg_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly_goal|set:progress_bg_colour|display_name',
|
||||
"Bar Bg"
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly_goal|set:progress_bg_colour|desc',
|
||||
""
|
||||
)
|
||||
)
|
||||
|
||||
progress_colour = ColourSetting(
|
||||
card=MonthlyGoalCard,
|
||||
property_name='progress_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly_goal|set:progress_colour|display_name',
|
||||
"Bar Fg"
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly_goal|set:progress_colour|desc',
|
||||
""
|
||||
)
|
||||
)
|
||||
|
||||
attendance_rate_colour = ColourSetting(
|
||||
card=MonthlyGoalCard,
|
||||
property_name='attendance_rate_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly_goal|set:attendance_rate_colour|display_name',
|
||||
""
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly_goal|set:attendance_rate_colour|desc',
|
||||
""
|
||||
)
|
||||
)
|
||||
|
||||
attendance_colour = ColourSetting(
|
||||
card=MonthlyGoalCard,
|
||||
property_name='attendance_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly_goal|set:attendance_colour|display_name',
|
||||
""
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly_goal|set:attendance_colour|desc',
|
||||
""
|
||||
)
|
||||
)
|
||||
|
||||
task_count_colour = ColourSetting(
|
||||
card=MonthlyGoalCard,
|
||||
property_name='task_count_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly_goal|set:task_count_colour|display_name',
|
||||
""
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly_goal|set:task_count_colour|desc',
|
||||
""
|
||||
)
|
||||
)
|
||||
|
||||
task_done_colour = ColourSetting(
|
||||
card=MonthlyGoalCard,
|
||||
property_name='task_done_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly_goal|set:task_done_colour|display_name',
|
||||
""
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly_goal|set:task_done_colour|desc',
|
||||
""
|
||||
)
|
||||
)
|
||||
|
||||
task_goal_colour = ColourSetting(
|
||||
card=MonthlyGoalCard,
|
||||
property_name='task_goal_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly_goal|set:task_goal_colour|display_name',
|
||||
""
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly_goal|set:task_goal_colour|desc',
|
||||
""
|
||||
)
|
||||
)
|
||||
|
||||
task_goal_number_colour = ColourSetting(
|
||||
card=MonthlyGoalCard,
|
||||
property_name='task_goal_number_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly_goal|set:task_goal_number_colour|display_name',
|
||||
"Task Goal"
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly_goal|set:task_goal_number_colour|desc',
|
||||
""
|
||||
)
|
||||
)
|
||||
|
||||
studied_text_colour = ColourSetting(
|
||||
card=MonthlyGoalCard,
|
||||
property_name='studied_text_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly_goal|set:studied_text_colour|display_name',
|
||||
""
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly_goal|set:studied_text_colour|desc',
|
||||
""
|
||||
)
|
||||
)
|
||||
|
||||
studied_hour_colour = ColourSetting(
|
||||
card=MonthlyGoalCard,
|
||||
property_name='studied_hour_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly_goal|set:studied_hour_colour|display_name',
|
||||
""
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly_goal|set:studied_hour_colour|desc',
|
||||
""
|
||||
)
|
||||
)
|
||||
|
||||
text_highlight_colour = ColoursSetting(
|
||||
attendance_rate_colour,
|
||||
task_count_colour,
|
||||
studied_hour_colour,
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly_goal|set:text_highlight_colour|display_name',
|
||||
"Highlight Text"
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly_goal|set:text_highlight_colour|desc',
|
||||
"Progress text colour."
|
||||
)
|
||||
)
|
||||
|
||||
text_colour = ColoursSetting(
|
||||
attendance_colour,
|
||||
task_done_colour,
|
||||
studied_text_colour,
|
||||
task_goal_colour,
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly_goal|set:text_colour|display_name',
|
||||
"Text"
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly_goal|set:text_colour|desc',
|
||||
"Achievement description text colour."
|
||||
)
|
||||
)
|
||||
|
||||
task_header_colour = ColourSetting(
|
||||
card=MonthlyGoalCard,
|
||||
property_name='task_header_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly_goal|set:task_header_colour|display_name',
|
||||
"Task Header"
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly_goal|set:task_header_colour|desc',
|
||||
""
|
||||
)
|
||||
)
|
||||
|
||||
task_done_number_colour = ColourSetting(
|
||||
card=MonthlyGoalCard,
|
||||
property_name='task_done_number_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly_goal|set:task_done_number_colour|display_name',
|
||||
"Checked Number"
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly_goal|set:task_done_number_colour|desc',
|
||||
""
|
||||
)
|
||||
)
|
||||
|
||||
task_undone_number_colour = ColourSetting(
|
||||
card=MonthlyGoalCard,
|
||||
property_name='task_undone_number_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly_goal|set:task_undone_number_colour|display_name',
|
||||
"Unchecked Number"
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly_goal|set:task_undone_number_colour|desc',
|
||||
""
|
||||
)
|
||||
)
|
||||
|
||||
task_done_text_colour = ColourSetting(
|
||||
card=MonthlyGoalCard,
|
||||
property_name='task_done_text_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly_goal|set:task_done_text_colour|display_name',
|
||||
"Checked Text"
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly_goal|set:task_done_text_colour|desc',
|
||||
""
|
||||
)
|
||||
)
|
||||
|
||||
task_undone_text_colour = ColourSetting(
|
||||
card=MonthlyGoalCard,
|
||||
property_name='task_undone_text_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly_goal|set:task_undone_text_colour|display_name',
|
||||
"Unchecked Text"
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly_goal|set:task_undone_text_colour|desc',
|
||||
""
|
||||
)
|
||||
)
|
||||
|
||||
footer_colour = ColourSetting(
|
||||
card=MonthlyGoalCard,
|
||||
property_name='footer_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly_goal|set:footer_colour|display_name',
|
||||
"Footer"
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly_goal|set:footer_colour|desc',
|
||||
""
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
mini_profile_badge_colour = ColourSetting(
|
||||
card=MonthlyGoalCard,
|
||||
property_name='mini_profile_badge_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly_goal|set:mini_profile_badge_colour|display_name',
|
||||
'Badge Background'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly_goal|set:mini_profile_badge_colour|desc',
|
||||
"Mini-profile badge background colour."
|
||||
)
|
||||
)
|
||||
|
||||
mini_profile_badge_text_colour = ColourSetting(
|
||||
card=MonthlyGoalCard,
|
||||
property_name='mini_profile_badge_text_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly_goal|set:mini_profile_badge_text_colour|display_name',
|
||||
'Badge Text'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly_goal|set:mini_profile_badge_text_colour|desc',
|
||||
""
|
||||
)
|
||||
)
|
||||
|
||||
mini_profile_name_colour = ColourSetting(
|
||||
card=MonthlyGoalCard,
|
||||
property_name='mini_profile_name_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly_goal|set:mini_profile_name_colour|display_name',
|
||||
'Username'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly_goal|set:mini_profile_name_colour|desc',
|
||||
"Mini-profile username colour."
|
||||
)
|
||||
)
|
||||
|
||||
mini_profile_discrim_colour = ColourSetting(
|
||||
card=MonthlyGoalCard,
|
||||
property_name='mini_profile_discrim_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly_goal|set:mini_profile_discrim_colour|display_name',
|
||||
'Discriminator'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly_goal|set:mini_profile_discrim_colour|desc',
|
||||
"Mini-profile discriminator colour."
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
mini_profile_group = SettingGroup(
|
||||
_p('skinsettings|page:monthly_goal|grp:mini_profile', "Profile"),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly_goal|grp:mini_profile|desc',
|
||||
"Customise the mini-profile shown above the goals."
|
||||
),
|
||||
custom_id='monthlygoal-profile',
|
||||
settings=(
|
||||
mini_profile_name_colour,
|
||||
mini_profile_discrim_colour,
|
||||
mini_profile_badge_colour,
|
||||
mini_profile_badge_text_colour,
|
||||
)
|
||||
)
|
||||
|
||||
misc_group = SettingGroup(
|
||||
_p('skinsettings|page:monthly_goal|grp:misc', "Miscellaneous"),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly_goal|grp:misc|desc',
|
||||
"Other miscellaneous colours."
|
||||
),
|
||||
custom_id='monthlygoal-misc',
|
||||
settings=(
|
||||
title_colour,
|
||||
footer_colour,
|
||||
)
|
||||
)
|
||||
|
||||
task_colour_group = SettingGroup(
|
||||
_p('skinsettings|page:monthly_goal|grp:task_colour', "Task colours"),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly_goal|grp:task_colour|desc',
|
||||
"Text and number colours for (in)complete goals."
|
||||
),
|
||||
custom_id='monthlygoal-tasks',
|
||||
settings=(
|
||||
task_undone_number_colour,
|
||||
task_done_number_colour,
|
||||
task_undone_text_colour,
|
||||
task_done_text_colour,
|
||||
)
|
||||
)
|
||||
|
||||
progress_colour_group = SettingGroup(
|
||||
_p('skinsettings|page:monthly_goal|grp:progress_colour', "Progress Colours"),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly_goal|grp:progress_colour|desc',
|
||||
"Customise colours for the monthly achievement progress."
|
||||
),
|
||||
custom_id='monthlygoal-progress',
|
||||
settings=(
|
||||
progress_bg_colour,
|
||||
progress_colour,
|
||||
text_colour,
|
||||
text_highlight_colour,
|
||||
task_goal_number_colour
|
||||
)
|
||||
)
|
||||
|
||||
base_skin = SkinSetting(
|
||||
card=MonthlyGoalCard,
|
||||
property_name='base_skin_id',
|
||||
display_name=_p(
|
||||
'skinsettings|page:monthly_goal|set:base_skin|display_name',
|
||||
'Skin'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly_goal|set:base_skin|desc',
|
||||
"Select a Skin Preset."
|
||||
)
|
||||
)
|
||||
|
||||
base_skin_group = SettingGroup(
|
||||
_p('skinsettings|page:monthly_goal|grp:base_skin', "Monthly Goals Skin"),
|
||||
description=_p(
|
||||
'skinsettings|page:monthly_goal|grp:base_skin|desc',
|
||||
"Asset pack and default values for the Monthly Goals."
|
||||
),
|
||||
custom_id='monthlygoals-skin',
|
||||
settings=(base_skin,),
|
||||
ungrouped=True
|
||||
)
|
||||
|
||||
monthly_goal_page.groups = [
|
||||
base_skin_group,
|
||||
mini_profile_group,
|
||||
misc_group,
|
||||
progress_colour_group,
|
||||
task_colour_group
|
||||
]
|
||||
|
||||
|
||||
@@ -0,0 +1,266 @@
|
||||
from gui.cards import ProfileCard
|
||||
|
||||
from ... import babel
|
||||
from ..skinsetting import ColourSetting, SkinSetting, ColoursSetting
|
||||
from ..layout import Page, SettingGroup
|
||||
|
||||
_p = babel._p
|
||||
|
||||
|
||||
|
||||
profile_page = Page(
|
||||
display_name=_p('skinsettings|page:profile|display_name', "Member Profile"),
|
||||
editing_description=_p(
|
||||
'skinsettings|page:profile|edit_desc',
|
||||
"Options for the member profile card."
|
||||
),
|
||||
preview_description=None,
|
||||
visible_in_preview=True,
|
||||
render_card=ProfileCard
|
||||
)
|
||||
|
||||
|
||||
header_colour_1 = ColourSetting(
|
||||
card=ProfileCard,
|
||||
property_name='header_colour_1',
|
||||
display_name=_p(
|
||||
'skinsettings|page:profile|set:header_colour_1|display_name',
|
||||
'Username'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:profile|set:header_colour_1|desc',
|
||||
"Text colour of the profile username."
|
||||
)
|
||||
)
|
||||
|
||||
header_colour_2 = ColourSetting(
|
||||
card=ProfileCard,
|
||||
property_name='header_colour_2',
|
||||
display_name=_p(
|
||||
'skinsettings|page:profile|set:header_colour_2|display_name',
|
||||
'Discriminator'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:profile|set:header_colour_2|desc',
|
||||
"Text colour of the profile dscriminator."
|
||||
)
|
||||
)
|
||||
|
||||
counter_bg_colour = ColourSetting(
|
||||
card=ProfileCard,
|
||||
property_name='counter_bg_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:profile|set:counter_bg_colour|display_name',
|
||||
'Background'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:profile|set:counter_bg_colour|desc',
|
||||
"Colour of the coin/gem/gift backgrounds."
|
||||
)
|
||||
)
|
||||
|
||||
counter_colour = ColourSetting(
|
||||
card=ProfileCard,
|
||||
property_name='counter_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:profile|set:counter_colour|display_name',
|
||||
'Text'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:profile|set:counter_colour|desc',
|
||||
"Colour of the coin/gem/gift text."
|
||||
)
|
||||
)
|
||||
|
||||
subheader_colour = ColourSetting(
|
||||
card=ProfileCard,
|
||||
property_name='subheader_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:profile|set:subheader_colour|display_name',
|
||||
'Column Header'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:profile|set:subheader_colour|desc',
|
||||
"Colour of the Profile/Achievements header."
|
||||
)
|
||||
)
|
||||
|
||||
badge_text_colour = ColourSetting(
|
||||
card=ProfileCard,
|
||||
property_name='badge_text_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:profile|set:badge_text_colour|display_name',
|
||||
'Badge Text'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:profile|set:badge_text_colour|desc',
|
||||
"Colour of the profile badge text."
|
||||
)
|
||||
)
|
||||
|
||||
badge_blob_colour = ColourSetting(
|
||||
card=ProfileCard,
|
||||
property_name='badge_blob_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:profile|set:badge_blob_colour|display_name',
|
||||
'Background'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:profile|set:badge_blob_colour|desc',
|
||||
"Colour of the profile badge background."
|
||||
)
|
||||
)
|
||||
|
||||
rank_name_colour = ColourSetting(
|
||||
card=ProfileCard,
|
||||
property_name='rank_name_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:profile|set:rank_name_colour|display_name',
|
||||
'Current Rank'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:profile|set:rank_name_colour|desc',
|
||||
"Colour of the current study rank name."
|
||||
)
|
||||
)
|
||||
|
||||
rank_hours_colour = ColourSetting(
|
||||
card=ProfileCard,
|
||||
property_name='rank_hours_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:profile|set:rank_hours_colour|display_name',
|
||||
'Required Hours'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:profile|set:rank_hours_colour|desc',
|
||||
"Colour of the study rank hour range."
|
||||
)
|
||||
)
|
||||
|
||||
bar_full_colour = ColourSetting(
|
||||
card=ProfileCard,
|
||||
property_name='bar_full_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:profile|set:bar_full_colour|display_name',
|
||||
'Bar Full'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:profile|set:bar_full_colour|desc',
|
||||
"Foreground progress bar colour."
|
||||
)
|
||||
)
|
||||
|
||||
bar_empty_colour = ColourSetting(
|
||||
card=ProfileCard,
|
||||
property_name='bar_empty_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:profile|set:bar_empty_colour|display_name',
|
||||
'Bar Empty'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:profile|set:bar_empty_colour|desc',
|
||||
"Background progress bar colour."
|
||||
)
|
||||
)
|
||||
|
||||
next_rank_colour = ColourSetting(
|
||||
card=ProfileCard,
|
||||
property_name='next_rank_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:profile|set:next_rank_colour|display_name',
|
||||
'Next Rank'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:profile|set:next_rank_colour|desc',
|
||||
"Colour of the next rank name and hours."
|
||||
)
|
||||
)
|
||||
|
||||
title_colour_group = SettingGroup(
|
||||
_p('skinsettings|page:profile|grp:title_colour', "Title Colours"),
|
||||
description=_p(
|
||||
'skinsettings|page:profile|grp:title_colour|desc',
|
||||
"Header and suheader text colours."
|
||||
),
|
||||
custom_id='profile-titles',
|
||||
settings=(
|
||||
header_colour_1,
|
||||
header_colour_2,
|
||||
subheader_colour
|
||||
),
|
||||
)
|
||||
|
||||
badge_colour_group = SettingGroup(
|
||||
_p('skinsettings|page:profile|grp:badge_colour', "Profile Badge Colours"),
|
||||
description=_p(
|
||||
'skinsettings|page:profile|grp:badge_colour|desc',
|
||||
"Text and background for the profile badges."
|
||||
),
|
||||
custom_id='profile-badges',
|
||||
settings=(
|
||||
badge_text_colour,
|
||||
badge_blob_colour
|
||||
),
|
||||
)
|
||||
|
||||
counter_colour_group = SettingGroup(
|
||||
_p('skinsettings|page:profile|grp:counter_colour', "Counter Colours"),
|
||||
description=_p(
|
||||
'skinsettings|page:profile|grp:counter_colour|desc',
|
||||
"Text and background for the coin/gem/gift counters."
|
||||
),
|
||||
custom_id='profile-counters',
|
||||
settings=(
|
||||
counter_colour,
|
||||
counter_bg_colour
|
||||
),
|
||||
)
|
||||
|
||||
rank_colour_group = SettingGroup(
|
||||
_p('skinsettings|page:profile|grp:rank_colour', "Progress Bar"),
|
||||
description=_p(
|
||||
'skinsettings|page:profile|grp:rank_colour|desc',
|
||||
"Colours for the study badge/rank progress bar."
|
||||
),
|
||||
custom_id='profile-progress',
|
||||
settings=(
|
||||
rank_name_colour,
|
||||
rank_hours_colour,
|
||||
next_rank_colour,
|
||||
bar_full_colour,
|
||||
bar_empty_colour
|
||||
),
|
||||
)
|
||||
|
||||
base_skin = SkinSetting(
|
||||
card=ProfileCard,
|
||||
property_name='base_skin_id',
|
||||
display_name=_p(
|
||||
'skinsettings|page:profile|set:base_skin|display_name',
|
||||
'Skin'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:profile|set:base_skin|desc',
|
||||
"Select a Skin Preset."
|
||||
)
|
||||
)
|
||||
|
||||
base_skin_group = SettingGroup(
|
||||
_p('skinsettings|page:profile|grp:base_skin', "Profile Skin"),
|
||||
description=_p(
|
||||
'skinsettings|page:profile|grp:base_skin|desc',
|
||||
"Asset pack and default values for this card."
|
||||
),
|
||||
custom_id='profile-skin',
|
||||
settings=(base_skin,),
|
||||
ungrouped=True
|
||||
)
|
||||
|
||||
profile_page.groups = [
|
||||
base_skin_group,
|
||||
title_colour_group,
|
||||
badge_colour_group,
|
||||
rank_colour_group,
|
||||
counter_colour_group,
|
||||
]
|
||||
|
||||
|
||||
@@ -0,0 +1,211 @@
|
||||
from gui.cards import StatsCard
|
||||
|
||||
from ... import babel
|
||||
from ..skinsetting import ColourSetting, SkinSetting, ColoursSetting
|
||||
from ..layout import Page, SettingGroup
|
||||
|
||||
_p = babel._p
|
||||
|
||||
|
||||
stats_page = Page(
|
||||
display_name=_p('skinsettings|page:stats|display_name', "Statistics"),
|
||||
editing_description=_p(
|
||||
'skinsettings|page:stats|edit_desc',
|
||||
"Options for the member statistics card."
|
||||
),
|
||||
preview_description=None,
|
||||
visible_in_preview=True,
|
||||
render_card=StatsCard
|
||||
)
|
||||
|
||||
|
||||
header_colour = ColourSetting(
|
||||
card=StatsCard,
|
||||
property_name='header_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:stats|set:header_colour|display_name',
|
||||
'Titles'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:stats|set:header_colour|desc',
|
||||
"Top header text colour."
|
||||
)
|
||||
)
|
||||
|
||||
stats_subheader_colour = ColourSetting(
|
||||
card=StatsCard,
|
||||
property_name='stats_subheader_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:stats|set:stats_subheader_colour|display_name',
|
||||
'Sections'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:stats|set:stats_subheader_colour|desc',
|
||||
"Text colour of the Statistics section titles."
|
||||
)
|
||||
)
|
||||
|
||||
stats_text_colour = ColourSetting(
|
||||
card=StatsCard,
|
||||
property_name='stats_text_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:stats|set:stats_text_colour|display_name',
|
||||
'Statistics'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:stats|set:stats_text_colour|desc',
|
||||
"Text colour of the Statistics section bodies."
|
||||
)
|
||||
)
|
||||
|
||||
col2_date_colour = ColourSetting(
|
||||
card=StatsCard,
|
||||
property_name='col2_date_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:stats|set:col2_date_colour|display_name',
|
||||
'Date'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:stats|set:col2_date_colour|desc',
|
||||
"Colour of the current month and year."
|
||||
)
|
||||
)
|
||||
|
||||
col2_hours_colour = ColourSetting(
|
||||
card=StatsCard,
|
||||
property_name='col2_hours_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:stats|set:col2_hours_colour|display_name',
|
||||
'Hours'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:stats|set:col2_hours_colour|desc',
|
||||
"Colour of the monthly hour total."
|
||||
)
|
||||
)
|
||||
|
||||
text_colour_group = SettingGroup(
|
||||
_p('skinsettings|page:stats|grp:text_colour', "Text Colours"),
|
||||
description=_p(
|
||||
'skinsettings|page:stats|grp:text_colour|desc',
|
||||
"Header colours and statistics text colours."
|
||||
),
|
||||
custom_id='stats-text',
|
||||
settings=(
|
||||
header_colour,
|
||||
stats_subheader_colour,
|
||||
stats_text_colour,
|
||||
col2_date_colour,
|
||||
col2_hours_colour
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
cal_weekday_colour = ColourSetting(
|
||||
card=StatsCard,
|
||||
property_name='cal_weekday_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:stats|set:cal_weekday_colour|display_name',
|
||||
'Weekdays'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:stats|set:cal_weekday_colour|desc',
|
||||
"Colour of the week day letters."
|
||||
),
|
||||
)
|
||||
|
||||
cal_number_colour = ColourSetting(
|
||||
card=StatsCard,
|
||||
property_name='cal_number_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:stats|set:cal_number_colour|display_name',
|
||||
'Numbers'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:stats|set:cal_number_colour|desc',
|
||||
"General calender day colour."
|
||||
),
|
||||
)
|
||||
|
||||
cal_number_end_colour = ColourSetting(
|
||||
card=StatsCard,
|
||||
property_name='cal_number_end_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:stats|set:cal_number_end_colour|display_name',
|
||||
'Streak Ends'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:stats|set:cal_number_end_colour|desc',
|
||||
"Day colour where streaks start or end."
|
||||
),
|
||||
)
|
||||
|
||||
cal_streak_middle_colour = ColourSetting(
|
||||
card=StatsCard,
|
||||
property_name='cal_streak_middle_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:stats|set:cal_streak_middle_colour|display_name',
|
||||
'Streak BG'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:stats|set:cal_streak_middle_colour|desc',
|
||||
"Background colour on streak days."
|
||||
),
|
||||
)
|
||||
|
||||
cal_streak_end_colour = ColourSetting(
|
||||
card=StatsCard,
|
||||
property_name='cal_streak_end_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:stats|set:cal_streak_end_colour|display_name',
|
||||
'Streak End BG'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:stats|set:cal_streak_end_colour|desc',
|
||||
"Background colour where streaks start/end."
|
||||
),
|
||||
)
|
||||
|
||||
calender_colour_group = SettingGroup(
|
||||
_p('skinsettings|page:stats|grp:calender_colour', "Calender Colours"),
|
||||
description=_p(
|
||||
'skinsettings|page:stats|grp:calender_colour|desc',
|
||||
"Number and streak colours for the current calender."
|
||||
),
|
||||
custom_id='stats-cal',
|
||||
settings=(
|
||||
cal_weekday_colour,
|
||||
cal_number_colour,
|
||||
cal_number_end_colour,
|
||||
cal_streak_middle_colour,
|
||||
cal_streak_end_colour
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
base_skin = SkinSetting(
|
||||
card=StatsCard,
|
||||
property_name='base_skin_id',
|
||||
display_name=_p(
|
||||
'skinsettings|page:stats|set:base_skin|display_name',
|
||||
'Skin'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:stats|set:base_skin|desc',
|
||||
"Select a Skin Preset."
|
||||
)
|
||||
)
|
||||
|
||||
base_skin_group = SettingGroup(
|
||||
_p('skinsettings|page:stats|grp:base_skin', "Statistics Skin"),
|
||||
description=_p(
|
||||
'skinsettings|page:stats|grp:base_skin|desc',
|
||||
"Asset pack and default values for this card."
|
||||
),
|
||||
custom_id='stats-skin',
|
||||
settings=(base_skin,),
|
||||
ungrouped=True
|
||||
)
|
||||
|
||||
stats_page.groups = [base_skin_group, text_colour_group, calender_colour_group]
|
||||
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
from gui.cards import ProfileCard
|
||||
|
||||
from ... import babel
|
||||
from ..skinsetting import ColourSetting, SkinSetting, ColoursSetting
|
||||
from ..layout import Page, SettingGroup
|
||||
|
||||
from . import stats, profile
|
||||
|
||||
_p = babel._p
|
||||
|
||||
|
||||
summary_page = Page(
|
||||
display_name=_p('skinsettings|page:summary|display_name', "Setting Summary"),
|
||||
editing_description=_p(
|
||||
'skinsettings|page:summary|edit_desc',
|
||||
"Simple setup for creating a unified interface theme."
|
||||
),
|
||||
preview_description=_p(
|
||||
'skinsettings|page:summary|preview_desc',
|
||||
"Summary of common settings across the entire interface."
|
||||
),
|
||||
visible_in_preview=True,
|
||||
render_card=ProfileCard
|
||||
)
|
||||
|
||||
name_colours = ColoursSetting(
|
||||
profile.header_colour_1,
|
||||
display_name=_p(
|
||||
'skinsettings|page:summary|set:name_colours|display_name',
|
||||
"username colour"
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:summary|set:name_colours|desc',
|
||||
"Author username colour."
|
||||
)
|
||||
)
|
||||
|
||||
discrim_colours = ColoursSetting(
|
||||
profile.header_colour_2,
|
||||
display_name=_p(
|
||||
'skinsettings|page:summary|set:discrim_colours|display_name',
|
||||
"discrim colour"
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:summary|set:discrim_colours|desc',
|
||||
"Author discriminator colour."
|
||||
)
|
||||
)
|
||||
|
||||
subheader_colour = ColoursSetting(
|
||||
stats.header_colour,
|
||||
profile.subheader_colour,
|
||||
display_name=_p(
|
||||
'skinsettings|page:summary|set:subheader_colour|display_name',
|
||||
"subheadings"
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:summary|set:subheader_colour|desc',
|
||||
"Colour of subheadings and column headings."
|
||||
)
|
||||
)
|
||||
|
||||
header_colour_group = SettingGroup(
|
||||
_p('skinsettings|page:summary|grp:header_colour', "Title Colours"),
|
||||
description=_p(
|
||||
'skinsettings|page:summary|grp:header_colour|desc',
|
||||
"Title and header text colours."
|
||||
),
|
||||
custom_id='shared-titles',
|
||||
settings=(
|
||||
subheader_colour,
|
||||
)
|
||||
)
|
||||
|
||||
profile_colour_group = SettingGroup(
|
||||
_p('skinsettings|page:summary|grp:profile_colour', "Profile Colours"),
|
||||
description=_p(
|
||||
'skinsettings|page:summary|grp:profile_colour|desc',
|
||||
"Profile elements shared across various cards."
|
||||
),
|
||||
custom_id='shared-profile',
|
||||
settings=(
|
||||
name_colours,
|
||||
discrim_colours
|
||||
)
|
||||
)
|
||||
|
||||
summary_page.groups = [header_colour_group, profile_colour_group]
|
||||
|
||||
|
||||
@@ -0,0 +1,350 @@
|
||||
from gui.cards import WeeklyStatsCard
|
||||
|
||||
from ... import babel
|
||||
from ..skinsetting import ColourSetting, SkinSetting, ColoursSetting
|
||||
from ..layout import Page, SettingGroup
|
||||
|
||||
_p = babel._p
|
||||
|
||||
|
||||
weekly_page = Page(
|
||||
display_name=_p('skinsettings|page:weekly|display_name', "Weekly Statistics"),
|
||||
editing_description=_p(
|
||||
'skinsettings|page:weekly|edit_desc',
|
||||
"Options for the weekly statistis card."
|
||||
),
|
||||
preview_description=None,
|
||||
visible_in_preview=True,
|
||||
render_card=WeeklyStatsCard
|
||||
)
|
||||
|
||||
title_colour = ColourSetting(
|
||||
card=WeeklyStatsCard,
|
||||
property_name='title_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly|set:title_colour|display_name',
|
||||
'Title'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly|set:title_colour|desc',
|
||||
"Colour of the card title."
|
||||
)
|
||||
)
|
||||
top_hours_colour = ColourSetting(
|
||||
card=WeeklyStatsCard,
|
||||
property_name='top_hours_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly|set:top_hours_colour|display_name',
|
||||
'Hours'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly|set:top_hours_colour|desc',
|
||||
"Hours axis labels."
|
||||
)
|
||||
)
|
||||
top_hours_bg_colour = ColourSetting(
|
||||
card=WeeklyStatsCard,
|
||||
property_name='top_hours_bg_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly|set:top_hours_bg_colour|display_name',
|
||||
'Hour Bg'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly|set:top_hours_bg_colour|desc',
|
||||
"Hours axis label background."
|
||||
)
|
||||
)
|
||||
top_line_colour = ColourSetting(
|
||||
card=WeeklyStatsCard,
|
||||
property_name='top_line_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly|set:top_line_colour|display_name',
|
||||
'Lines'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly|set:top_line_colour|desc',
|
||||
"Horizontal graph lines."
|
||||
)
|
||||
)
|
||||
top_weekday_colour = ColourSetting(
|
||||
card=WeeklyStatsCard,
|
||||
property_name='top_weekday_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly|set:top_weekday_colour|display_name',
|
||||
'Weekdays'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly|set:top_weekday_colour|desc',
|
||||
"Weekday axis labels."
|
||||
)
|
||||
)
|
||||
top_date_colour = ColourSetting(
|
||||
card=WeeklyStatsCard,
|
||||
property_name='top_date_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly|set:top_date_colour|display_name',
|
||||
'Dates'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly|set:top_date_colour|desc',
|
||||
"Weekday date axis labels."
|
||||
)
|
||||
)
|
||||
top_this_colour = ColourSetting(
|
||||
card=WeeklyStatsCard,
|
||||
property_name='top_this_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly|set:top_this_colour|display_name',
|
||||
'This Week'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly|set:top_this_colour|desc',
|
||||
"This week bar fill colour."
|
||||
)
|
||||
)
|
||||
top_last_colour = ColourSetting(
|
||||
card=WeeklyStatsCard,
|
||||
property_name='top_last_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly|set:top_last_colour|display_name',
|
||||
'Last Week'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly|set:top_last_colour|desc',
|
||||
"Last week bar fill colour."
|
||||
)
|
||||
)
|
||||
btm_weekday_colour = ColourSetting(
|
||||
card=WeeklyStatsCard,
|
||||
property_name='btm_weekday_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly|set:btm_weekday_colour|display_name',
|
||||
'Weekdays'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly|set:btm_weekday_colour|desc',
|
||||
"Weekday axis labels."
|
||||
)
|
||||
)
|
||||
btm_weekly_background_colour = ColourSetting(
|
||||
card=WeeklyStatsCard,
|
||||
property_name='btm_weekly_background_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly|set:btm_weekly_background_colour|display_name',
|
||||
'Weekday Bg'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly|set:btm_weekly_background_colour|desc',
|
||||
"Weekday axis background."
|
||||
)
|
||||
)
|
||||
btm_bar_horiz_colour = ColourSetting(
|
||||
card=WeeklyStatsCard,
|
||||
property_name='btm_bar_horiz_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly|set:btm_bar_horiz_colour|display_name',
|
||||
'Bars (Horiz)'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly|set:btm_bar_horiz_colour|desc',
|
||||
"Horizontal graph bars."
|
||||
)
|
||||
)
|
||||
btm_bar_vert_colour = ColourSetting(
|
||||
card=WeeklyStatsCard,
|
||||
property_name='btm_bar_vert_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly|set:btm_bar_vert_colour|display_name',
|
||||
'Bars (Vertical)'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly|set:btm_bar_vert_colour|desc',
|
||||
"Vertical graph bars."
|
||||
)
|
||||
)
|
||||
btm_this_colour = ColourSetting(
|
||||
card=WeeklyStatsCard,
|
||||
property_name='btm_this_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly|set:btm_this_colour|display_name',
|
||||
'This Week'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly|set:btm_this_colour|desc',
|
||||
"This week bar fill colour."
|
||||
)
|
||||
)
|
||||
btm_last_colour = ColourSetting(
|
||||
card=WeeklyStatsCard,
|
||||
property_name='btm_last_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly|set:btm_last_colour|display_name',
|
||||
'Last Week'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly|set:btm_last_colour|desc',
|
||||
"Last week bar fill colour."
|
||||
)
|
||||
)
|
||||
btm_day_colour = ColourSetting(
|
||||
card=WeeklyStatsCard,
|
||||
property_name='btm_day_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly|set:btm_day_colour|display_name',
|
||||
'Hours'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly|set:btm_day_colour|desc',
|
||||
"Hour axis labels."
|
||||
)
|
||||
)
|
||||
this_week_colour = ColourSetting(
|
||||
card=WeeklyStatsCard,
|
||||
property_name='this_week_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly|set:this_week_colour|display_name',
|
||||
'This Week Legend'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly|set:this_week_colour|desc',
|
||||
"This week legend text."
|
||||
)
|
||||
)
|
||||
last_week_colour = ColourSetting(
|
||||
card=WeeklyStatsCard,
|
||||
property_name='last_week_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly|set:last_week_colour|display_name',
|
||||
'Last Week Legend'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly|set:last_week_colour|desc',
|
||||
"Last week legend text."
|
||||
)
|
||||
)
|
||||
legend_colour = ColoursSetting(
|
||||
this_week_colour,
|
||||
last_week_colour,
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly|set:legend_colour|display_name',
|
||||
'Legend'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly|set:legend_colour|desc',
|
||||
"Legend text colour."
|
||||
)
|
||||
)
|
||||
footer_colour = ColourSetting(
|
||||
card=WeeklyStatsCard,
|
||||
property_name='footer_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly|set:footer_colour|display_name',
|
||||
'Footer'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly|set:footer_colour|desc',
|
||||
"Footer text colour."
|
||||
)
|
||||
)
|
||||
|
||||
base_skin = SkinSetting(
|
||||
card=WeeklyStatsCard,
|
||||
property_name='base_skin_id',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly|set:base_skin|display_name',
|
||||
'Skin'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly|set:base_skin|desc',
|
||||
"Select a Skin Preset."
|
||||
)
|
||||
)
|
||||
|
||||
base_skin_group = SettingGroup(
|
||||
_p('skinsettings|page:weekly|grp:base_skin', "Weekly Stats Skin"),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly|grp:base_skin|desc',
|
||||
"Asset pack and default values for this card."
|
||||
),
|
||||
custom_id='weekly-skin',
|
||||
settings=(base_skin,),
|
||||
ungrouped=True
|
||||
)
|
||||
|
||||
top_colour_group = SettingGroup(
|
||||
_p('skinsettings|page:weekly|grp:top_colour', "Top Graph"),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly|grp:top_colour|desc',
|
||||
"Customise the top graph colourscheme."
|
||||
),
|
||||
custom_id='weekly-top',
|
||||
settings=(
|
||||
top_hours_colour,
|
||||
top_weekday_colour,
|
||||
top_date_colour,
|
||||
top_this_colour,
|
||||
top_last_colour,
|
||||
)
|
||||
)
|
||||
|
||||
bottom_colour_group = SettingGroup(
|
||||
_p('skinsettings|page:weekly|grp:bottom_colour', "Bottom Graph"),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly|grp:bottom_colour|desc',
|
||||
"Customise the bottom graph colourscheme."
|
||||
),
|
||||
custom_id='weekly-bottom',
|
||||
settings=(
|
||||
btm_weekday_colour,
|
||||
btm_day_colour,
|
||||
btm_this_colour,
|
||||
btm_last_colour,
|
||||
btm_bar_horiz_colour,
|
||||
)
|
||||
)
|
||||
|
||||
misc_group = SettingGroup(
|
||||
_p('skinsettings|page:weekly|grp:misc', "Misc Colours"),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly|grp:misc|desc',
|
||||
"Miscellaneous card colours."
|
||||
),
|
||||
custom_id='weekly-misc',
|
||||
settings=(
|
||||
title_colour,
|
||||
legend_colour,
|
||||
footer_colour,
|
||||
)
|
||||
)
|
||||
|
||||
base_skin = SkinSetting(
|
||||
card=WeeklyStatsCard,
|
||||
property_name='base_skin_id',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly|set:base_skin|display_name',
|
||||
'Skin'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly|set:base_skin|desc',
|
||||
"Select a Skin Preset."
|
||||
)
|
||||
)
|
||||
|
||||
base_skin_group = SettingGroup(
|
||||
_p('skinsettings|page:weekly|grp:base_skin', "Weekly Stats Skin"),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly|grp:base_skin|desc',
|
||||
"Asset pack and default values for the Weekly Statistics."
|
||||
),
|
||||
custom_id='weekly-skin',
|
||||
settings=(base_skin,),
|
||||
ungrouped=True
|
||||
)
|
||||
|
||||
weekly_page.groups = [
|
||||
base_skin_group,
|
||||
top_colour_group,
|
||||
bottom_colour_group,
|
||||
misc_group,
|
||||
]
|
||||
|
||||
|
||||
@@ -0,0 +1,438 @@
|
||||
from gui.cards import WeeklyGoalCard
|
||||
|
||||
from ... import babel
|
||||
from ..skinsetting import ColourSetting, SkinSetting, ColoursSetting
|
||||
from ..layout import Page, SettingGroup
|
||||
|
||||
_p = babel._p
|
||||
|
||||
|
||||
"""
|
||||
mini_profile_name_colour
|
||||
mini_profile_badge_colour
|
||||
mini_profile_badge_text_colour
|
||||
mini_profile_discrim_colour
|
||||
|
||||
title_colour
|
||||
footer_colour
|
||||
|
||||
progress_bg_colour
|
||||
progress_colour
|
||||
[attendance_rate_colour, task_count_colour, studied_hour_colour]
|
||||
[attendance_colour, task_done_colour, studied_text_colour, task_goal_colour]
|
||||
task_goal_number_colour
|
||||
|
||||
task_header_colour
|
||||
task_done_number_colour
|
||||
task_undone_number_colour
|
||||
task_done_text_colour
|
||||
task_undone_text_colour
|
||||
"""
|
||||
|
||||
weekly_goal_page = Page(
|
||||
display_name=_p('skinsettings|page:weekly_goal|display_name', "Weekly Goals"),
|
||||
editing_description=_p(
|
||||
'skinsettings|page:weekly_goal|edit_desc',
|
||||
"Options for the weekly goal card."
|
||||
),
|
||||
preview_description=None,
|
||||
visible_in_preview=True,
|
||||
render_card=WeeklyGoalCard
|
||||
)
|
||||
|
||||
title_colour = ColourSetting(
|
||||
card=WeeklyGoalCard,
|
||||
property_name='title_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly_goal|set:title_colour|display_name',
|
||||
"Title"
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly_goal|set:title_colour|desc',
|
||||
""
|
||||
)
|
||||
)
|
||||
|
||||
progress_bg_colour = ColourSetting(
|
||||
card=WeeklyGoalCard,
|
||||
property_name='progress_bg_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly_goal|set:progress_bg_colour|display_name',
|
||||
"Bar Bg"
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly_goal|set:progress_bg_colour|desc',
|
||||
""
|
||||
)
|
||||
)
|
||||
|
||||
progress_colour = ColourSetting(
|
||||
card=WeeklyGoalCard,
|
||||
property_name='progress_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly_goal|set:progress_colour|display_name',
|
||||
"Bar Fg"
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly_goal|set:progress_colour|desc',
|
||||
""
|
||||
)
|
||||
)
|
||||
|
||||
attendance_rate_colour = ColourSetting(
|
||||
card=WeeklyGoalCard,
|
||||
property_name='attendance_rate_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly_goal|set:attendance_rate_colour|display_name',
|
||||
""
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly_goal|set:attendance_rate_colour|desc',
|
||||
""
|
||||
)
|
||||
)
|
||||
|
||||
attendance_colour = ColourSetting(
|
||||
card=WeeklyGoalCard,
|
||||
property_name='attendance_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly_goal|set:attendance_colour|display_name',
|
||||
""
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly_goal|set:attendance_colour|desc',
|
||||
""
|
||||
)
|
||||
)
|
||||
|
||||
task_count_colour = ColourSetting(
|
||||
card=WeeklyGoalCard,
|
||||
property_name='task_count_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly_goal|set:task_count_colour|display_name',
|
||||
""
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly_goal|set:task_count_colour|desc',
|
||||
""
|
||||
)
|
||||
)
|
||||
|
||||
task_done_colour = ColourSetting(
|
||||
card=WeeklyGoalCard,
|
||||
property_name='task_done_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly_goal|set:task_done_colour|display_name',
|
||||
""
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly_goal|set:task_done_colour|desc',
|
||||
""
|
||||
)
|
||||
)
|
||||
|
||||
task_goal_colour = ColourSetting(
|
||||
card=WeeklyGoalCard,
|
||||
property_name='task_goal_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly_goal|set:task_goal_colour|display_name',
|
||||
""
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly_goal|set:task_goal_colour|desc',
|
||||
""
|
||||
)
|
||||
)
|
||||
|
||||
task_goal_number_colour = ColourSetting(
|
||||
card=WeeklyGoalCard,
|
||||
property_name='task_goal_number_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly_goal|set:task_goal_number_colour|display_name',
|
||||
"Task Goal"
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly_goal|set:task_goal_number_colour|desc',
|
||||
""
|
||||
)
|
||||
)
|
||||
|
||||
studied_text_colour = ColourSetting(
|
||||
card=WeeklyGoalCard,
|
||||
property_name='studied_text_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly_goal|set:studied_text_colour|display_name',
|
||||
""
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly_goal|set:studied_text_colour|desc',
|
||||
""
|
||||
)
|
||||
)
|
||||
|
||||
studied_hour_colour = ColourSetting(
|
||||
card=WeeklyGoalCard,
|
||||
property_name='studied_hour_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly_goal|set:studied_hour_colour|display_name',
|
||||
""
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly_goal|set:studied_hour_colour|desc',
|
||||
""
|
||||
)
|
||||
)
|
||||
|
||||
text_highlight_colour = ColoursSetting(
|
||||
attendance_rate_colour,
|
||||
task_count_colour,
|
||||
studied_hour_colour,
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly_goal|set:text_highlight_colour|display_name',
|
||||
"Highlight Text"
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly_goal|set:text_highlight_colour|desc',
|
||||
"Progress text colour."
|
||||
)
|
||||
)
|
||||
|
||||
text_colour = ColoursSetting(
|
||||
attendance_colour,
|
||||
task_done_colour,
|
||||
studied_text_colour,
|
||||
task_goal_colour,
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly_goal|set:text_colour|display_name',
|
||||
"Text"
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly_goal|set:text_colour|desc',
|
||||
"Achievement description text colour."
|
||||
)
|
||||
)
|
||||
|
||||
task_header_colour = ColourSetting(
|
||||
card=WeeklyGoalCard,
|
||||
property_name='task_header_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly_goal|set:task_header_colour|display_name',
|
||||
"Task Header"
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly_goal|set:task_header_colour|desc',
|
||||
""
|
||||
)
|
||||
)
|
||||
|
||||
task_done_number_colour = ColourSetting(
|
||||
card=WeeklyGoalCard,
|
||||
property_name='task_done_number_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly_goal|set:task_done_number_colour|display_name',
|
||||
"Checked Number"
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly_goal|set:task_done_number_colour|desc',
|
||||
""
|
||||
)
|
||||
)
|
||||
|
||||
task_undone_number_colour = ColourSetting(
|
||||
card=WeeklyGoalCard,
|
||||
property_name='task_undone_number_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly_goal|set:task_undone_number_colour|display_name',
|
||||
"Unchecked Number"
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly_goal|set:task_undone_number_colour|desc',
|
||||
""
|
||||
)
|
||||
)
|
||||
|
||||
task_done_text_colour = ColourSetting(
|
||||
card=WeeklyGoalCard,
|
||||
property_name='task_done_text_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly_goal|set:task_done_text_colour|display_name',
|
||||
"Checked Text"
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly_goal|set:task_done_text_colour|desc',
|
||||
""
|
||||
)
|
||||
)
|
||||
|
||||
task_undone_text_colour = ColourSetting(
|
||||
card=WeeklyGoalCard,
|
||||
property_name='task_undone_text_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly_goal|set:task_undone_text_colour|display_name',
|
||||
"Unchecked Text"
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly_goal|set:task_undone_text_colour|desc',
|
||||
""
|
||||
)
|
||||
)
|
||||
|
||||
footer_colour = ColourSetting(
|
||||
card=WeeklyGoalCard,
|
||||
property_name='footer_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly_goal|set:footer_colour|display_name',
|
||||
"Footer"
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly_goal|set:footer_colour|desc',
|
||||
""
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
mini_profile_badge_colour = ColourSetting(
|
||||
card=WeeklyGoalCard,
|
||||
property_name='mini_profile_badge_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly_goal|set:mini_profile_badge_colour|display_name',
|
||||
'Badge Background'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly_goal|set:mini_profile_badge_colour|desc',
|
||||
"Mini-profile badge background colour."
|
||||
)
|
||||
)
|
||||
|
||||
mini_profile_badge_text_colour = ColourSetting(
|
||||
card=WeeklyGoalCard,
|
||||
property_name='mini_profile_badge_text_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly_goal|set:mini_profile_badge_text_colour|display_name',
|
||||
'Badge Text'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly_goal|set:mini_profile_badge_text_colour|desc',
|
||||
""
|
||||
)
|
||||
)
|
||||
|
||||
mini_profile_name_colour = ColourSetting(
|
||||
card=WeeklyGoalCard,
|
||||
property_name='mini_profile_name_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly_goal|set:mini_profile_name_colour|display_name',
|
||||
'Username'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly_goal|set:mini_profile_name_colour|desc',
|
||||
"Mini-profile username colour."
|
||||
)
|
||||
)
|
||||
|
||||
mini_profile_discrim_colour = ColourSetting(
|
||||
card=WeeklyGoalCard,
|
||||
property_name='mini_profile_discrim_colour',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly_goal|set:mini_profile_discrim_colour|display_name',
|
||||
'Discriminator'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly_goal|set:mini_profile_discrim_colour|desc',
|
||||
"Mini-profile discriminator colour."
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
mini_profile_group = SettingGroup(
|
||||
_p('skinsettings|page:weekly_goal|grp:mini_profile', "Profile"),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly_goal|grp:mini_profile|desc',
|
||||
"Customise the mini-profile shown above the goals."
|
||||
),
|
||||
custom_id='weeklygoal-profile',
|
||||
settings=(
|
||||
mini_profile_name_colour,
|
||||
mini_profile_discrim_colour,
|
||||
mini_profile_badge_colour,
|
||||
mini_profile_badge_text_colour,
|
||||
)
|
||||
)
|
||||
|
||||
misc_group = SettingGroup(
|
||||
_p('skinsettings|page:weekly_goal|grp:misc', "Miscellaneous"),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly_goal|grp:misc|desc',
|
||||
"Other miscellaneous colours."
|
||||
),
|
||||
custom_id='weeklygoal-misc',
|
||||
settings=(
|
||||
title_colour,
|
||||
footer_colour,
|
||||
)
|
||||
)
|
||||
|
||||
task_colour_group = SettingGroup(
|
||||
_p('skinsettings|page:weekly_goal|grp:task_colour', "Task colours"),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly_goal|grp:task_colour|desc',
|
||||
"Text and number colours for (in)complete goals."
|
||||
),
|
||||
custom_id='weeklygoal-tasks',
|
||||
settings=(
|
||||
task_undone_number_colour,
|
||||
task_done_number_colour,
|
||||
task_undone_text_colour,
|
||||
task_done_text_colour,
|
||||
)
|
||||
)
|
||||
|
||||
progress_colour_group = SettingGroup(
|
||||
_p('skinsettings|page:weekly_goal|grp:progress_colour', "Progress Colours"),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly_goal|grp:progress_colour|desc',
|
||||
"Customise colours for the weekly achievement progress."
|
||||
),
|
||||
custom_id='weeklygoal-progress',
|
||||
settings=(
|
||||
progress_bg_colour,
|
||||
progress_colour,
|
||||
text_colour,
|
||||
text_highlight_colour,
|
||||
task_goal_number_colour
|
||||
)
|
||||
)
|
||||
|
||||
base_skin = SkinSetting(
|
||||
card=WeeklyGoalCard,
|
||||
property_name='base_skin_id',
|
||||
display_name=_p(
|
||||
'skinsettings|page:weekly_goal|set:base_skin|display_name',
|
||||
'Skin'
|
||||
),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly_goal|set:base_skin|desc',
|
||||
"Select a Skin Preset."
|
||||
)
|
||||
)
|
||||
|
||||
base_skin_group = SettingGroup(
|
||||
_p('skinsettings|page:weekly_goal|grp:base_skin', "Weekly Goals Skin"),
|
||||
description=_p(
|
||||
'skinsettings|page:weekly_goal|grp:base_skin|desc',
|
||||
"Asset pack and default values for the Weekly Goals."
|
||||
),
|
||||
custom_id='weeklygoals-skin',
|
||||
settings=(base_skin,),
|
||||
ungrouped=True
|
||||
)
|
||||
|
||||
|
||||
weekly_goal_page.groups = [
|
||||
base_skin_group,
|
||||
mini_profile_group,
|
||||
misc_group,
|
||||
progress_colour_group,
|
||||
task_colour_group
|
||||
]
|
||||
|
||||
|
||||
@@ -0,0 +1,598 @@
|
||||
from io import StringIO
|
||||
import json
|
||||
from typing import Optional
|
||||
import asyncio
|
||||
import datetime as dt
|
||||
|
||||
import discord
|
||||
from discord.ui.button import button, Button, ButtonStyle
|
||||
from discord.ui.select import select, Select, SelectOption
|
||||
from gui.base.AppSkin import AppSkin
|
||||
|
||||
from meta import LionBot, conf
|
||||
from meta.errors import ResponseTimedOut, UserInputError
|
||||
from meta.logger import log_wrap
|
||||
from utils.ui import FastModal, Confirm, MessageUI, error_handler_for, ModalRetryUI, AButton, AsComponents
|
||||
from utils.lib import MessageArgs, utc_now
|
||||
from constants import DATA_VERSION
|
||||
|
||||
from .. import babel, logger
|
||||
from ..skinlib import CustomSkin, FrozenCustomSkin, appskin_as_option
|
||||
from .pages import pages
|
||||
from .skinsetting import Setting, SettingInputType, SkinSetting
|
||||
from .layout import SettingGroup, Page
|
||||
|
||||
|
||||
_p = babel._p
|
||||
|
||||
|
||||
class SettingInput(FastModal):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
@error_handler_for(UserInputError)
|
||||
async def rerequest(self, interaction, error):
|
||||
await ModalRetryUI(self, error.msg).respond_to(interaction)
|
||||
|
||||
|
||||
class CustomSkinEditor(MessageUI):
|
||||
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, skin: CustomSkin, **kwargs):
|
||||
super().__init__(timeout=600, **kwargs)
|
||||
self._children = super()._init_children()
|
||||
|
||||
self.skin = skin
|
||||
self.bot = skin.bot
|
||||
self.cog = self.bot.get_cog('CustomSkinCog')
|
||||
|
||||
self.global_themes = self._get_available()
|
||||
|
||||
# UI State
|
||||
|
||||
# Whether we are currently in customisation mode
|
||||
self.customising = False
|
||||
self.page_index = 0
|
||||
self.showing_skin_setting: Optional[SkinSetting] = None
|
||||
|
||||
# Last item in history is current state
|
||||
# Last item in future is next state
|
||||
self.history = [skin.freeze()]
|
||||
self.future = []
|
||||
self.dirty = False
|
||||
|
||||
@property
|
||||
def page(self) -> Page:
|
||||
return pages[self.page_index]
|
||||
|
||||
# ----- UI API -----
|
||||
def push_state(self):
|
||||
"""
|
||||
Push a state onto the history stack.
|
||||
Run this on each change _before_ the refresh.
|
||||
"""
|
||||
state = self.skin.freeze()
|
||||
self.history.append(state)
|
||||
self.future.clear()
|
||||
self.dirty = True
|
||||
|
||||
def _get_available(self) -> dict[str, AppSkin]:
|
||||
skins = {
|
||||
skin.skin_id: skin for skin in AppSkin.get_all()
|
||||
if skin.public
|
||||
}
|
||||
skins['default'] = self._make_default()
|
||||
return skins
|
||||
|
||||
def _make_default(self) -> AppSkin:
|
||||
"""
|
||||
Create a placeholder 'default' skin.
|
||||
"""
|
||||
t = self.bot.translator.t
|
||||
|
||||
skin = AppSkin(None)
|
||||
skin.skin_id = 'default'
|
||||
skin.display_name = t(_p(
|
||||
'ui:skineditor|default_skin:display_name',
|
||||
"Default"
|
||||
))
|
||||
skin.description = t(_p(
|
||||
'ui:skineditor|default_skin:description',
|
||||
"My default interface theme"
|
||||
))
|
||||
skin.price = 0
|
||||
return skin
|
||||
|
||||
# ----- UI Components -----
|
||||
|
||||
# Download button
|
||||
# NOTE: property_id, card_id, property_name, value
|
||||
# Metadata with version, time generated, skinid, generating user
|
||||
# Special field for the global_skin_id
|
||||
@button(
|
||||
label="DOWNLOAD_BUTTON_PLACEHOLDER",
|
||||
style=ButtonStyle.blurple
|
||||
)
|
||||
async def download_button(self, press: discord.Interaction, pressed: Button):
|
||||
await press.response.defer(thinking=True, ephemeral=True)
|
||||
|
||||
data = {}
|
||||
data['metadata'] = {
|
||||
'requested_by': press.user.id,
|
||||
'requested_in': press.guild.id if press.guild else None,
|
||||
'skinid': self.skin.skinid,
|
||||
'created_at': utc_now().isoformat(),
|
||||
'data_version': DATA_VERSION,
|
||||
}
|
||||
data['custom_skin'] = {
|
||||
'skinid': self.skin.skinid,
|
||||
'base_skin': self.skin.base_skin_name,
|
||||
}
|
||||
properties = {}
|
||||
for card, card_props in self.skin.properties.items():
|
||||
props = {}
|
||||
for name, value in card_props.items():
|
||||
propid = (await self.cog.fetch_property_ids((card, name)))[0]
|
||||
props[name] = {
|
||||
'property_id': propid,
|
||||
'value': value
|
||||
}
|
||||
properties[card] = props
|
||||
data['custom_skin']['properties'] = properties
|
||||
|
||||
content = json.dumps(data, indent=2)
|
||||
with StringIO(content) as fp:
|
||||
fp.seek(0)
|
||||
file = discord.File(fp, filename=f"skin-{self.skin.skinid}.json")
|
||||
await press.followup.send("Here is your custom skin data!", file=file, ephemeral=True)
|
||||
|
||||
async def download_button_refresh(self):
|
||||
button = self.download_button
|
||||
t = self.bot.translator.t
|
||||
button.label = t(_p(
|
||||
'ui:skineditor|button:download|label',
|
||||
"Download"
|
||||
))
|
||||
|
||||
# Save button
|
||||
@button(
|
||||
label="SAVE_BUTTON_PLACEHOLDER",
|
||||
style=ButtonStyle.green
|
||||
)
|
||||
async def save_button(self, press: discord.Interaction, pressed: Button):
|
||||
await press.response.defer(thinking=True, ephemeral=True)
|
||||
await self.skin.save()
|
||||
self.history = self.history[-1:]
|
||||
self.dirty = False
|
||||
await self.refresh(thinking=press)
|
||||
|
||||
async def save_button_refresh(self):
|
||||
button = self.save_button
|
||||
t = self.bot.translator.t
|
||||
button.label = t(_p(
|
||||
'ui:skineditor|button:save|label',
|
||||
"Save"
|
||||
))
|
||||
button.disabled = not self.dirty
|
||||
|
||||
# Back button
|
||||
@button(
|
||||
label="BACK_BUTTON_PLACEHOLDER",
|
||||
style=ButtonStyle.red
|
||||
)
|
||||
async def back_button(self, press: discord.Interaction, pressed: Button):
|
||||
await press.response.defer(thinking=True, ephemeral=True)
|
||||
self.customising = False
|
||||
await self.refresh(thinking=press)
|
||||
|
||||
async def back_button_refresh(self):
|
||||
button = self.back_button
|
||||
t = self.bot.translator.t
|
||||
button.label = t(_p(
|
||||
'ui:skineditor|button:back|label',
|
||||
"Back"
|
||||
))
|
||||
|
||||
# Customise button
|
||||
@button(
|
||||
label="CUSTOMISE_BUTTON_PLACEHOLDER",
|
||||
style=ButtonStyle.green
|
||||
)
|
||||
async def customise_button(self, press: discord.Interaction, pressed: Button):
|
||||
await press.response.defer(thinking=True, ephemeral=True)
|
||||
self.customising = True
|
||||
await self.refresh(thinking=press)
|
||||
|
||||
async def customise_button_refresh(self):
|
||||
button = self.customise_button
|
||||
t = self.bot.translator.t
|
||||
button.label = t(_p(
|
||||
'ui:skineditor|button:customise|label',
|
||||
"Customise"
|
||||
))
|
||||
|
||||
# Reset card button
|
||||
@button(
|
||||
label="RESET_CARD_BUTTON_PLACEHOLDER",
|
||||
style=ButtonStyle.red
|
||||
)
|
||||
async def reset_card_button(self, press: discord.Interaction, pressed: Button):
|
||||
# Note this actually resets the page, not the card
|
||||
await press.response.defer(thinking=True, ephemeral=True)
|
||||
|
||||
for group in self.page.groups:
|
||||
for setting in group.settings:
|
||||
setting.set_in(self.skin, None)
|
||||
|
||||
self.push_state()
|
||||
await self.refresh(thinking=press)
|
||||
|
||||
async def reset_card_button_refresh(self):
|
||||
button = self.reset_card_button
|
||||
t = self.bot.translator.t
|
||||
button.label = t(_p(
|
||||
'ui:skineditor|button:reset_card|label',
|
||||
"Reset Card"
|
||||
))
|
||||
|
||||
# Reset all button
|
||||
@button(
|
||||
label="RESET_ALL_BUTTON_PLACEHOLDER",
|
||||
style=ButtonStyle.red
|
||||
)
|
||||
async def reset_all_button(self, press: discord.Interaction, pressed: Button):
|
||||
await press.response.defer(thinking=True, ephemeral=True)
|
||||
|
||||
self.skin.properties.clear()
|
||||
self.skin.base_skin_name = None
|
||||
|
||||
self.push_state()
|
||||
await self.refresh(thinking=press)
|
||||
|
||||
async def reset_all_button_refresh(self):
|
||||
button = self.reset_all_button
|
||||
t = self.bot.translator.t
|
||||
button.label = t(_p(
|
||||
'ui:skineditor|button:reset_all|label',
|
||||
"Reset All"
|
||||
))
|
||||
|
||||
# Page selector
|
||||
@select(
|
||||
cls=Select,
|
||||
placeholder="PAGE_MENU_PLACEHOLDER",
|
||||
min_values=1, max_values=1
|
||||
)
|
||||
async def page_menu(self, selection: discord.Interaction, selected: Select):
|
||||
await selection.response.defer(thinking=True, ephemeral=True)
|
||||
self.page_index = int(selected.values[0])
|
||||
self.showing_skin_setting = None
|
||||
await self.refresh(thinking=selection)
|
||||
|
||||
async def page_menu_refresh(self):
|
||||
menu = self.page_menu
|
||||
t = self.bot.translator.t
|
||||
|
||||
options = []
|
||||
if not self.customising:
|
||||
menu.placeholder = t(_p(
|
||||
'ui:skineditor|menu:page|placeholder:preview',
|
||||
"Select a card to preview"
|
||||
))
|
||||
for i, page in enumerate(pages):
|
||||
if page.visible_in_preview:
|
||||
option = SelectOption(
|
||||
label=t(page.display_name),
|
||||
value=str(i),
|
||||
description=t(page.preview_description) if page.preview_description else None
|
||||
)
|
||||
option.default = (i == self.page_index)
|
||||
options.append(option)
|
||||
else:
|
||||
menu.placeholder = t(_p(
|
||||
'ui:skineditor|menu:page|placeholder:edit',
|
||||
"Select a card to customise"
|
||||
))
|
||||
for i, page in enumerate(pages):
|
||||
option = SelectOption(
|
||||
label=t(page.display_name),
|
||||
value=str(i),
|
||||
description=t(page.editing_description) if page.editing_description else None
|
||||
)
|
||||
option.default = (i == self.page_index)
|
||||
options.append(option)
|
||||
menu.options = options
|
||||
|
||||
# Setting group selector
|
||||
@select(
|
||||
cls=Select,
|
||||
placeholder="GROUP_MENU_PLACEHOLDER",
|
||||
min_values=1, max_values=1
|
||||
)
|
||||
async def group_menu(self, selection: discord.Interaction, selected: Select):
|
||||
groupid = selected.values[0]
|
||||
group = next(group for group in self.page.groups if group.custom_id == groupid)
|
||||
|
||||
if group.settings[0].input_type is SettingInputType.SkinInput:
|
||||
self.showing_skin_setting = group.settings[0]
|
||||
await selection.response.defer(thinking=True, ephemeral=True)
|
||||
await self.refresh(thinking=selection)
|
||||
else:
|
||||
await self._launch_group_editor(selection, group)
|
||||
|
||||
async def _launch_group_editor(self, interaction: discord.Interaction, group: SettingGroup):
|
||||
t = self.bot.translator.t
|
||||
|
||||
editable = group.editable_settings
|
||||
items = [
|
||||
setting.make_input_field(self.skin)
|
||||
for setting in editable
|
||||
]
|
||||
modal = SettingInput(*items, title=t(group.name))
|
||||
|
||||
@modal.submit_callback()
|
||||
async def group_modal_callback(interaction: discord.Interaction):
|
||||
values = []
|
||||
for item, setting in zip(items, editable):
|
||||
value = await setting.parse_input(self.skin, item.value)
|
||||
values.append(value)
|
||||
|
||||
await interaction.response.defer(thinking=True, ephemeral=True)
|
||||
for value, setting in zip(values, editable):
|
||||
setting.set_in(self.skin, value)
|
||||
|
||||
self.push_state()
|
||||
await self.refresh(thinking=interaction)
|
||||
|
||||
await interaction.response.send_modal(modal)
|
||||
|
||||
async def group_menu_refresh(self):
|
||||
menu = self.group_menu
|
||||
t = self.bot.translator.t
|
||||
menu.placeholder = t(_p(
|
||||
'ui:skineditor|menu:group|placeholder',
|
||||
"Select a group or option to customise"
|
||||
))
|
||||
options = []
|
||||
for group in self.page.groups:
|
||||
option = group.select_option_for(self.skin)
|
||||
options.append(option)
|
||||
menu.options = options
|
||||
|
||||
# Base skin selector
|
||||
@select(
|
||||
cls=Select,
|
||||
placeholder="SKIN_MENU_PLACEHOLDER",
|
||||
min_values=1, max_values=1
|
||||
)
|
||||
async def skin_menu(self, selection: discord.Interaction, selected: Select):
|
||||
await selection.response.defer(thinking=True, ephemeral=True)
|
||||
|
||||
skin_id = selected.values[0]
|
||||
if skin_id == 'default':
|
||||
skin_id = None
|
||||
|
||||
if self.customising:
|
||||
if self.showing_skin_setting:
|
||||
# Update the current page card with this skin id.
|
||||
self.showing_skin_setting.set_in(self.skin, skin_id)
|
||||
else:
|
||||
# Far more brutal
|
||||
# Update the global base skin id, and wipe the base skin id for each card
|
||||
self.skin.base_skin_name = skin_id
|
||||
for card_id in self.skin.properties:
|
||||
self.skin.set_prop(card_id, 'base_skin_id', None)
|
||||
|
||||
self.push_state()
|
||||
await self.refresh(thinking=selection)
|
||||
|
||||
async def skin_menu_refresh(self):
|
||||
menu = self.skin_menu
|
||||
t = self.bot.translator.t
|
||||
menu.placeholder = t(_p(
|
||||
'ui:skineditor|menu:skin|placeholder',
|
||||
"Select a theme"
|
||||
))
|
||||
options = []
|
||||
for skin in self.global_themes.values():
|
||||
option = appskin_as_option(skin)
|
||||
options.append(option)
|
||||
menu.options = options
|
||||
|
||||
# Quit button, with confirmation
|
||||
@button(style=ButtonStyle.grey, emoji=conf.emojis.cancel)
|
||||
async def quit_button(self, press: discord.Interaction, pressed: Button):
|
||||
# Confirm quit if there are unsaved changes
|
||||
if self.dirty:
|
||||
t = self.bot.translator.t
|
||||
confirm_msg = t(_p(
|
||||
'ui:skineditor|button:quit|confirm',
|
||||
"You have unsaved changes! Are you sure you want to quit?"
|
||||
))
|
||||
confirm = Confirm(confirm_msg, self._callerid)
|
||||
confirm.confirm_button.label = t(_p(
|
||||
'ui:skineditor|button:quit|confirm|button:yes',
|
||||
"Yes, Quit Now"
|
||||
))
|
||||
confirm.confirm_button.style = ButtonStyle.red
|
||||
confirm.cancel_button.style = ButtonStyle.green
|
||||
confirm.cancel_button.label = t(_p(
|
||||
'ui:skineditor|button:quit|confirm|button:no',
|
||||
"No, Go Back"
|
||||
))
|
||||
try:
|
||||
result = await confirm.ask(press, ephemeral=True)
|
||||
except ResponseTimedOut:
|
||||
result = False
|
||||
|
||||
if result:
|
||||
await self.quit()
|
||||
else:
|
||||
await self.quit()
|
||||
|
||||
@button(label="UNDO_BUTTON_PLACEHOLDER", style=ButtonStyle.blurple)
|
||||
async def undo_button(self, press: discord.Interaction, pressed: Button):
|
||||
"""
|
||||
Pop the history stack.
|
||||
"""
|
||||
if len(self.history) > 1:
|
||||
state = self.history.pop()
|
||||
self.future.append(state)
|
||||
|
||||
current = self.history[-1]
|
||||
self.skin.load_frozen(current)
|
||||
|
||||
await press.response.defer(thinking=True, ephemeral=True)
|
||||
await self.refresh(thinking=press)
|
||||
|
||||
async def undo_button_refresh(self):
|
||||
t = self.bot.translator.t
|
||||
button = self.undo_button
|
||||
button.label = t(_p(
|
||||
'ui:skineditor|button:undo|label',
|
||||
"Undo"
|
||||
))
|
||||
button.disabled = (len(self.history) <= 1)
|
||||
|
||||
@button(label="REDO_BUTTON_PLACEHOLDER", style=ButtonStyle.blurple)
|
||||
async def redo_button(self, press: discord.Interaction, pressed: Button):
|
||||
"""
|
||||
Pop the future stack.
|
||||
"""
|
||||
if len(self.future) > 0:
|
||||
state = self.future.pop()
|
||||
self.history.append(state)
|
||||
|
||||
current = self.history[-1]
|
||||
self.skin.load_frozen(current)
|
||||
|
||||
await press.response.defer(thinking=True, ephemeral=True)
|
||||
await self.refresh(thinking=press)
|
||||
|
||||
async def redo_button_refresh(self):
|
||||
t = self.bot.translator.t
|
||||
button = self.redo_button
|
||||
button.label = t(_p(
|
||||
'ui:skineditor|button:redo|label',
|
||||
"Redo"
|
||||
))
|
||||
button.disabled = (len(self.future) == 0)
|
||||
|
||||
# ----- UI Flow -----
|
||||
async def make_message(self) -> MessageArgs:
|
||||
page = self.page
|
||||
|
||||
embed = page.make_embed_for(self.skin)
|
||||
if page.render_card is not None:
|
||||
args = self.skin.args_for(page.render_card.card_id)
|
||||
args.setdefault('base_skin_id', self.cog.current_default)
|
||||
file = await page.render_card.generate_sample(skin=args)
|
||||
files = [file]
|
||||
else:
|
||||
files = []
|
||||
|
||||
return MessageArgs(embed=embed, files=files)
|
||||
|
||||
async def refresh_layout(self):
|
||||
"""
|
||||
Customising mode:
|
||||
(card_menu)
|
||||
(skin_menu?)
|
||||
(download, save, undo, redo, back,)
|
||||
Other:
|
||||
(card_menu)
|
||||
(theme_menu)
|
||||
(customise, save, reset_card, reset_all, X)
|
||||
"""
|
||||
to_refresh = (
|
||||
self.page_menu_refresh(),
|
||||
self.skin_menu_refresh(),
|
||||
self.undo_button_refresh(),
|
||||
self.redo_button_refresh(),
|
||||
self.reset_card_button_refresh(),
|
||||
self.reset_all_button_refresh(),
|
||||
self.customise_button_refresh(),
|
||||
self.back_button_refresh(),
|
||||
self.save_button_refresh(),
|
||||
self.group_menu_refresh(),
|
||||
self.download_button_refresh(),
|
||||
)
|
||||
await asyncio.gather(*to_refresh)
|
||||
|
||||
if self.customising:
|
||||
self.set_layout(
|
||||
(self.page_menu,),
|
||||
(self.group_menu,),
|
||||
(self.skin_menu,) if self.showing_skin_setting else (),
|
||||
(
|
||||
self.save_button,
|
||||
self.undo_button,
|
||||
self.redo_button,
|
||||
self.download_button,
|
||||
self.back_button,
|
||||
),
|
||||
)
|
||||
else:
|
||||
self.set_layout(
|
||||
(self.page_menu,),
|
||||
(self.skin_menu,),
|
||||
(
|
||||
self.customise_button,
|
||||
self.save_button,
|
||||
self.reset_card_button,
|
||||
self.reset_all_button,
|
||||
self.quit_button,
|
||||
),
|
||||
)
|
||||
|
||||
async def reload(self):
|
||||
...
|
||||
|
||||
async def pre_timeout(self):
|
||||
# Timeout confirmation
|
||||
if self.dirty:
|
||||
t = self.bot.translator.t
|
||||
grace_period = 60
|
||||
grace_time = utc_now() + dt.timedelta(seconds=grace_period)
|
||||
embed = discord.Embed(
|
||||
title=t(_p(
|
||||
'ui:skineditor|timeout_warning|title',
|
||||
"Warning!"
|
||||
)),
|
||||
description=t(_p(
|
||||
'ui:skineditor|timeout_warning|desc',
|
||||
"This interface will time out {timestamp}. Press 'Continue' below to keep editing."
|
||||
)).format(
|
||||
timestamp=discord.utils.format_dt(grace_time, style='R')
|
||||
),
|
||||
)
|
||||
|
||||
components = None
|
||||
stopped = False
|
||||
|
||||
@AButton(label=t(_p('ui:skineditor|timeout_warning|continue', "Continue")), style=ButtonStyle.green)
|
||||
async def cont_button(interaction: discord.Interaction, pressed):
|
||||
await interaction.response.defer()
|
||||
if interaction.message:
|
||||
await interaction.message.delete()
|
||||
nonlocal stopped
|
||||
stopped = True
|
||||
# TODO: Clean up this mess. It works, but needs to be refactored to a timeout confirmation mixin.
|
||||
# TODO: Consider moving the message to the interaction response
|
||||
self._refresh_timeout()
|
||||
components.stop()
|
||||
|
||||
components = AsComponents(cont_button, timeout=grace_period)
|
||||
channel = self._original.channel if self._original else self._message.channel
|
||||
|
||||
message = await channel.send(content=f"<@{self._callerid}>", embed=embed, view=components)
|
||||
await components.wait()
|
||||
|
||||
if not stopped:
|
||||
try:
|
||||
await message.delete()
|
||||
except discord.HTTPException:
|
||||
pass
|
||||
|
||||
@@ -0,0 +1,298 @@
|
||||
from typing import Literal, Optional
|
||||
from enum import Enum
|
||||
|
||||
from discord.ui import TextInput
|
||||
|
||||
from meta import LionBot
|
||||
from meta.errors import UserInputError
|
||||
from babel.translator import LazyStr
|
||||
from gui.base import Card, FieldDesc, AppSkin
|
||||
|
||||
from .. import babel
|
||||
from ..skinlib import CustomSkin
|
||||
|
||||
_p = babel._p
|
||||
|
||||
|
||||
class SettingInputType(Enum):
|
||||
SkinInput = -1
|
||||
ModalInput = 0
|
||||
MenuInput = 1
|
||||
ButtonInput = 2
|
||||
|
||||
|
||||
class Setting:
|
||||
"""
|
||||
An abstract base interface for a custom skin 'setting'.
|
||||
|
||||
A skin setting is considered to be some readable and usually writeable
|
||||
information extractable from a `CustomSkin`.
|
||||
This will usually consist of the value of one or more properties,
|
||||
which are themselves associated to fields of GUI Cards.
|
||||
|
||||
The methods in this ABC describe the interface for such a setting.
|
||||
Each method accepts a `CustomSkin`,
|
||||
and an implementation should describe how to
|
||||
get, set, parse, format, or display the setting
|
||||
for that given skin.
|
||||
|
||||
This is very similar to how Settings are implemented in the bot,
|
||||
except here all settings have a shared external source of state, the CustomSkin.
|
||||
Thus, each setting is simply an instance of an appropriate setting class,
|
||||
rather than a class itself.
|
||||
"""
|
||||
|
||||
# What type of input method this setting requires for input
|
||||
input_type: SettingInputType = SettingInputType.ModalInput
|
||||
|
||||
def __init__(self, *args, display_name, description, **kwargs):
|
||||
self.display_name: LazyStr = display_name
|
||||
self.description: LazyStr = description
|
||||
|
||||
def default_value_in(self, skin: CustomSkin) -> Optional[str]:
|
||||
"""
|
||||
The default value of this setting in this skin.
|
||||
|
||||
This takes into account base skin data and localisation.
|
||||
May be `None` if the setting does not have a default value.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def value_in(self, skin: CustomSkin) -> Optional[str]:
|
||||
"""
|
||||
The current value of this setting from this skin.
|
||||
|
||||
May be None if the setting is not set or does not have a value.
|
||||
Usually should not take into account defaults.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def set_in(self, skin: CustomSkin, value: Optional[str]):
|
||||
"""
|
||||
Set this setting to the given value in this skin.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def format_value_in(self, skin: CustomSkin, value: Optional[str]) -> str:
|
||||
"""
|
||||
Format the given setting value for display (typically in a setting table).
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
async def parse_input(self, skin: CustomSkin, userstr: str) -> Optional[str]:
|
||||
"""
|
||||
Parse a user provided string into a value for this setting.
|
||||
|
||||
Will raise 'UserInputError' with a readable message if parsing fails.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def make_input_field(self, skin: CustomSkin) -> TextInput:
|
||||
"""
|
||||
Create a TextInput field for this setting, using the current value.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class PropertySetting(Setting):
|
||||
"""
|
||||
A skin setting corresponding to a single property of a single card.
|
||||
|
||||
Note that this is still abstract,
|
||||
as it does not implement any formatting or parsing methods.
|
||||
|
||||
This will usually (but may not always) correspond to a single Field of the card skin.
|
||||
"""
|
||||
def __init__(self, card: type[Card], property_name: str, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
self.card = card
|
||||
self.property_name = property_name
|
||||
|
||||
@property
|
||||
def card_id(self):
|
||||
"""
|
||||
The `card_id` of the Card class this setting belongs to.
|
||||
"""
|
||||
return self.card.card_id
|
||||
|
||||
@property
|
||||
def field(self) -> Optional[FieldDesc]:
|
||||
"""
|
||||
The CardSkin field overwrriten by this setting, if it exists.
|
||||
"""
|
||||
return self.card.skin._fields.get(self.property_name, None)
|
||||
|
||||
def default_value_in(self, skin: CustomSkin) -> Optional[str]:
|
||||
"""
|
||||
For a PropertySetting, the default value is determined as follows:
|
||||
base skin value from:
|
||||
- card base skin
|
||||
- custom base skin
|
||||
- global app base skin
|
||||
fallback (field) value from the CardSkin
|
||||
"""
|
||||
base_skin = skin.get_prop(self.card_id, 'base_skin_id')
|
||||
base_skin = base_skin or skin.base_skin_name
|
||||
base_skin = base_skin or skin.cog.current_default
|
||||
|
||||
app_skin_args = AppSkin.get(base_skin).for_card(self.card_id)
|
||||
|
||||
if self.property_name in app_skin_args:
|
||||
return app_skin_args[self.property_name]
|
||||
elif self.field:
|
||||
return self.field.default
|
||||
else:
|
||||
return None
|
||||
|
||||
def value_in(self, skin: CustomSkin) -> Optional[str]:
|
||||
return skin.get_prop(self.card_id, self.property_name)
|
||||
|
||||
def set_in(self, skin: CustomSkin, value: Optional[str]):
|
||||
skin.set_prop(self.card_id, self.property_name, value)
|
||||
|
||||
|
||||
class _ColourInterface(Setting):
|
||||
"""
|
||||
Skin setting mixin for parsing and formatting colour typed settings.
|
||||
"""
|
||||
|
||||
def format_value_in(self, skin: CustomSkin, value: Optional[str]) -> str:
|
||||
if value:
|
||||
formatted = f"`{value}`"
|
||||
else:
|
||||
formatted = skin.bot.translator.t(_p(
|
||||
'skinsettings|colours|format:not_set',
|
||||
"Not Set"
|
||||
))
|
||||
return formatted
|
||||
|
||||
async def parse_input(self, skin: CustomSkin, userstr: str) -> Optional[str]:
|
||||
stripped = userstr.strip('# ').upper()
|
||||
if not stripped:
|
||||
value = None
|
||||
elif len(stripped) not in (6, 8) or any(c not in '0123456789ABCDEF' for c in stripped):
|
||||
raise UserInputError(
|
||||
skin.bot.translator.t(_p(
|
||||
'skinsettings|colours|parse|error:invalid',
|
||||
"Could not parse `{given}` as a colour!"
|
||||
" Please use RGB/RGBA format (e.g. `#ABABABF0`)."
|
||||
)).format(given=userstr)
|
||||
)
|
||||
else:
|
||||
value = f"#{stripped}"
|
||||
return value
|
||||
|
||||
def make_input_field(self, skin: CustomSkin) -> TextInput:
|
||||
t = skin.bot.translator.t
|
||||
|
||||
value = self.value_in(skin)
|
||||
default_value = self.default_value_in(skin)
|
||||
|
||||
label = t(self.display_name)
|
||||
default = value
|
||||
if default_value:
|
||||
placeholder = f"{default_value} ({t(self.description)})"
|
||||
else:
|
||||
placeholder = t(self.description)
|
||||
|
||||
return TextInput(
|
||||
label=label,
|
||||
placeholder=placeholder,
|
||||
default=default,
|
||||
min_length=0,
|
||||
max_length=9,
|
||||
required=False,
|
||||
)
|
||||
|
||||
|
||||
class ColourSetting(_ColourInterface, PropertySetting):
|
||||
"""
|
||||
A Property skin setting representing a single colour field.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class SkinSetting(PropertySetting):
|
||||
"""
|
||||
A Property setting representing the base skin of a card.
|
||||
"""
|
||||
input_type = SettingInputType.SkinInput
|
||||
|
||||
def format_value_in(self, skin: CustomSkin, value: Optional[str]) -> str:
|
||||
if value:
|
||||
app_skin = AppSkin.get(value)
|
||||
formatted = f"`{app_skin.display_name}`"
|
||||
else:
|
||||
formatted = skin.bot.translator.t(_p(
|
||||
'skinsettings|base_skin|format:not_set',
|
||||
"Default"
|
||||
))
|
||||
return formatted
|
||||
|
||||
def default_value_in(self, skin: CustomSkin) -> Optional[str]:
|
||||
return skin.base_skin_name
|
||||
|
||||
|
||||
class CompoundSetting(Setting):
|
||||
"""
|
||||
A Setting combining several PropertySettings across (potentially) multiple cards.
|
||||
"""
|
||||
NOTSHARED = ''
|
||||
|
||||
def __init__(self, *settings: PropertySetting, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
self.settings = settings
|
||||
|
||||
def default_value_in(self, skin: CustomSkin) -> Optional[str]:
|
||||
"""
|
||||
The default value of a CompoundSetting is the shared default of the component settings.
|
||||
|
||||
If the components do not share a default value, returns None.
|
||||
"""
|
||||
value = None
|
||||
for setting in self.settings:
|
||||
setting_value = setting.default_value_in(skin)
|
||||
if setting_value is None:
|
||||
value = None
|
||||
break
|
||||
if value is None:
|
||||
value = setting_value
|
||||
elif value != setting_value:
|
||||
value = None
|
||||
break
|
||||
return value
|
||||
|
||||
def value_in(self, skin: CustomSkin) -> Optional[str]:
|
||||
"""
|
||||
The value of a compound setting is the shared value of the components.
|
||||
"""
|
||||
value = self.NOTSHARED
|
||||
for setting in self.settings:
|
||||
setting_value = setting.value_in(skin) or setting.default_value_in(skin)
|
||||
|
||||
if value is self.NOTSHARED:
|
||||
value = setting_value
|
||||
elif value != setting_value:
|
||||
value = self.NOTSHARED
|
||||
break
|
||||
return value
|
||||
|
||||
def set_in(self, skin: CustomSkin, value: Optional[str]):
|
||||
"""
|
||||
Set all of the components individually.
|
||||
"""
|
||||
for setting in self.settings:
|
||||
setting.set_in(skin, value)
|
||||
|
||||
|
||||
class ColoursSetting(_ColourInterface, CompoundSetting):
|
||||
"""
|
||||
Compound setting representing multiple colours.
|
||||
"""
|
||||
def format_value_in(self, skin: CustomSkin, value: Optional[str]) -> str:
|
||||
if value is self.NOTSHARED:
|
||||
return "Mixed"
|
||||
elif value is None:
|
||||
return "Not Set"
|
||||
else:
|
||||
return f"`{value}`"
|
||||
|
||||
@@ -16,6 +16,7 @@ _p = babel._p
|
||||
class GlobalSkinSettings(SettingGroup):
|
||||
class DefaultSkin(ModelData, StringSetting):
|
||||
setting_id = 'default_app_skin'
|
||||
_event = 'botset_skin'
|
||||
_write_ward = sys_admin_iward
|
||||
|
||||
_display_name = _p(
|
||||
|
||||
@@ -110,7 +110,7 @@ class CustomSkin:
|
||||
async with conn.transaction():
|
||||
skinid = self.skinid
|
||||
await self.data.update(base_skin_id=self.base_skin_id)
|
||||
await self.cog.data.skin_properties.delete_where(skinid=skinid)
|
||||
await self.cog.data.skin_properties.delete_where(custom_skin_id=skinid)
|
||||
|
||||
props = {
|
||||
(card, name): value
|
||||
@@ -122,31 +122,37 @@ class CustomSkin:
|
||||
await self.cog.fetch_property_ids(*props.keys())
|
||||
|
||||
# Now bulk insert
|
||||
await self.cog.data.skin_properties.insert_many(
|
||||
('custom_skin_id', 'property_id', 'value'),
|
||||
*(
|
||||
(skinid, self.cog.skin_properties[propkey], value)
|
||||
for propkey, value in props.items()
|
||||
if props:
|
||||
await self.cog.data.skin_properties.insert_many(
|
||||
('custom_skin_id', 'property_id', 'value'),
|
||||
*(
|
||||
(skinid, self.cog.skin_properties.inverse[propkey], value)
|
||||
for propkey, value in props.items()
|
||||
)
|
||||
)
|
||||
)
|
||||
await self.bot.global_dispatch('skin_updated', skinid)
|
||||
|
||||
def get_prop(self, card_id: str, prop_name: str) -> Optional[str]:
|
||||
return self.properties.get(card_id, {}).get(prop_name, None)
|
||||
|
||||
def set_prop(self, card_id: str, prop_name: str, value: Optional[str]):
|
||||
cardprops = self.properties.get(card_id, None)
|
||||
if value is None:
|
||||
if cardprops is not None:
|
||||
cardprops.pop(prop_name, None)
|
||||
else:
|
||||
if cardprops is None:
|
||||
cardprops = self.properties[card_id] = {}
|
||||
cardprops[prop_name] = value
|
||||
|
||||
def resolve_propid(self, propid: int) -> tuple[str, str]:
|
||||
return self.cog.skin_properties[propid]
|
||||
|
||||
def __getitem__(self, propid: int) -> Optional[str]:
|
||||
card, name = self.resolve_propid(propid)
|
||||
return self.properties.get(card, {}).get(name, None)
|
||||
return self.get_prop(*self.resolve_propid(propid))
|
||||
|
||||
def __setitem__(self, propid: int, value: Optional[str]):
|
||||
card, name = self.resolve_propid(propid)
|
||||
cardprops = self.properties.get(card, None)
|
||||
if value is None:
|
||||
if cardprops is not None:
|
||||
cardprops.pop(name, None)
|
||||
else:
|
||||
if cardprops is None:
|
||||
cardprops = self.properties[card] = {}
|
||||
cardprops[name] = value
|
||||
return self.set_prop(*self.resolve_propid(propid), value)
|
||||
|
||||
def __delitem__(self, propid: int):
|
||||
card, name = self.resolve_propid(propid)
|
||||
@@ -163,7 +169,7 @@ class CustomSkin:
|
||||
Update state from the given frozen state.
|
||||
"""
|
||||
self.base_skin_name = frozen.base_skin_name
|
||||
self.properties = dict((card, dict(props)) for card, props in frozen.properties)
|
||||
self.properties = dict((card, dict(props)) for card, props in frozen.properties.items())
|
||||
return self
|
||||
|
||||
def args_for(self, card_id: str):
|
||||
|
||||
Reference in New Issue
Block a user