Chepuhagram/lib/data/models/message_model.dart

171 lines
5.4 KiB
Dart
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'dart:typed_data';
import 'dart:io';
enum MessageStatus { encrypting, sending, sent, delivered, read, failed }
enum MessageType { text, image, video, file, videoNote, voiceNote }
class MessageModel {
final int? id; // server id (null пока не подтверждено сервером)
final int? tempId; // client temp id (для сопоставления ack)
final int senderId;
final int receiverId;
final String text; // текст для UI (у нас уже расшифрованный)
final DateTime createdAt;
final bool isMe;
final MessageStatus status;
final int? replyToId; // ID сообщения, на которое отвечают
final String? replyToText; // текст сообщения, на которое отвечают (для отображения)
final DateTime? editedAt;
final File? localFile;
final MessageType messageType;
final String? fileId;
final String? encryptedFileKey;
final String? fileName;
final int? fileSize;
MessageModel({
this.id,
this.tempId,
required this.senderId,
required this.receiverId,
required this.text,
required this.createdAt,
required this.isMe,
this.status = MessageStatus.sent,
this.replyToId,
this.replyToText,
this.editedAt,
this.localFile,
this.messageType = MessageType.text,
this.fileId,
this.encryptedFileKey,
this.fileName,
this.fileSize
});
MessageModel copyWith({
int? id,
int? tempId,
int? senderId,
int? receiverId,
String? text,
DateTime? createdAt,
bool? isMe,
MessageStatus? status,
int? replyToId,
String? replyToText,
DateTime? editedAt,
File? localFile,
MessageType? messageType,
String? fileId,
String? encryptedFileKey,
String? fileName,
int? fileSize,
}) {
return MessageModel(
id: id ?? this.id,
tempId: tempId ?? this.tempId,
senderId: senderId ?? this.senderId,
receiverId: receiverId ?? this.receiverId,
text: text ?? this.text,
createdAt: createdAt ?? this.createdAt,
isMe: isMe ?? this.isMe,
status: status ?? this.status,
replyToId: replyToId ?? this.replyToId,
replyToText: replyToText ?? this.replyToText,
editedAt: editedAt ?? this.editedAt,
localFile: localFile ?? this.localFile,
messageType: messageType ?? this.messageType,
fileId: fileId ?? this.fileId,
encryptedFileKey: encryptedFileKey ?? this.encryptedFileKey,
fileName: fileName ?? this.fileName,
fileSize: fileSize ?? this.fileSize,
);
}
factory MessageModel.fromJson(Map<String, dynamic> json, int currentUserId) {
final senderId = int.parse(json['sender_id'].toString());
final receiverId = int.parse((json['receiver_id'] ?? json['recipient_id']).toString());
final createdAtRaw = (json['created_at'] ?? json['timestamp']).toString();
final messageTypeStr = json['message_type']?.toString() ?? 'text';
return MessageModel(
id: json['id'] == null ? null : int.tryParse(json['id'].toString()),
tempId: json['temp_id'] == null ? null : int.tryParse(json['temp_id'].toString()),
senderId: senderId,
receiverId: receiverId,
text: (json['text'] ?? json['content'] ?? '').toString(),
createdAt: DateTime.tryParse(createdAtRaw) ?? DateTime.now(),
isMe: senderId == currentUserId,
status: MessageStatus.sent,
replyToId: json['reply_to_id'] == null ? null : int.tryParse(json['reply_to_id'].toString()),
replyToText: json['reply_to_text'] == null ? null : json['reply_to_text'].toString(),
editedAt: json['edited_at'] == null ? null : DateTime.tryParse(json['edited_at'].toString()),
messageType: MessageModel.parseMessageType(messageTypeStr),
fileId: json['file_id']?.toString(),
encryptedFileKey: json['encrypted_key']?.toString(),
fileName: json['file_name']?.toString(),
fileSize: json['file_size'] == null ? null : int.tryParse(json['file_size'].toString()),
);
}
static MessageType parseMessageType(String typeStr) {
switch (typeStr.toLowerCase()) {
case 'image':
return MessageType.image;
case 'video':
return MessageType.video;
case 'file':
return MessageType.file;
case 'video_note':
case 'videonote':
return MessageType.videoNote;
case 'voice_note':
case 'voicenote':
return MessageType.voiceNote;
case 'text':
default:
return MessageType.text;
}
}
static String getMediaPreview(MessageType type) {
switch (type) {
case MessageType.videoNote:
return '[Кружок]';
case MessageType.voiceNote:
return '[Голосовое]';
case MessageType.image:
return '[Фото]';
case MessageType.video:
return '[Видео]';
case MessageType.file:
return '[Файл]';
case MessageType.text:
return '';
}
}
Map<String, dynamic> toJson() {
return {
'id': id,
'temp_id': tempId,
'sender_id': senderId,
'receiver_id': receiverId,
'text': text,
'created_at': createdAt.toIso8601String(),
'status': status.name,
'reply_to_id': replyToId,
'reply_to_text': replyToText,
'edited_at': editedAt?.toIso8601String(),
'message_type': messageType.name,
'file_id': fileId,
'encrypted_key': encryptedFileKey,
'file_name': fileName,
'file_size': fileSize,
};
}
}