Load last read messages, enable lazy-loading the future, might fix #136

This commit is contained in:
Sebastian Wolf 2020-11-15 23:05:22 +01:00
parent 5e7d62982f
commit 85d1bebc3a
5 changed files with 63 additions and 30 deletions

View file

@ -116,13 +116,18 @@ ListItem {
Connections {
target: chatModel
onUnreadCountUpdated: {
messageBackground.isUnread = index > ( chatView.count - unreadCount - 1 );
onMessagesReceived: {
messageBackground.isUnread = index > chatModel.getLastReadMessageIndex();
}
onMessagesIncrementalUpdate: {
messageBackground.isUnread = index > chatModel.getLastReadMessageIndex();
}
onNewMessageReceived: {
messageBackground.isUnread = index > ( chatView.count - page.chatInformation.unread_count - 1 );
messageBackground.isUnread = index > chatModel.getLastReadMessageIndex();
}
onUnreadCountUpdated: {
messageBackground.isUnread = index > chatModel.getLastReadMessageIndex();
}
onLastReadSentMessageUpdated: {
console.log("[ChatModel] Messages in this chat were read, new last read: " + lastReadSentIndex + ", updating description for index " + index + ", status: " + (index <= lastReadSentIndex));
messageDateText.text = getMessageStatusText(myMessage, index, lastReadSentIndex, messageDateText.useElapsed);
@ -216,6 +221,7 @@ ListItem {
Rectangle {
id: messageBackground
anchors {
left: parent.left
leftMargin: messageListItem.isOwnMessage ? precalculatedValues.pageMarginDouble : 0
@ -223,7 +229,7 @@ ListItem {
}
height: messageTextColumn.height + precalculatedValues.paddingMediumDouble
width: precalculatedValues.backgroundWidth
property bool isUnread: index > ( chatView.count - page.chatInformation.unread_count - 1 )
property bool isUnread: index > chatModel.getLastReadMessageIndex()
color: isUnread ? Theme.secondaryHighlightColor : Theme.secondaryColor
radius: parent.width / 50
opacity: isUnread ? 0.5 : 0.2

View file

@ -356,6 +356,11 @@ Page {
chatView.lastReadSentIndex = lastReadSentIndex;
chatView.scrollToIndex(modelIndex);
chatPage.loading = false;
if (modelIndex >= (chatView.count - 10)) {
chatView.inCooldown = true;
chatModel.triggerLoadMoreFuture();
}
if (chatView.height > chatView.contentHeight) {
console.log("[ChatPage] Chat content quite small...");
viewMessageTimer.queueViewMessage(chatView.count - 1);
@ -640,10 +645,16 @@ Page {
}
onContentYChanged: {
if (!chatPage.loading && !chatView.inCooldown && chatView.indexAt(chatView.contentX, chatView.contentY) < 10) {
if (!chatPage.loading && !chatView.inCooldown) {
if (chatView.indexAt(chatView.contentX, chatView.contentY) < 10) {
console.log("[ChatPage] Trying to get older history items...");
chatView.inCooldown = true;
chatModel.triggerLoadMoreHistory();
} else if (chatView.indexAt(chatView.contentX, chatView.contentY) > ( count - 10)) {
console.log("[ChatPage] Trying to get newer history items...");
chatView.inCooldown = true;
chatModel.triggerLoadMoreFuture();
}
}
}

View file

@ -30,6 +30,7 @@ namespace {
const QString CHAT_ID("chat_id");
const QString PHOTO("photo");
const QString SMALL("small");
const QString LAST_READ_INBOX_MESSAGE_ID("last_read_inbox_message_id");
}
ChatModel::ChatModel(TDLibWrapper *tdLibWrapper) :
@ -90,7 +91,7 @@ void ChatModel::initialize(const QVariantMap &chatInformation)
this->messagesToBeAdded.clear();
endResetModel();
emit smallPhotoChanged();
tdLibWrapper->getChatHistory(chatId);
tdLibWrapper->getChatHistory(chatId, this->chatInformation.value(LAST_READ_INBOX_MESSAGE_ID).toLongLong());
}
void ChatModel::triggerLoadMoreHistory()
@ -102,6 +103,15 @@ void ChatModel::triggerLoadMoreHistory()
}
}
void ChatModel::triggerLoadMoreFuture()
{
if (!this->inIncrementalUpdate && !messages.isEmpty()) {
LOG("Trigger loading newer future...");
this->inIncrementalUpdate = true;
this->tdLibWrapper->getChatHistory(chatId, messages.last().toMap().value(ID).toLongLong(), -49);
}
}
QVariantMap ChatModel::getChatInformation()
{
return this->chatInformation;
@ -116,6 +126,11 @@ QVariantMap ChatModel::getMessage(int index)
}
}
int ChatModel::getLastReadMessageIndex()
{
return this->messageIndexMap.value(this->chatInformation.value(LAST_READ_INBOX_MESSAGE_ID).toString()).toInt();
}
QVariantMap ChatModel::smallPhoto() const
{
return chatInformation.value(PHOTO).toMap().value(SMALL).toMap();
@ -149,17 +164,21 @@ void ChatModel::handleMessagesReceived(const QVariantList &messages, int totalCo
QListIterator<QVariant> messagesIterator(messages);
while (messagesIterator.hasNext()) {
QVariantMap currentMessage = messagesIterator.next().toMap();
if (currentMessage.value(CHAT_ID).toLongLong() == chatId) {
if (currentMessage.value(CHAT_ID).toLongLong() == chatId && !this->messageIndexMap.contains(currentMessage.value(ID).toString())) {
LOG("New message will be added: " + currentMessage.value(ID).toString());
this->messagesToBeAdded.append(currentMessage);
}
}
std::sort(this->messagesToBeAdded.begin(), this->messagesToBeAdded.end(), compareMessages);
if (!this->messagesToBeAdded.isEmpty()) {
this->insertMessages();
}
this->messagesMutex.unlock();
// First call only returns a few messages, we need to get a little more than that...
if (this->messagesToBeAdded.size() < 10 && !this->inReload) {
if ((this->messagesToBeAdded.size() + this->messages.size()) < 10 && !this->inReload) {
LOG("Only a few messages received in first call, loading more...");
this->inReload = true;
this->tdLibWrapper->getChatHistory(this->chatId, this->messagesToBeAdded.first().toMap().value(ID).toLongLong());
@ -181,7 +200,7 @@ void ChatModel::handleMessagesReceived(const QVariantList &messages, int totalCo
void ChatModel::handleNewMessageReceived(const QString &id, const QVariantMap &message)
{
if (id.toLongLong() == chatId) {
if (id.toLongLong() == chatId && !this->messageIndexMap.contains(id)) {
LOG("New message received for this chat");
this->messagesMutex.lock();
@ -199,7 +218,7 @@ void ChatModel::handleChatReadInboxUpdated(const QString &id, const QString &las
if (id.toLongLong() == chatId) {
LOG("Updating chat unread count, unread messages" << unreadCount << ", last read message ID:" << lastReadInboxMessageId);
this->chatInformation.insert("unread_count", unreadCount);
this->chatInformation.insert("last_read_inbox_message_id", lastReadInboxMessageId);
this->chatInformation.insert(LAST_READ_INBOX_MESSAGE_ID, lastReadInboxMessageId);
emit unreadCountUpdated(unreadCount, lastReadInboxMessageId);
}
}
@ -299,11 +318,16 @@ void ChatModel::insertMessages()
endResetModel();
} else {
// There is only an append or a prepend, tertium non datur! (probably ;))
if (this->messages.last().toMap().value(ID).toLongLong() < this->messagesToBeAdded.first().toMap().value(ID).toLongLong()) {
qlonglong lastKnownId = this->messages.last().toMap().value(ID).toLongLong();
qlonglong firstNewId = this->messagesToBeAdded.first().toMap().value(ID).toLongLong();
LOG("Inserting messages, last known ID: " + QString::number(lastKnownId) + ", first new ID: " + QString::number(firstNewId));
if (lastKnownId < firstNewId) {
// Append
LOG("Appending new messages...");
this->insertRows(rowCount(QModelIndex()), this->messagesToBeAdded.size());
} else {
// Prepend
LOG("Prepending new messages...");
this->insertRows(0, this->messagesToBeAdded.size());
}
}
@ -343,7 +367,7 @@ QVariantMap ChatModel::enhanceMessage(const QVariantMap &message)
int ChatModel::calculateLastKnownMessageId()
{
LOG("calculateLastKnownMessageId");
QString lastKnownMessageId = this->chatInformation.value("last_read_inbox_message_id").toString();
QString lastKnownMessageId = this->chatInformation.value(LAST_READ_INBOX_MESSAGE_ID).toString();
LOG("lastKnownMessageId" << lastKnownMessageId);
LOG("size messageIndexMap" << messageIndexMap.size());
LOG("contains ID?" << messageIndexMap.contains(lastKnownMessageId));

View file

@ -41,8 +41,10 @@ public:
Q_INVOKABLE void initialize(const QVariantMap &chatInformation);
Q_INVOKABLE void triggerLoadMoreHistory();
Q_INVOKABLE void triggerLoadMoreFuture();
Q_INVOKABLE QVariantMap getChatInformation();
Q_INVOKABLE QVariantMap getMessage(int index);
Q_INVOKABLE int getLastReadMessageIndex();
QVariantMap smallPhoto() const;
signals:

View file

@ -321,14 +321,12 @@
<source>%n Messages deleted</source>
<translation type="unfinished">
<numerusform></numerusform>
<numerusform></numerusform>
</translation>
</message>
<message numerus="yes">
<source>%n messages have been copied</source>
<translation type="unfinished">
<numerusform></numerusform>
<numerusform></numerusform>
</translation>
</message>
<message numerus="yes">
@ -336,7 +334,6 @@
<comment>number of messages selected</comment>
<translation type="unfinished">
<numerusform></numerusform>
<numerusform></numerusform>
</translation>
</message>
<message numerus="yes">
@ -344,7 +341,6 @@
<comment>dialog header</comment>
<translation type="unfinished">
<numerusform></numerusform>
<numerusform></numerusform>
</translation>
</message>
</context>
@ -941,7 +937,6 @@
<source>Question (%n1 characters left)</source>
<translation type="unfinished">
<numerusform></numerusform>
<numerusform></numerusform>
</translation>
</message>
<message>
@ -957,7 +952,6 @@
<source>Answer (%n1 characters left)</source>
<translation type="unfinished">
<numerusform></numerusform>
<numerusform></numerusform>
</translation>
</message>
<message>
@ -1006,7 +1000,6 @@
<comment>number of total votes</comment>
<translation type="unfinished">
<numerusform></numerusform>
<numerusform></numerusform>
</translation>
</message>
<message>
@ -1033,7 +1026,6 @@
<comment>number of total votes</comment>
<translation type="unfinished">
<numerusform></numerusform>
<numerusform></numerusform>
</translation>
</message>
<message>
@ -1051,7 +1043,6 @@
<comment>number of votes for option</comment>
<translation type="unfinished">
<numerusform></numerusform>
<numerusform></numerusform>
</translation>
</message>
<message>
@ -1069,7 +1060,6 @@
<comment>number of votes for option</comment>
<translation type="unfinished">
<numerusform></numerusform>
<numerusform></numerusform>
</translation>
</message>
</context>