-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmessagegroupmodel.cpp
141 lines (120 loc) · 5.68 KB
/
messagegroupmodel.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#include "messagegroupmodel.h"
#include <QDebug>
#include <stdlib.h>
MessageGroupModel::MessageGroupModel(QString selfUser, uint64_t maxCombineDiff)
: selfUser(selfUser), maxCombineDiff(maxCombineDiff)
{
}
void MessageGroupModel::addMessage(Message newMsg) {
// Plan:
// - Iterate from bottom to top of the groups
// until a message is found with a timestamp
// less (earlier) than the new message.
// - If first message, create a new group.
// - If between two groups, check to see which
// group has the same user. If neither, create
// a new group between them. If the earlier
// group, add to the end of the last group.
// If the later group, add to the beginning.
// - If in middle of a group, check user. If
// the user is the same, add to that group.
// If the user is different, split the group,
// and call the code for when it's between
// two groups to create a new group.
for (int groupIndex = groupList.length() - 1; groupIndex >= 0; groupIndex--) {
auto msgGroup = groupList.at(groupIndex);
QVector<Message>& msgList = msgGroup.getModel()->msgList;
QString newUser = newMsg.getUser();
for (int msgIndex = msgList.length() - 1; msgIndex >= 0; msgIndex--) {
auto msg = msgList.at(msgIndex);
uint64_t timeDiff = newMsg.getTimestamp() - msg.getTimestamp();
if (timeDiff >= 0) {
// Place after this message
if (msgGroup.getUser() == newUser && timeDiff <= maxCombineDiff) {
// Add to existing group
msgList.insert(msgIndex + 1, newMsg);
} else {
// New or beginning of next group.
if (msgIndex == msgList.length() - 1) {
// Can insert to a group after this one
// Check to see if it can be added to the next group.
// If not, create a new one.
if (groupIndex + 1 < groupList.length() && groupList.at(groupIndex + 1).getUser() == newUser && timeDiff <= maxCombineDiff) {
groupList.at(groupIndex + 1).getModel()->msgList.insert(0, newMsg);
} else {
MessageModel * model = new MessageModel;
model->msgList.append(newMsg);
groupList.insert(groupIndex + 1, MessageGroup{ newMsg.getUser(), model, newMsg.getUser() == selfUser });
}
} else {
// Split the group
// Add the new group for the new message
MessageModel * newMsgModel = new MessageModel;
newMsgModel->msgList.append(newMsg);
groupList.insert(groupIndex + 1, MessageGroup{ newMsg.getUser(), newMsgModel, newMsg.getUser() == selfUser });
// Add the new group for the remaining messages from the split group
MessageModel * remainingMsgsModel = new MessageModel;
// Add all from end to but NOT including the one at msgIndex
for (int i = msgList.length() - 1; i > msgIndex; i--) {
remainingMsgsModel->msgList.append(msgList.takeAt(i));
}
groupList.insert(groupIndex + 2, MessageGroup{ msgGroup.getUser(), remainingMsgsModel, msgGroup.getUser() == selfUser });
}
}
return;
}
}
}
// Reached the end. Add to beginning of timeline
// Check if the first group has the same user.
if (!groupList.isEmpty() && groupList.first().getUser() == newMsg.getUser()) {
groupList.first().getModel()->msgList.insert(0, newMsg);
} else {
MessageModel * newMsgModel = new MessageModel;
newMsgModel->msgList.append(newMsg);
groupList.insert(0, MessageGroup{ newMsg.getUser(), newMsgModel, newMsg.getUser() == selfUser });
}
}
// Copy constructor needed for Q_DECLARE_METATYPE for QVariant
MessageGroupModel::MessageGroupModel(const MessageGroupModel &other) {
this->groupList = other.groupList;
}
// The way that you need to move data to and from this QML is
// to have every bit of data be a role.
QHash<int, QByteArray> MessageGroupModel::roleNames() const {
QHash<int, QByteArray> hash;
hash[UsernameRole] = "user";
hash[MessagesModelRole] = "msg_model";
hash[SelfRole] = "self";
return hash;
}
int MessageGroupModel::rowCount(const QModelIndex & parent = QModelIndex()) const {
if (parent.isValid())
return 0;
return groupList.size();
}
bool MessageGroupModel::setData(const QModelIndex &index, const QVariant &value, int role) {
if (!hasIndex(index.row(), index.column(), index.parent()) || !value.isValid())
return false;
/*Message &item = m_list[index.row()];
if (role == UsernameRole)
item.user = value.toString();
else if (role == MessageRole)
item.msg = value.toString();
else
return false;*/
emit dataChanged(index, index, { role } );
return true ;
}
QVariant MessageGroupModel::data(const QModelIndex & index, int role = Qt::DisplayRole) const {
if (!hasIndex(index.row(), index.column(), index.parent()))
return {};
const MessageGroup &item = groupList.at(index.row());
if (role == UsernameRole) return item.getUser();
if (role == MessagesModelRole) {
return QVariant::fromValue(item.getModel());
}
if (role == SelfRole) return item.getSelf();
qDebug() << "Unknown role in group data " << roleNames()[role];
return {};
}