Ruby-Cogs/autoroom/waiting_room.py
Valerie 628f2dae90
Some checks are pending
Run pre-commit / Run pre-commit (push) Waiting to run
Add message ID fields and refactor text channel retrieval in AutoRoom
This update introduces two new fields for message IDs in the AutoRoom class, enhancing the tracking of messages related to the autoroom functionality. Additionally, the text channel retrieval logic has been refactored in both the ControlPanel and WaitingRoom classes to use the voice channel's ID, improving accuracy and reliability in channel interactions.
2025-06-13 19:57:44 -04:00

189 lines
No EOL
7.3 KiB
Python

"""Waiting room 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 WaitingRoomView(ui.View):
"""View for waiting room control buttons."""
def __init__(self, cog: Any):
super().__init__(timeout=None)
self.cog = cog
@discord.ui.button(label="Allow", style=discord.ButtonStyle.green, custom_id="waiting_room_allow")
async def allow_button(self, interaction: discord.Interaction, button: discord.ui.Button):
"""Allow a user into the AutoRoom."""
if not interaction.message:
return
# Get the waiting user from the message
waiting_user_id = int(interaction.message.content.split("User: <@")[1].split(">")[0])
waiting_user = interaction.guild.get_member(waiting_user_id)
if not waiting_user:
await interaction.response.send_message("User no longer in the server.", ephemeral=True)
return
# Get the AutoRoom info
autoroom_info = await self.cog.get_autoroom_info(interaction.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
# Move the user to the AutoRoom
try:
await waiting_user.move_to(interaction.channel)
await interaction.message.delete()
await interaction.response.send_message(f"Allowed {waiting_user.mention} into the AutoRoom.", ephemeral=True)
except discord.HTTPException:
await interaction.response.send_message("Failed to move user to the AutoRoom.", ephemeral=True)
@discord.ui.button(label="Deny", style=discord.ButtonStyle.red, custom_id="waiting_room_deny")
async def deny_button(self, interaction: discord.Interaction, button: discord.ui.Button):
"""Deny a user access to the AutoRoom."""
if not interaction.message:
return
# Get the waiting user from the message
waiting_user_id = int(interaction.message.content.split("User: <@")[1].split(">")[0])
waiting_user = interaction.guild.get_member(waiting_user_id)
if not waiting_user:
await interaction.response.send_message("User no longer in the server.", ephemeral=True)
return
# Get the AutoRoom info
autoroom_info = await self.cog.get_autoroom_info(interaction.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
# Add user to denied list
denied = autoroom_info.get("denied", [])
if waiting_user.id not in denied:
denied.append(waiting_user.id)
await self.cog.config.channel(interaction.channel).denied.set(denied)
# Move user back to waiting room
waiting_room = interaction.guild.get_channel(autoroom_info["waiting_room_channel_id"])
if waiting_room:
try:
await waiting_user.move_to(waiting_room)
except discord.HTTPException:
pass
await interaction.message.delete()
await interaction.response.send_message(f"Denied {waiting_user.mention} access to the AutoRoom.", ephemeral=True)
class WaitingRoom:
"""Handles waiting room functionality."""
def __init__(self, cog: Any):
self.cog = cog
self.bot: Red = cog.bot
self.config: Config = cog.config
async def setup_waiting_room(self, autoroom_source: discord.VoiceChannel, text_channel: discord.TextChannel) -> bool:
"""Set up the waiting room for an AutoRoom source."""
try:
# Create waiting room channel
waiting_room = await autoroom_source.guild.create_voice_channel(
name="Waiting Room",
category=autoroom_source.category,
reason="AutoRoom: Setting up waiting room."
)
# Set up permissions
perms = discord.PermissionOverwrite(
view_channel=True,
connect=True,
speak=True,
stream=True,
use_voice_activation=True
)
await waiting_room.set_permissions(autoroom_source.guild.default_role, overwrite=perms)
# Save waiting room channel ID
await self.config.custom(
"AUTOROOM_SOURCE",
str(autoroom_source.guild.id),
str(autoroom_source.id)
).waiting_room_channel_id.set(waiting_room.id)
# Enable waiting room
await self.config.custom(
"AUTOROOM_SOURCE",
str(autoroom_source.guild.id),
str(autoroom_source.id)
).waiting_room_enabled.set(True)
return True
except discord.HTTPException:
return False
async def handle_waiting_user(self, member: discord.Member, autoroom: discord.VoiceChannel) -> None:
"""Handle a user joining the waiting room."""
autoroom_info = await self.cog.get_autoroom_info(autoroom)
if not autoroom_info:
return
# Get the voice channel's text chat using the voice channel's ID
text_channel = None
for channel in autoroom.guild.text_channels:
if channel.id == autoroom.id:
text_channel = channel
break
if not text_channel:
return
# Create waiting message with buttons
view = WaitingRoomView(self.cog)
message = await text_channel.send(
f"User: {member.mention} is waiting to join the AutoRoom.",
view=view
)
# Save message ID
await self.config.channel(autoroom).waiting_room_message_id.set(message.id)
async def cleanup_waiting_room(self, autoroom_source: discord.VoiceChannel) -> None:
"""Clean up the waiting room when disabling it."""
config = await self.config.custom(
"AUTOROOM_SOURCE",
str(autoroom_source.guild.id),
str(autoroom_source.id)
).all()
if config["waiting_room_channel_id"]:
waiting_room = autoroom_source.guild.get_channel(config["waiting_room_channel_id"])
if waiting_room:
try:
await waiting_room.delete(reason="AutoRoom: Disabling waiting room.")
except discord.HTTPException:
pass
await self.config.custom(
"AUTOROOM_SOURCE",
str(autoroom_source.guild.id),
str(autoroom_source.id)
).waiting_room_enabled.set(False)
await self.config.custom(
"AUTOROOM_SOURCE",
str(autoroom_source.guild.id),
str(autoroom_source.id)
).waiting_room_channel_id.set(None)