mirror of
https://gitlab.com/comunic/comunicmobile
synced 2025-06-19 00:05:16 +00:00
Start conversation upgrade
This commit is contained in:
@ -1,7 +1,6 @@
|
||||
import 'package:comunic/helpers/database/database_contract.dart';
|
||||
import 'package:comunic/models/cache_model.dart';
|
||||
import 'package:comunic/helpers/serialization/base_serialization_helper.dart';
|
||||
import 'package:comunic/models/conversation_member.dart';
|
||||
import 'package:comunic/utils/account_utils.dart';
|
||||
import 'package:comunic/utils/list_utils.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
/// Conversation model
|
||||
@ -10,79 +9,86 @@ import 'package:meta/meta.dart';
|
||||
|
||||
enum CallCapabilities { NONE, AUDIO, VIDEO }
|
||||
|
||||
class Conversation extends CacheModel implements Comparable {
|
||||
final int ownerID;
|
||||
final int lastActive;
|
||||
class Conversation extends SerializableElement<Conversation> {
|
||||
final int id;
|
||||
final int lastActivity;
|
||||
final String name;
|
||||
final bool following;
|
||||
final bool sawLastMessage;
|
||||
final List<int> members;
|
||||
final String color;
|
||||
final String logoURL;
|
||||
final int groupID;
|
||||
final List<ConversationMember> members;
|
||||
final bool canEveryoneAddMembers;
|
||||
final CallCapabilities callCapabilities;
|
||||
final bool isHavingCall;
|
||||
|
||||
const Conversation({
|
||||
@required int id,
|
||||
@required this.ownerID,
|
||||
@required this.lastActive,
|
||||
Conversation({
|
||||
@required this.id,
|
||||
@required this.lastActivity,
|
||||
@required this.name,
|
||||
@required this.following,
|
||||
@required this.sawLastMessage,
|
||||
@required this.color,
|
||||
@required this.logoURL,
|
||||
@required this.groupID,
|
||||
@required this.members,
|
||||
@required this.canEveryoneAddMembers,
|
||||
this.callCapabilities = CallCapabilities.NONE,
|
||||
this.isHavingCall = false,
|
||||
}) : assert(id != null),
|
||||
assert(ownerID != null),
|
||||
assert(lastActive != null),
|
||||
assert(following != null),
|
||||
assert(sawLastMessage != null),
|
||||
assert(lastActivity != null),
|
||||
assert(members != null),
|
||||
assert(canEveryoneAddMembers != null),
|
||||
assert(callCapabilities != null),
|
||||
assert(isHavingCall != null),
|
||||
super(id: id);
|
||||
assert(isHavingCall != null);
|
||||
|
||||
/// Check out whether a conversation has a fixed name or not
|
||||
bool get hasName => this.name != null;
|
||||
|
||||
/// Check out whether current user of the application is the owner of it or
|
||||
/// not
|
||||
bool get isOwner => this.ownerID == userID();
|
||||
/// Get current user membership
|
||||
ConversationMember get membership =>
|
||||
members.firstWhere((m) => m.userID == userID());
|
||||
|
||||
Conversation.fromMap(Map<String, dynamic> map)
|
||||
: ownerID = map[ConversationTableContract.C_OWNER_ID],
|
||||
lastActive = map[ConversationTableContract.C_LAST_ACTIVE],
|
||||
name = map[ConversationTableContract.C_NAME],
|
||||
following = map[ConversationTableContract.C_FOLLOWING] == 1,
|
||||
sawLastMessage = map[ConversationTableContract.C_SAW_LAST_MESSAGE] == 1,
|
||||
members =
|
||||
listToIntList(map[ConversationTableContract.C_MEMBERS].split(",")),
|
||||
canEveryoneAddMembers =
|
||||
map[ConversationTableContract.C_CAN_EVERYONE_ADD_MEMBERS] == 1,
|
||||
/// Check out whether current user of the application is an admin
|
||||
bool get isAdmin => membership.isAdmin;
|
||||
|
||||
/// Check it current user is following the conversation or not
|
||||
bool get following => membership.following;
|
||||
|
||||
/// Get the list of members in the conversation
|
||||
Set<int> get membersID => members.map((e) => e.userID).toSet();
|
||||
|
||||
/// Check if the last message has been seen or not
|
||||
bool get sawLastMessage => lastActivity <= membership.lastAccessTime;
|
||||
|
||||
Conversation.fromJson(Map<String, dynamic> map)
|
||||
: id = map["id"],
|
||||
name = map["name"],
|
||||
color = map["color"],
|
||||
logoURL = map["logoURL"],
|
||||
groupID = map["groupID"],
|
||||
lastActivity = map["lastActivity"],
|
||||
members = map["members"]
|
||||
.map((el) => ConversationMember.fromJSON(el))
|
||||
.toList(),
|
||||
canEveryoneAddMembers = map["canEveryoneAddMembers"],
|
||||
|
||||
// By default, we can not do any call
|
||||
callCapabilities = CallCapabilities.NONE,
|
||||
isHavingCall = false,
|
||||
super.fromMap(map);
|
||||
isHavingCall = false;
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toMap() {
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
ConversationTableContract.C_ID: id,
|
||||
ConversationTableContract.C_OWNER_ID: ownerID,
|
||||
ConversationTableContract.C_LAST_ACTIVE: lastActive,
|
||||
ConversationTableContract.C_NAME: name,
|
||||
ConversationTableContract.C_FOLLOWING: following ? 1 : 0,
|
||||
ConversationTableContract.C_SAW_LAST_MESSAGE: sawLastMessage ? 1 : 0,
|
||||
ConversationTableContract.C_MEMBERS: members.join(","),
|
||||
ConversationTableContract.C_CAN_EVERYONE_ADD_MEMBERS:
|
||||
canEveryoneAddMembers ? 1 : 0
|
||||
"id": id,
|
||||
"name": name,
|
||||
"color": color,
|
||||
"logoURL": logoURL,
|
||||
"groupID": groupID,
|
||||
"lastActivity": lastActivity,
|
||||
"members": members.map((e) => e.toJson()).toList(),
|
||||
"canEveryoneAddMembers": canEveryoneAddMembers,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
int compareTo(other) {
|
||||
return other.lastActive.compareTo(this.lastActive);
|
||||
int compareTo(Conversation other) {
|
||||
return other.lastActivity.compareTo(this.lastActivity);
|
||||
}
|
||||
}
|
||||
|
40
lib/models/conversation_member.dart
Normal file
40
lib/models/conversation_member.dart
Normal file
@ -0,0 +1,40 @@
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
/// Conversation member
|
||||
///
|
||||
/// @author Pierre Hubert
|
||||
|
||||
class ConversationMember {
|
||||
final int userID;
|
||||
final int lastMessageSeen;
|
||||
final int lastAccessTime;
|
||||
final bool following;
|
||||
final bool isAdmin;
|
||||
|
||||
const ConversationMember({
|
||||
@required this.userID,
|
||||
@required this.lastMessageSeen,
|
||||
@required this.lastAccessTime,
|
||||
@required this.following,
|
||||
@required this.isAdmin,
|
||||
}) : assert(userID != null),
|
||||
assert(lastMessageSeen != null),
|
||||
assert(lastAccessTime != null),
|
||||
assert(following != null),
|
||||
assert(isAdmin != null);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'userID': userID,
|
||||
'lastMessageSeen': lastMessageSeen,
|
||||
'lastAccessTime': lastAccessTime,
|
||||
'following': following,
|
||||
'isAdmin': isAdmin,
|
||||
};
|
||||
|
||||
ConversationMember.fromJSON(Map<String, dynamic> json)
|
||||
: userID = json["userID"],
|
||||
lastMessageSeen = json["lastMessageSeen"],
|
||||
lastAccessTime = json["lastAccessTime"],
|
||||
following = json["following"],
|
||||
isAdmin = json["isAdmin"];
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
import 'package:comunic/helpers/database/database_contract.dart';
|
||||
import 'package:comunic/models/cache_model.dart';
|
||||
import 'package:comunic/helpers/serialization/base_serialization_helper.dart';
|
||||
import 'package:comunic/models/displayed_content.dart';
|
||||
import 'package:comunic/utils/account_utils.dart' as account;
|
||||
import 'package:meta/meta.dart';
|
||||
@ -8,59 +7,171 @@ import 'package:meta/meta.dart';
|
||||
///
|
||||
/// @author Pierre HUBERT
|
||||
|
||||
class ConversationMessage extends CacheModel implements Comparable {
|
||||
final int id;
|
||||
final int conversationID;
|
||||
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);
|
||||
|
||||
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 timeInsert;
|
||||
final DisplayedString message;
|
||||
final String imageURL;
|
||||
final int userWhoAdded;
|
||||
final int userAdded;
|
||||
final int userWhoRemoved;
|
||||
final int userRemoved;
|
||||
|
||||
const ConversationMessage({
|
||||
@required this.id,
|
||||
@required this.conversationID,
|
||||
const ConversationServerMessage({
|
||||
@required this.type,
|
||||
@required this.userID,
|
||||
@required this.timeInsert,
|
||||
@required this.message,
|
||||
@required this.imageURL,
|
||||
}) : assert(id != null),
|
||||
assert(userID != null),
|
||||
assert(timeInsert != null),
|
||||
assert(message != null),
|
||||
super(id: id);
|
||||
@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);
|
||||
|
||||
DateTime get date => DateTime.fromMillisecondsSinceEpoch(timeInsert * 1000);
|
||||
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!");
|
||||
}
|
||||
|
||||
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> {
|
||||
final int id;
|
||||
final int convID;
|
||||
final int userID;
|
||||
final int timeSent;
|
||||
final DisplayedString message;
|
||||
final ConversationMessageFile file;
|
||||
final ConversationServerMessage serverMessage;
|
||||
|
||||
ConversationMessage({
|
||||
@required this.id,
|
||||
@required this.convID,
|
||||
@required this.userID,
|
||||
@required this.timeSent,
|
||||
@required this.message,
|
||||
@required this.file,
|
||||
@required this.serverMessage,
|
||||
}) : assert(id != null),
|
||||
assert(convID != null),
|
||||
assert(userID != null),
|
||||
assert(timeSent != null),
|
||||
assert(message != null || file != null || serverMessage != null);
|
||||
|
||||
DateTime get date => DateTime.fromMillisecondsSinceEpoch(timeSent * 1000);
|
||||
|
||||
bool get hasMessage => !message.isNull && message.length > 0;
|
||||
|
||||
bool get hasImage => imageURL != null && imageURL != "null";
|
||||
bool get hasFile => file != null;
|
||||
|
||||
bool get hasThumbnail => hasFile && file.thumbnail != null;
|
||||
|
||||
bool get hasImage => hasFile && file.type.startsWith("image/");
|
||||
|
||||
bool get isOwner => account.userID() == userID;
|
||||
|
||||
/// Get the list of the ID of the users implied in this message
|
||||
Set<int> get usersID {
|
||||
if (userID != null) return Set()..add(userID);
|
||||
|
||||
return serverMessage.usersID;
|
||||
}
|
||||
|
||||
@override
|
||||
int compareTo(other) {
|
||||
int compareTo(ConversationMessage other) {
|
||||
return id.compareTo(other.id);
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toMap() {
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
ConversationsMessagesTableContract.C_ID: id,
|
||||
ConversationsMessagesTableContract.C_CONVERSATION_ID: conversationID,
|
||||
ConversationsMessagesTableContract.C_USER_ID: userID,
|
||||
ConversationsMessagesTableContract.C_TIME_INSERT: timeInsert,
|
||||
ConversationsMessagesTableContract.C_MESSAGE: message.content,
|
||||
ConversationsMessagesTableContract.C_IMAGE_URL: imageURL
|
||||
"id": id,
|
||||
"convID": convID,
|
||||
"userID": userID,
|
||||
"timeSent": timeSent,
|
||||
"message": message,
|
||||
"file": file?.toJson(),
|
||||
"serverMessage": serverMessage?.toJson(),
|
||||
};
|
||||
}
|
||||
|
||||
ConversationMessage.fromMap(Map<String, dynamic> map)
|
||||
: id = map[ConversationsMessagesTableContract.C_ID],
|
||||
conversationID =
|
||||
map[ConversationsMessagesTableContract.C_CONVERSATION_ID],
|
||||
userID = map[ConversationsMessagesTableContract.C_USER_ID],
|
||||
timeInsert = map[ConversationsMessagesTableContract.C_TIME_INSERT],
|
||||
message = DisplayedString(map[ConversationsMessagesTableContract.C_MESSAGE]),
|
||||
imageURL = map[ConversationsMessagesTableContract.C_IMAGE_URL],
|
||||
super.fromMap(map);
|
||||
ConversationMessage.fromJson(Map<String, dynamic> map)
|
||||
: id = map["id"],
|
||||
convID = map["convID"],
|
||||
userID = map["userID"],
|
||||
timeSent = map["timeSent"],
|
||||
message = DisplayedString(map["message"]),
|
||||
file = map["file"],
|
||||
serverMessage = map["serverMessage"];
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ class Membership {
|
||||
case MembershipType.GROUP:
|
||||
return groupLastActive;
|
||||
case MembershipType.CONVERSATION:
|
||||
return conversation.lastActive;
|
||||
return conversation.lastActivity;
|
||||
default:
|
||||
throw Exception("Unreachable statment!");
|
||||
}
|
||||
|
24
lib/models/new_conversation.dart
Normal file
24
lib/models/new_conversation.dart
Normal file
@ -0,0 +1,24 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
|
||||
/// New conversation information
|
||||
///
|
||||
/// @author Pierre Hubert
|
||||
|
||||
class NewConversation {
|
||||
final String name;
|
||||
final List<int> members;
|
||||
final bool follow;
|
||||
final bool canEveryoneAddMembers;
|
||||
final String color;
|
||||
|
||||
const NewConversation({
|
||||
@required this.name,
|
||||
@required this.members,
|
||||
@required this.follow,
|
||||
@required this.canEveryoneAddMembers,
|
||||
@required this.color,
|
||||
}) : assert(members != null),
|
||||
assert(members.length > 0),
|
||||
assert(follow != null),
|
||||
assert(canEveryoneAddMembers != null);
|
||||
}
|
27
lib/models/new_conversation_settings.dart
Normal file
27
lib/models/new_conversation_settings.dart
Normal file
@ -0,0 +1,27 @@
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
/// Conversation settings update
|
||||
///
|
||||
/// @author Pierre Hubert
|
||||
|
||||
class NewConversationsSettings {
|
||||
final int convID;
|
||||
final bool following;
|
||||
final bool isComplete;
|
||||
final String name;
|
||||
final bool canEveryoneAddMembers;
|
||||
final String color;
|
||||
|
||||
const NewConversationsSettings({
|
||||
@required this.convID,
|
||||
@required this.following,
|
||||
@required this.isComplete,
|
||||
@required this.name,
|
||||
@required this.canEveryoneAddMembers,
|
||||
@required this.color,
|
||||
}) : assert(convID != null),
|
||||
assert(convID > 0),
|
||||
assert(following != null),
|
||||
assert(isComplete != null),
|
||||
assert(!isComplete && canEveryoneAddMembers != null);
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
import 'package:comunic/models/conversation.dart';
|
||||
import 'package:comunic/models/conversation_message.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// Unread conversation information
|
||||
@ -5,21 +7,12 @@ import 'package:flutter/material.dart';
|
||||
/// @author Pierre Hubert
|
||||
|
||||
class UnreadConversation {
|
||||
final int id;
|
||||
final String convName;
|
||||
final int lastActive;
|
||||
final int userID;
|
||||
final String message;
|
||||
final Conversation conv;
|
||||
final ConversationMessage message;
|
||||
|
||||
const UnreadConversation({
|
||||
@required this.id,
|
||||
@required this.convName,
|
||||
@required this.lastActive,
|
||||
@required this.userID,
|
||||
@required this.conv,
|
||||
@required this.message,
|
||||
}) : assert(id != null),
|
||||
assert(convName != null),
|
||||
assert(lastActive != null),
|
||||
assert(userID != null),
|
||||
}) : assert(conv != null),
|
||||
assert(message != null);
|
||||
}
|
||||
|
Reference in New Issue
Block a user