Custom Structures
Relevant source files
The following files were used as context for generating this wiki page:
The custom structures in the Amina project are a foundational part of the v3.0 architectural overhaul, which implemented "Mina's unified personality system." These structures are designed to standardize UI/UX elements such as embeds, buttons, and response messages across the entire codebase. By centralizing the creation and styling of these components, the system ensures a consistent look, feel, and voice for the bot, making development more efficient and the user experience more cohesive.
The core components of this system include MinaEmbed for creating styled message embeds, MinaButton and MinaRows for generating interactive components, and the mina helper for managing response strings and personality quirks like random quotes and tips. These structures work in concert to enforce Mina's specific persona—sharp, energetic, and blunt—as defined in the project's core identity guidelines.
Sources: CHANGELOG.md:16-21, src/data/prompt.md:3-8
MinaEmbed
MinaEmbed is a custom class that extends discord.js's EmbedBuilder to provide a centralized factory for creating embeds with Mina's distinct styling and personality. It standardizes color themes, automatically injects personality elements, and offers context-aware builders to simplify embed creation.
Sources: src/structures/embeds/MinaEmbed.ts:4-5, CHANGELOG.md:23-29
Class Diagram
This diagram illustrates how MinaEmbed extends EmbedBuilder and includes its own specialized methods for styling, personality, and context.
Sources: src/structures/embeds/MinaEmbed.ts
Preset Factory Methods
MinaEmbed provides several static factory methods for creating embeds with preset colors and behaviors. These methods ensure a consistent color palette across the application.
| Method | Color | Description |
|---|---|---|
success(description?) | Green | For successful operations. Has a 30% chance to add a quote. |
error(description?) | Red | For errors. Has a 10% chance to add a quote. |
warning(description?) | Amber | For warnings. Has a 10% chance to add a quote. |
info(description?) | Blue | For informational messages. Has a 30% chance to add a quote. |
primary(description?) | Crimson | The default embed type. Has a 30% chance to add a quote. |
secondary(description?) | Electric Blue | An alternative primary style. Has a 30% chance to add a quote. |
gold(description?) | Gold | For achievements or special events. Has a 30% chance to add a quote. |
loading(description?) | Muted Gray | A clean embed for loading states, with no extra personality. |
mod(action, description?) | Varies | For moderation actions (ban, kick, etc.). Uses professional colors and has no extra personality. |
plain(description?) | Crimson | A basic embed with no automatic quote or tip, for full manual control. |
Sources: src/structures/embeds/MinaEmbed.ts:323-399, src/helpers/mina.ts:203-215
Contextual Builders
These methods automatically populate embed fields based on the provided context object, such as a User, Member, or Guild.
| Method | Context Object | Description |
|---|---|---|
withUser(ctx) | UserContext | Adds user avatar and banner. |
withMember(ctx) | MemberContext | Adds member avatar, join date, and roles. |
withGuild(ctx) | GuildContext | Adds guild icon, banner, and member count. |
withModeration(ctx) | ModerationContext | Formats a moderation log with target, moderator, reason, and duration. |
withEconomy(ctx) | EconomyContext | Displays economy-related transactions, including amount and balance. |
withMusic(ctx) | MusicContext | Shows music track information like title, artist, and requester. |
withLevel(ctx) | LevelContext | Displays user level, XP, and rank. |
Sources: src/structures/embeds/MinaEmbed.ts:167-320
Personality Injection
A key feature of MinaEmbed is its ability to inject personality into messages automatically.
withQuote()/withQuoteSync(): Appends a random anime quote to the embed's description. The quote is fetched from an external API or a local cache.withTip(): Adds a random "tip" to the embed's footer.withRandomExtras()/withRandomFooter(): Conditionally adds a quote or tip based on a given probability, ensuring that not every message is decorated and keeping the personality from feeling repetitive.
Sources: src/structures/embeds/MinaEmbed.ts:85-164, src/helpers/mina.ts:40-155
Mina Components
To standardize interactive components, the project uses MinaButton and MinaRows, which are custom factories for creating discord.js buttons and action rows.
MinaButton
MinaButton extends ButtonBuilder to provide a factory for creating consistently styled and labeled buttons that match Mina's casual, lowercase voice.
Sources: src/structures/components/MinaButton.ts, CHANGELOG.md:31-36
Semantic Button Presets
The class offers numerous static methods for generating common buttons, which abstracts away the need to manually set labels, styles, and custom IDs.
| Method | Default Label | Style | Purpose |
|---|---|---|---|
yeah(customId?) | yeah | Success (Green) | Confirmation |
nah(customId?) | nah | Secondary (Gray) | Cancellation |
prev(customId?, disabled?) | prev | Secondary (Gray) | Pagination: previous page |
next(customId?, disabled?) | next | Secondary (Gray) | Pagination: next page |
back(customId?) | back | Secondary (Gray) | Navigation: return to a previous menu |
hub(customId?) | hub | Primary (Blue) | Navigation: return to a main hub |
delete(customId?) | delete | Danger (Red) | Destructive action |
link(url, label?) | link | Link | A URL button |
Sources: src/structures/components/MinaButton.ts:98-293
State Management in Custom IDs
MinaButton includes a system for embedding state within a button's customId. This allows handlers to retrieve contextual data (like a page number or a user ID) directly from the interaction without needing a separate state store.
The buildCustomId function creates a customId string by concatenating a base ID with state key-value pairs, separated by | and :. The parseState function reverses this process.
This diagram shows the flow of creating and parsing a stateful customId.
MinaRows
MinaRows is a helper object that provides factory functions for creating ActionRowBuilder instances populated with pre-defined sets of MinaButtons. This simplifies the creation of common button layouts.
from(...buttons): Creates a row from the provided buttons.prevNext(...): Creates a row with "prev" and "next" buttons for pagination.yesNoRow(): Creates a row with "yeah" and "nah" buttons for confirmation prompts.backRow(): Creates a row with a single "back" button.
Sources: src/helpers/componentHelper.ts, src/commands/bot/bot.ts:129, src/commands/admin/settings/status.ts:223
Mina Response & Personality Helper
The mina helper, located in src/helpers/mina.ts, is the central utility for managing the bot's voice, responses, colors, and personality quirks. It ensures that all bot-generated text aligns with the defined persona.
Sources: src/helpers/mina.ts, CHANGELOG.md:38-42
Core Functions
mina.say(path): Retrieves a random response string from a nested JSON object using dot notation (e.g.,botInfo.dm.sent). This allows for organized and varied responses.mina.sayf(path, vars): Combinessay()with a template formatter. It fetches a response string and substitutes placeholders like{user}with provided values.mina.quote()/mina.quoteSync(): Fetches a random anime quote, either asynchronously from an API or synchronously from a cache.mina.tip(): Retrieves a random helpful tip.mina.color/mina.modColors: Provides access to the standardized color palette for embeds.
Sources: src/helpers/mina.ts:159-232
Example Workflow: /bot stats
This sequence diagram illustrates how the custom structures work together when a user executes the /bot stats command.
Conclusion
The custom structures (MinaEmbed, MinaButton, MinaRows, and the mina helper) are a cornerstone of the Amina project's architecture. They successfully abstract the complexities of creating styled and personality-rich Discord UI components. This system not only enforces a consistent and engaging user experience that reflects the bot's defined persona but also significantly improves developer productivity by providing reusable, high-level factories for common UI patterns. The result is a more maintainable, scalable, and character-driven application.