From 2b2b42388df0d7beddbdd7bb0c19c48c0db34458 Mon Sep 17 00:00:00 2001 From: seria Date: Tue, 5 Mar 2024 19:42:52 +0800 Subject: [PATCH] feat: Allow users to choose default account for commands --- migrations/models/4_20240305192811_update.py | 8 ++++++++ src/cogs/hoyo.py | 20 ++++++++++++++------ src/db/models.py | 9 +++++---- src/ui/account/items/acc_select.py | 10 +++++++--- src/ui/account/items/add_acc_select.py | 4 ++-- src/ui/account/items/with_email_pswd.py | 4 ++-- src/ui/account/view.py | 13 +++++++++---- 7 files changed, 47 insertions(+), 21 deletions(-) create mode 100644 migrations/models/4_20240305192811_update.py diff --git a/migrations/models/4_20240305192811_update.py b/migrations/models/4_20240305192811_update.py new file mode 100644 index 00000000..5d8348ef --- /dev/null +++ b/migrations/models/4_20240305192811_update.py @@ -0,0 +1,8 @@ +async def upgrade(db) -> str: + return """ + ALTER TABLE "hoyoaccount" ADD "current" BOOL NOT NULL DEFAULT False;""" + + +async def downgrade(db) -> str: + return """ + ALTER TABLE "hoyoaccount" DROP COLUMN "current";""" diff --git a/src/cogs/hoyo.py b/src/cogs/hoyo.py index a2be8c95..041999cd 100644 --- a/src/cogs/hoyo.py +++ b/src/cogs/hoyo.py @@ -156,8 +156,9 @@ def _get_error_app_command_choice(error_message: str) -> app_commands.Choice[str ) @app_commands.describe( account=app_commands.locale_str( - "Account to run this command with, defaults to the first one", + "Account to run this command with, defaults to the selected one in /accounts", key="account_autocomplete_param_description", + replace_command_mentions=False, ) ) async def checkin_command( @@ -166,10 +167,13 @@ async def checkin_command( account: app_commands.Transform[HoyoAccount | None, HoyoAccountTransformer] = None, ) -> Any: settings = await Settings.get(user_id=i.user.id) + account = ( + account + or await HoyoAccount.filter(user_id=i.user.id, current=True).first() + or await HoyoAccount.filter(user_id=i.user.id).first() + ) if account is None: - account = await HoyoAccount.filter(user_id=i.user.id).first() - if account is None: - raise NoAccountFoundError + raise NoAccountFoundError view = CheckInUI( account, @@ -475,8 +479,9 @@ async def search_command_query_autocomplete( ) @app_commands.describe( account=app_commands.locale_str( - "Account to run this command with, defaults to the first one", + "Account to run this command with, defaults to the selected one in /accounts", key="account_autocomplete_param_description", + replace_command_mentions=False, ), uid=app_commands.locale_str( "UID of the player, this overrides the account parameter if provided", @@ -559,7 +564,10 @@ async def _get_uid_and_game( ) game = Game(game_value) elif account is None: - account_ = await HoyoAccount.filter(user_id=user_id).first() + account_ = ( + await HoyoAccount.filter(user_id=user_id, current=True).first() + or await HoyoAccount.filter(user_id=user_id).first() + ) if account_ is None: raise NoAccountFoundError uid_ = account_.uid diff --git a/src/db/models.py b/src/db/models.py index 27ee621f..ad5749b7 100644 --- a/src/db/models.py +++ b/src/db/models.py @@ -14,7 +14,7 @@ class User(Model): id = fields.BigIntField(pk=True, index=True, generated=False) # noqa: A003 settings: fields.BackwardOneToOneRelation["Settings"] - temp_data: dict[str, Any] = fields.JSONField(default=dict) # type: ignore + temp_data: fields.Field[dict[str, Any]] = fields.JSONField(default=dict) # type: ignore accounts: fields.ReverseRelation["HoyoAccount"] def __str__(self) -> str: @@ -32,6 +32,7 @@ class HoyoAccount(Model): "models.User", related_name="accounts" ) daily_checkin = fields.BooleanField(default=True) + current = fields.BooleanField(default=False) notif_settings: fields.BackwardOneToOneRelation["AccountNotifSettings"] class Meta: @@ -75,10 +76,10 @@ class CardSettings(Model): "models.User", related_name="card_settings" ) dark_mode = fields.BooleanField() - custom_images: list[str] = fields.JSONField(default=[]) # type: ignore + custom_images: fields.Field[list[str]] = fields.JSONField(default=[]) # type: ignore """URLs of custom images.""" - custom_primary_color: str | None = fields.CharField(max_length=7, null=True) # type: ignore - current_image: str | None = fields.CharField(max_length=100, null=True) # type: ignore + custom_primary_color: fields.Field[str | None] = fields.CharField(max_length=7, null=True) # type: ignore + current_image: fields.Field[str | None] = fields.CharField(max_length=100, null=True) # type: ignore template = fields.CharField(max_length=32, default="hb1") class Meta: diff --git a/src/ui/account/items/acc_select.py b/src/ui/account/items/acc_select.py index 7395ee82..200d4063 100644 --- a/src/ui/account/items/acc_select.py +++ b/src/ui/account/items/acc_select.py @@ -2,6 +2,8 @@ from discord.utils import get as dget +from src.db.models import HoyoAccount + from ...components import Select, SelectOption if TYPE_CHECKING: @@ -17,9 +19,11 @@ def __init__(self, options: list[SelectOption]) -> None: async def callback(self, i: "INTERACTION") -> None: uid, game = self.values[0].split("_") selected_account = dget(self.view.accounts, uid=int(uid), game__value=game) - if selected_account is None: - msg = "Invalid account selected" - raise ValueError(msg) + assert selected_account is not None + + await HoyoAccount.filter(user=self.view.user).update(current=False) + selected_account.current = True + await selected_account.save(update_fields=["current"]) self.view.selected_account = selected_account await self.view.refresh(i, soft=True) diff --git a/src/ui/account/items/add_acc_select.py b/src/ui/account/items/add_acc_select.py index 7b55475d..3bc1a03e 100644 --- a/src/ui/account/items/add_acc_select.py +++ b/src/ui/account/items/add_acc_select.py @@ -5,10 +5,10 @@ from tortoise.exceptions import IntegrityError from src.bot.translator import LocaleStr +from src.db.models import AccountNotifSettings, HoyoAccount from src.emojis import get_game_emoji +from src.enums import GAME_CONVERTER -from ....db.models import AccountNotifSettings, HoyoAccount -from ....enums import GAME_CONVERTER from ...components import Select, SelectOption if TYPE_CHECKING: diff --git a/src/ui/account/items/with_email_pswd.py b/src/ui/account/items/with_email_pswd.py index 5a234272..be31395e 100644 --- a/src/ui/account/items/with_email_pswd.py +++ b/src/ui/account/items/with_email_pswd.py @@ -8,11 +8,11 @@ from discord import ButtonStyle from src.bot.translator import LocaleStr +from src.db.models import User from src.embeds import DefaultEmbed, ErrorEmbed from src.emojis import PASSWORD +from src.hoyo.dataclasses import LoginNotifPayload -from ....db.models import User -from ....hoyo.dataclasses import LoginNotifPayload from ...components import Button, GoBackButton, Modal, TextInput from .add_acc_select import AddAccountSelect diff --git a/src/ui/account/view.py b/src/ui/account/view.py index e0d35111..d22fd5d1 100644 --- a/src/ui/account/view.py +++ b/src/ui/account/view.py @@ -38,7 +38,9 @@ def __init__( async def init(self) -> None: if self.accounts: - self.selected_account = self.accounts[0] + self.selected_account = ( + next((a for a in self.accounts if a.current), None) or self.accounts[0] + ) self.add_item(AccountSelect(self.get_account_options())) self.add_item(AddAccountButton()) self.add_item(EditNicknameButton()) @@ -69,19 +71,22 @@ def get_account_embed(self) -> DefaultEmbed: embed.add_field( name=LocaleStr("Game", key="account_game"), value=LocaleStr(account.game.value, warn_no_key=False), - inline=False, ) embed.add_field( name=LocaleStr("Server", key="account_server"), value=LocaleStr(account.server, warn_no_key=False), - inline=False, ) if account.nickname: embed.add_field( name=LocaleStr("Username", key="account_username"), value=account.username, - inline=False, ) + embed.set_footer( + text=LocaleStr( + "Selected account will be the default one used for all commands", + key="account_manager_footer", + ) + ) return embed def get_account_options(self) -> list[SelectOption]: