sendMessage method

Future<void> sendMessage(
  1. String content
)

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();
  }
}