2021-03-10 16:54:41 +00:00
|
|
|
import 'package:comunic/helpers/serialization/base_serialization_helper.dart';
|
2021-03-10 18:08:18 +00:00
|
|
|
import 'package:comunic/lists/users_list.dart';
|
2020-04-16 13:10:47 +00:00
|
|
|
import 'package:comunic/models/displayed_content.dart';
|
2019-05-04 06:58:14 +00:00
|
|
|
import 'package:comunic/utils/account_utils.dart' as account;
|
2021-03-10 18:08:18 +00:00
|
|
|
import 'package:comunic/utils/intl_utils.dart';
|
2021-03-10 23:02:41 +00:00
|
|
|
import 'package:flutter/material.dart';
|
2019-04-25 06:56:16 +00:00
|
|
|
import 'package:meta/meta.dart';
|
|
|
|
|
|
|
|
/// Single conversation message
|
|
|
|
///
|
|
|
|
/// @author Pierre HUBERT
|
|
|
|
|
2021-03-10 23:02:41 +00:00
|
|
|
enum ConversationMessageFileType {
|
|
|
|
IMAGE,
|
|
|
|
VIDEO,
|
|
|
|
AUDIO,
|
|
|
|
PDF,
|
|
|
|
ZIP,
|
|
|
|
OTHER,
|
|
|
|
}
|
|
|
|
|
|
|
|
const _ConversationFileMimeTypeMapping = {
|
|
|
|
"image/jpeg": ConversationMessageFileType.IMAGE,
|
|
|
|
"image/png": ConversationMessageFileType.IMAGE,
|
|
|
|
"image/gif": ConversationMessageFileType.IMAGE,
|
|
|
|
"video/mp4": ConversationMessageFileType.VIDEO,
|
|
|
|
"audio/m4a": ConversationMessageFileType.AUDIO,
|
|
|
|
"audio/mpeg": ConversationMessageFileType.AUDIO,
|
|
|
|
"application/pdf": ConversationMessageFileType.PDF,
|
|
|
|
"application/zip": ConversationMessageFileType.ZIP,
|
|
|
|
};
|
|
|
|
|
2021-03-10 16:54:41 +00:00
|
|
|
class ConversationMessageFile {
|
|
|
|
final String url;
|
|
|
|
final int size;
|
|
|
|
final String name;
|
|
|
|
final String thumbnail;
|
|
|
|
final String type;
|
|
|
|
|
|
|
|
const ConversationMessageFile({
|
|
|
|
@required this.url,
|
|
|
|
@required this.size,
|
|
|
|
@required this.name,
|
|
|
|
@required this.thumbnail,
|
|
|
|
@required this.type,
|
|
|
|
}) : assert(url != null),
|
|
|
|
assert(size != null),
|
|
|
|
assert(name != null),
|
|
|
|
assert(type != null);
|
|
|
|
|
2021-03-10 23:02:41 +00:00
|
|
|
/// Get the type of file
|
|
|
|
ConversationMessageFileType get fileType {
|
|
|
|
if (type != null && _ConversationFileMimeTypeMapping.containsKey(type))
|
|
|
|
return _ConversationFileMimeTypeMapping[type];
|
|
|
|
else
|
|
|
|
return ConversationMessageFileType.OTHER;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Get the icon associated with file type
|
|
|
|
IconData get icon {
|
|
|
|
switch (fileType) {
|
|
|
|
case ConversationMessageFileType.IMAGE:
|
|
|
|
return Icons.image;
|
|
|
|
case ConversationMessageFileType.VIDEO:
|
|
|
|
return Icons.video_library;
|
|
|
|
case ConversationMessageFileType.AUDIO:
|
|
|
|
return Icons.audiotrack;
|
|
|
|
case ConversationMessageFileType.PDF:
|
|
|
|
return Icons.picture_as_pdf;
|
|
|
|
|
|
|
|
case ConversationMessageFileType.ZIP:
|
|
|
|
return Icons.archive;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return Icons.insert_drive_file;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool get hasThumbnail => thumbnail != null;
|
|
|
|
|
2021-03-10 16:54:41 +00:00
|
|
|
Map<String, dynamic> toJson() => {
|
|
|
|
"url": url,
|
|
|
|
"size": size,
|
|
|
|
"name": name,
|
|
|
|
"thumbnail": thumbnail,
|
|
|
|
"type": type
|
|
|
|
};
|
|
|
|
|
|
|
|
ConversationMessageFile.fromJson(Map<String, dynamic> json)
|
|
|
|
: url = json["url"],
|
|
|
|
size = json["size"],
|
|
|
|
name = json["name"],
|
|
|
|
thumbnail = json["thumbnail"],
|
|
|
|
type = json["type"];
|
|
|
|
}
|
|
|
|
|
|
|
|
enum ConversationServerMessageType {
|
|
|
|
USER_CREATED_CONVERSATION,
|
|
|
|
USER_ADDED_ANOTHER_USER,
|
|
|
|
USER_LEFT_CONV,
|
|
|
|
USER_REMOVED_ANOTHER_USER
|
|
|
|
}
|
|
|
|
|
|
|
|
class ConversationServerMessage {
|
|
|
|
final ConversationServerMessageType type;
|
|
|
|
final int userID;
|
|
|
|
final int userWhoAdded;
|
|
|
|
final int userAdded;
|
|
|
|
final int userWhoRemoved;
|
|
|
|
final int userRemoved;
|
|
|
|
|
|
|
|
const ConversationServerMessage({
|
|
|
|
@required this.type,
|
|
|
|
@required this.userID,
|
|
|
|
@required this.userWhoAdded,
|
|
|
|
@required this.userAdded,
|
|
|
|
@required this.userWhoRemoved,
|
|
|
|
@required this.userRemoved,
|
|
|
|
}) : assert(type != null),
|
|
|
|
assert(userID != null ||
|
|
|
|
(type != ConversationServerMessageType.USER_CREATED_CONVERSATION &&
|
|
|
|
type != ConversationServerMessageType.USER_LEFT_CONV)),
|
|
|
|
assert((userWhoAdded != null && userAdded != null) ||
|
|
|
|
type != ConversationServerMessageType.USER_ADDED_ANOTHER_USER),
|
|
|
|
assert((userWhoRemoved != null && userRemoved != null) ||
|
|
|
|
type != ConversationServerMessageType.USER_REMOVED_ANOTHER_USER);
|
|
|
|
|
|
|
|
Set<int> get usersID {
|
|
|
|
switch (type) {
|
|
|
|
case ConversationServerMessageType.USER_CREATED_CONVERSATION:
|
|
|
|
case ConversationServerMessageType.USER_LEFT_CONV:
|
|
|
|
return Set()..add(userID);
|
|
|
|
|
|
|
|
case ConversationServerMessageType.USER_ADDED_ANOTHER_USER:
|
|
|
|
return Set()..add(userWhoAdded)..add(userAdded);
|
|
|
|
|
|
|
|
case ConversationServerMessageType.USER_REMOVED_ANOTHER_USER:
|
|
|
|
return Set()..add(userWhoRemoved)..add(userRemoved);
|
|
|
|
}
|
|
|
|
|
|
|
|
throw Exception("Unsupported server message type!");
|
|
|
|
}
|
|
|
|
|
2021-03-10 18:08:18 +00:00
|
|
|
String getText(UsersList list) {
|
|
|
|
switch (type) {
|
|
|
|
case ConversationServerMessageType.USER_CREATED_CONVERSATION:
|
|
|
|
return tr("%1% created the conversation",
|
|
|
|
args: {"1": list.getUser(userID).fullName});
|
|
|
|
|
|
|
|
case ConversationServerMessageType.USER_ADDED_ANOTHER_USER:
|
|
|
|
return tr("%1% added %2% to the conversation", args: {
|
|
|
|
"1": list.getUser(userWhoAdded).fullName,
|
|
|
|
"2": list.getUser(userAdded).fullName,
|
|
|
|
});
|
|
|
|
|
|
|
|
case ConversationServerMessageType.USER_LEFT_CONV:
|
|
|
|
return tr("%1% left the conversation", args: {
|
|
|
|
"1": list.getUser(userID).fullName,
|
|
|
|
});
|
|
|
|
|
|
|
|
case ConversationServerMessageType.USER_REMOVED_ANOTHER_USER:
|
|
|
|
return tr("%1% removed %2% from the conversation", args: {
|
|
|
|
"1": list.getUser(userWhoRemoved).fullName,
|
|
|
|
"2": list.getUser(userRemoved).fullName,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
throw Exception("Unsupported message type!");
|
|
|
|
}
|
|
|
|
|
2021-03-10 16:54:41 +00:00
|
|
|
Map<String, dynamic> toJson() => {
|
|
|
|
"type": type.toString(),
|
|
|
|
"userID": userID,
|
|
|
|
"userWhoAdded": userWhoAdded,
|
|
|
|
"userAdded": userAdded,
|
|
|
|
"userWhoRemoved": userWhoRemoved,
|
|
|
|
"userRemoved": userRemoved,
|
|
|
|
};
|
|
|
|
|
|
|
|
ConversationServerMessage.fromJson(Map<String, dynamic> json)
|
|
|
|
: type = ConversationServerMessageType.values
|
|
|
|
.firstWhere((el) => el.toString() == json["type"]),
|
|
|
|
userID = json["userID"],
|
|
|
|
userWhoAdded = json["userWhoAdded"],
|
|
|
|
userAdded = json["userAdded"],
|
|
|
|
userWhoRemoved = json["userWhoRemoved"],
|
|
|
|
userRemoved = json["userRemoved"];
|
|
|
|
}
|
|
|
|
|
|
|
|
class ConversationMessage extends SerializableElement<ConversationMessage> {
|
2019-04-25 06:56:16 +00:00
|
|
|
final int id;
|
2021-03-10 16:54:41 +00:00
|
|
|
final int convID;
|
2019-04-25 06:56:16 +00:00
|
|
|
final int userID;
|
2021-03-10 16:54:41 +00:00
|
|
|
final int timeSent;
|
2020-04-16 13:10:47 +00:00
|
|
|
final DisplayedString message;
|
2021-03-10 16:54:41 +00:00
|
|
|
final ConversationMessageFile file;
|
|
|
|
final ConversationServerMessage serverMessage;
|
2019-04-25 06:56:16 +00:00
|
|
|
|
2021-03-10 16:54:41 +00:00
|
|
|
ConversationMessage({
|
2019-04-25 06:56:16 +00:00
|
|
|
@required this.id,
|
2021-03-10 16:54:41 +00:00
|
|
|
@required this.convID,
|
2019-04-25 06:56:16 +00:00
|
|
|
@required this.userID,
|
2021-03-10 16:54:41 +00:00
|
|
|
@required this.timeSent,
|
2019-04-25 06:56:16 +00:00
|
|
|
@required this.message,
|
2021-03-10 16:54:41 +00:00
|
|
|
@required this.file,
|
|
|
|
@required this.serverMessage,
|
2019-04-25 06:56:16 +00:00
|
|
|
}) : assert(id != null),
|
2021-03-10 16:54:41 +00:00
|
|
|
assert(convID != null),
|
2021-03-10 18:08:18 +00:00
|
|
|
assert(userID != null || serverMessage != null),
|
2021-03-10 16:54:41 +00:00
|
|
|
assert(timeSent != null),
|
|
|
|
assert(message != null || file != null || serverMessage != null);
|
2019-04-25 06:56:16 +00:00
|
|
|
|
2021-03-10 16:54:41 +00:00
|
|
|
DateTime get date => DateTime.fromMillisecondsSinceEpoch(timeSent * 1000);
|
2019-04-27 06:42:27 +00:00
|
|
|
|
2020-04-16 13:10:47 +00:00
|
|
|
bool get hasMessage => !message.isNull && message.length > 0;
|
2019-04-26 09:28:33 +00:00
|
|
|
|
2021-03-10 16:54:41 +00:00
|
|
|
bool get hasFile => file != null;
|
|
|
|
|
2019-05-04 06:58:14 +00:00
|
|
|
bool get isOwner => account.userID() == userID;
|
|
|
|
|
2021-03-10 18:08:18 +00:00
|
|
|
bool get isServerMessage => serverMessage != null;
|
|
|
|
|
2021-03-10 16:54:41 +00:00
|
|
|
/// Get the list of the ID of the users implied in this message
|
|
|
|
Set<int> get usersID {
|
|
|
|
if (userID != null) return Set()..add(userID);
|
|
|
|
|
2021-03-11 17:50:36 +00:00
|
|
|
if (serverMessage != null) return serverMessage.usersID;
|
|
|
|
return Set();
|
2021-03-10 16:54:41 +00:00
|
|
|
}
|
|
|
|
|
2019-04-25 06:56:16 +00:00
|
|
|
@override
|
2021-03-10 16:54:41 +00:00
|
|
|
int compareTo(ConversationMessage other) {
|
2019-04-25 06:56:16 +00:00
|
|
|
return id.compareTo(other.id);
|
|
|
|
}
|
2019-04-27 06:42:27 +00:00
|
|
|
|
2021-03-10 16:54:41 +00:00
|
|
|
Map<String, dynamic> toJson() {
|
2019-04-27 06:42:27 +00:00
|
|
|
return {
|
2021-03-10 16:54:41 +00:00
|
|
|
"id": id,
|
|
|
|
"convID": convID,
|
|
|
|
"userID": userID,
|
|
|
|
"timeSent": timeSent,
|
2021-03-10 18:08:18 +00:00
|
|
|
"message": message.content,
|
2021-03-10 16:54:41 +00:00
|
|
|
"file": file?.toJson(),
|
|
|
|
"serverMessage": serverMessage?.toJson(),
|
2019-04-27 06:42:27 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2021-03-10 16:54:41 +00:00
|
|
|
ConversationMessage.fromJson(Map<String, dynamic> map)
|
|
|
|
: id = map["id"],
|
|
|
|
convID = map["convID"],
|
|
|
|
userID = map["userID"],
|
|
|
|
timeSent = map["timeSent"],
|
|
|
|
message = DisplayedString(map["message"]),
|
2021-03-10 23:02:41 +00:00
|
|
|
file = map["file"] == null
|
|
|
|
? null
|
|
|
|
: ConversationMessageFile.fromJson(map["file"]),
|
|
|
|
serverMessage = map["serverMessage"] == null
|
|
|
|
? null
|
|
|
|
: ConversationServerMessage.fromJson(map["serverMessage"]);
|
2019-04-25 06:56:16 +00:00
|
|
|
}
|