Added updating role group messages and exclusive roles

Added a context menu for messages for updating a role group message.
Ideally this would be done automatically, but this works fine for now.
Alternatively, this may be ideal if one doesn't want changes to immediately propagate.

Added the option for some role groups to have their roles be mutually exclusive.
I.e. one would only be able to pick one role from the group.
This commit is contained in:
Vegard Berg 2022-08-04 00:56:46 +02:00
parent 7e2f113c52
commit 40b347c875
2 changed files with 153 additions and 21 deletions

View File

@ -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",

View File

@ -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")