Message Bubble
Chat message bubble for user, assistant, system, and tool messages with markdown support, thinking blocks, tool call chips, citation cards, streaming cursors, and error retry actions.
Installation
$
flai add message_bubble
Import
import 'package:my_app/flai/components/message_bubble/message_bubble.dart';
Preview
Preview
What's the weather in San Francisco?
It's currently 18°C and sunny in San Francisco. Perfect weather for a walk!
You are a helpful weather assistant.
Usage
The bubble automatically adapts its layout based on the message role:
// User message
MessageBubble(
message: Message(
id: '1',
role: MessageRole.user,
content: 'What is Flutter?',
timestamp: DateTime.now(),
),
)
// Assistant message with citations
MessageBubble(
message: Message(
id: '2',
role: MessageRole.assistant,
content: 'Flutter is a UI toolkit...',
timestamp: DateTime.now(),
citations: [
Citation(title: 'Flutter Docs', url: 'https://flutter.dev'),
],
),
onTapCitation: (citation) {
launchUrl(Uri.parse(citation.url!));
},
)
// Streaming message (shows blinking cursor)
MessageBubble(
message: Message(
id: '3',
role: MessageRole.assistant,
content: 'Flutter is a...',
timestamp: DateTime.now(),
status: MessageStatus.streaming,
),
)
Message Roles
The bubble renders four distinct layouts based on MessageRole:
| Role | Alignment | Style |
|---|---|---|
| user | Right-aligned | Uses userBubble color, rounded bottom-right corner |
| assistant | Left-aligned | Uses assistantBubble color, rounded bottom-left corner |
| system | Centered | Muted background, smaller text, bordered |
| tool | Left-aligned | Compact, bordered, with wrench icon |
Features
- Thinking blocks — Collapsible panel showing AI reasoning when
message.thinkingContentis set - Tool call chips — Inline chips for each tool call with status indicator
- Citation cards — Tappable cards linking to source material
- Streaming cursor — Blinking cursor animation when
status == MessageStatus.streaming - Error retry — Retry button on error messages when
onRetryis provided - Long press — Copy/share action when
onLongPressis provided - Timestamps — Subtle time label below each bubble
Properties
| Property | Type | Default | Description |
|---|---|---|---|
| message | Message | required | The message to display. |
| onTapCitation | Function(Citation)? | null | Called when a citation is tapped. |
| onRetry | Function(Message)? | null | Called when retry is tapped on an error message. |
| onLongPress | Function(Message)? | null | Called when the bubble is long-pressed. |
Message Model
class Message {
final String id;
final MessageRole role; // user, assistant, system, tool
final String content;
final DateTime timestamp;
final List<Attachment>? attachments;
final List<ToolCall>? toolCalls;
final String? thinkingContent;
final List<Citation>? citations;
final MessageStatus status; // streaming, complete, error
final UsageInfo? usage;
}