204 lines
7.9 KiB
Dart
204 lines
7.9 KiB
Dart
import 'dart:convert';
|
|
|
|
import 'package:bloc/bloc.dart';
|
|
import 'package:equatable/equatable.dart';
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:hoshan/core/utils/strings.dart';
|
|
import 'package:hoshan/data/model/ai/ai_response_model.dart';
|
|
import 'package:hoshan/data/model/ai/messages_model.dart';
|
|
import 'package:hoshan/data/model/ai/send_message_model.dart';
|
|
import 'package:hoshan/data/repository/chatbot_repository.dart';
|
|
import 'package:string_validator/string_validator.dart';
|
|
|
|
part 'receive_message_state.dart';
|
|
|
|
class ReceiveMessageCubit extends Cubit<ReceiveMessageState> {
|
|
ReceiveMessageCubit() : super(ReceiveMessageInitial());
|
|
|
|
static ScrollController scrollController = ScrollController();
|
|
static ValueNotifier<bool> onResponse = ValueNotifier(false);
|
|
|
|
static Future<void> scrollToEnd({final double? extra}) async {
|
|
try {
|
|
await scrollController.animateTo(
|
|
scrollController.position.minScrollExtent + (extra ?? 0),
|
|
duration: const Duration(milliseconds: 600),
|
|
curve: Curves.easeInOut,
|
|
);
|
|
} catch (e) {
|
|
if (kDebugMode) {
|
|
// print('Error in Scroll:$e');
|
|
}
|
|
}
|
|
}
|
|
|
|
static Future<void> scrollToStart({final double? extra}) async {
|
|
try {
|
|
await scrollController.animateTo(
|
|
scrollController.position.maxScrollExtent + (extra ?? 0),
|
|
duration: const Duration(milliseconds: 600),
|
|
curve: Curves.easeInOut,
|
|
);
|
|
} catch (e) {
|
|
if (kDebugMode) {
|
|
// print('Error in Scroll:$e');
|
|
}
|
|
}
|
|
}
|
|
|
|
void execute({required final SendMessageModel request}) async {
|
|
emit(ReceiveMessageLoading());
|
|
onResponse.value = true;
|
|
String result = '';
|
|
AiResponseModel aiResponseModel = AiResponseModel();
|
|
await scrollToEnd();
|
|
try {
|
|
// Call your streaming message function and yield states accordingly
|
|
await for (String message in request.tool!
|
|
? ChatbotRepository.sendMessageTool(request)
|
|
: ChatbotRepository.sendMessage(request)) {
|
|
Map<String, dynamic> jsonMap;
|
|
try {
|
|
jsonMap = jsonDecode(message);
|
|
} catch (e) {
|
|
if (kDebugMode) {
|
|
print('Error in Parse: $e');
|
|
}
|
|
jsonMap = {};
|
|
jsonMap['content'] = '';
|
|
try {
|
|
message = message.trim();
|
|
|
|
List<String> jsonStrings = message.split('}{').map((s) {
|
|
if (!s.startsWith('{')) s = '{$s';
|
|
if (!s.endsWith('}')) s = '$s}';
|
|
return s;
|
|
}).toList();
|
|
|
|
for (String json in jsonStrings) {
|
|
json = json.replaceAll(
|
|
RegExp(r'[{}"]'), ''); // Remove braces and quotes
|
|
List<String> pairs = json.split(', ');
|
|
for (String pair in pairs) {
|
|
if (pair.contains('chat_id:')) {
|
|
jsonMap['chat_id'] =
|
|
int.tryParse(pair.replaceAll('chat_id: ', ''));
|
|
} else if (pair.contains('chat_title:')) {
|
|
jsonMap['chat_title'] = pair.replaceAll('chat_title: ', '');
|
|
} else if (pair.contains('ai_message_id:')) {
|
|
jsonMap['ai_message_id'] =
|
|
pair.replaceAll('ai_message_id: ', '');
|
|
} else if (pair.contains('human_message_id:')) {
|
|
jsonMap['human_message_id'] =
|
|
pair.replaceAll('human_message_id: ', '');
|
|
} else if (pair.contains('credit:')) {
|
|
jsonMap['credit'] = pair.replaceAll('credit: ', '');
|
|
} else if (pair.contains('credit:')) {
|
|
jsonMap['credit'] = pair.replaceAll('credit: ', '');
|
|
} else if (pair.contains('free:')) {
|
|
jsonMap['free'] = pair.replaceAll('free: ', '');
|
|
} else if (pair.contains('human_message_created_at:')) {
|
|
jsonMap['human_message_created_at'] =
|
|
pair.replaceAll('human_message_created_at: ', '');
|
|
} else if (pair.contains('ai_message_created_at:')) {
|
|
jsonMap['ai_message_created_at'] =
|
|
pair.replaceAll('ai_message_created_at: ', '');
|
|
} else {
|
|
jsonMap['content'] += pair
|
|
.replaceAll('content: ', '')
|
|
.replaceAll('\\n', '\n\n');
|
|
}
|
|
}
|
|
}
|
|
} catch (e) {
|
|
if (kDebugMode) {
|
|
print('Error in Manul Parse: $e');
|
|
}
|
|
jsonMap = {};
|
|
}
|
|
}
|
|
|
|
final res = AiResponseModel.fromJson(jsonMap);
|
|
|
|
if (res.content != null) {
|
|
result += res.content ?? ''; // Add each content to the list
|
|
if (!(res.content!.startsWith('http'))) {
|
|
emit(ReceiveMessageOnResponsing(text: result));
|
|
}
|
|
}
|
|
aiResponseModel = aiResponseModel.copyWith(
|
|
error: res.error,
|
|
credit: res.credit,
|
|
detail: res.detail,
|
|
statusCode: res.statusCode,
|
|
aiMessageId: res.aiMessageId,
|
|
chatId: res.chatId,
|
|
chatTitle: res.chatTitle,
|
|
content: result.isEmpty ? res.content : result,
|
|
freeCredit: res.freeCredit,
|
|
humanMessageId: res.humanMessageId);
|
|
// Yield the received message line by line
|
|
}
|
|
await scrollToEnd();
|
|
|
|
if (aiResponseModel.error ?? true) {
|
|
emit(ReceiveMessageOnFail(
|
|
oldHumanMessageId: request.messageId ?? '',
|
|
detail: 'خطا از سمت سرور لطفا لحظاتی دیگر دوباره تلاش کنید',
|
|
statusCode: aiResponseModel.statusCode ?? 500));
|
|
} else {
|
|
final message = Messages(
|
|
id: aiResponseModel.aiMessageId,
|
|
query: request.query,
|
|
role: 'ai',
|
|
content: [
|
|
if (aiResponseModel.content != null)
|
|
Content(
|
|
audioUrl: aiResponseModel.content!.isURL() &&
|
|
aiResponseModel.content!.isAudio()
|
|
? FileUrl(url: aiResponseModel.content)
|
|
: null,
|
|
pdfUrl: aiResponseModel.content!.isURL() &&
|
|
aiResponseModel.content!.isDocument()
|
|
? FileUrl(url: aiResponseModel.content)
|
|
: null,
|
|
type: aiResponseModel.content!.isURL()
|
|
? aiResponseModel.content!.isAudio()
|
|
? 'audio'
|
|
: aiResponseModel.content!.isImage()
|
|
? 'image'
|
|
: aiResponseModel.content!.isDocument()
|
|
? 'doc'
|
|
: 'text'
|
|
: 'text',
|
|
text: aiResponseModel.content!.isURL()
|
|
? null
|
|
: aiResponseModel.content,
|
|
imageUrl: aiResponseModel.content!.isURL() &&
|
|
aiResponseModel.content!.isImage()
|
|
? FileUrl(url: aiResponseModel.content)
|
|
: null)
|
|
]);
|
|
emit(ReceiveMessageDone(
|
|
model: aiResponseModel,
|
|
message: message,
|
|
oldHumanMessageId: request.messageId!));
|
|
}
|
|
} catch (e) {
|
|
// if (e.response?.statusCode == 403) {
|
|
// emit(const SendMessageError('موجودی شماکافی نمیباشد'));
|
|
// } else {
|
|
// emit(SendMessageError('Error: $e'));
|
|
// }
|
|
emit(ReceiveMessageOnFail(
|
|
detail: 'خطا از سمت سرور لطفا لحظاتی دیگر دوباره تلاش کنید',
|
|
statusCode: 500,
|
|
oldHumanMessageId: request.messageId ?? ''));
|
|
}
|
|
onResponse.value = false;
|
|
await Future.delayed(const Duration(milliseconds: 300));
|
|
await scrollToEnd();
|
|
}
|
|
}
|