sendMessage method
Sends a message to the AI service and adds it to the current conversation.
If no conversation is currently selected, a new one will be created. The method handles:
- Adding the user message to the conversation
- Setting loading state
- Calling the AI service with streaming support
- Adding the AI response in real-time as chunks arrive
- Updating conversation title
- Error handling
Throws an exception if the AI service fails.
Implementation
Future<void> sendMessage(final String content) async {
if (_currentConversation == null) {
createNewConversation();
}
final userMessage = ChatMessage(
id: DateTime.now().millisecondsSinceEpoch.toString(),
content: content,
isUser: true,
timestamp: DateTime.now(),
);
// Update conversation with user message
_currentConversation = _currentConversation!.addMessage(userMessage);
_updateConversationInList(_currentConversation!);
_isLoading = true;
_error = '';
notifyListeners();
try {
// Create AI message placeholder for streaming
final aiMessageId = DateTime.now().millisecondsSinceEpoch.toString();
var aiMessageContent = '';
final aiMessage = ChatMessage(
id: aiMessageId,
content: aiMessageContent,
isUser: false,
timestamp: DateTime.now(),
);
// Add empty AI message first
_currentConversation = _currentConversation!.addMessage(aiMessage);
_updateConversationInList(_currentConversation!);
// Stream the AI response
final buffer = StringBuffer();
await for (final chunk in _aiService.sendMessageStream(content)) {
buffer.write(chunk);
aiMessageContent = buffer.toString();
// Update the AI message with accumulated content
final updatedAiMessage = ChatMessage(
id: aiMessageId,
content: aiMessageContent,
isUser: false,
timestamp: DateTime.now(),
);
// Replace the last message (AI message) with updated content
final messages = List<ChatMessage>.from(_currentConversation!.messages);
messages[messages.length - 1] = updatedAiMessage;
_currentConversation = _currentConversation!.copyWith(
messages: messages,
updatedAt: DateTime.now(),
);
_updateConversationInList(_currentConversation!);
notifyListeners();
}
_updateConversationTitle();
} on Exception catch (e) {
_error = 'Failed to get AI response: $e';
// Remove the empty AI message if there was an error
if (_currentConversation != null &&
_currentConversation!.messages.isNotEmpty &&
!_currentConversation!.messages.last.isUser &&
_currentConversation!.messages.last.content.isEmpty) {
final messages = List<ChatMessage>.from(_currentConversation!.messages)
..removeLast();
_currentConversation = _currentConversation!.copyWith(
messages: messages,
);
_updateConversationInList(_currentConversation!);
}
} finally {
_isLoading = false;
notifyListeners();
}
}