- Deleted .env.example file as it is no longer needed. - Added .gitignore to manage ignored files and directories. - Introduced CLAUDE.md for AI provider integration documentation. - Created dev.sh for development setup and scripts. - Updated Dockerfile and Dockerfile.production for improved build processes. - Added multiple test files and directories for comprehensive testing. - Introduced new utility and service files for enhanced functionality. - Organized codebase with new directories and files for better maintainability.
331 lines
12 KiB
Python
331 lines
12 KiB
Python
"""
|
|
Feedback Modal Components for Discord Voice Chat Quote Bot
|
|
|
|
Provides interactive modal dialogs for collecting different types of feedback
|
|
from users to improve the quote analysis system.
|
|
"""
|
|
|
|
import logging
|
|
from typing import Optional
|
|
|
|
import discord
|
|
|
|
from .feedback_system import FeedbackSystem, FeedbackType
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class FeedbackRatingModal(discord.ui.Modal):
|
|
"""Modal for collecting rating and general feedback"""
|
|
|
|
def __init__(self, feedback_system: FeedbackSystem, quote_id: Optional[int] = None):
|
|
super().__init__(title="Rate the Analysis")
|
|
self.feedback_system = feedback_system
|
|
self.quote_id = quote_id
|
|
|
|
# Rating input
|
|
self.rating_input = discord.ui.TextInput(
|
|
label="Rating (1-5 stars)",
|
|
placeholder="Rate the analysis quality from 1 (poor) to 5 (excellent)",
|
|
min_length=1,
|
|
max_length=1,
|
|
)
|
|
self.add_item(self.rating_input)
|
|
|
|
# Feedback text
|
|
self.feedback_input = discord.ui.TextInput(
|
|
label="Feedback (Optional)",
|
|
placeholder="Tell us what you liked or what could be improved...",
|
|
style=discord.TextStyle.paragraph,
|
|
min_length=0,
|
|
max_length=1000,
|
|
required=False,
|
|
)
|
|
self.add_item(self.feedback_input)
|
|
|
|
async def on_submit(self, interaction: discord.Interaction):
|
|
"""Handle modal submission"""
|
|
try:
|
|
# Validate rating
|
|
try:
|
|
rating = int(self.rating_input.value.strip())
|
|
if not 1 <= rating <= 5:
|
|
raise ValueError()
|
|
except ValueError:
|
|
await interaction.response.send_message(
|
|
"❌ Please enter a valid rating between 1 and 5.", ephemeral=True
|
|
)
|
|
return
|
|
|
|
# Get feedback text
|
|
feedback_text = (
|
|
self.feedback_input.value.strip()
|
|
or f"User rated the analysis {rating}/5 stars"
|
|
)
|
|
|
|
# Collect feedback
|
|
feedback_id = await self.feedback_system.collect_feedback(
|
|
user_id=interaction.user.id,
|
|
guild_id=interaction.guild_id,
|
|
feedback_type=FeedbackType.OVERALL,
|
|
text_feedback=feedback_text,
|
|
rating=rating,
|
|
quote_id=self.quote_id,
|
|
)
|
|
|
|
if feedback_id:
|
|
# Create success embed
|
|
embed = discord.Embed(
|
|
title="✅ Feedback Submitted",
|
|
description=f"Thank you for rating the analysis **{rating}/5 stars**!",
|
|
color=0x2ECC71,
|
|
)
|
|
embed.add_field(
|
|
name="Your Impact",
|
|
value="Your feedback helps improve the AI's analysis accuracy for everyone.",
|
|
inline=False,
|
|
)
|
|
|
|
await interaction.response.send_message(embed=embed, ephemeral=True)
|
|
else:
|
|
await interaction.response.send_message(
|
|
"❌ Failed to submit feedback. You may have reached the daily limit.",
|
|
ephemeral=True,
|
|
)
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error in feedback rating modal: {e}")
|
|
await interaction.response.send_message(
|
|
"❌ An error occurred while submitting your feedback.", ephemeral=True
|
|
)
|
|
|
|
|
|
class CategoryFeedbackModal(discord.ui.Modal):
|
|
"""Modal for collecting category-specific feedback"""
|
|
|
|
def __init__(self, feedback_system: FeedbackSystem, quote_id: Optional[int] = None):
|
|
super().__init__(title="Category Feedback")
|
|
self.feedback_system = feedback_system
|
|
self.quote_id = quote_id
|
|
|
|
# Category selection
|
|
self.category_input = discord.ui.TextInput(
|
|
label="Category (funny, dark, silly, suspicious, asinine)",
|
|
placeholder="Which category would you like to provide feedback on?",
|
|
min_length=3,
|
|
max_length=20,
|
|
)
|
|
self.add_item(self.category_input)
|
|
|
|
# Suggested score
|
|
self.score_input = discord.ui.TextInput(
|
|
label="Suggested Score (0-10)",
|
|
placeholder="What score do you think this category should have?",
|
|
min_length=1,
|
|
max_length=4,
|
|
)
|
|
self.add_item(self.score_input)
|
|
|
|
# Reasoning
|
|
self.reasoning_input = discord.ui.TextInput(
|
|
label="Reasoning",
|
|
placeholder="Why do you think this score is more accurate?",
|
|
style=discord.TextStyle.paragraph,
|
|
min_length=10,
|
|
max_length=500,
|
|
)
|
|
self.add_item(self.reasoning_input)
|
|
|
|
async def on_submit(self, interaction: discord.Interaction):
|
|
"""Handle modal submission"""
|
|
try:
|
|
# Validate category
|
|
category = self.category_input.value.strip().lower()
|
|
valid_categories = ["funny", "dark", "silly", "suspicious", "asinine"]
|
|
|
|
if category not in valid_categories:
|
|
await interaction.response.send_message(
|
|
f"❌ Invalid category. Please use one of: {', '.join(valid_categories)}",
|
|
ephemeral=True,
|
|
)
|
|
return
|
|
|
|
# Validate score
|
|
try:
|
|
score = float(self.score_input.value.strip())
|
|
if not 0 <= score <= 10:
|
|
raise ValueError()
|
|
except ValueError:
|
|
await interaction.response.send_message(
|
|
"❌ Please enter a valid score between 0 and 10.", ephemeral=True
|
|
)
|
|
return
|
|
|
|
# Get reasoning
|
|
reasoning = self.reasoning_input.value.strip()
|
|
|
|
# Create feedback text
|
|
feedback_text = f"Category feedback for '{category}': Suggested score {score}/10. Reasoning: {reasoning}"
|
|
|
|
# Create categories feedback
|
|
categories_feedback = {category: score}
|
|
|
|
# Collect feedback
|
|
feedback_id = await self.feedback_system.collect_feedback(
|
|
user_id=interaction.user.id,
|
|
guild_id=interaction.guild_id,
|
|
feedback_type=FeedbackType.CATEGORY,
|
|
text_feedback=feedback_text,
|
|
quote_id=self.quote_id,
|
|
categories_feedback=categories_feedback,
|
|
)
|
|
|
|
if feedback_id:
|
|
embed = discord.Embed(
|
|
title="✅ Category Feedback Submitted",
|
|
description=f"Thank you for the feedback on **{category}** category!",
|
|
color=0x2ECC71,
|
|
)
|
|
embed.add_field(
|
|
name="Your Suggestion",
|
|
value=f"**Category:** {category.title()}\n**Suggested Score:** {score}/10\n**Reasoning:** {reasoning[:100]}{'...' if len(reasoning) > 100 else ''}",
|
|
inline=False,
|
|
)
|
|
|
|
await interaction.response.send_message(embed=embed, ephemeral=True)
|
|
else:
|
|
await interaction.response.send_message(
|
|
"❌ Failed to submit feedback. You may have reached the daily limit.",
|
|
ephemeral=True,
|
|
)
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error in category feedback modal: {e}")
|
|
await interaction.response.send_message(
|
|
"❌ An error occurred while submitting your feedback.", ephemeral=True
|
|
)
|
|
|
|
|
|
class GeneralFeedbackModal(discord.ui.Modal):
|
|
"""Modal for collecting general feedback and suggestions"""
|
|
|
|
def __init__(self, feedback_system: FeedbackSystem, quote_id: Optional[int] = None):
|
|
super().__init__(title="General Feedback")
|
|
self.feedback_system = feedback_system
|
|
self.quote_id = quote_id
|
|
|
|
# Feedback type selection
|
|
self.type_input = discord.ui.TextInput(
|
|
label="Feedback Type (accuracy, relevance, suggestion)",
|
|
placeholder="What type of feedback are you providing?",
|
|
min_length=3,
|
|
max_length=20,
|
|
)
|
|
self.add_item(self.type_input)
|
|
|
|
# Main feedback
|
|
self.feedback_input = discord.ui.TextInput(
|
|
label="Your Feedback",
|
|
placeholder="Share your thoughts, suggestions, or report issues...",
|
|
style=discord.TextStyle.paragraph,
|
|
min_length=10,
|
|
max_length=1000,
|
|
)
|
|
self.add_item(self.feedback_input)
|
|
|
|
# Optional improvement suggestion
|
|
self.suggestion_input = discord.ui.TextInput(
|
|
label="Improvement Suggestion (Optional)",
|
|
placeholder="How could we make this better?",
|
|
style=discord.TextStyle.paragraph,
|
|
min_length=0,
|
|
max_length=500,
|
|
required=False,
|
|
)
|
|
self.add_item(self.suggestion_input)
|
|
|
|
async def on_submit(self, interaction: discord.Interaction):
|
|
"""Handle modal submission"""
|
|
try:
|
|
# Validate feedback type
|
|
feedback_type_str = self.type_input.value.strip().lower()
|
|
|
|
# Map string to enum
|
|
feedback_type_map = {
|
|
"accuracy": FeedbackType.ACCURACY,
|
|
"relevance": FeedbackType.RELEVANCE,
|
|
"suggestion": FeedbackType.SUGGESTION,
|
|
"overall": FeedbackType.OVERALL,
|
|
}
|
|
|
|
feedback_type = feedback_type_map.get(feedback_type_str)
|
|
if not feedback_type:
|
|
valid_types = list(feedback_type_map.keys())
|
|
await interaction.response.send_message(
|
|
f"❌ Invalid feedback type. Please use one of: {', '.join(valid_types)}",
|
|
ephemeral=True,
|
|
)
|
|
return
|
|
|
|
# Get feedback text
|
|
main_feedback = self.feedback_input.value.strip()
|
|
suggestion = self.suggestion_input.value.strip()
|
|
|
|
# Combine feedback
|
|
feedback_text = main_feedback
|
|
if suggestion:
|
|
feedback_text += f" | Improvement suggestion: {suggestion}"
|
|
|
|
# Collect feedback
|
|
feedback_id = await self.feedback_system.collect_feedback(
|
|
user_id=interaction.user.id,
|
|
guild_id=interaction.guild_id,
|
|
feedback_type=feedback_type,
|
|
text_feedback=feedback_text,
|
|
quote_id=self.quote_id,
|
|
)
|
|
|
|
if feedback_id:
|
|
embed = discord.Embed(
|
|
title="✅ Feedback Submitted",
|
|
description=f"Thank you for your **{feedback_type_str}** feedback!",
|
|
color=0x2ECC71,
|
|
)
|
|
embed.add_field(
|
|
name="Your Feedback",
|
|
value=main_feedback[:200]
|
|
+ ("..." if len(main_feedback) > 200 else ""),
|
|
inline=False,
|
|
)
|
|
|
|
if suggestion:
|
|
embed.add_field(
|
|
name="Your Suggestion",
|
|
value=suggestion[:200]
|
|
+ ("..." if len(suggestion) > 200 else ""),
|
|
inline=False,
|
|
)
|
|
|
|
embed.add_field(
|
|
name="Next Steps",
|
|
value="Our team will review your feedback and use it to improve the system.",
|
|
inline=False,
|
|
)
|
|
|
|
await interaction.response.send_message(embed=embed, ephemeral=True)
|
|
else:
|
|
await interaction.response.send_message(
|
|
"❌ Failed to submit feedback. You may have reached the daily limit.",
|
|
ephemeral=True,
|
|
)
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error in general feedback modal: {e}")
|
|
await interaction.response.send_message(
|
|
"❌ An error occurred while submitting your feedback.", ephemeral=True
|
|
)
|
|
|
|
|
|
# Background processing functions have been moved to feedback_system.py
|
|
# to avoid circular dependencies and improve code organization
|