Houshan-Basa/lib/data/model/ai/messages_model.dart

298 lines
7.9 KiB
Dart

import 'package:cross_file/cross_file.dart';
import 'package:hoshan/data/model/ai/bots_model.dart';
class MessagesModel {
int? id;
String? title;
String? createdAt;
Bots? bot;
List<Messages>? messages;
MessagesModel({this.id, this.title, this.createdAt, this.bot, this.messages});
MessagesModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
title = json['title'];
createdAt = json['created_at'];
bot = json['bot'] != null ? Bots.fromJson(json['bot']) : null;
if (json['messages'] != null) {
messages = <Messages>[];
json['messages'].forEach((v) {
messages!.add(Messages.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['title'] = title;
data['created_at'] = createdAt;
if (bot != null) {
data['bot'] = bot!.toJson();
}
if (messages != null) {
data['messages'] = messages!.map((v) => v.toJson()).toList();
}
return data;
}
}
class Messages {
String? id;
List<Content>? content;
String? query;
String? role;
String? fileUrl;
bool? like;
bool? fromBot;
bool? error;
XFile? file;
bool? retry;
String? createdAt;
Messages(
{this.id,
this.content,
this.query,
this.role,
this.like,
this.file,
this.createdAt,
this.error = false,
this.retry = false}) {
fromBot = (role == 'ai');
if (content != null && content!.isNotEmpty) {
// Sort content list: "image" first, then "text"
content!.sort((a, b) {
if (a.type == 'image_url' && b.type != 'image_url') {
return -1; // a comes before b
} else if (a.type != 'image_url' && b.type == 'image_url') {
return 1; // b comes before a
}
return 0; // maintain original order if both are the same type
});
}
// _getFile();
}
// Future<void> _getFile() async {
// file = await ChatbotRepository.createXFileFromUrl(fileUrl ?? '');
// }
Messages.fromJson(Map<String, dynamic> json) {
error = false;
id = json['id'];
if (json['content'] != null) {
if (json['content'] is List) {
content = <Content>[];
json['content'].forEach((v) {
content!.add(Content.fromJson(v));
});
} else if (json['content'] is String) {
content = [Content(type: 'text', text: json['content'])];
}
}
role = json['role'];
like = json['like'];
createdAt = json['created_at'];
fromBot = role == 'ai';
if (content != null && content!.isNotEmpty) {
// Sort content list: "image" first, then "text"
content!.sort((a, b) {
if (a.type == 'image_url' && b.type != 'image_url') {
return -1; // a comes before b
} else if (a.type != 'image_url' && b.type == 'image_url') {
return 1; // b comes before a
}
return 0; // maintain original order if both are the same type
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
if (content != null) {
data['content'] = content!.map((v) => v.toJson()).toList();
}
data['role'] = role;
data['like'] = like;
data['created_at'] = createdAt;
return data;
}
Messages copyWith(
{String? id,
List<Content>? content,
String? role,
String? createdAt,
bool? like,
bool? error,
bool? retry,
String? query,
XFile? file}) {
return Messages(
id: id ?? this.id,
content: content ?? this.content,
like: like ?? this.like,
error: error ?? this.error,
role: role ?? this.role,
file: file ?? this.file,
createdAt: createdAt ?? this.createdAt,
query: query ?? this.query,
retry: retry ?? this.retry);
}
}
class Content {
String? type;
String? text;
FileUrl? imageUrl;
FileUrl? audioUrl;
FileUrl? pdfUrl;
FileUrl? videoUrl;
Content(
{this.type,
this.text,
this.imageUrl,
this.audioUrl,
this.pdfUrl,
this.videoUrl});
Content.fromJson(Map<String, dynamic> json) {
type = json['type'];
text = json['text'];
imageUrl =
json['image_url'] != null ? FileUrl.fromJson(json['image_url']) : null;
audioUrl =
json['audio_url'] != null ? FileUrl.fromJson(json['audio_url']) : null;
pdfUrl = json['pdf_url'] != null ? FileUrl.fromJson(json['pdf_url']) : null;
videoUrl =
json['video_url'] != null ? FileUrl.fromJson(json['video_url']) : null;
// اگر سرور audioUrl/imageUrl/pdfUrl/videoUrl را ارسال نکرده باشد،
// از روی text چک می‌کنیم که آیا URL است یا نه
if (text != null && text!.isNotEmpty) {
final trimmedText = text!.trim();
if (trimmedText._isURL()) {
if (audioUrl == null && trimmedText._isAudio()) {
audioUrl = FileUrl(url: trimmedText);
type = 'audio';
} else if (imageUrl == null && trimmedText._isImage()) {
imageUrl = FileUrl(url: trimmedText);
type = 'image';
} else if (pdfUrl == null && trimmedText._isDocument()) {
pdfUrl = FileUrl(url: trimmedText);
type = 'doc';
} else if (videoUrl == null && trimmedText._isVideo()) {
videoUrl = FileUrl(url: trimmedText);
type = 'video';
}
}
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['type'] = type;
data['text'] = text;
if (imageUrl != null) {
data['image_url'] = imageUrl!.toJson();
}
if (audioUrl != null) {
data['audio_url'] = audioUrl!.toJson();
}
if (pdfUrl != null) {
data['pdf_url'] = pdfUrl!.toJson();
}
if (videoUrl != null) {
data['video_url'] = videoUrl!.toJson();
}
return data;
}
}
class FileUrl {
String? url;
String? query;
bool? attachment;
FileUrl({this.url});
FileUrl.fromJson(Map<String, dynamic> json) {
url = json['url'];
query = json['query'];
attachment = json['attachment'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['url'] = url;
data['query'] = query;
data['attachment'] = attachment;
return data;
}
}
// توابع کمکی برای چک کردن نوع URL
extension _StringUrlCheck on String {
bool _isURL() {
return startsWith('http://') || startsWith('https://');
}
bool _isImage() {
final lower = toLowerCase();
return lower.endsWith('.jpg') ||
lower.endsWith('.jpeg') ||
lower.endsWith('.png') ||
lower.endsWith('.gif') ||
lower.endsWith('.webp') ||
lower.endsWith('.bmp') ||
lower.contains('.jpg?') ||
lower.contains('.jpeg?') ||
lower.contains('.png?') ||
lower.contains('.gif?') ||
lower.contains('.webp?');
}
bool _isAudio() {
final lower = toLowerCase();
return lower.endsWith('.mp3') ||
lower.endsWith('.wav') ||
lower.endsWith('.ogg') ||
lower.endsWith('.m4a') ||
lower.endsWith('.aac') ||
lower.endsWith('.flac') ||
lower.contains('.mp3?') ||
lower.contains('.wav?') ||
lower.contains('.ogg?') ||
lower.contains('.m4a?') ||
lower.contains('.aac?');
}
bool _isDocument() {
final lower = toLowerCase();
return lower.endsWith('.pdf') ||
lower.endsWith('.doc') ||
lower.endsWith('.docx') ||
lower.contains('.pdf?') ||
lower.contains('.doc?') ||
lower.contains('.docx?');
}
bool _isVideo() {
final lower = toLowerCase();
return lower.endsWith('.mp4') ||
lower.endsWith('.avi') ||
lower.endsWith('.mov') ||
lower.endsWith('.mkv') ||
lower.endsWith('.webm') ||
lower.contains('.mp4?') ||
lower.contains('.avi?') ||
lower.contains('.mov?') ||
lower.contains('.mkv?');
}
}