Firebot icon indicating copy to clipboard operation
Firebot copied to clipboard

Injecting custom UI components into chat feed

Open TheStaticMage opened this issue 1 month ago • 1 comments

Describe the solution you'd like

As a plugin developer, I would like support for injecting custom UI components into the chat feed panel alongside messages, alerts, and reward redemptions. I propose a new chat queue item type ("custom") that can render arbitrary Angular components dynamically, enabling scripts and extensions to programmatically insert UI elements into the chat feed.

The primary purpose is to allow script developers to build rich, context-aware interfaces that can display information or provide quick actions directly in the chat feed. Panels can be positioned strategically (append, prepend, before/after specific messages) and removed dynamically, enabling ephemeral UI elements that appear based on events or conditions.

My use case is for what I'm calling "action buttons" -- a custom plugin that will let me put buttons in my chat feed under a message. I have a redemption that calls OpenAI to write a poem which I display with a Chat Feed Alert. I want to have buttons right there to approve the poem for TTS, read myself, or reject the output.

Image

I can keep "Action Buttons" as a plugin rather than a Firebot core feature, but I need support in core Firebot to be able to display the components in the chat feed. Some other use cases that I think this could unlock:

  • Moderation Alerts: Insert highlighted panels for important moderation events (raid incoming, suspicious activity detected) with quick action button for the streamer.
  • Queue Management: Show dynamic queue status panels for song requests, giveaway entries, or viewer questions with inline management controls.
  • Poll Management: Display poll results in real time along with management buttons.

Additional context

As a proof of concept and for my own use, I built a working implementation of this in my private fork of Firebot using the following approach:

Commit: https://github.com/TheStaticMage/Firebot/commit/8b07c7f85df4db10fa6acc37d7ff4717dd6c6c96

The frontend receives panel injection/update/removal requests via the existing chatUpdate event handler and manages items with type: "custom" in the chat queue. A new custom-chat-panel component acts as a wrapper that conditionally renders based on the presence of a component name, delegating to a dynamic-component directive that handles Angular's $compile service to dynamically instantiate components at runtime. The directive includes camelCase-to-kebab-case conversion since Angular normalizes component names (e.g., helloWorldPanel becomes <hello-world-panel>).

Panels can be shown/hidden dynamically without removal, and their data can be updated in place. A filter (hideCustomPanels) ensures hidden panels don't render while preserving their position in the queue.

Some specifics about my implementation:

  • Minimal Change Set (Frontend Only - 5 files)

    1. src/gui/app/directives/chat/feed items/custom-chat-panel.js (new, 34 lines) Angular component wrapper for custom chat panels

    2. src/gui/app/directives/dynamic-component.js (new, 32 lines) Directive for dynamic component compilation with camelCase-to-kebab-case conversion

    3. src/gui/app/services/chat-messages.service.js (~112 lines added) Added injectCustomPanel(), updateCustomPanel(), removeCustomPanel(), and getCustomPanel() methods Added InjectCustomPanel, UpdateCustomPanel, and RemoveCustomPanel cases to chatUpdateHandler() Registered firebot:get-chat-panel async handler for backend queries about current panel state

    4. src/gui/app/templates/chat/_chat-messages.html (~6 lines added) Added hideCustomPanels filter to ng-repeat Added <custom-chat-panel> rendering block for custom type

    5. src/gui/app/app-main.js (11 lines added) Added hideCustomPanels filter definition

  • Complete Change Set (Including Optional Backend Manager - 8 files)

    1. src/backend/chat/custom-chat-panel-manager.ts (new, 98 lines) Manager class with injectPanel(), updatePanel(), removePanel(), and getPanel() methods Sends events via Frontend Communicator, no IPC listeners needed (direct method calls only)

    2. src/backend/app-management/electron/events/when-ready.ts (3 lines added) Import of custom chat panel manager to load it into memory

    3. src/backend/common/handlers/custom-scripts/custom-script-helpers.js (2 lines added) Exposed customChatPanelManager to custom scripts via modules object

    4. A backend manager would also need to be added to firebot-custom-scripts-types.

Total diff size: ~195 lines for minimal implementation, ~298 lines for complete implementation with backend manager.

This represents a flexible approach where the backend manager is optional - scripts can work directly with Frontend Communicator for full control, or use the convenience methods from the backend manager.

TheStaticMage avatar Nov 30 '25 20:11 TheStaticMage

This is an awesome suggestion and something we very much want to do. Chat needs an overhaul, both frontend and backend, and we would integrate chat extensions in at that point. So let's hold off on this for now until we do the chat overhaul, then we'll definitely revisit this.

zunderscore avatar Dec 01 '25 00:12 zunderscore