119 lines
4.0 KiB
Dart
119 lines
4.0 KiB
Dart
import 'dart:typed_data';
|
||
|
||
enum MessageStatus { sending, sent, delivered, read, failed }
|
||
|
||
enum MessageType { text, image }
|
||
|
||
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 Uint8List? localFileBytes;
|
||
final MessageType messageType;
|
||
final String? fileId;
|
||
final String? encryptedFileKey;
|
||
|
||
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.localFileBytes,
|
||
this.messageType = MessageType.text,
|
||
this.fileId,
|
||
this.encryptedFileKey,
|
||
});
|
||
|
||
MessageModel copyWith({
|
||
int? id,
|
||
int? tempId,
|
||
int? senderId,
|
||
int? receiverId,
|
||
String? text,
|
||
DateTime? createdAt,
|
||
bool? isMe,
|
||
MessageStatus? status,
|
||
int? replyToId,
|
||
String? replyToText,
|
||
DateTime? editedAt,
|
||
Uint8List? localFileBytes,
|
||
MessageType? messageType,
|
||
String? fileId,
|
||
String? encryptedFileKey,
|
||
}) {
|
||
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,
|
||
localFileBytes: localFileBytes ?? this.localFileBytes,
|
||
messageType: messageType ?? this.messageType,
|
||
fileId: fileId ?? this.fileId,
|
||
encryptedFileKey: encryptedFileKey ?? this.encryptedFileKey,
|
||
);
|
||
}
|
||
|
||
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();
|
||
|
||
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: json['message_type'] == 'image' ? MessageType.image : MessageType.text,
|
||
fileId: json['file_id']?.toString(),
|
||
encryptedFileKey: json['encrypted_key']?.toString(),
|
||
);
|
||
}
|
||
|
||
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 == MessageType.image ? 'image' : 'text',
|
||
'file_id': fileId,
|
||
'encrypted_key': encryptedFileKey,
|
||
};
|
||
}
|
||
}
|