sendAudioMessage method

Future<void> sendAudioMessage(
  1. File audioFile
)

Implementation

Future<void> sendAudioMessage(File audioFile) async {
  keyboardFocusNode.unfocus();
  resetLoadingMessage();
  currentWebSearchType.value = null;
  scrollToBottomChat();
  setExternalSearchButton(false);
  messageNotifier = MessageNotifier();
  messageNotifier.setAssistantId(assistant.value?.id ?? "");
  incomingMessages = [];
  kbReferencesBackup = [];
  isStreaming.value = true;
  assistantsReplying.value = 1;
  final PupauMessage senderMessage = PupauMessage(
    id: "",
    attachments: const [],
    answer: "",
    status: MessageStatus.sent,
    createdAt: DateTime.now(),
    isAudioInput: true,
    assistantId: assistantId,
    assistantType: assistant.value?.type ?? AssistantType.assistant,
  );
  addMessage(senderMessage, bypassCheck: true);
  addTaggedAssistants();
  if (conversation.value == null) await createNewConversation();
  if (conversation.value == null) return;
  bool isFirstSSEData = true;
  listHeight =
      chatScrollController.positions.lastOrNull?.maxScrollExtent ?? 0;
  messageNotifier.setConversationId(conversation.value?.id ?? "");
  Stream<SSEModel>? sseStream = await SSEService.createSSEStreamAudio(
    assistantId,
    conversation.value?.id ?? "",
    conversation.value?.token ?? "",
    audioFile,
    isWebSearch: isWebSearchActive.value,
    chatController: this,
  );
  if (sseStream != null) {
    _bumpSseIdleTimer();
  }
  if (sseStream == null) {
    showErrorSnackbar(
      "${Strings.apiErrorGeneric.tr} ${Strings.apiErrorSendMessage.tr}",
    );
    _lastFailedAudioFilePath = audioFile.path;
    manageCancelAndErrorMessage();
    assistantsReplying.value = 0;
    return;
  }
  messageSendStream = sseStream.listen(
    (event) {
      _bumpSseIdleTimer();
      setLastEventId(event);
      if (event.data == null || event.data!.trim().isEmpty) return;
      try {
        final Map<String, dynamic> data = jsonDecode(event.data!);
        manageSSEData(data, false);
        // Stream accepted; we can clear the retry path.
        _lastFailedAudioFilePath = null;
        if (isFirstSSEData) {
          isFirstSSEData = false;
          autoScrollEnabled = true;
        }
      } catch (_) {}
    },
    onError: (e) {
      _cancelSseIdleTimer();
      showErrorSnackbar(
        "${Strings.apiErrorGeneric.tr} ${Strings.apiErrorSendMessage.tr}",
      );
      _lastFailedAudioFilePath = audioFile.path;
      manageCancelAndErrorMessage();
      assistantsReplying.value = 0;
    },
    onDone: () => _cancelSseIdleTimer(),
  );
}