Source code for views.embed_builder

"""Views for embed builder interface"""

from collections.abc import Callable

import discord
from modals.embed_builder import EmbedBuilderModal, EmbedFieldModal


[docs] class EmbedBuilderView(discord.ui.View): """View for building embeds with multiple options"""
[docs] def __init__( self, timeout: float | None = 300, embed_data: dict | None = None, macro_name: str = "", callback_func: Callable | None = None, ): super().__init__(timeout=timeout) self.embed_data = embed_data or {} self.macro_name = macro_name self.callback_func = callback_func self.fields = self.embed_data.get("fields", [])
[docs] def create_preview_embed(self) -> discord.Embed: """Create a preview embed from current data""" embed = discord.Embed() # Set title if self.embed_data.get("title"): embed.title = self.embed_data["title"] # Set description if self.embed_data.get("description"): embed.description = self.embed_data["description"] # Set color if self.embed_data.get("color"): embed.color = self.embed_data["color"] # Set footer if self.embed_data.get("footer"): embed.set_footer(text=self.embed_data["footer"]) # Set image if self.embed_data.get("image"): embed.set_image(url=self.embed_data["image"]) # Add fields for field in self.fields: embed.add_field( name=field["name"], value=field["value"], inline=field.get("inline", False), ) # If embed is empty, add placeholder if not any( [ embed.title, embed.description, embed.footer.text if embed.footer else None, embed.image, self.fields, ] ): embed.title = "Embed Preview" embed.description = ( "*No content added yet. Use the buttons below to build your embed.*" ) embed.color = discord.Color.greyple() return embed
[docs] async def update_preview(self, interaction: discord.Interaction): """Update the embed preview""" preview_embed = self.create_preview_embed() # Create status text status_parts = [] if self.embed_data.get("title"): status_parts.append("✅ Title") if self.embed_data.get("description"): status_parts.append("✅ Description") if self.embed_data.get("color"): status_parts.append("✅ Color") if self.embed_data.get("footer"): status_parts.append("✅ Footer") if self.embed_data.get("image"): status_parts.append("✅ Image") if self.fields: status_parts.append(f"✅ {len(self.fields)} Field(s)") status_text = ( " | ".join(status_parts) if status_parts else "No content added yet" ) content = ( f"**Building Embed Macro: `{self.macro_name}`**\n*Status: {status_text}*" ) await interaction.response.edit_message( content=content, embed=preview_embed, view=self )
[docs] @discord.ui.button( label="Edit Basic Info", style=discord.ButtonStyle.primary, emoji="📝" ) async def edit_basic_info( self, interaction: discord.Interaction, _button: discord.ui.Button ): """Edit basic embed information""" async def handle_basic_embed_data( interaction: discord.Interaction, embed_data: dict ): self.embed_data.update(embed_data) await self.update_preview(interaction) modal = EmbedBuilderModal( title_text="Edit Embed Info", embed_data=self.embed_data, callback_func=handle_basic_embed_data, ) await interaction.response.send_modal(modal)
[docs] @discord.ui.button( label="Add Field", style=discord.ButtonStyle.secondary, emoji="➕" ) async def add_field( self, interaction: discord.Interaction, _button: discord.ui.Button ): """Add a custom field to the embed""" async def handle_field_data(interaction: discord.Interaction, field_data: dict): self.fields.append(field_data) self.embed_data["fields"] = self.fields await self.update_preview(interaction) modal = EmbedFieldModal(callback_func=handle_field_data) await interaction.response.send_modal(modal)
[docs] @discord.ui.button( label="Clear Fields", style=discord.ButtonStyle.secondary, emoji="🗑️" ) async def clear_fields( self, interaction: discord.Interaction, _button: discord.ui.Button ): """Clear all custom fields""" if not self.fields: await interaction.response.send_message( "❌ No fields to clear!", ephemeral=True ) return self.fields.clear() self.embed_data["fields"] = self.fields await self.update_preview(interaction)
[docs] @discord.ui.button( label="Save Macro", style=discord.ButtonStyle.success, emoji="💾" ) async def save_macro( self, interaction: discord.Interaction, _button: discord.ui.Button ): """Save the embed macro""" # Validate embed has content if not any( [ self.embed_data.get("title"), self.embed_data.get("description"), self.embed_data.get("footer"), self.embed_data.get("image"), self.fields, ] ): await interaction.response.send_message( "❌ Please add some content to your embed before saving!", ephemeral=True, ) return # Call the callback function to save if self.callback_func: await self.callback_func(interaction, self.embed_data) else: await interaction.response.send_message( "✅ Embed macro saved successfully!", ephemeral=True ) # Disable all buttons after saving for item in self.children: item.disabled = True await interaction.edit_original_response(view=self)
[docs] @discord.ui.button(label="Cancel", style=discord.ButtonStyle.danger, emoji="❌") async def cancel( self, interaction: discord.Interaction, _button: discord.ui.Button ): """Cancel embed creation""" await interaction.response.edit_message( content="❌ Embed creation cancelled.", embed=None, view=None )
[docs] async def on_timeout(self): """Handle view timeout""" # Disable all buttons on timeout for item in self.children: item.disabled = True