import 'dart:io'; import 'package:flutter_openim_sdk/flutter_openim_sdk.dart'; class Message { /// Message ID, a unique identifier. String? clientMsgID; /// Server-generated ID. String? serverMsgID; /// Creation time. int? createTime; /// Sending time. int? sendTime; /// Conversation type [ConversationType]. int? sessionType; /// Sender's ID. String? sendID; /// Receiver's ID. String? recvID; /// Source. int? msgFrom; /// Message type [MessageType]. int? contentType; /// Platform [Platform]. int? senderPlatformID; /// Sender's nickname. String? senderNickname; /// Sender's avatar. String? senderFaceUrl; /// Group ID. String? groupID; /// Message content. // String? content; /// Message sequence number. int? seq; /// Whether it's read. bool? isRead; /// Read time. int? hasReadTime; /// Message sending status [MessageStatus]. int? status; /// Is it a reaction. bool? isReact; /// Is it an external extension. bool? isExternalExtensions; /// Offline display content. OfflinePushInfo? offlinePush; /// Additional information. String? attachedInfo; /// Extended information. String? ex; /// Custom extended information, currently used for message time segmentation on the client side. Map exMap = {}; /// Image. PictureElem? pictureElem; /// Voice. SoundElem? soundElem; /// Video. VideoElem? videoElem; /// File. FileElem? fileElem; /// @ Information. AtTextElem? atTextElem; /// Location. LocationElem? locationElem; /// Custom. CustomElem? customElem; /// Quote. QuoteElem? quoteElem; /// Merge. MergeElem? mergeElem; /// Notification. NotificationElem? notificationElem; /// Custom emoji. FaceElem? faceElem; /// Additional information. AttachedInfoElem? attachedInfoElem; /// Text content. TextElem? textElem; /// Business card. CardElem? cardElem; /// AdvancedTextElem? advancedTextElem; /// TypingElem? typingElem; Message({ this.clientMsgID, this.serverMsgID, this.createTime, this.sendTime, this.sessionType, this.sendID, this.recvID, this.msgFrom, this.contentType, this.senderPlatformID, this.senderNickname, this.senderFaceUrl, this.groupID, // this.content, this.seq, this.isRead, this.hasReadTime, this.status, this.offlinePush, this.attachedInfo, this.ex, this.exMap = const {}, this.pictureElem, this.soundElem, this.videoElem, this.fileElem, this.atTextElem, this.locationElem, this.customElem, this.quoteElem, this.mergeElem, this.notificationElem, this.faceElem, this.attachedInfoElem, this.isExternalExtensions, this.isReact, this.textElem, this.cardElem, this.advancedTextElem, this.typingElem, }); Message.fromJson(Map json) { clientMsgID = json['clientMsgID']; serverMsgID = json['serverMsgID']; createTime = json['createTime']; sendTime = json['sendTime']; sendID = json['sendID']; recvID = json['recvID']; msgFrom = json['msgFrom']; contentType = json['contentType']; senderPlatformID = json['senderPlatformID']; senderNickname = json['senderNickname']; senderFaceUrl = json['senderFaceUrl']; groupID = json['groupID']; // content = json['content']; seq = json['seq']; isRead = json['isRead']; status = json['status']; offlinePush = json['offlinePush'] != null ? OfflinePushInfo.fromJson(json['offlinePush']) : null; attachedInfo = json['attachedInfo']; ex = json['ex']; exMap = json['exMap'] ?? {}; sessionType = json['sessionType']; pictureElem = json['pictureElem'] != null ? PictureElem.fromJson(json['pictureElem']) : null; soundElem = json['soundElem'] != null ? SoundElem.fromJson(json['soundElem']) : null; videoElem = json['videoElem'] != null ? VideoElem.fromJson(json['videoElem']) : null; fileElem = json['fileElem'] != null ? FileElem.fromJson(json['fileElem']) : null; atTextElem = json['atTextElem'] != null ? AtTextElem.fromJson(json['atTextElem']) : null; locationElem = json['locationElem'] != null ? LocationElem.fromJson(json['locationElem']) : null; customElem = json['customElem'] != null ? CustomElem.fromJson(json['customElem']) : null; quoteElem = json['quoteElem'] != null ? QuoteElem.fromJson(json['quoteElem']) : null; mergeElem = json['mergeElem'] != null ? MergeElem.fromJson(json['mergeElem']) : null; notificationElem = json['notificationElem'] != null ? NotificationElem.fromJson(json['notificationElem']) : null; faceElem = json['faceElem'] != null ? FaceElem.fromJson(json['faceElem']) : null; attachedInfoElem = json['attachedInfoElem'] != null ? AttachedInfoElem.fromJson(json['attachedInfoElem']) : null; hasReadTime = json['hasReadTime'] ?? attachedInfoElem?.hasReadTime; isExternalExtensions = json['isExternalExtensions']; isReact = json['isReact']; textElem = json['textElem'] != null ? TextElem.fromJson(json['textElem']) : null; cardElem = json['cardElem'] != null ? CardElem.fromJson(json['cardElem']) : null; advancedTextElem = json['advancedTextElem'] != null ? AdvancedTextElem.fromJson(json['advancedTextElem']) : null; typingElem = json['typingElem'] != null ? TypingElem.fromJson(json['typingElem']) : null; } Map toJson() { final data = Map(); data['clientMsgID'] = this.clientMsgID; data['serverMsgID'] = this.serverMsgID; data['createTime'] = this.createTime; data['sendTime'] = this.sendTime; data['sendID'] = this.sendID; data['recvID'] = this.recvID; data['msgFrom'] = this.msgFrom; data['contentType'] = this.contentType; data['senderPlatformID'] = this.senderPlatformID; data['senderNickname'] = this.senderNickname; data['senderFaceUrl'] = this.senderFaceUrl; data['groupID'] = this.groupID; // data['content'] = this.content; data['seq'] = this.seq; data['isRead'] = this.isRead; data['hasReadTime'] = this.hasReadTime; data['status'] = this.status; data['offlinePush'] = this.offlinePush?.toJson(); data['attachedInfo'] = this.attachedInfo; data['ex'] = this.ex; data['exMap'] = this.exMap; data['sessionType'] = this.sessionType; data['pictureElem'] = this.pictureElem?.toJson(); data['soundElem'] = this.soundElem?.toJson(); data['videoElem'] = this.videoElem?.toJson(); data['fileElem'] = this.fileElem?.toJson(); data['atTextElem'] = this.atTextElem?.toJson(); data['locationElem'] = this.locationElem?.toJson(); data['customElem'] = this.customElem?.toJson(); data['quoteElem'] = this.quoteElem?.toJson(); data['mergeElem'] = this.mergeElem?.toJson(); data['notificationElem'] = this.notificationElem?.toJson(); data['faceElem'] = this.faceElem?.toJson(); data['attachedInfoElem'] = this.attachedInfoElem?.toJson(); data['isExternalExtensions'] = this.isExternalExtensions; data['isReact'] = this.isReact; data['textElem'] = this.textElem?.toJson(); data['cardElem'] = this.cardElem?.toJson(); data['advancedTextElem'] = this.advancedTextElem?.toJson(); data['typingElem'] = this.typingElem?.toJson(); return data; } @override bool operator ==(Object other) => identical(this, other) || other is Message && runtimeType == other.runtimeType && clientMsgID == other.clientMsgID; @override int get hashCode => clientMsgID.hashCode; void update(Message message) { if (this != message) return; serverMsgID = message.serverMsgID; createTime = message.createTime; sendTime = message.sendTime; sendID = message.sendID; recvID = message.recvID; msgFrom = message.msgFrom; contentType = message.contentType; senderPlatformID = message.senderPlatformID; senderNickname = message.senderNickname; senderFaceUrl = message.senderFaceUrl; groupID = message.groupID; // content = message.content; seq = message.seq; isRead = message.isRead; hasReadTime = message.hasReadTime; status = message.status; offlinePush = message.offlinePush; attachedInfo = message.attachedInfo; ex = message.ex; exMap = message.exMap; sessionType = message.sessionType; pictureElem = message.pictureElem; soundElem = message.soundElem; videoElem = message.videoElem; fileElem = message.fileElem; atTextElem = message.atTextElem; locationElem = message.locationElem; customElem = message.customElem; quoteElem = message.quoteElem; mergeElem = message.mergeElem; notificationElem = message.notificationElem; faceElem = message.faceElem; attachedInfoElem = message.attachedInfoElem; textElem = message.textElem; cardElem = message.cardElem; advancedTextElem = message.advancedTextElem; typingElem = message.typingElem; } /// Single chat message bool get isSingleChat => sessionType == ConversationType.single; /// Group chat message bool get isGroupChat => sessionType == ConversationType.group || sessionType == ConversationType.superGroup; } /// Image message content class PictureElem { /// Original path String? sourcePath; /// Original picture object PictureInfo? sourcePicture; /// Big picture object PictureInfo? bigPicture; /// Thumbnail picture object PictureInfo? snapshotPicture; PictureElem( {this.sourcePath, this.sourcePicture, this.bigPicture, this.snapshotPicture}); PictureElem.fromJson(Map json) { sourcePath = json['sourcePath']; sourcePicture = json['sourcePicture'] != null ? new PictureInfo.fromJson(json['sourcePicture']) : null; bigPicture = json['bigPicture'] != null ? new PictureInfo.fromJson(json['bigPicture']) : null; snapshotPicture = json['snapshotPicture'] != null ? new PictureInfo.fromJson(json['snapshotPicture']) : null; } Map toJson() { final data = Map(); data['sourcePath'] = this.sourcePath; if (this.sourcePicture != null) { data['sourcePicture'] = this.sourcePicture?.toJson(); } if (this.bigPicture != null) { data['bigPicture'] = this.bigPicture?.toJson(); } if (this.snapshotPicture != null) { data['snapshotPicture'] = this.snapshotPicture?.toJson(); } return data; } } /// Image information class PictureInfo { /// ID String? uuid; /// Image MIME type String? type; /// Size int? size; /// Width int? width; /// Height int? height; /// Image URL String? url; PictureInfo( {this.uuid, this.type, this.size, this.width, this.height, this.url}); PictureInfo.fromJson(Map json) { uuid = json['uuid']; type = json['type']; size = json['size']; width = json['width']; height = json['height']; url = json['url']; } Map toJson() { final data = Map(); data['uuid'] = this.uuid; data['type'] = this.type; data['size'] = this.size; data['width'] = this.width; data['height'] = this.height; data['url'] = this.url; return data; } } /// Voice message content class SoundElem { /// ID String? uuid; /// Original path String? soundPath; /// URL address String? sourceUrl; /// Size int? dataSize; /// Duration in seconds int? duration; SoundElem( {this.uuid, this.soundPath, this.sourceUrl, this.dataSize, this.duration}); SoundElem.fromJson(Map json) { uuid = json['uuid']; soundPath = json['soundPath']; sourceUrl = json['sourceUrl']; dataSize = json['dataSize']; duration = json['duration']; } Map toJson() { final data = Map(); data['uuid'] = this.uuid; data['soundPath'] = this.soundPath; data['sourceUrl'] = this.sourceUrl; data['dataSize'] = this.dataSize; data['duration'] = this.duration; return data; } } /// Video message content class VideoElem { /// Video path String? videoPath; /// UUID String? videoUUID; /// URL address of the video String? videoUrl; /// MIME type String? videoType; /// Size int? videoSize; /// Duration in seconds int? duration; /// Snapshot path String? snapshotPath; /// Snapshot UUID String? snapshotUUID; /// Snapshot size int? snapshotSize; /// Snapshot URL address String? snapshotUrl; /// Snapshot width int? snapshotWidth; /// Snapshot height int? snapshotHeight; VideoElem( {this.videoPath, this.videoUUID, this.videoUrl, this.videoType, this.videoSize, this.duration, this.snapshotPath, this.snapshotUUID, this.snapshotSize, this.snapshotUrl, this.snapshotWidth, this.snapshotHeight}); VideoElem.fromJson(Map json) { videoPath = json['videoPath']; videoUUID = json['videoUUID']; videoUrl = json['videoUrl']; videoType = json['videoType']; videoSize = json['videoSize']; duration = json['duration']; snapshotPath = json['snapshotPath']; snapshotUUID = json['snapshotUUID']; snapshotSize = json['snapshotSize']; snapshotUrl = json['snapshotUrl']; snapshotWidth = json['snapshotWidth']; snapshotHeight = json['snapshotHeight']; } Map toJson() { final data = Map(); data['videoPath'] = this.videoPath; data['videoUUID'] = this.videoUUID; data['videoUrl'] = this.videoUrl; data['videoType'] = this.videoType; data['videoSize'] = this.videoSize; data['duration'] = this.duration; data['snapshotPath'] = this.snapshotPath; data['snapshotUUID'] = this.snapshotUUID; data['snapshotSize'] = this.snapshotSize; data['snapshotUrl'] = this.snapshotUrl; data['snapshotWidth'] = this.snapshotWidth; data['snapshotHeight'] = this.snapshotHeight; return data; } } /// File message content class FileElem { /// File path String? filePath; /// UUID String? uuid; /// File URL address String? sourceUrl; /// File name String? fileName; /// File size int? fileSize; FileElem( {this.filePath, this.uuid, this.sourceUrl, this.fileName, this.fileSize}); FileElem.fromJson(Map json) { filePath = json['filePath']; uuid = json['uuid']; sourceUrl = json['sourceUrl']; fileName = json['fileName']; fileSize = json['fileSize']; } Map toJson() { final data = Map(); data['filePath'] = this.filePath; data['uuid'] = this.uuid; data['sourceUrl'] = this.sourceUrl; data['fileName'] = this.fileName; data['fileSize'] = this.fileSize; return data; } } /// @ Message Content class AtTextElem { /// Message content String? text; /// List of user IDs mentioned in the message List? atUserList; /// Whether it includes a mention of oneself bool? isAtSelf; /// List of user IDs and their nicknames mentioned in the message, used to replace user IDs with nicknames in the message content List? atUsersInfo; /// Message that is being replied to, when replying to someone and mentioning others Message? quoteMessage; AtTextElem({ this.text, this.atUserList, this.isAtSelf, this.atUsersInfo, this.quoteMessage, }); AtTextElem.fromJson(Map json) { text = json['text']; if (json['atUserList'] is List) { atUserList = (json['atUserList'] as List).map((e) => '$e').toList(); } isAtSelf = json['isAtSelf']; if (json['atUsersInfo'] is List) { atUsersInfo = (json['atUsersInfo'] as List) .map((e) => AtUserInfo.fromJson(e)) .toList(); } quoteMessage = null != json['quoteMessage'] ? Message.fromJson(json['quoteMessage']) : null; } Map toJson() { final data = Map(); data['text'] = this.text; data['atUserList'] = this.atUserList; data['isAtSelf'] = this.isAtSelf; data['atUsersInfo'] = this.atUsersInfo?.map((e) => e.toJson()).toList(); data['quoteMessage'] = this.quoteMessage?.toJson(); return data; } } /// Location Message class LocationElem { /// Location description String? description; /// Longitude double? longitude; /// Latitude double? latitude; LocationElem({this.description, this.longitude, this.latitude}); LocationElem.fromJson(Map json) { description = json['description']; if (json['longitude'] is int) { longitude = (json['longitude'] as int).toDouble(); } else { longitude = json['longitude']; } if (json['latitude'] is int) { latitude = (json['latitude'] as int).toDouble(); } else { latitude = json['latitude']; } } Map toJson() { final data = Map(); data['description'] = this.description; data['longitude'] = this.longitude; data['latitude'] = this.latitude; return data; } } /// Custom Message class CustomElem { /// Custom data String? data; /// Extended content String? extension; /// Description String? description; CustomElem({this.data, this.extension, this.description}); CustomElem.fromJson(Map json) { data = json['data']; extension = json['extension']; description = json['description']; } Map toJson() { final data = Map(); data['data'] = this.data; data['extension'] = this.extension; data['description'] = this.description; return data; } } /// Quoted Message (Reply to a message) class QuoteElem { /// Reply content String? text; /// The message being replied to Message? quoteMessage; QuoteElem({this.text, this.quoteMessage}); QuoteElem.fromJson(Map json) { text = json['text']; if (json['quoteMessage'] is Map) { quoteMessage = Message.fromJson(json['quoteMessage']); } } Map toJson() { final data = Map(); data['text'] = this.text; data['quoteMessage'] = this.quoteMessage?.toJson(); return data; } } /// Merged Message Body class MergeElem { /// Title String? title; /// Summary List? abstractList; /// List of specific messages to merge List? multiMessage; MergeElem({this.title, this.abstractList, this.multiMessage}); MergeElem.fromJson(Map json) { title = json['title']; if (json['abstractList'] is List) { abstractList = json['abstractList'].cast(); } if (json['multiMessage'] is List) { multiMessage = (json['multiMessage'] as List) .map((e) => Message.fromJson(e)) .toList(); } } Map toJson() { final data = Map(); data['title'] = this.title; data['abstractList'] = this.abstractList; data['multiMessage'] = this.multiMessage?.map((e) => e.toJson()).toList(); return data; } } /// Notification class NotificationElem { /// Details String? detail; /// Default tips String? defaultTips; NotificationElem({this.detail, this.defaultTips}); NotificationElem.fromJson(Map json) { detail = json['detail']; defaultTips = json['defaultTips']; } Map toJson() { final data = Map(); data['detail'] = this.detail; data['defaultTips'] = this.defaultTips; return data; } } /// Emoticon class FaceElem { /// Position emoticon, user-defined embedded emoticon for peer-to-peer communication int? index; /// Other emoticons, such as URL emoticons directly returning the URL String? data; FaceElem({this.index, this.data}); FaceElem.fromJson(Map json) { index = json['index']; data = json['data']; } Map toJson() { final data = Map(); data['index'] = this.index; data['data'] = this.data; return data; } } /// Additional Information class AttachedInfoElem { /// Group message read information GroupHasReadInfo? groupHasReadInfo; /// Whether it is a private chat message (burn after reading message), valid for one-on-one chats bool? isPrivateChat; /// Read time int? hasReadTime; /// Reading duration in seconds /// That is, it triggers destruction after burnDuration seconds from the hasReadTime time int? burnDuration; /// Do not send offline push notifications bool? notSenderNotificationPush; AttachedInfoElem({ this.groupHasReadInfo, this.isPrivateChat, this.hasReadTime, this.burnDuration, this.notSenderNotificationPush, }); AttachedInfoElem.fromJson(Map json) { groupHasReadInfo = json['groupHasReadInfo'] == null ? null : GroupHasReadInfo.fromJson(json['groupHasReadInfo']); isPrivateChat = json['isPrivateChat']; hasReadTime = json['hasReadTime']; burnDuration = json['burnDuration']; notSenderNotificationPush = json['notSenderNotificationPush']; } Map toJson() { final data = Map(); data['groupHasReadInfo'] = this.groupHasReadInfo?.toJson(); data['isPrivateChat'] = this.isPrivateChat; data['hasReadTime'] = this.hasReadTime; data['burnDuration'] = this.burnDuration; data['notSenderNotificationPush'] = this.notSenderNotificationPush; return data; } } class TextElem { String? content; TextElem({this.content}); TextElem.fromJson(Map json) { content = json['content']; } Map toJson() { final data = Map(); data['content'] = content; return data; } } class CardElem { String? userID; String? nickname; String? faceURL; String? ex; CardElem({this.userID, this.nickname, this.faceURL, this.ex}); CardElem.fromJson(Map json) { userID = json['userID']; nickname = json['nickname']; faceURL = json['faceURL']; ex = json['ex']; } Map toJson() { final data = Map(); data['userID'] = userID; data['nickname'] = nickname; data['faceURL'] = faceURL; data['ex'] = ex; return data; } } class TypingElem { String? msgTips; TypingElem({this.msgTips}); TypingElem.fromJson(Map json) { msgTips = json['msgTips']; } Map toJson() { final data = Map(); data['msgTips'] = msgTips; return data; } } class AdvancedTextElem { String? text; List? messageEntityList; AdvancedTextElem({this.text, this.messageEntityList}); AdvancedTextElem.fromJson(Map json) { text = json['text']; messageEntityList = json['messageEntityList'] == null ? null : (json['messageEntityList'] as List) .map((e) => MessageEntity.fromJson(e)) .toList(); } Map toJson() { final data = Map(); data['text'] = text; data['messageEntityList'] = messageEntityList?.map((e) => e.toJson()).toList(); return data; } } class MessageEntity { String? type; int? offset; int? length; String? url; String? ex; MessageEntity({this.type, this.offset, this.length, this.url, this.ex}); MessageEntity.fromJson(Map json) { type = json['type']; offset = json['offset']; length = json['length']; url = json['url']; ex = json['ex']; } Map toJson() { final data = Map(); data['type'] = type; data['offset'] = offset; data['length'] = length; data['url'] = url; data['ex'] = ex; return data; } } /// Group message read information class GroupHasReadInfo { /// List of user IDs that have read the message List? hasReadUserIDList; /// Total number of messages read int? hasReadCount; /// Number of group members when this message was sent int? groupMemberCount; GroupHasReadInfo.fromJson(Map json) { if (json['hasReadUserIDList'] == null) { hasReadUserIDList = []; } else { hasReadUserIDList = (json['hasReadUserIDList'] as List).cast(); } hasReadCount = json['hasReadCount'] ?? 0; groupMemberCount = json['groupMemberCount'] ?? 0; } Map toJson() { final data = Map(); data['hasReadUserIDList'] = this.hasReadUserIDList; data['hasReadCount'] = this.hasReadCount; data['groupMemberCount'] = this.groupMemberCount; return data; } } /// Message read receipt information class ReadReceiptInfo { /// Sender's ID String? userID; /// Group ID String? groupID; /// List of clientMsgIDs for read messages List? msgIDList; /// Read time int? readTime; /// Message source int? msgFrom; /// Message type [MessageType] int? contentType; /// Conversation type [ConversationType] int? sessionType; ReadReceiptInfo( {this.userID, this.groupID, this.msgIDList, this.readTime, this.msgFrom, this.contentType, this.sessionType}); ReadReceiptInfo.fromJson(Map json) { userID = json['uid'] ?? json['userID']; groupID = json['groupID']; if (json['msgIDList'] is List) { msgIDList = (json['msgIDList'] as List).map((e) => '$e').toList(); } readTime = json['readTime']; msgFrom = json['msgFrom']; contentType = json['contentType']; sessionType = json['sessionType']; } Map toJson() { final data = Map(); data['userID'] = this.userID; data['msgIDList'] = this.msgIDList; data['readTime'] = this.readTime; data['msgFrom'] = this.msgFrom; data['contentType'] = this.contentType; data['sessionType'] = this.sessionType; return data; } } /// Offline push information class OfflinePushInfo { /// Notification title String? title; /// Notification description String? desc; /// Extended content String? ex; /// iOS-specific String? iOSPushSound; /// iOS-specific bool? iOSBadgeCount; OfflinePushInfo( {this.title, this.desc, this.ex, this.iOSPushSound, this.iOSBadgeCount}); OfflinePushInfo.fromJson(Map json) { title = json['title']; desc = json['desc']; ex = json['ex']; iOSPushSound = json['iOSPushSound']; iOSBadgeCount = json['iOSBadgeCount']; } Map toJson() { final data = Map(); data['title'] = this.title; data['desc'] = this.desc; data['ex'] = this.ex; data['iOSPushSound'] = this.iOSPushSound; data['iOSBadgeCount'] = this.iOSBadgeCount; return data; } } /// @ message user ID and nickname relationship object class AtUserInfo { /// User ID who was @ mentioned String? atUserID; /// User nickname who was @ mentioned String? groupNickname; AtUserInfo({this.atUserID, this.groupNickname}); AtUserInfo.fromJson(Map json) { atUserID = json['atUserID']; groupNickname = json['groupNickname']; } Map toJson() { final data = Map(); data['atUserID'] = this.atUserID; data['groupNickname'] = this.groupNickname; return data; } } /// Message revocation details class RevokedInfo { /// Revoker's ID String? revokerID; /// Revoker's group role [GroupRoleLevel] int? revokerRole; /// Revoker's nickname String? revokerNickname; /// Message ID String? clientMsgID; /// Revocation time int? revokeTime; /// Message sending time int? sourceMessageSendTime; /// Message sender String? sourceMessageSendID; /// Message sender's nickname String? sourceMessageSenderNickname; /// Conversation type [ConversationType] int? sessionType; RevokedInfo({ this.revokerID, this.revokerRole, this.revokerNickname, this.clientMsgID, this.revokeTime, this.sourceMessageSendTime, this.sourceMessageSendID, this.sourceMessageSenderNickname, this.sessionType, }); RevokedInfo.fromJson(Map json) { revokerID = json['revokerID']; revokerRole = json['revokerRole']; revokerNickname = json['revokerNickname']; clientMsgID = json['clientMsgID']; revokeTime = json['revokeTime']; sourceMessageSendTime = json['sourceMessageSendTime']; sourceMessageSendID = json['sourceMessageSendID']; sourceMessageSenderNickname = json['sourceMessageSenderNickname']; sessionType = json['sessionType']; } Map toJson() { final data = Map(); data['revokerID'] = this.revokerID; data['revokerRole'] = this.revokerRole; data['revokerNickname'] = this.revokerNickname; data['clientMsgID'] = this.clientMsgID; data['revokeTime'] = this.revokeTime; data['sourceMessageSendTime'] = this.sourceMessageSendTime; data['sourceMessageSendID'] = this.sourceMessageSendID; data['sourceMessageSenderNickname'] = this.sourceMessageSenderNickname; data['sessionType'] = this.sessionType; return data; } } class AdvancedMessage { List? messageList; bool? isEnd; int? errCode; String? errMsg; int? lastMinSeq; AdvancedMessage({ this.messageList, this.isEnd, this.errCode, this.errMsg, this.lastMinSeq, }); AdvancedMessage.fromJson(Map json) { messageList = json['messageList'] == null ? null : (json['messageList'] as List) .map((e) => Message.fromJson(e)) .toList(); isEnd = json['isEnd']; errCode = json['errCode']; errMsg = json['errMsg']; lastMinSeq = json['lastMinSeq']; } Map toJson() { final data = Map(); data['messageList'] = this.messageList?.map((e) => e.toJson()).toList(); data['isEnd'] = this.isEnd; data['errCode'] = this.errCode; data['errMsg'] = this.errMsg; data['lastMinSeq'] = this.lastMinSeq; return data; } } class RichMessageInfo { String? type; int? offset; int? length; String? url; String? info; RichMessageInfo({ this.type, this.offset, this.length, this.url, this.info, }); RichMessageInfo.fromJson(Map json) { type = json['type']; offset = json['offset']; length = json['length']; url = json['url']; info = json['info']; } Map toJson() { final data = Map(); data['type'] = this.type; data['offset'] = this.offset; data['length'] = this.length; data['url'] = this.url; data['info'] = this.info; return data; } } class UserExInfo { String? userID; String? ex; UserExInfo({this.userID, this.ex}); UserExInfo.fromJson(Map json) { userID = json['userID']; ex = json['ex']; } Map toJson() { final data = Map(); data['userID'] = this.userID; data['ex'] = this.ex; return data; } }