Ruby-Cogs/autoroom/control_panel.py
Valerie 6e7092a4b2
Some checks are pending
Run pre-commit / Run pre-commit (push) Waiting to run
Refactor ControlPanel to correctly retrieve associated text channel
This update modifies the ControlPanel class to ensure the correct text channel is retrieved based on the AutoRoom name, enhancing the reliability of message sending. Additionally, it updates the configuration reference for storing message IDs, improving overall clarity and functionality in channel interactions.
2025-06-13 19:44:23 -04:00

238 lines
No EOL
10 KiB
Python

"""Control panel functionality for AutoRoom cog."""
from typing import Any, Optional
import discord
from discord import ui
from redbot.core import Config
from redbot.core.bot import Red
class ControlPanelView(ui.View):
"""View for AutoRoom control panel buttons."""
def __init__(self, cog: Any, voice_channel_id: int):
super().__init__(timeout=None)
self.cog = cog
self.voice_channel_id = voice_channel_id
@discord.ui.button(label="🔓 Public", style=discord.ButtonStyle.green, custom_id="autoroom_public")
async def public_button(self, interaction: discord.Interaction, button: discord.ui.Button):
"""Make the AutoRoom public."""
# Get the voice channel
voice_channel = interaction.guild.get_channel(self.voice_channel_id)
if not isinstance(voice_channel, discord.VoiceChannel):
await interaction.response.send_message("Could not find the voice channel.", ephemeral=True)
return
# Get the AutoRoom info
autoroom_info = await self.cog.get_autoroom_info(voice_channel)
if not autoroom_info:
await interaction.response.send_message("This is not an AutoRoom.", ephemeral=True)
return
# Check if the interaction user is the owner
if interaction.user.id != autoroom_info["owner"]:
await interaction.response.send_message("Only the AutoRoom owner can use these buttons.", ephemeral=True)
return
# Make the AutoRoom public
ctx = await self.cog.bot.get_context(interaction.message)
ctx.author = interaction.user
await self.cog._process_allow_deny(ctx, "allow")
await interaction.response.send_message("AutoRoom is now public.", ephemeral=True)
@discord.ui.button(label="🔒 Locked", style=discord.ButtonStyle.grey, custom_id="autoroom_locked")
async def locked_button(self, interaction: discord.Interaction, button: discord.ui.Button):
"""Make the AutoRoom locked."""
# Get the voice channel
voice_channel = interaction.guild.get_channel(self.voice_channel_id)
if not isinstance(voice_channel, discord.VoiceChannel):
await interaction.response.send_message("Could not find the voice channel.", ephemeral=True)
return
# Get the AutoRoom info
autoroom_info = await self.cog.get_autoroom_info(voice_channel)
if not autoroom_info:
await interaction.response.send_message("This is not an AutoRoom.", ephemeral=True)
return
# Check if the interaction user is the owner
if interaction.user.id != autoroom_info["owner"]:
await interaction.response.send_message("Only the AutoRoom owner can use these buttons.", ephemeral=True)
return
# Make the AutoRoom locked
ctx = await self.cog.bot.get_context(interaction.message)
ctx.author = interaction.user
await self.cog._process_allow_deny(ctx, "lock")
await interaction.response.send_message("AutoRoom is now locked.", ephemeral=True)
@discord.ui.button(label="🔐 Private", style=discord.ButtonStyle.red, custom_id="autoroom_private")
async def private_button(self, interaction: discord.Interaction, button: discord.ui.Button):
"""Make the AutoRoom private."""
# Get the voice channel
voice_channel = interaction.guild.get_channel(self.voice_channel_id)
if not isinstance(voice_channel, discord.VoiceChannel):
await interaction.response.send_message("Could not find the voice channel.", ephemeral=True)
return
# Get the AutoRoom info
autoroom_info = await self.cog.get_autoroom_info(voice_channel)
if not autoroom_info:
await interaction.response.send_message("This is not an AutoRoom.", ephemeral=True)
return
# Check if the interaction user is the owner
if interaction.user.id != autoroom_info["owner"]:
await interaction.response.send_message("Only the AutoRoom owner can use these buttons.", ephemeral=True)
return
# Make the AutoRoom private
ctx = await self.cog.bot.get_context(interaction.message)
ctx.author = interaction.user
await self.cog._process_allow_deny(ctx, "deny")
await interaction.response.send_message("AutoRoom is now private.", ephemeral=True)
@discord.ui.button(label="👥 Add User", style=discord.ButtonStyle.blurple, custom_id="autoroom_add_user")
async def add_user_button(self, interaction: discord.Interaction, button: discord.ui.Button):
"""Add a user to the AutoRoom."""
# Get the voice channel
voice_channel = interaction.guild.get_channel(self.voice_channel_id)
if not isinstance(voice_channel, discord.VoiceChannel):
await interaction.response.send_message("Could not find the voice channel.", ephemeral=True)
return
# Get the AutoRoom info
autoroom_info = await self.cog.get_autoroom_info(voice_channel)
if not autoroom_info:
await interaction.response.send_message("This is not an AutoRoom.", ephemeral=True)
return
# Check if the interaction user is the owner
if interaction.user.id != autoroom_info["owner"]:
await interaction.response.send_message("Only the AutoRoom owner can use these buttons.", ephemeral=True)
return
# Create a modal for user selection
modal = UserSelectModal(self.cog, "allow", self.voice_channel_id)
await interaction.response.send_modal(modal)
@discord.ui.button(label="🚫 Remove User", style=discord.ButtonStyle.danger, custom_id="autoroom_remove_user")
async def remove_user_button(self, interaction: discord.Interaction, button: discord.ui.Button):
"""Remove a user from the AutoRoom."""
# Get the voice channel
voice_channel = interaction.guild.get_channel(self.voice_channel_id)
if not isinstance(voice_channel, discord.VoiceChannel):
await interaction.response.send_message("Could not find the voice channel.", ephemeral=True)
return
# Get the AutoRoom info
autoroom_info = await self.cog.get_autoroom_info(voice_channel)
if not autoroom_info:
await interaction.response.send_message("This is not an AutoRoom.", ephemeral=True)
return
# Check if the interaction user is the owner
if interaction.user.id != autoroom_info["owner"]:
await interaction.response.send_message("Only the AutoRoom owner can use these buttons.", ephemeral=True)
return
# Create a modal for user selection
modal = UserSelectModal(self.cog, "deny", self.voice_channel_id)
await interaction.response.send_modal(modal)
class UserSelectModal(ui.Modal, title="Select User"):
"""Modal for selecting a user to add/remove."""
def __init__(self, cog: Any, action: str, voice_channel_id: int):
super().__init__()
self.cog = cog
self.action = action
self.voice_channel_id = voice_channel_id
self.user_id = ui.TextInput(
label="User ID or @mention",
placeholder="Enter user ID or @mention",
required=True
)
self.add_item(self.user_id)
async def on_submit(self, interaction: discord.Interaction):
"""Handle the modal submission."""
user_input = self.user_id.value.strip()
# Try to get user from mention
if user_input.startswith("<@") and user_input.endswith(">"):
user_id = int(user_input[2:-1])
else:
try:
user_id = int(user_input)
except ValueError:
await interaction.response.send_message("Invalid user ID or mention.", ephemeral=True)
return
user = interaction.guild.get_member(user_id)
if not user:
await interaction.response.send_message("User not found in this server.", ephemeral=True)
return
# Get the voice channel
voice_channel = interaction.guild.get_channel(self.voice_channel_id)
if not isinstance(voice_channel, discord.VoiceChannel):
await interaction.response.send_message("Could not find the voice channel.", ephemeral=True)
return
# Process the allow/deny action
ctx = await self.cog.bot.get_context(interaction.message)
ctx.author = interaction.user
await self.cog._process_allow_deny(ctx, self.action, member_or_role=user)
await interaction.response.send_message(f"User {user.mention} has been {'allowed' if self.action == 'allow' else 'denied'} access.", ephemeral=True)
class ControlPanel:
"""Handles control panel functionality."""
def __init__(self, cog: Any):
self.cog = cog
self.bot: Red = cog.bot
self.config: Config = cog.config
async def create_control_panel(self, autoroom: discord.VoiceChannel) -> None:
"""Create the control panel embed in the voice channel's text chat."""
autoroom_info = await self.cog.get_autoroom_info(autoroom)
if not autoroom_info:
return
owner = autoroom.guild.get_member(autoroom_info["owner"])
if not owner:
return
# Get the associated text channel
text_channel = None
for channel in autoroom.guild.text_channels:
if channel.name == autoroom.name:
text_channel = channel
break
if not text_channel:
return
# Create the embed
embed = discord.Embed(
title="AutoRoom Control Panel",
description=f"Control panel for {autoroom.mention}\nOwner: {owner.mention}",
color=discord.Color.blue()
)
# Add current status
status = "Public" if autoroom.permissions_for(autoroom.guild.default_role).connect else "Private"
embed.add_field(name="Status", value=status, inline=True)
# Add member count
embed.add_field(name="Members", value=str(len(autoroom.members)), inline=True)
# Create view with buttons
view = ControlPanelView(self.cog, autoroom.id)
# Send the embed to the text channel
message = await text_channel.send(embed=embed, view=view)
# Store the message ID for reference
await self.config.channel(autoroom).message_id.set(message.id)