diff --git a/commands/self_roles.py b/commands/self_roles.py index 0e3ad59..acaea6e 100644 --- a/commands/self_roles.py +++ b/commands/self_roles.py @@ -16,7 +16,9 @@ from naff import ( Select, SelectOption, listen, - component_callback, + context_menu, + CommandTypes, + Message, ) from naff.api import events from naff import components @@ -124,8 +126,18 @@ class SelfRoles(Extension): required=False, opt_type=OptionTypes.STRING, ) + @slash_option( + name="exclusive", + description="Whether each role in this group is exclusive", + required=False, + opt_type=OptionTypes.BOOLEAN, + ) async def role_group_add_group( - self, ctx: InteractionContext, group: str, description: str = None + self, + ctx: InteractionContext, + group: str, + description: str = None, + exclusive: bool = False, ): await ctx.defer(ephemeral=True) @@ -133,6 +145,7 @@ class SelfRoles(Extension): guild_id=int(ctx.guild_id), group_name=group, group_description=description, + exclusive=exclusive, ).on_conflict_replace().execute() await ctx.send( @@ -391,18 +404,28 @@ class SelfRoles(Extension): autocomplete=True, ) async def role_group_generate(self, ctx: InteractionContext, group: str): - await ctx.defer(ephemeral=False) + await ctx.defer(ephemeral=True) roles_q: List[SelfRolesModel] = ( - SelfRolesModel.select(SelfRolesModel.role_name, SelfRolesModel.role_id, SelfRolesModel.role_description) - .join(SelfRoleGroupRelationsModel, on=(SelfRolesModel.role_id == SelfRoleGroupRelationsModel.role_id)) + SelfRolesModel.select( + SelfRolesModel.role_name, + SelfRolesModel.role_id, + SelfRolesModel.role_description, + ) + .join( + SelfRoleGroupRelationsModel, + on=(SelfRolesModel.role_id == SelfRoleGroupRelationsModel.role_id), + ) .where( SelfRoleGroupRelationsModel.guild_id == int(ctx.guild_id), SelfRoleGroupRelationsModel.group_name == group, - ).objects() + ) + .objects() ) - group_q = SelfRoleGroupsModel.get(SelfRoleGroupsModel.group_name == group) + group_q: SelfRoleGroupsModel = SelfRoleGroupsModel.get( + SelfRoleGroupsModel.group_name == group + ) options = [] for role in roles_q: @@ -413,15 +436,17 @@ class SelfRoles(Extension): ) options.append(opt) + max_vals = 1 if group_q.exclusive else len(options) + select = Select( options=options, placeholder=f"Select roles from the group {group}", custom_id=f"role-group-assign:{group}", min_values=0, - max_values=len(options), + max_values=max_vals, ) - await ctx.send( + msg = await ctx.channel.send( embed=Embed( title=f"{group}", description=group_q.group_description, @@ -429,7 +454,11 @@ class SelfRoles(Extension): components=select, ) - + if msg is not None: + await ctx.send("Created!", ephemeral=True) + else: + await ctx.send("Failed to create message!", ephemeral=True) + @role_group_generate.autocomplete("group") async def role_group_generate_group_autocomplete( self, ctx: AutocompleteContext, group: str @@ -457,12 +486,21 @@ class SelfRoles(Extension): role_ids = [int(r) for r in ctx.values] roles_q: List[SelfRolesModel] = ( - SelfRolesModel.select(SelfRolesModel.role_name, SelfRolesModel.role_id, SelfRolesModel.requires, SelfRoleGroupRelationsModel.group_name) - .join(SelfRoleGroupRelationsModel, on=(SelfRolesModel.role_id == SelfRoleGroupRelationsModel.role_id)) + SelfRolesModel.select( + SelfRolesModel.role_name, + SelfRolesModel.role_id, + SelfRolesModel.requires, + SelfRoleGroupRelationsModel.group_name, + ) + .join( + SelfRoleGroupRelationsModel, + on=(SelfRolesModel.role_id == SelfRoleGroupRelationsModel.role_id), + ) .where( SelfRoleGroupRelationsModel.guild_id == int(ctx.guild_id), SelfRoleGroupRelationsModel.group_name == group, - ).objects() + ) + .objects() ) actions = [] @@ -471,7 +509,9 @@ class SelfRoles(Extension): if not ctx.author.has_role(role.role_id): if not role.requires is None: if not ctx.author.has_role(role.requires): - actions.append(f"{role.role_name} requires {role.requires} and was not added.") + actions.append( + f"{role.role_name} requires {role.requires} and was not added." + ) continue await ctx.author.add_role(role.role_id) @@ -480,20 +520,110 @@ class SelfRoles(Extension): if ctx.author.has_role(role.role_id): if not role.requires is None: if not ctx.author.has_role(role.requires): - actions.append(f"{role.role_name} requires {role.requires} to be managed, and was therefore not removed.") + actions.append( + f"{role.role_name} requires {role.requires} to be managed, and was therefore not removed." + ) continue await ctx.author.remove_role(role.role_id) actions.append(f"Removed role {role.role_name}") - await ctx.send( - content="\n".join(actions), - ephemeral=True, + if len(actions) == 0: + await ctx.send("No roles were added or removed.") + else: + await ctx.send( + content="\n".join(actions), + ephemeral=True, + ) + + @context_menu( + name="Regenerate group", + context_type=CommandTypes.MESSAGE, + dm_permission=False, + default_member_permissions=Permissions.MANAGE_ROLES, + ) + async def role_group_regenerate(self, ctx: InteractionContext): + await ctx.defer(ephemeral=True) + msg: Message = ctx.target + + if msg.author.id != self.client.user.id: + await ctx.send("This message is not from the bot!", ephemeral=True) + return + + if ( + len(msg.embeds) < 1 + or msg.embeds[0].title is None + or len(msg.components) < 1 + or len(msg.components[0].components) < 1 + or not isinstance(msg.components[0].components[0], Select) + or not msg.components[0].components[0].custom_id.startswith("role-group-assign") + ): + await ctx.send("Could not identify this as a role-group message!", ephemeral=True) + return + + embed = msg.embeds[0] + group = msg.components[0].components[0].custom_id.split(":")[1] + if ( + group is None + or group == "" + or embed.title != group + ): + await ctx.send("Could not identify this as a role-group message!", ephemeral=True) + return + + roles_q: List[SelfRolesModel] = ( + SelfRolesModel.select( + SelfRolesModel.role_name, + SelfRolesModel.role_id, + SelfRolesModel.role_description, + ) + .join( + SelfRoleGroupRelationsModel, + on=(SelfRolesModel.role_id == SelfRoleGroupRelationsModel.role_id), + ) + .where( + SelfRoleGroupRelationsModel.guild_id == int(ctx.guild_id), + SelfRoleGroupRelationsModel.group_name == group, + ) + .objects() ) + group_q: SelfRoleGroupsModel = SelfRoleGroupsModel.get( + SelfRoleGroupsModel.group_name == group + ) + + options = [] + for role in roles_q: + opt = SelectOption( + label=role.role_name, + value=str(role.role_id), + description=role.role_description, + ) + options.append(opt) + + max_vals = 1 if group_q.exclusive else len(options) + + select = Select( + options=options, + placeholder=f"Select roles from the group {group}", + custom_id=f"role-group-assign:{group}", + min_values=0, + max_values=max_vals, + ) + + msg = await msg.edit( + embed=Embed( + title=f"{group}", + description=group_q.group_description, + ), + components=select, + ) + + await ctx.send("Role group message regenerated!", ephemeral=True) + + + - - - + @slash_command( name="role", diff --git a/database.py b/database.py index 4c1c9a6..e443044 100644 --- a/database.py +++ b/database.py @@ -122,6 +122,8 @@ class SelfRoleGroups(Model): """The name of the self-role group.""" group_description = TextField(null=True) """The description of the self-role group.""" + exclusive = BooleanField(default=False) + """Whether the self-role group is exclusive.""" class Meta: primary_key = CompositeKey("guild_id", "group_name")