213 lines
4.9 KiB
Dart
213 lines
4.9 KiB
Dart
/// Domain Entity: Message
|
|
///
|
|
/// Represents a chat message in a conversation.
|
|
library;
|
|
|
|
/// Content type enum
|
|
enum ContentType {
|
|
/// Plain text message
|
|
text,
|
|
|
|
/// Image message
|
|
image,
|
|
|
|
/// File attachment
|
|
file,
|
|
|
|
/// Product reference
|
|
product,
|
|
|
|
/// System notification
|
|
system;
|
|
|
|
/// Get display name for content type
|
|
String get displayName {
|
|
switch (this) {
|
|
case ContentType.text:
|
|
return 'Text';
|
|
case ContentType.image:
|
|
return 'Image';
|
|
case ContentType.file:
|
|
return 'File';
|
|
case ContentType.product:
|
|
return 'Product';
|
|
case ContentType.system:
|
|
return 'System';
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Message Entity
|
|
///
|
|
/// Contains information about a chat message:
|
|
/// - Message content
|
|
/// - Sender information
|
|
/// - Attachments
|
|
/// - Read status
|
|
/// - Edit history
|
|
class Message {
|
|
/// Unique message identifier
|
|
final String messageId;
|
|
|
|
/// Chat room ID this message belongs to
|
|
final String chatRoomId;
|
|
|
|
/// Sender user ID
|
|
final String senderId;
|
|
|
|
/// Content type
|
|
final ContentType contentType;
|
|
|
|
/// Message content/text
|
|
final String content;
|
|
|
|
/// Attachment URL (for images/files)
|
|
final String? attachmentUrl;
|
|
|
|
/// Product reference ID (if product message)
|
|
final String? productReference;
|
|
|
|
/// Message is read
|
|
final bool isRead;
|
|
|
|
/// Message has been edited
|
|
final bool isEdited;
|
|
|
|
/// Message has been deleted
|
|
final bool isDeleted;
|
|
|
|
/// User IDs who have read this message
|
|
final List<String> readBy;
|
|
|
|
/// Message timestamp
|
|
final DateTime timestamp;
|
|
|
|
/// Edit timestamp
|
|
final DateTime? editedAt;
|
|
|
|
const Message({
|
|
required this.messageId,
|
|
required this.chatRoomId,
|
|
required this.senderId,
|
|
required this.contentType,
|
|
required this.content,
|
|
this.attachmentUrl,
|
|
this.productReference,
|
|
required this.isRead,
|
|
required this.isEdited,
|
|
required this.isDeleted,
|
|
required this.readBy,
|
|
required this.timestamp,
|
|
this.editedAt,
|
|
});
|
|
|
|
/// Check if message is text
|
|
bool get isText => contentType == ContentType.text;
|
|
|
|
/// Check if message is image
|
|
bool get isImage => contentType == ContentType.image;
|
|
|
|
/// Check if message is file
|
|
bool get isFile => contentType == ContentType.file;
|
|
|
|
/// Check if message is product reference
|
|
bool get isProductReference => contentType == ContentType.product;
|
|
|
|
/// Check if message is system notification
|
|
bool get isSystemMessage => contentType == ContentType.system;
|
|
|
|
/// Check if message has attachment
|
|
bool get hasAttachment =>
|
|
attachmentUrl != null && attachmentUrl!.isNotEmpty;
|
|
|
|
/// Check if message references a product
|
|
bool get hasProductReference =>
|
|
productReference != null && productReference!.isNotEmpty;
|
|
|
|
/// Get number of readers
|
|
int get readerCount => readBy.length;
|
|
|
|
/// Check if user has read this message
|
|
bool isReadBy(String userId) {
|
|
return readBy.contains(userId);
|
|
}
|
|
|
|
/// Check if message is sent by user
|
|
bool isSentBy(String userId) {
|
|
return senderId == userId;
|
|
}
|
|
|
|
/// Get time since message was sent
|
|
Duration get timeSinceSent {
|
|
return DateTime.now().difference(timestamp);
|
|
}
|
|
|
|
/// Copy with method for immutability
|
|
Message copyWith({
|
|
String? messageId,
|
|
String? chatRoomId,
|
|
String? senderId,
|
|
ContentType? contentType,
|
|
String? content,
|
|
String? attachmentUrl,
|
|
String? productReference,
|
|
bool? isRead,
|
|
bool? isEdited,
|
|
bool? isDeleted,
|
|
List<String>? readBy,
|
|
DateTime? timestamp,
|
|
DateTime? editedAt,
|
|
}) {
|
|
return Message(
|
|
messageId: messageId ?? this.messageId,
|
|
chatRoomId: chatRoomId ?? this.chatRoomId,
|
|
senderId: senderId ?? this.senderId,
|
|
contentType: contentType ?? this.contentType,
|
|
content: content ?? this.content,
|
|
attachmentUrl: attachmentUrl ?? this.attachmentUrl,
|
|
productReference: productReference ?? this.productReference,
|
|
isRead: isRead ?? this.isRead,
|
|
isEdited: isEdited ?? this.isEdited,
|
|
isDeleted: isDeleted ?? this.isDeleted,
|
|
readBy: readBy ?? this.readBy,
|
|
timestamp: timestamp ?? this.timestamp,
|
|
editedAt: editedAt ?? this.editedAt,
|
|
);
|
|
}
|
|
|
|
@override
|
|
bool operator ==(Object other) {
|
|
if (identical(this, other)) return true;
|
|
|
|
return other is Message &&
|
|
other.messageId == messageId &&
|
|
other.chatRoomId == chatRoomId &&
|
|
other.senderId == senderId &&
|
|
other.contentType == contentType &&
|
|
other.content == content &&
|
|
other.isRead == isRead &&
|
|
other.isEdited == isEdited &&
|
|
other.isDeleted == isDeleted;
|
|
}
|
|
|
|
@override
|
|
int get hashCode {
|
|
return Object.hash(
|
|
messageId,
|
|
chatRoomId,
|
|
senderId,
|
|
contentType,
|
|
content,
|
|
isRead,
|
|
isEdited,
|
|
isDeleted,
|
|
);
|
|
}
|
|
|
|
@override
|
|
String toString() {
|
|
return 'Message(messageId: $messageId, senderId: $senderId, '
|
|
'contentType: $contentType, isRead: $isRead, timestamp: $timestamp)';
|
|
}
|
|
}
|