CLAUDE: Add confirmation flow and autocomplete to /injury clear
- Added confirmation embed before clearing injury
- Shows player info, team, expected return, games missed
- User prompted: "Is {Player} cleared to return?"
- Buttons: "Clear Injury" / "Cancel"
- 3-minute timeout for response
- Team GMs can also confirm/cancel
- Added player autocomplete to /injury clear command
- Uses same autocomplete as /injury roll
- Prioritizes user's team players
- Updated commands/injuries/CLAUDE.md documentation
- Documented new confirmation flow
- Added autocomplete parameter details
- Clarified user flow and responders
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
216f8112d2
commit
9fca0bc279
@ -17,6 +17,9 @@ from discord import app_commands
|
||||
from discord.ext import commands
|
||||
|
||||
from config import get_config
|
||||
from models.current import Current
|
||||
from models.injury import Injury
|
||||
from models.player import Player
|
||||
from services.player_service import player_service
|
||||
from services.injury_service import injury_service
|
||||
from services.league_service import league_service
|
||||
@ -24,7 +27,9 @@ from services.giphy_service import GiphyService
|
||||
from utils.logging import get_contextual_logger
|
||||
from utils.decorators import logged_command
|
||||
from utils.autocomplete import player_autocomplete
|
||||
from views.base import ConfirmationView
|
||||
from views.embeds import EmbedTemplate
|
||||
from views.modals import PitcherRestModal, BatterInjuryModal
|
||||
from exceptions import BotException
|
||||
|
||||
|
||||
@ -77,6 +82,16 @@ class InjuryGroup(app_commands.Group):
|
||||
|
||||
player = players[0]
|
||||
|
||||
# Check if player already has an active injury
|
||||
existing_injury = await injury_service.get_active_injury(player.id, current.season)
|
||||
if existing_injury:
|
||||
embed = EmbedTemplate.error(
|
||||
title="Already Injured",
|
||||
description=f"Hm. It looks like {player.name} is already hurt."
|
||||
)
|
||||
await interaction.followup.send(embed=embed, ephemeral=True)
|
||||
return
|
||||
|
||||
# Check for injury_rating field
|
||||
if not player.injury_rating:
|
||||
embed = EmbedTemplate.error(
|
||||
@ -145,16 +160,55 @@ class InjuryGroup(app_commands.Group):
|
||||
inline=False
|
||||
)
|
||||
|
||||
# Format result
|
||||
view = None
|
||||
|
||||
# Format result and create callbacks for confirmation
|
||||
if isinstance(injury_result, int):
|
||||
result_text = f"**{injury_result} game{'s' if injury_result > 1 else ''}**"
|
||||
embed.color = discord.Color.orange()
|
||||
|
||||
if injury_result > 6:
|
||||
gif_search_text = ['well shit', 'well fuck', 'god dammit']
|
||||
else:
|
||||
gif_search_text = ['bummer', 'well damn']
|
||||
|
||||
if player.is_pitcher:
|
||||
result_text += ' plus their current rest requirement'
|
||||
|
||||
# Pitcher callback shows modal to collect rest games
|
||||
async def pitcher_confirm_callback(button_interaction: discord.Interaction):
|
||||
"""Show modal to collect pitcher rest information."""
|
||||
modal = PitcherRestModal(
|
||||
player=player,
|
||||
injury_games=injury_result,
|
||||
season=current.season
|
||||
)
|
||||
await button_interaction.response.send_modal(modal)
|
||||
|
||||
injury_callback = pitcher_confirm_callback
|
||||
|
||||
else:
|
||||
# Batter callback shows modal to collect current week/game
|
||||
async def batter_confirm_callback(button_interaction: discord.Interaction):
|
||||
"""Show modal to collect current week/game information for batter injury."""
|
||||
modal = BatterInjuryModal(
|
||||
player=player,
|
||||
injury_games=injury_result,
|
||||
season=current.season
|
||||
)
|
||||
await button_interaction.response.send_modal(modal)
|
||||
|
||||
injury_callback = batter_confirm_callback
|
||||
|
||||
# Create confirmation view with appropriate callback
|
||||
view = ConfirmationView(
|
||||
user_id=interaction.user.id,
|
||||
timeout=180.0, # 3 minutes for confirmation
|
||||
responders=[player.team.gmid, player.team.gmid2] if player.team else None,
|
||||
confirm_callback=injury_callback,
|
||||
confirm_label="Log Injury",
|
||||
cancel_label="Ignore Injury"
|
||||
)
|
||||
elif injury_result == 'REM':
|
||||
if player.is_pitcher:
|
||||
result_text = '**FATIGUED**'
|
||||
@ -167,8 +221,6 @@ class InjuryGroup(app_commands.Group):
|
||||
embed.color = discord.Color.green()
|
||||
gif_search_text = ['we are so back', 'all good', 'totally fine']
|
||||
|
||||
# embed.add_field(name='', value='', inline=False)
|
||||
|
||||
embed.add_field(
|
||||
name="Injury Length",
|
||||
value=result_text,
|
||||
@ -184,7 +236,12 @@ class InjuryGroup(app_commands.Group):
|
||||
|
||||
embed.set_image(url=injury_gif)
|
||||
|
||||
await interaction.followup.send(embed=embed)
|
||||
# Send confirmation (only include view if injury requires logging)
|
||||
if view is not None:
|
||||
await interaction.followup.send(embed=embed, view=view)
|
||||
else:
|
||||
await interaction.followup.send(embed=embed)
|
||||
|
||||
|
||||
def _get_injury_result(self, rating: str, games_played: int, roll: int):
|
||||
"""
|
||||
@ -397,7 +454,7 @@ class InjuryGroup(app_commands.Group):
|
||||
# Success response
|
||||
embed = EmbedTemplate.success(
|
||||
title="Injury Recorded",
|
||||
description=f"{player.name} has been placed on the injured list."
|
||||
description=f"{player.name}'s injury has been logged"
|
||||
)
|
||||
|
||||
embed.add_field(
|
||||
@ -435,8 +492,45 @@ class InjuryGroup(app_commands.Group):
|
||||
injury_id=injury.id
|
||||
)
|
||||
|
||||
def _calc_injury_dates(self, start_week: int, start_game: int, injury_games: int) -> dict:
|
||||
"""
|
||||
Calculate injury dates from start week/game and injury duration.
|
||||
|
||||
Args:
|
||||
start_week: Starting week number
|
||||
start_game: Starting game number (1-4)
|
||||
injury_games: Number of games player will be out
|
||||
|
||||
Returns:
|
||||
Dictionary with calculated injury date fields
|
||||
"""
|
||||
# Calculate return date
|
||||
out_weeks = math.floor(injury_games / 4)
|
||||
out_games = injury_games % 4
|
||||
|
||||
return_week = start_week + out_weeks
|
||||
return_game = start_game + 1 + out_games
|
||||
|
||||
if return_game > 4:
|
||||
return_week += 1
|
||||
return_game -= 4
|
||||
|
||||
# Adjust start date if injury starts after game 4
|
||||
actual_start_week = start_week if start_game != 4 else start_week + 1
|
||||
actual_start_game = start_game + 1 if start_game != 4 else 1
|
||||
|
||||
return {
|
||||
'total_games': injury_games,
|
||||
'start_week': actual_start_week,
|
||||
'start_game': actual_start_game,
|
||||
'end_week': return_week,
|
||||
'end_game': return_game
|
||||
}
|
||||
|
||||
|
||||
@app_commands.command(name="clear", description="Clear a player's injury (requires SBA Players role)")
|
||||
@app_commands.describe(player_name="Player name to clear injury")
|
||||
@app_commands.autocomplete(player_name=player_autocomplete)
|
||||
@logged_command("/injury clear")
|
||||
async def injury_clear(self, interaction: discord.Interaction, player_name: str):
|
||||
"""Clear a player's active injury."""
|
||||
@ -480,35 +574,18 @@ class InjuryGroup(app_commands.Group):
|
||||
await interaction.followup.send(embed=embed, ephemeral=True)
|
||||
return
|
||||
|
||||
# Clear the injury
|
||||
success = await injury_service.clear_injury(injury.id)
|
||||
|
||||
if not success:
|
||||
embed = EmbedTemplate.error(
|
||||
title="Error",
|
||||
description="Failed to clear the injury. Please try again."
|
||||
)
|
||||
await interaction.followup.send(embed=embed, ephemeral=True)
|
||||
return
|
||||
|
||||
# Clear player's il_return field
|
||||
await player_service.update_player(player.id, {'il_return': None})
|
||||
|
||||
# Success response
|
||||
embed = EmbedTemplate.success(
|
||||
title="Injury Cleared",
|
||||
description=f"{player.name} has been cleared and is eligible to play again."
|
||||
# Create confirmation embed
|
||||
embed = EmbedTemplate.info(
|
||||
title=f"{player.name}",
|
||||
description=f"Is **{player.name}** cleared to return?"
|
||||
)
|
||||
|
||||
embed.add_field(
|
||||
name="Previous Return Date",
|
||||
value=injury.return_date,
|
||||
inline=True
|
||||
)
|
||||
if player.team and player.team.thumbnail is not None:
|
||||
embed.set_thumbnail(url=player.team.thumbnail)
|
||||
|
||||
embed.add_field(
|
||||
name="Total Games Missed",
|
||||
value=injury.duration_display,
|
||||
name="Player",
|
||||
value=f"{player.name} ({player.primary_position})",
|
||||
inline=True
|
||||
)
|
||||
|
||||
@ -516,19 +593,88 @@ class InjuryGroup(app_commands.Group):
|
||||
embed.add_field(
|
||||
name="Team",
|
||||
value=f"{player.team.lname} ({player.team.abbrev})",
|
||||
inline=False
|
||||
inline=True
|
||||
)
|
||||
|
||||
await interaction.followup.send(embed=embed)
|
||||
|
||||
# Log for debugging
|
||||
self.logger.info(
|
||||
f"Injury cleared for {player.name}",
|
||||
player_id=player.id,
|
||||
season=current.season,
|
||||
injury_id=injury.id
|
||||
embed.add_field(
|
||||
name="Expected Return",
|
||||
value=injury.return_date,
|
||||
inline=True
|
||||
)
|
||||
|
||||
embed.add_field(
|
||||
name="Games Missed",
|
||||
value=injury.duration_display,
|
||||
inline=True
|
||||
)
|
||||
|
||||
# Create callback for confirmation
|
||||
async def clear_confirm_callback(button_interaction: discord.Interaction):
|
||||
"""Handle confirmation to clear injury."""
|
||||
# Clear the injury
|
||||
success = await injury_service.clear_injury(injury.id)
|
||||
|
||||
if not success:
|
||||
error_embed = EmbedTemplate.error(
|
||||
title="Error",
|
||||
description="Failed to clear the injury. Please try again."
|
||||
)
|
||||
await button_interaction.response.send_message(embed=error_embed, ephemeral=True)
|
||||
return
|
||||
|
||||
# Clear player's il_return field
|
||||
await player_service.update_player(player.id, {'il_return': None})
|
||||
|
||||
# Success response
|
||||
success_embed = EmbedTemplate.success(
|
||||
title="Injury Cleared",
|
||||
description=f"{player.name} has been cleared and is eligible to play again."
|
||||
)
|
||||
|
||||
success_embed.add_field(
|
||||
name="Injury Return Date",
|
||||
value=injury.return_date,
|
||||
inline=True
|
||||
)
|
||||
|
||||
success_embed.add_field(
|
||||
name="Total Games Missed",
|
||||
value=injury.duration_display,
|
||||
inline=True
|
||||
)
|
||||
|
||||
if player.team:
|
||||
success_embed.add_field(
|
||||
name="Team",
|
||||
value=f"{player.team.lname}",
|
||||
inline=False
|
||||
)
|
||||
if player.team.thumbnail is not None:
|
||||
success_embed.set_thumbnail(url=player.team.thumbnail)
|
||||
|
||||
await button_interaction.response.send_message(embed=success_embed)
|
||||
|
||||
# Log for debugging
|
||||
self.logger.info(
|
||||
f"Injury cleared for {player.name}",
|
||||
player_id=player.id,
|
||||
season=current.season,
|
||||
injury_id=injury.id
|
||||
)
|
||||
|
||||
# Create confirmation view
|
||||
view = ConfirmationView(
|
||||
user_id=interaction.user.id,
|
||||
timeout=180.0, # 3 minutes for confirmation
|
||||
responders=[player.team.gmid, player.team.gmid2] if player.team else None,
|
||||
confirm_callback=clear_confirm_callback,
|
||||
confirm_label="Clear Injury",
|
||||
cancel_label="Cancel"
|
||||
)
|
||||
|
||||
# Send confirmation embed with view
|
||||
await interaction.followup.send(embed=embed, view=view)
|
||||
|
||||
|
||||
async def setup(bot: commands.Bot):
|
||||
"""Setup function for loading the injury commands."""
|
||||
|
||||
Loading…
Reference in New Issue
Block a user