Refactor Shop and UI components to improve timeout handling for interactive views. Update timeout duration to 3 minutes and implement message replies for user feedback upon timeout in ShopView, PurchaseView, and InventoryView.
Some checks are pending
Run pre-commit / Run pre-commit (push) Waiting to run
Some checks are pending
Run pre-commit / Run pre-commit (push) Waiting to run
This commit is contained in:
parent
3ee6707cc5
commit
85de2c70c1
2 changed files with 38 additions and 16 deletions
12
shop/shop.py
12
shop/shop.py
|
@ -129,14 +129,14 @@ class Shop(commands.Cog):
|
|||
color=discord.Color.blue()
|
||||
)
|
||||
view = InventoryView(ctx, inventory)
|
||||
await ctx.send(embed=embed, view=view)
|
||||
view.message = await ctx.send(embed=embed, view=view)
|
||||
|
||||
try:
|
||||
await view.wait()
|
||||
if view.selected_item: # An item was selected to use
|
||||
await self.pending_prompt(ctx, instance, inventory, view.selected_item)
|
||||
except asyncio.TimeoutError:
|
||||
await ctx.send("Inventory view timed out.", ephemeral=True)
|
||||
pass # Handled by view's on_timeout
|
||||
|
||||
async def inv_hook(self, user):
|
||||
"""Inventory Hook for outside cogs
|
||||
|
@ -244,7 +244,7 @@ class Shop(commands.Cog):
|
|||
|
||||
view = PurchaseView(ctx, shop, item, item_data)
|
||||
embed = view.build_embed()
|
||||
await ctx.send(embed=embed, view=view)
|
||||
view.message = await ctx.send(embed=embed, view=view)
|
||||
|
||||
try:
|
||||
await view.wait()
|
||||
|
@ -253,7 +253,7 @@ class Shop(commands.Cog):
|
|||
sm = ShopManager(ctx, instance, user_data)
|
||||
await sm.order(shop, item, view.quantity)
|
||||
except asyncio.TimeoutError:
|
||||
await ctx.send("Purchase menu timed out.", ephemeral=True)
|
||||
pass # Handled by view's on_timeout
|
||||
|
||||
else:
|
||||
# Open interactive shop menu
|
||||
|
@ -263,7 +263,7 @@ class Shop(commands.Cog):
|
|||
color=discord.Color.blue()
|
||||
)
|
||||
view = ShopView(ctx, shops)
|
||||
await ctx.send(embed=embed, view=view)
|
||||
view.message = await ctx.send(embed=embed, view=view)
|
||||
|
||||
try:
|
||||
await view.wait()
|
||||
|
@ -272,7 +272,7 @@ class Shop(commands.Cog):
|
|||
sm = ShopManager(ctx, instance, user_data)
|
||||
await sm.order(view.current_shop, view.current_item, view.quantity)
|
||||
except asyncio.TimeoutError:
|
||||
await ctx.send("Shop menu timed out.", ephemeral=True)
|
||||
pass # Handled by view's on_timeout
|
||||
|
||||
@commands.max_concurrency(1, commands.BucketType.user)
|
||||
@shop.command()
|
||||
|
|
42
shop/ui.py
42
shop/ui.py
|
@ -4,15 +4,15 @@ from typing import Optional, List, Dict, Any
|
|||
from redbot.core.utils.chat_formatting import box, humanize_list
|
||||
|
||||
class ShopView(View):
|
||||
def __init__(self, ctx, shops: Dict[str, Any], timeout: int = 60):
|
||||
def __init__(self, ctx, shops: Dict[str, Any], timeout: int = 180): # 3 minutes timeout
|
||||
super().__init__(timeout=timeout)
|
||||
self.ctx = ctx
|
||||
self.shops = shops
|
||||
self.current_shop = None
|
||||
self.current_item = None
|
||||
self.quantity = None
|
||||
self.message = None # Store message for timeout handling
|
||||
self.setup_shop_select()
|
||||
# Add cancel button to a different row
|
||||
cancel_button = Button(label="Cancel", style=discord.ButtonStyle.red, custom_id="cancel", row=4)
|
||||
cancel_button.callback = self.cancel
|
||||
self.add_item(cancel_button)
|
||||
|
@ -104,14 +104,20 @@ class ShopView(View):
|
|||
self.quantity = purchase_view.quantity # Store the quantity from purchase view
|
||||
self.stop() # Stop the shop view since we're done
|
||||
|
||||
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)
|
||||
|
||||
class PurchaseView(View):
|
||||
def __init__(self, ctx, shop: str, item: str, item_data: Dict[str, Any], timeout: int = 60):
|
||||
def __init__(self, ctx, shop: str, item: str, item_data: Dict[str, Any], timeout: int = 180): # 3 minutes timeout
|
||||
super().__init__(timeout=timeout)
|
||||
self.ctx = ctx
|
||||
self.shop = shop
|
||||
self.item = item
|
||||
self.item_data = item_data
|
||||
self.quantity = None
|
||||
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)
|
||||
|
@ -162,7 +168,7 @@ class PurchaseView(View):
|
|||
await self.handle_purchase(interaction)
|
||||
|
||||
@button(label="Custom Amount", style=discord.ButtonStyle.blurple, row=1)
|
||||
async def custom_amount(self, interaction: discord.Interaction, button: Button):
|
||||
async def custom_amount(self, interaction: discord.Interaction):
|
||||
embed = discord.Embed(
|
||||
title="Custom Purchase Amount",
|
||||
description="How many would you like to buy? Type a number in chat.",
|
||||
|
@ -178,11 +184,11 @@ class PurchaseView(View):
|
|||
)
|
||||
|
||||
try:
|
||||
msg = await self.ctx.bot.wait_for("message", timeout=30.0, check=check)
|
||||
msg = await self.ctx.bot.wait_for("message", timeout=60.0, check=check) # 1 minute to type amount
|
||||
self.quantity = int(msg.content)
|
||||
await self.handle_purchase(interaction)
|
||||
except asyncio.TimeoutError:
|
||||
await interaction.followup.send("Purchase cancelled - took too long to respond.", ephemeral=True)
|
||||
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)
|
||||
|
@ -227,14 +233,19 @@ class PurchaseView(View):
|
|||
self.stop()
|
||||
await interaction.response.edit_message(embed=embed, view=None)
|
||||
|
||||
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)
|
||||
|
||||
class InventoryView(View):
|
||||
def __init__(self, ctx, inventory: Dict[str, Any], timeout: int = 60):
|
||||
def __init__(self, ctx, inventory: Dict[str, Any], timeout: int = 180): # 3 minutes timeout
|
||||
super().__init__(timeout=timeout)
|
||||
self.ctx = ctx
|
||||
self.inventory = inventory
|
||||
self.selected_item = None
|
||||
self.message = None # Store message for timeout handling
|
||||
self.setup_inventory_select()
|
||||
# Add close button to a different row
|
||||
close_button = Button(label="Close", style=discord.ButtonStyle.red, custom_id="close", row=4)
|
||||
close_button.callback = self.close
|
||||
self.add_item(close_button)
|
||||
|
@ -293,13 +304,19 @@ class InventoryView(View):
|
|||
else:
|
||||
await interaction.response.edit_message(embed=embed)
|
||||
|
||||
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)
|
||||
|
||||
class UseItemView(View):
|
||||
def __init__(self, ctx, item: str, item_data: Dict[str, Any], timeout: int = 60):
|
||||
def __init__(self, ctx, item: str, item_data: Dict[str, Any], timeout: int = 180): # 3 minutes timeout
|
||||
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
|
||||
|
||||
async def interaction_check(self, interaction: discord.Interaction) -> bool:
|
||||
if interaction.user != self.ctx.author:
|
||||
|
@ -322,4 +339,9 @@ class UseItemView(View):
|
|||
async def cancel(self, interaction: discord.Interaction, button: Button):
|
||||
self.value = False
|
||||
await interaction.response.edit_message(content="Cancelled.", embed=None, view=None)
|
||||
self.stop()
|
||||
self.stop()
|
||||
|
||||
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)
|
Loading…
Add table
Reference in a new issue