Files
worker/lib/features/chat/domain/entities/message.dart
2025-10-24 11:31:48 +07:00

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)';
}
}