Compare commits

...

2 Commits

2 changed files with 67 additions and 20 deletions

2
.gitignore vendored
View File

@@ -27,3 +27,5 @@ Thumbs.db
# Runtime artifacts
*.log
.codex

View File

@@ -98,6 +98,9 @@ class TempVoiceDashboardView(discord.ui.View):
ephemeral=True,
)
return
allowed, _ = await self.cog._validate_interaction_access(interaction, channel)
if not allowed:
return
await interaction.response.send_modal(TempVoiceInputModal(self.cog, action, channel.id))
@discord.ui.button(
@@ -318,7 +321,7 @@ class TempVoice(commands.Cog):
def _can_control_tempvoice_channel(self, member: discord.Member, owner_id: Optional[int]) -> bool:
if owner_id is None:
return False
return member.id == owner_id or member.guild_permissions.manage_guild
return member.id == owner_id
async def _find_message_target(
self, guild: discord.Guild, preferred_voice: Optional[discord.VoiceChannel] = None
@@ -344,9 +347,17 @@ class TempVoice(commands.Cog):
return ch
return None
def _build_dashboard_embed(self, guild: discord.Guild, channel: discord.VoiceChannel, owner_id: int) -> discord.Embed:
def _build_dashboard_embed(
self,
guild: discord.Guild,
channel: discord.VoiceChannel,
owner_id: int,
*,
is_private: Optional[bool] = None,
) -> discord.Embed:
everyone = guild.default_role
overwrite = channel.overwrites_for(everyone)
if is_private is None:
is_private = overwrite.connect is False or overwrite.view_channel is False
owner_mention = f"<@{owner_id}>"
@@ -579,22 +590,28 @@ class TempVoice(commands.Cog):
return False, None
if not self._can_control_tempvoice_channel(interaction.user, owner_id):
await interaction.response.send_message(
_("Only the channel owner (or server manager) can use this panel."),
_("Only the current channel owner can use this panel."),
ephemeral=True,
)
return False, owner_id
return True, owner_id
async def _send_interaction_notice(self, interaction: discord.Interaction, message: str) -> None:
if interaction.response.is_done():
await interaction.followup.send(message, ephemeral=True)
else:
await interaction.response.send_message(message, ephemeral=True)
async def handle_panel_button(
self, interaction: discord.Interaction, action: str, channel: Optional[discord.VoiceChannel]
):
allowed, _ = await self._validate_interaction_access(interaction, channel)
allowed, owner_id = await self._validate_interaction_access(interaction, channel)
if not allowed or channel is None:
return
guild = interaction.guild
assert guild is not None
me = guild.me
if me is None or not guild.me.guild_permissions.manage_channels:
if me is None or not channel.permissions_for(me).manage_channels:
await interaction.response.send_message(
_("I need Manage Channels permission to modify this channel."),
ephemeral=True,
@@ -602,35 +619,53 @@ class TempVoice(commands.Cog):
return
if action == "toggle_private":
await interaction.response.defer(ephemeral=True)
everyone = guild.default_role
ow = channel.overwrites_for(everyone)
currently_private = ow.connect is False or ow.view_channel is False
new_is_private = not currently_private
if currently_private:
ow.connect = None
ow.view_channel = None
new_state = _("public")
else:
ow.connect = False
ow.view_channel = False
new_state = _("private")
try:
await channel.set_permissions(
everyone, overwrite=ow, reason=f"TempVoice panel toggle {new_state}"
everyone,
view_channel=not new_is_private,
connect=not new_is_private,
reason=f"TempVoice panel toggle {new_state}",
)
await interaction.response.send_message(
if interaction.message is not None and owner_id is not None:
embed = self._build_dashboard_embed(
guild,
channel,
owner_id,
is_private=new_is_private,
)
await interaction.message.edit(embed=embed, view=self._dashboard_view)
await self._send_interaction_notice(
interaction,
_("Channel visibility changed. New state: {state}.").format(state=new_state),
ephemeral=True,
)
await self._refresh_dashboard_message(interaction, channel)
except discord.Forbidden:
await interaction.response.send_message(
await self._send_interaction_notice(
interaction,
_("I cannot update channel permissions."),
ephemeral=True,
)
except discord.HTTPException:
await interaction.response.send_message(
await self._send_interaction_notice(
interaction,
_("Discord rejected the permission update."),
ephemeral=True,
)
except Exception:
log.exception(
"Unexpected error while toggling TempVoice privacy for channel %s in guild %s.",
channel.id,
guild.id,
)
await self._send_interaction_notice(
interaction,
_("Unexpected error while updating channel permissions."),
)
return
@@ -658,6 +693,7 @@ class TempVoice(commands.Cog):
if me is None:
await interaction.response.send_message(_("Bot state is not ready."), ephemeral=True)
return
bot_channel_perms = channel.permissions_for(me)
try:
if action == "change_limit":
@@ -669,7 +705,7 @@ class TempVoice(commands.Cog):
if value < 0 or value > 99:
await interaction.response.send_message(_("User limit must be between 0 and 99."), ephemeral=True)
return
if not me.guild_permissions.manage_channels:
if not bot_channel_perms.manage_channels:
await interaction.response.send_message(
_("I need Manage Channels permission to change the user limit."),
ephemeral=True,
@@ -684,7 +720,7 @@ class TempVoice(commands.Cog):
return
if action == "change_name":
if not me.guild_permissions.manage_channels:
if not bot_channel_perms.manage_channels:
await interaction.response.send_message(
_("I need Manage Channels permission to change channel name."),
ephemeral=True,
@@ -709,8 +745,17 @@ class TempVoice(commands.Cog):
if target is None:
await interaction.response.send_message(_("Could not find that member."), ephemeral=True)
return
previous_owner = guild.get_member(owner_id) if owner_id is not None else None
await self._set_channel_owner(guild, channel.id, target.id)
await self._ensure_owner_permissions(channel, target)
if previous_owner is not None and previous_owner.id != target.id:
previous_overwrite = channel.overwrites_for(previous_owner)
previous_overwrite.manage_channels = None
await channel.set_permissions(
previous_owner,
overwrite=previous_overwrite,
reason="TempVoice owner changed",
)
await interaction.response.send_message(
_("Channel owner changed to {member}.").format(member=target.mention),
ephemeral=True,