class ChatTranscriptWidget extends StatefulWidget {
@override
_ChatTranscriptWidgetState createState() => _ChatTranscriptWidgetState();
}
class _ChatTranscriptWidgetState extends State<ChatTranscriptWidget> {
List<TranscriptItem> _transcript = [];
ScrollController _scrollController = ScrollController();
@override
void initState() {
super.initState();
_telnyxClient.onTranscriptUpdate = (List<TranscriptItem> transcript) {
setState(() {
_transcript = transcript;
});
// Auto-scroll to bottom
WidgetsBinding.instance.addPostFrameCallback((_) {
if (_scrollController.hasClients) {
_scrollController.animateTo(
_scrollController.position.maxScrollExtent,
duration: Duration(milliseconds: 300),
curve: Curves.easeOut,
);
}
});
};
}
@override
Widget build(BuildContext context) {
return ListView.builder(
controller: _scrollController,
itemCount: _transcript.length,
itemBuilder: (context, index) {
final item = _transcript[index];
final isUser = item.role == 'user';
return Align(
alignment: isUser ? Alignment.centerRight : Alignment.centerLeft,
child: Container(
margin: EdgeInsets.symmetric(vertical: 4, horizontal: 8),
padding: EdgeInsets.all(12),
decoration: BoxDecoration(
color: isUser ? Colors.blue[100] : Colors.grey[200],
borderRadius: BorderRadius.circular(16),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
item.content,
style: TextStyle(fontSize: 16),
),
SizedBox(height: 4),
Text(
DateFormat('HH:mm:ss').format(item.timestamp),
style: TextStyle(fontSize: 10, color: Colors.grey[600]),
),
],
),
),
);
},
);
}
@override
void dispose() {
_scrollController.dispose();
super.dispose();
}
}