Improve modals and waitlist handling in KofiShop
Updated modal handling for order and review submissions with more user-friendly error messages. Added `waitlist_entries` to manage waitlist data. Refactored the `waitlist` command for better user mention handling and added error handling for permission issues. Overall enhancements improve functionality and user experience.
This commit is contained in:
@@ -1,7 +1,12 @@
|
|||||||
import discord
|
import discord
|
||||||
from redbot.core import commands, Config
|
from redbot.core import commands, Config, app_commands
|
||||||
from redbot.core.bot import Red
|
from typing import Optional, TYPE_CHECKING
|
||||||
from typing import Optional
|
import datetime
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from redbot.core.bot import Red
|
||||||
|
|
||||||
|
# --- Modals for the Forms ---
|
||||||
|
|
||||||
class OrderModal(discord.ui.Modal, title="Commission Order Form"):
|
class OrderModal(discord.ui.Modal, title="Commission Order Form"):
|
||||||
commission_type = discord.ui.TextInput(label="What type of commission?")
|
commission_type = discord.ui.TextInput(label="What type of commission?")
|
||||||
@@ -20,15 +25,16 @@ class OrderModal(discord.ui.Modal, title="Commission Order Form"):
|
|||||||
|
|
||||||
channel_id = await self.cog.config.guild(guild).order_channel()
|
channel_id = await self.cog.config.guild(guild).order_channel()
|
||||||
if not channel_id:
|
if not channel_id:
|
||||||
await interaction.response.send_message("Order channel not set.", ephemeral=True)
|
await interaction.response.send_message("The order channel has not been set by an admin.", ephemeral=True)
|
||||||
return
|
return
|
||||||
|
|
||||||
channel = guild.get_channel(channel_id)
|
channel = guild.get_channel(channel_id)
|
||||||
if not isinstance(channel, discord.TextChannel):
|
if not isinstance(channel, discord.TextChannel):
|
||||||
await interaction.response.send_message("Invalid order channel.", ephemeral=True)
|
await interaction.response.send_message("The configured order channel is invalid.", ephemeral=True)
|
||||||
return
|
return
|
||||||
|
|
||||||
embed = discord.Embed(title=f"New Order from {interaction.user.name}", color=discord.Color.blurple())
|
embed = discord.Embed(title=f"New Order from {interaction.user.name}", color=discord.Color.blurple())
|
||||||
|
embed.set_author(name=interaction.user.name, icon_url=interaction.user.display_avatar.url)
|
||||||
embed.add_field(name="Commission Type", value=self.commission_type.value, inline=False)
|
embed.add_field(name="Commission Type", value=self.commission_type.value, inline=False)
|
||||||
embed.add_field(name="Payment Status", value=self.payment_status.value, inline=False)
|
embed.add_field(name="Payment Status", value=self.payment_status.value, inline=False)
|
||||||
embed.add_field(name="Description", value=self.description.value, inline=False)
|
embed.add_field(name="Description", value=self.description.value, inline=False)
|
||||||
@@ -38,6 +44,7 @@ class OrderModal(discord.ui.Modal, title="Commission Order Form"):
|
|||||||
await channel.send(embed=embed)
|
await channel.send(embed=embed)
|
||||||
await interaction.response.send_message("Your order has been submitted!", ephemeral=True)
|
await interaction.response.send_message("Your order has been submitted!", ephemeral=True)
|
||||||
|
|
||||||
|
|
||||||
class ReviewModal(discord.ui.Modal, title="Shop Review"):
|
class ReviewModal(discord.ui.Modal, title="Shop Review"):
|
||||||
item_name = discord.ui.TextInput(label="What item/commission are you reviewing?")
|
item_name = discord.ui.TextInput(label="What item/commission are you reviewing?")
|
||||||
rating = discord.ui.TextInput(label="Rating (out of 10)", max_length=2)
|
rating = discord.ui.TextInput(label="Rating (out of 10)", max_length=2)
|
||||||
@@ -54,12 +61,12 @@ class ReviewModal(discord.ui.Modal, title="Shop Review"):
|
|||||||
|
|
||||||
channel_id = await self.cog.config.guild(guild).review_channel()
|
channel_id = await self.cog.config.guild(guild).review_channel()
|
||||||
if not channel_id:
|
if not channel_id:
|
||||||
await interaction.response.send_message("Review channel not set.", ephemeral=True)
|
await interaction.response.send_message("The review channel has not been set by an admin.", ephemeral=True)
|
||||||
return
|
return
|
||||||
|
|
||||||
channel = guild.get_channel(channel_id)
|
channel = guild.get_channel(channel_id)
|
||||||
if not isinstance(channel, discord.TextChannel):
|
if not isinstance(channel, discord.TextChannel):
|
||||||
await interaction.response.send_message("Invalid review channel.", ephemeral=True)
|
await interaction.response.send_message("The configured review channel is invalid.", ephemeral=True)
|
||||||
return
|
return
|
||||||
|
|
||||||
embed = discord.Embed(title=f"New Review for {self.item_name.value}", color=discord.Color.gold())
|
embed = discord.Embed(title=f"New Review for {self.item_name.value}", color=discord.Color.gold())
|
||||||
@@ -71,17 +78,21 @@ class ReviewModal(discord.ui.Modal, title="Shop Review"):
|
|||||||
await interaction.response.send_message("Thank you for your review!", ephemeral=True)
|
await interaction.response.send_message("Thank you for your review!", ephemeral=True)
|
||||||
|
|
||||||
|
|
||||||
|
# --- Main Cog Class ---
|
||||||
|
|
||||||
class KofiShop(commands.Cog):
|
class KofiShop(commands.Cog):
|
||||||
"""
|
"""
|
||||||
An interactive front-end for a Ko-fi store.
|
An interactive front-end for a Ko-fi store.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, bot: "Red"):
|
def __init__(self, bot: "Red"):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.config = Config.get_conf(self, identifier=1234567894, force_registration=True)
|
self.config = Config.get_conf(self, identifier=1234567894, force_registration=True)
|
||||||
default_guild = {
|
default_guild = {
|
||||||
"order_channel": None,
|
"order_channel": None,
|
||||||
"review_channel": None,
|
"review_channel": None,
|
||||||
"waitlist_channel": None
|
"waitlist_channel": None,
|
||||||
|
"waitlist_entries": {} # For DataManager
|
||||||
}
|
}
|
||||||
self.config.register_guild(**default_guild)
|
self.config.register_guild(**default_guild)
|
||||||
|
|
||||||
@@ -91,33 +102,20 @@ class KofiShop(commands.Cog):
|
|||||||
"""Place an order for a commission."""
|
"""Place an order for a commission."""
|
||||||
await interaction.response.send_modal(OrderModal(self))
|
await interaction.response.send_modal(OrderModal(self))
|
||||||
|
|
||||||
@app_commands.command()
|
@app_commands.command(name="rev")
|
||||||
@app_commands.guild_only()
|
@app_commands.guild_only()
|
||||||
async def review(self, interaction: discord.Interaction):
|
async def review(self, interaction: discord.Interaction):
|
||||||
"""Leave a review for a completed commission."""
|
"""Leave a review for a completed commission."""
|
||||||
await interaction.response.send_modal(ReviewModal(self))
|
await interaction.response.send_modal(ReviewModal(self))
|
||||||
|
|
||||||
@app_commands.command()
|
|
||||||
@app_commands.guild_only()
|
|
||||||
async def waitlist(self, interaction: discord.Interaction, *, item: str):
|
|
||||||
"""Add an item to the waitlist."""
|
|
||||||
guild = interaction.guild
|
|
||||||
if not guild:
|
|
||||||
return
|
|
||||||
|
|
||||||
channel_id = await self.config.guild(guild).waitlist_channel()
|
|
||||||
if not channel_id:
|
|
||||||
await interaction.response.send_message("Waitlist channel not set.", ephemeral=True)
|
|
||||||
return
|
|
||||||
await ctx.interaction.response.send_modal(ReviewModal(self))
|
|
||||||
|
|
||||||
@commands.hybrid_command() # type: ignore
|
@commands.hybrid_command() # type: ignore
|
||||||
@commands.guild_only()
|
@app_commands.guild_only()
|
||||||
@commands.admin_or_permissions(manage_guild=True)
|
async def waitlist(self, ctx: commands.Context, user: Optional[discord.Member], *, item: str):
|
||||||
async def waitlist(self, ctx: commands.Context, user: discord.Member, *, item: str):
|
|
||||||
"""Add a user and their requested item to the waitlist."""
|
"""Add a user and their requested item to the waitlist."""
|
||||||
if not ctx.guild or not isinstance(ctx.channel, discord.TextChannel):
|
if not ctx.guild:
|
||||||
return await ctx.send("This command must be used in a server's text channel.", ephemeral=True)
|
return
|
||||||
|
|
||||||
|
target_user = user or ctx.author
|
||||||
|
|
||||||
waitlist_channel_id = await self.config.guild(ctx.guild).waitlist_channel()
|
waitlist_channel_id = await self.config.guild(ctx.guild).waitlist_channel()
|
||||||
if not waitlist_channel_id:
|
if not waitlist_channel_id:
|
||||||
@@ -127,16 +125,22 @@ class KofiShop(commands.Cog):
|
|||||||
if not isinstance(waitlist_channel, discord.TextChannel):
|
if not isinstance(waitlist_channel, discord.TextChannel):
|
||||||
return await ctx.send("The configured waitlist channel is invalid.", ephemeral=True)
|
return await ctx.send("The configured waitlist channel is invalid.", ephemeral=True)
|
||||||
|
|
||||||
message = f"**{item}** ིྀ {user.mention} ✧ in {ctx.channel.mention}"
|
message_to_send = f"**{item}** ིྀ {target_user.mention} ✧ in {ctx.channel.mention if isinstance(ctx.channel, discord.TextChannel) else 'this ticket'}"
|
||||||
|
|
||||||
channel = guild.get_channel(channel_id)
|
try:
|
||||||
if not isinstance(channel, discord.TextChannel):
|
sent_message = await waitlist_channel.send(message_to_send)
|
||||||
await interaction.response.send_message("Invalid waitlist channel.", ephemeral=True)
|
# For DataManager
|
||||||
return
|
async with self.config.guild(ctx.guild).waitlist_entries() as entries:
|
||||||
|
entries[str(sent_message.id)] = datetime.datetime.now(datetime.timezone.utc).isoformat()
|
||||||
|
|
||||||
|
await ctx.send(f"{target_user.mention} has been added to the waitlist for '{item}'.", ephemeral=True)
|
||||||
|
# Also send confirmation to user's ticket if it's a ticket channel
|
||||||
|
if isinstance(ctx.channel, discord.TextChannel) and "ticket" in ctx.channel.name.lower():
|
||||||
|
await ctx.channel.send(f"You have been added to the waitlist for **{item}**.")
|
||||||
|
|
||||||
|
except discord.Forbidden:
|
||||||
|
await ctx.send("I do not have permission to send messages in the waitlist channel.", ephemeral=True)
|
||||||
|
|
||||||
embed = discord.Embed(description=f"{item} ིྀ {interaction.user.mention}✧ {interaction.channel.mention if isinstance(interaction.channel, discord.TextChannel) else ''}")
|
|
||||||
await channel.send(embed=embed)
|
|
||||||
await interaction.response.send_message("You have been added to the waitlist!", ephemeral=True)
|
|
||||||
|
|
||||||
@commands.group(aliases=["kset"]) # type: ignore
|
@commands.group(aliases=["kset"]) # type: ignore
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
@@ -171,3 +175,4 @@ class KofiShop(commands.Cog):
|
|||||||
|
|
||||||
async def setup(bot: "Red"):
|
async def setup(bot: "Red"):
|
||||||
await bot.add_cog(KofiShop(bot))
|
await bot.add_cog(KofiShop(bot))
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user