diff --git a/shop/ui.py b/shop/ui.py index dc83842..5198f21 100644 --- a/shop/ui.py +++ b/shop/ui.py @@ -2,6 +2,7 @@ import discord from discord.ui import View, Select, Button, button, Item from typing import Optional, List, Dict, Any from redbot.core.utils.chat_formatting import box, humanize_list +import asyncio class ShopView(View): def __init__(self, ctx, shops: Dict[str, Any], timeout: int = 180): # 3 minutes timeout @@ -50,6 +51,9 @@ class ShopView(View): self.add_item(shop_select) async def shop_selected(self, interaction: discord.Interaction): + if interaction.user != self.ctx.author: + return await interaction.response.send_message("This menu is not for you!", ephemeral=True) + shop_name = interaction.data["values"][0] self.current_shop = shop_name @@ -89,6 +93,9 @@ class ShopView(View): await interaction.response.edit_message(embed=embed, view=self) async def item_selected(self, interaction: discord.Interaction): + if interaction.user != self.ctx.author: + return await interaction.response.send_message("This menu is not for you!", ephemeral=True) + item_name = interaction.data["values"][0] self.current_item = item_name item_data = self.shops[self.current_shop]["Items"][item_name] @@ -106,8 +113,7 @@ class ShopView(View): async def on_timeout(self) -> None: if self.message: - await self.message.reply("Shop menu timed out after 3 minutes of inactivity.", mention_author=True) - await self.message.edit(view=None) + await self.message.edit(content="Shop menu timed out after 3 minutes of inactivity.", view=None) class PurchaseView(View): def __init__(self, ctx, shop: str, item: str, item_data: Dict[str, Any], timeout: int = 180): # 3 minutes timeout @@ -120,19 +126,19 @@ class PurchaseView(View): self.message = None # Store message for timeout handling # Add buttons with explicit row assignments - buy_one = Button(label="Buy 1", style=discord.ButtonStyle.green, row=1) + buy_one = Button(label="Buy 1", style=discord.ButtonStyle.green, row=0) buy_one.callback = self.buy_one self.add_item(buy_one) - buy_five = Button(label="Buy 5", style=discord.ButtonStyle.green, row=1) + buy_five = Button(label="Buy 5", style=discord.ButtonStyle.green, row=0) buy_five.callback = self.buy_five self.add_item(buy_five) - custom = Button(label="Custom Amount", style=discord.ButtonStyle.blurple, row=1) + custom = Button(label="Custom Amount", style=discord.ButtonStyle.blurple, row=0) custom.callback = self.custom_amount self.add_item(custom) - cancel = Button(label="Cancel", style=discord.ButtonStyle.red, row=1) + cancel = Button(label="Cancel", style=discord.ButtonStyle.red, row=0) cancel.callback = self.cancel self.add_item(cancel) @@ -148,26 +154,27 @@ class PurchaseView(View): description=self.item_data["Info"], color=discord.Color.blue() ) - qty = "Infinite" if self.item_data["Qty"] == "--" else self.item_data["Qty"] - e.add_field(name="Stock", value=qty, inline=True) + + # First row of fields + e.add_field(name="Stock", value="Infinite" if self.item_data["Qty"] == "--" else self.item_data["Qty"], inline=True) e.add_field(name="Cost", value=self.item_data["Cost"], inline=True) e.add_field(name="Type", value=self.item_data["Type"].title(), inline=True) + + # Add role in a new row if it's a role type item if self.item_data["Type"] == "role": - e.add_field(name="Role", value=self.item_data["Role"], inline=True) + e.add_field(name="Role", value=self.item_data["Role"], inline=False) + e.set_footer(text="Select a quantity to purchase") return e - @button(label="Buy 1", style=discord.ButtonStyle.green, row=1) - async def buy_one(self, interaction: discord.Interaction, button: Button): + async def buy_one(self, interaction: discord.Interaction): self.quantity = 1 await self.handle_purchase(interaction) - @button(label="Buy 5", style=discord.ButtonStyle.green, row=1) - async def buy_five(self, interaction: discord.Interaction, button: Button): + async def buy_five(self, interaction: discord.Interaction): self.quantity = 5 await self.handle_purchase(interaction) - @button(label="Custom Amount", style=discord.ButtonStyle.blurple, row=1) async def custom_amount(self, interaction: discord.Interaction): embed = discord.Embed( title="Custom Purchase Amount", @@ -191,8 +198,7 @@ class PurchaseView(View): await interaction.message.reply("Custom amount entry timed out after 1 minute.", mention_author=True) self.stop() - @button(label="Cancel", style=discord.ButtonStyle.red, row=1) - async def cancel(self, interaction: discord.Interaction, button: Button): + async def cancel(self, interaction: discord.Interaction): await interaction.response.edit_message(content="Purchase cancelled.", embed=None, view=None) self.stop() @@ -235,8 +241,7 @@ class PurchaseView(View): async def on_timeout(self) -> None: if self.message: - await self.message.reply("Purchase menu timed out after 3 minutes of inactivity.", mention_author=True) - await self.message.edit(view=None) + await self.message.edit(content="Purchase menu timed out after 3 minutes of inactivity.", view=None) class InventoryView(View): def __init__(self, ctx, inventory: Dict[str, Any], timeout: int = 180): # 3 minutes timeout @@ -281,67 +286,40 @@ class InventoryView(View): self.add_item(inv_select) async def item_selected(self, interaction: discord.Interaction): - item_name = interaction.data["values"][0] - self.selected_item = item_name - item_data = self.inventory[item_name] - - embed = discord.Embed( - title=item_name, - description=item_data["Info"], - color=discord.Color.blue() - ) - embed.add_field(name="Quantity", value=item_data["Qty"], inline=True) - embed.add_field(name="Type", value=item_data["Type"].title(), inline=True) - - if item_data["Type"] == "role": - use_view = UseItemView(self.ctx, item_name, item_data) - await interaction.response.edit_message(embed=embed, view=use_view) + if interaction.user != self.ctx.author: + return await interaction.response.send_message("This menu is not for you!", ephemeral=True) - # Wait for the use view to complete - await use_view.wait() - if use_view.value: # If item was used - self.stop() # Stop the inventory view - else: - await interaction.response.edit_message(embed=embed) + self.selected_item = interaction.data["values"][0] + self.stop() async def on_timeout(self) -> None: if self.message: - await self.message.reply("Inventory menu timed out after 3 minutes of inactivity.", mention_author=True) - await self.message.edit(view=None) + await self.message.edit(content="Inventory menu timed out after 3 minutes of inactivity.", view=None) class UseItemView(View): - def __init__(self, ctx, item: str, item_data: Dict[str, Any], timeout: int = 180): # 3 minutes timeout + def __init__(self, ctx, item_name: str, timeout: int = 60): super().__init__(timeout=timeout) self.ctx = ctx - self.item = item - self.item_data = item_data - self.value = False - self.message = None # Store message for timeout handling + self.item_name = item_name + self.value = None + self.message = None - async def interaction_check(self, interaction: discord.Interaction) -> bool: + @button(label="Use", style=discord.ButtonStyle.green) + async def use(self, interaction: discord.Interaction, button: Button): if interaction.user != self.ctx.author: - await interaction.response.send_message("This menu is not for you!", ephemeral=True) - return False - return True - - @button(label="Use Item", style=discord.ButtonStyle.green) - async def use_item(self, interaction: discord.Interaction, button: Button): + return await interaction.response.send_message("This menu is not for you!", ephemeral=True) self.value = True - embed = discord.Embed( - title="Using Item", - description=f"Processing use of {self.item}...", - color=discord.Color.green() - ) - await interaction.response.edit_message(embed=embed, view=None) self.stop() + await interaction.response.defer() @button(label="Cancel", style=discord.ButtonStyle.red) async def cancel(self, interaction: discord.Interaction, button: Button): + if interaction.user != self.ctx.author: + return await interaction.response.send_message("This menu is not for you!", ephemeral=True) self.value = False - await interaction.response.edit_message(content="Cancelled.", embed=None, view=None) self.stop() - + await interaction.response.defer() + async def on_timeout(self) -> None: if self.message: - await self.message.reply("Item use menu timed out after 3 minutes of inactivity.", mention_author=True) - await self.message.edit(view=None) \ No newline at end of file + await self.message.edit(content="Item use menu timed out.", view=None) \ No newline at end of file