update database
This commit is contained in:
57
lib/features/chat/data/models/chat_room_model.dart
Normal file
57
lib/features/chat/data/models/chat_room_model.dart
Normal file
@@ -0,0 +1,57 @@
|
||||
import 'dart:convert';
|
||||
import 'package:hive_ce/hive.dart';
|
||||
import 'package:worker/core/constants/storage_constants.dart';
|
||||
import 'package:worker/core/database/models/enums.dart';
|
||||
|
||||
part 'chat_room_model.g.dart';
|
||||
|
||||
@HiveType(typeId: HiveTypeIds.chatRoomModel)
|
||||
class ChatRoomModel extends HiveObject {
|
||||
ChatRoomModel({required this.chatRoomId, required this.roomType, this.relatedQuoteId, this.relatedOrderId, required this.participants, this.roomName, required this.isActive, this.lastActivity, required this.createdAt, this.createdBy});
|
||||
|
||||
@HiveField(0) final String chatRoomId;
|
||||
@HiveField(1) final RoomType roomType;
|
||||
@HiveField(2) final String? relatedQuoteId;
|
||||
@HiveField(3) final String? relatedOrderId;
|
||||
@HiveField(4) final String participants;
|
||||
@HiveField(5) final String? roomName;
|
||||
@HiveField(6) final bool isActive;
|
||||
@HiveField(7) final DateTime? lastActivity;
|
||||
@HiveField(8) final DateTime createdAt;
|
||||
@HiveField(9) final String? createdBy;
|
||||
|
||||
factory ChatRoomModel.fromJson(Map<String, dynamic> json) => ChatRoomModel(
|
||||
chatRoomId: json['chat_room_id'] as String,
|
||||
roomType: RoomType.values.firstWhere((e) => e.name == json['room_type']),
|
||||
relatedQuoteId: json['related_quote_id'] as String?,
|
||||
relatedOrderId: json['related_order_id'] as String?,
|
||||
participants: jsonEncode(json['participants']),
|
||||
roomName: json['room_name'] as String?,
|
||||
isActive: json['is_active'] as bool? ?? true,
|
||||
lastActivity: json['last_activity'] != null ? DateTime.parse(json['last_activity']?.toString() ?? '') : null,
|
||||
createdAt: DateTime.parse(json['created_at']?.toString() ?? ''),
|
||||
createdBy: json['created_by'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'chat_room_id': chatRoomId,
|
||||
'room_type': roomType.name,
|
||||
'related_quote_id': relatedQuoteId,
|
||||
'related_order_id': relatedOrderId,
|
||||
'participants': jsonDecode(participants),
|
||||
'room_name': roomName,
|
||||
'is_active': isActive,
|
||||
'last_activity': lastActivity?.toIso8601String(),
|
||||
'created_at': createdAt.toIso8601String(),
|
||||
'created_by': createdBy,
|
||||
};
|
||||
|
||||
List<String>? get participantsList {
|
||||
try {
|
||||
final decoded = jsonDecode(participants) as List;
|
||||
return decoded.map((e) => e.toString()).toList();
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
68
lib/features/chat/data/models/chat_room_model.g.dart
Normal file
68
lib/features/chat/data/models/chat_room_model.g.dart
Normal file
@@ -0,0 +1,68 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'chat_room_model.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// TypeAdapterGenerator
|
||||
// **************************************************************************
|
||||
|
||||
class ChatRoomModelAdapter extends TypeAdapter<ChatRoomModel> {
|
||||
@override
|
||||
final typeId = 18;
|
||||
|
||||
@override
|
||||
ChatRoomModel read(BinaryReader reader) {
|
||||
final numOfFields = reader.readByte();
|
||||
final fields = <int, dynamic>{
|
||||
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
|
||||
};
|
||||
return ChatRoomModel(
|
||||
chatRoomId: fields[0] as String,
|
||||
roomType: fields[1] as RoomType,
|
||||
relatedQuoteId: fields[2] as String?,
|
||||
relatedOrderId: fields[3] as String?,
|
||||
participants: fields[4] as String,
|
||||
roomName: fields[5] as String?,
|
||||
isActive: fields[6] as bool,
|
||||
lastActivity: fields[7] as DateTime?,
|
||||
createdAt: fields[8] as DateTime,
|
||||
createdBy: fields[9] as String?,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void write(BinaryWriter writer, ChatRoomModel obj) {
|
||||
writer
|
||||
..writeByte(10)
|
||||
..writeByte(0)
|
||||
..write(obj.chatRoomId)
|
||||
..writeByte(1)
|
||||
..write(obj.roomType)
|
||||
..writeByte(2)
|
||||
..write(obj.relatedQuoteId)
|
||||
..writeByte(3)
|
||||
..write(obj.relatedOrderId)
|
||||
..writeByte(4)
|
||||
..write(obj.participants)
|
||||
..writeByte(5)
|
||||
..write(obj.roomName)
|
||||
..writeByte(6)
|
||||
..write(obj.isActive)
|
||||
..writeByte(7)
|
||||
..write(obj.lastActivity)
|
||||
..writeByte(8)
|
||||
..write(obj.createdAt)
|
||||
..writeByte(9)
|
||||
..write(obj.createdBy);
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => typeId.hashCode;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
other is ChatRoomModelAdapter &&
|
||||
runtimeType == other.runtimeType &&
|
||||
typeId == other.typeId;
|
||||
}
|
||||
67
lib/features/chat/data/models/message_model.dart
Normal file
67
lib/features/chat/data/models/message_model.dart
Normal file
@@ -0,0 +1,67 @@
|
||||
import 'dart:convert';
|
||||
import 'package:hive_ce/hive.dart';
|
||||
import 'package:worker/core/constants/storage_constants.dart';
|
||||
import 'package:worker/core/database/models/enums.dart';
|
||||
|
||||
part 'message_model.g.dart';
|
||||
|
||||
@HiveType(typeId: HiveTypeIds.messageModel)
|
||||
class MessageModel extends HiveObject {
|
||||
MessageModel({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, this.readBy, required this.timestamp, this.editedAt});
|
||||
|
||||
@HiveField(0) final String messageId;
|
||||
@HiveField(1) final String chatRoomId;
|
||||
@HiveField(2) final String senderId;
|
||||
@HiveField(3) final ContentType contentType;
|
||||
@HiveField(4) final String content;
|
||||
@HiveField(5) final String? attachmentUrl;
|
||||
@HiveField(6) final String? productReference;
|
||||
@HiveField(7) final bool isRead;
|
||||
@HiveField(8) final bool isEdited;
|
||||
@HiveField(9) final bool isDeleted;
|
||||
@HiveField(10) final String? readBy;
|
||||
@HiveField(11) final DateTime timestamp;
|
||||
@HiveField(12) final DateTime? editedAt;
|
||||
|
||||
factory MessageModel.fromJson(Map<String, dynamic> json) => MessageModel(
|
||||
messageId: json['message_id'] as String,
|
||||
chatRoomId: json['chat_room_id'] as String,
|
||||
senderId: json['sender_id'] as String,
|
||||
contentType: ContentType.values.firstWhere((e) => e.name == json['content_type']),
|
||||
content: json['content'] as String,
|
||||
attachmentUrl: json['attachment_url'] as String?,
|
||||
productReference: json['product_reference'] as String?,
|
||||
isRead: json['is_read'] as bool? ?? false,
|
||||
isEdited: json['is_edited'] as bool? ?? false,
|
||||
isDeleted: json['is_deleted'] as bool? ?? false,
|
||||
readBy: json['read_by'] != null ? jsonEncode(json['read_by']) : null,
|
||||
timestamp: DateTime.parse(json['timestamp']?.toString() ?? ''),
|
||||
editedAt: json['edited_at'] != null ? DateTime.parse(json['edited_at']?.toString() ?? '') : null,
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'message_id': messageId,
|
||||
'chat_room_id': chatRoomId,
|
||||
'sender_id': senderId,
|
||||
'content_type': contentType.name,
|
||||
'content': content,
|
||||
'attachment_url': attachmentUrl,
|
||||
'product_reference': productReference,
|
||||
'is_read': isRead,
|
||||
'is_edited': isEdited,
|
||||
'is_deleted': isDeleted,
|
||||
'read_by': readBy != null ? jsonDecode(readBy!) : null,
|
||||
'timestamp': timestamp.toIso8601String(),
|
||||
'edited_at': editedAt?.toIso8601String(),
|
||||
};
|
||||
|
||||
List<String>? get readByList {
|
||||
if (readBy == null) return null;
|
||||
try {
|
||||
final decoded = jsonDecode(readBy!) as List;
|
||||
return decoded.map((e) => e.toString()).toList();
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
77
lib/features/chat/data/models/message_model.g.dart
Normal file
77
lib/features/chat/data/models/message_model.g.dart
Normal file
@@ -0,0 +1,77 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'message_model.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// TypeAdapterGenerator
|
||||
// **************************************************************************
|
||||
|
||||
class MessageModelAdapter extends TypeAdapter<MessageModel> {
|
||||
@override
|
||||
final typeId = 19;
|
||||
|
||||
@override
|
||||
MessageModel read(BinaryReader reader) {
|
||||
final numOfFields = reader.readByte();
|
||||
final fields = <int, dynamic>{
|
||||
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
|
||||
};
|
||||
return MessageModel(
|
||||
messageId: fields[0] as String,
|
||||
chatRoomId: fields[1] as String,
|
||||
senderId: fields[2] as String,
|
||||
contentType: fields[3] as ContentType,
|
||||
content: fields[4] as String,
|
||||
attachmentUrl: fields[5] as String?,
|
||||
productReference: fields[6] as String?,
|
||||
isRead: fields[7] as bool,
|
||||
isEdited: fields[8] as bool,
|
||||
isDeleted: fields[9] as bool,
|
||||
readBy: fields[10] as String?,
|
||||
timestamp: fields[11] as DateTime,
|
||||
editedAt: fields[12] as DateTime?,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void write(BinaryWriter writer, MessageModel obj) {
|
||||
writer
|
||||
..writeByte(13)
|
||||
..writeByte(0)
|
||||
..write(obj.messageId)
|
||||
..writeByte(1)
|
||||
..write(obj.chatRoomId)
|
||||
..writeByte(2)
|
||||
..write(obj.senderId)
|
||||
..writeByte(3)
|
||||
..write(obj.contentType)
|
||||
..writeByte(4)
|
||||
..write(obj.content)
|
||||
..writeByte(5)
|
||||
..write(obj.attachmentUrl)
|
||||
..writeByte(6)
|
||||
..write(obj.productReference)
|
||||
..writeByte(7)
|
||||
..write(obj.isRead)
|
||||
..writeByte(8)
|
||||
..write(obj.isEdited)
|
||||
..writeByte(9)
|
||||
..write(obj.isDeleted)
|
||||
..writeByte(10)
|
||||
..write(obj.readBy)
|
||||
..writeByte(11)
|
||||
..write(obj.timestamp)
|
||||
..writeByte(12)
|
||||
..write(obj.editedAt);
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => typeId.hashCode;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
other is MessageModelAdapter &&
|
||||
runtimeType == other.runtimeType &&
|
||||
typeId == other.typeId;
|
||||
}
|
||||
186
lib/features/chat/domain/entities/chat_room.dart
Normal file
186
lib/features/chat/domain/entities/chat_room.dart
Normal file
@@ -0,0 +1,186 @@
|
||||
/// Domain Entity: Chat Room
|
||||
///
|
||||
/// Represents a chat conversation room.
|
||||
library;
|
||||
|
||||
/// Room type enum
|
||||
enum RoomType {
|
||||
/// Direct message between two users
|
||||
direct,
|
||||
|
||||
/// Group chat
|
||||
group,
|
||||
|
||||
/// Support chat with staff
|
||||
support,
|
||||
|
||||
/// Order-related chat
|
||||
order,
|
||||
|
||||
/// Quote-related chat
|
||||
quote;
|
||||
|
||||
/// Get display name for room type
|
||||
String get displayName {
|
||||
switch (this) {
|
||||
case RoomType.direct:
|
||||
return 'Direct';
|
||||
case RoomType.group:
|
||||
return 'Group';
|
||||
case RoomType.support:
|
||||
return 'Support';
|
||||
case RoomType.order:
|
||||
return 'Order';
|
||||
case RoomType.quote:
|
||||
return 'Quote';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Chat Room Entity
|
||||
///
|
||||
/// Contains information about a chat room:
|
||||
/// - Room type and participants
|
||||
/// - Related entities (order, quote)
|
||||
/// - Activity tracking
|
||||
class ChatRoom {
|
||||
/// Unique chat room identifier
|
||||
final String chatRoomId;
|
||||
|
||||
/// Room type
|
||||
final RoomType roomType;
|
||||
|
||||
/// Related quote ID (if quote chat)
|
||||
final String? relatedQuoteId;
|
||||
|
||||
/// Related order ID (if order chat)
|
||||
final String? relatedOrderId;
|
||||
|
||||
/// Participant user IDs
|
||||
final List<String> participants;
|
||||
|
||||
/// Room name (for group chats)
|
||||
final String? roomName;
|
||||
|
||||
/// Room is active
|
||||
final bool isActive;
|
||||
|
||||
/// Last activity timestamp
|
||||
final DateTime? lastActivity;
|
||||
|
||||
/// Room creation timestamp
|
||||
final DateTime createdAt;
|
||||
|
||||
/// User ID who created the room
|
||||
final String? createdBy;
|
||||
|
||||
const ChatRoom({
|
||||
required this.chatRoomId,
|
||||
required this.roomType,
|
||||
this.relatedQuoteId,
|
||||
this.relatedOrderId,
|
||||
required this.participants,
|
||||
this.roomName,
|
||||
required this.isActive,
|
||||
this.lastActivity,
|
||||
required this.createdAt,
|
||||
this.createdBy,
|
||||
});
|
||||
|
||||
/// Check if room is direct message
|
||||
bool get isDirect => roomType == RoomType.direct;
|
||||
|
||||
/// Check if room is group chat
|
||||
bool get isGroup => roomType == RoomType.group;
|
||||
|
||||
/// Check if room is support chat
|
||||
bool get isSupport => roomType == RoomType.support;
|
||||
|
||||
/// Check if room has order context
|
||||
bool get hasOrderContext =>
|
||||
roomType == RoomType.order && relatedOrderId != null;
|
||||
|
||||
/// Check if room has quote context
|
||||
bool get hasQuoteContext =>
|
||||
roomType == RoomType.quote && relatedQuoteId != null;
|
||||
|
||||
/// Get number of participants
|
||||
int get participantCount => participants.length;
|
||||
|
||||
/// Get display name for room
|
||||
String get displayName {
|
||||
if (roomName != null && roomName!.isNotEmpty) return roomName!;
|
||||
if (isSupport) return 'Customer Support';
|
||||
if (hasOrderContext) return 'Order Chat';
|
||||
if (hasQuoteContext) return 'Quote Discussion';
|
||||
return 'Chat';
|
||||
}
|
||||
|
||||
/// Get time since last activity
|
||||
Duration? get timeSinceLastActivity {
|
||||
if (lastActivity == null) return null;
|
||||
return DateTime.now().difference(lastActivity!);
|
||||
}
|
||||
|
||||
/// Check if user is participant
|
||||
bool isParticipant(String userId) {
|
||||
return participants.contains(userId);
|
||||
}
|
||||
|
||||
/// Copy with method for immutability
|
||||
ChatRoom copyWith({
|
||||
String? chatRoomId,
|
||||
RoomType? roomType,
|
||||
String? relatedQuoteId,
|
||||
String? relatedOrderId,
|
||||
List<String>? participants,
|
||||
String? roomName,
|
||||
bool? isActive,
|
||||
DateTime? lastActivity,
|
||||
DateTime? createdAt,
|
||||
String? createdBy,
|
||||
}) {
|
||||
return ChatRoom(
|
||||
chatRoomId: chatRoomId ?? this.chatRoomId,
|
||||
roomType: roomType ?? this.roomType,
|
||||
relatedQuoteId: relatedQuoteId ?? this.relatedQuoteId,
|
||||
relatedOrderId: relatedOrderId ?? this.relatedOrderId,
|
||||
participants: participants ?? this.participants,
|
||||
roomName: roomName ?? this.roomName,
|
||||
isActive: isActive ?? this.isActive,
|
||||
lastActivity: lastActivity ?? this.lastActivity,
|
||||
createdAt: createdAt ?? this.createdAt,
|
||||
createdBy: createdBy ?? this.createdBy,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(this, other)) return true;
|
||||
|
||||
return other is ChatRoom &&
|
||||
other.chatRoomId == chatRoomId &&
|
||||
other.roomType == roomType &&
|
||||
other.relatedQuoteId == relatedQuoteId &&
|
||||
other.relatedOrderId == relatedOrderId &&
|
||||
other.isActive == isActive;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return Object.hash(
|
||||
chatRoomId,
|
||||
roomType,
|
||||
relatedQuoteId,
|
||||
relatedOrderId,
|
||||
isActive,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ChatRoom(chatRoomId: $chatRoomId, roomType: $roomType, '
|
||||
'displayName: $displayName, participantCount: $participantCount, '
|
||||
'isActive: $isActive)';
|
||||
}
|
||||
}
|
||||
212
lib/features/chat/domain/entities/message.dart
Normal file
212
lib/features/chat/domain/entities/message.dart
Normal file
@@ -0,0 +1,212 @@
|
||||
/// 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)';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user