Load last read messages, enable lazy-loading the future, might fix #136
This commit is contained in:
parent
5e7d62982f
commit
85d1bebc3a
5 changed files with 63 additions and 30 deletions
|
@ -116,13 +116,18 @@ ListItem {
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: chatModel
|
target: chatModel
|
||||||
onUnreadCountUpdated: {
|
onMessagesReceived: {
|
||||||
messageBackground.isUnread = index > ( chatView.count - unreadCount - 1 );
|
messageBackground.isUnread = index > chatModel.getLastReadMessageIndex();
|
||||||
|
}
|
||||||
|
onMessagesIncrementalUpdate: {
|
||||||
|
messageBackground.isUnread = index > chatModel.getLastReadMessageIndex();
|
||||||
}
|
}
|
||||||
onNewMessageReceived: {
|
onNewMessageReceived: {
|
||||||
messageBackground.isUnread = index > ( chatView.count - page.chatInformation.unread_count - 1 );
|
messageBackground.isUnread = index > chatModel.getLastReadMessageIndex();
|
||||||
|
}
|
||||||
|
onUnreadCountUpdated: {
|
||||||
|
messageBackground.isUnread = index > chatModel.getLastReadMessageIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
onLastReadSentMessageUpdated: {
|
onLastReadSentMessageUpdated: {
|
||||||
console.log("[ChatModel] Messages in this chat were read, new last read: " + lastReadSentIndex + ", updating description for index " + index + ", status: " + (index <= lastReadSentIndex));
|
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);
|
messageDateText.text = getMessageStatusText(myMessage, index, lastReadSentIndex, messageDateText.useElapsed);
|
||||||
|
@ -216,6 +221,7 @@ ListItem {
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: messageBackground
|
id: messageBackground
|
||||||
|
|
||||||
anchors {
|
anchors {
|
||||||
left: parent.left
|
left: parent.left
|
||||||
leftMargin: messageListItem.isOwnMessage ? precalculatedValues.pageMarginDouble : 0
|
leftMargin: messageListItem.isOwnMessage ? precalculatedValues.pageMarginDouble : 0
|
||||||
|
@ -223,7 +229,7 @@ ListItem {
|
||||||
}
|
}
|
||||||
height: messageTextColumn.height + precalculatedValues.paddingMediumDouble
|
height: messageTextColumn.height + precalculatedValues.paddingMediumDouble
|
||||||
width: precalculatedValues.backgroundWidth
|
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
|
color: isUnread ? Theme.secondaryHighlightColor : Theme.secondaryColor
|
||||||
radius: parent.width / 50
|
radius: parent.width / 50
|
||||||
opacity: isUnread ? 0.5 : 0.2
|
opacity: isUnread ? 0.5 : 0.2
|
||||||
|
|
|
@ -356,6 +356,11 @@ Page {
|
||||||
chatView.lastReadSentIndex = lastReadSentIndex;
|
chatView.lastReadSentIndex = lastReadSentIndex;
|
||||||
chatView.scrollToIndex(modelIndex);
|
chatView.scrollToIndex(modelIndex);
|
||||||
chatPage.loading = false;
|
chatPage.loading = false;
|
||||||
|
if (modelIndex >= (chatView.count - 10)) {
|
||||||
|
chatView.inCooldown = true;
|
||||||
|
chatModel.triggerLoadMoreFuture();
|
||||||
|
}
|
||||||
|
|
||||||
if (chatView.height > chatView.contentHeight) {
|
if (chatView.height > chatView.contentHeight) {
|
||||||
console.log("[ChatPage] Chat content quite small...");
|
console.log("[ChatPage] Chat content quite small...");
|
||||||
viewMessageTimer.queueViewMessage(chatView.count - 1);
|
viewMessageTimer.queueViewMessage(chatView.count - 1);
|
||||||
|
@ -438,7 +443,7 @@ Page {
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
if(chatInformation.unread_count > 0 && lastQueuedIndex > -1) {
|
if(chatInformation.unread_count > 0 && lastQueuedIndex > -1) {
|
||||||
var messageToRead = chatModel.getMessage(lastQueuedIndex);
|
var messageToRead = chatModel.getMessage(lastQueuedIndex);
|
||||||
if(messageToRead && messageToRead.id) {
|
if (messageToRead && messageToRead.id) {
|
||||||
tdLibWrapper.viewMessage(chatInformation.id, messageToRead.id, false);
|
tdLibWrapper.viewMessage(chatInformation.id, messageToRead.id, false);
|
||||||
}
|
}
|
||||||
lastQueuedIndex = -1
|
lastQueuedIndex = -1
|
||||||
|
@ -620,9 +625,9 @@ Page {
|
||||||
|
|
||||||
function handleScrollPositionChanged() {
|
function handleScrollPositionChanged() {
|
||||||
console.log("Current position: " + chatView.contentY);
|
console.log("Current position: " + chatView.contentY);
|
||||||
if(chatInformation.unread_count > 0) {
|
if (chatInformation.unread_count > 0) {
|
||||||
var bottomIndex = chatView.indexAt(chatView.contentX, ( chatView.contentY + chatView.height - Theme.horizontalPageMargin ));
|
var bottomIndex = chatView.indexAt(chatView.contentX, ( chatView.contentY + chatView.height - Theme.horizontalPageMargin ));
|
||||||
if(bottomIndex > -1) {
|
if (bottomIndex > -1) {
|
||||||
viewMessageTimer.queueViewMessage(bottomIndex)
|
viewMessageTimer.queueViewMessage(bottomIndex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -640,10 +645,16 @@ Page {
|
||||||
}
|
}
|
||||||
|
|
||||||
onContentYChanged: {
|
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...");
|
console.log("[ChatPage] Trying to get older history items...");
|
||||||
chatView.inCooldown = true;
|
chatView.inCooldown = true;
|
||||||
chatModel.triggerLoadMoreHistory();
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@ namespace {
|
||||||
const QString CHAT_ID("chat_id");
|
const QString CHAT_ID("chat_id");
|
||||||
const QString PHOTO("photo");
|
const QString PHOTO("photo");
|
||||||
const QString SMALL("small");
|
const QString SMALL("small");
|
||||||
|
const QString LAST_READ_INBOX_MESSAGE_ID("last_read_inbox_message_id");
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatModel::ChatModel(TDLibWrapper *tdLibWrapper) :
|
ChatModel::ChatModel(TDLibWrapper *tdLibWrapper) :
|
||||||
|
@ -90,7 +91,7 @@ void ChatModel::initialize(const QVariantMap &chatInformation)
|
||||||
this->messagesToBeAdded.clear();
|
this->messagesToBeAdded.clear();
|
||||||
endResetModel();
|
endResetModel();
|
||||||
emit smallPhotoChanged();
|
emit smallPhotoChanged();
|
||||||
tdLibWrapper->getChatHistory(chatId);
|
tdLibWrapper->getChatHistory(chatId, this->chatInformation.value(LAST_READ_INBOX_MESSAGE_ID).toLongLong());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatModel::triggerLoadMoreHistory()
|
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()
|
QVariantMap ChatModel::getChatInformation()
|
||||||
{
|
{
|
||||||
return this->chatInformation;
|
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
|
QVariantMap ChatModel::smallPhoto() const
|
||||||
{
|
{
|
||||||
return chatInformation.value(PHOTO).toMap().value(SMALL).toMap();
|
return chatInformation.value(PHOTO).toMap().value(SMALL).toMap();
|
||||||
|
@ -149,17 +164,21 @@ void ChatModel::handleMessagesReceived(const QVariantList &messages, int totalCo
|
||||||
QListIterator<QVariant> messagesIterator(messages);
|
QListIterator<QVariant> messagesIterator(messages);
|
||||||
while (messagesIterator.hasNext()) {
|
while (messagesIterator.hasNext()) {
|
||||||
QVariantMap currentMessage = messagesIterator.next().toMap();
|
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);
|
this->messagesToBeAdded.append(currentMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::sort(this->messagesToBeAdded.begin(), this->messagesToBeAdded.end(), compareMessages);
|
std::sort(this->messagesToBeAdded.begin(), this->messagesToBeAdded.end(), compareMessages);
|
||||||
|
|
||||||
|
if (!this->messagesToBeAdded.isEmpty()) {
|
||||||
this->insertMessages();
|
this->insertMessages();
|
||||||
|
}
|
||||||
this->messagesMutex.unlock();
|
this->messagesMutex.unlock();
|
||||||
|
|
||||||
// First call only returns a few messages, we need to get a little more than that...
|
// 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...");
|
LOG("Only a few messages received in first call, loading more...");
|
||||||
this->inReload = true;
|
this->inReload = true;
|
||||||
this->tdLibWrapper->getChatHistory(this->chatId, this->messagesToBeAdded.first().toMap().value(ID).toLongLong());
|
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)
|
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");
|
LOG("New message received for this chat");
|
||||||
this->messagesMutex.lock();
|
this->messagesMutex.lock();
|
||||||
|
|
||||||
|
@ -199,7 +218,7 @@ void ChatModel::handleChatReadInboxUpdated(const QString &id, const QString &las
|
||||||
if (id.toLongLong() == chatId) {
|
if (id.toLongLong() == chatId) {
|
||||||
LOG("Updating chat unread count, unread messages" << unreadCount << ", last read message ID:" << lastReadInboxMessageId);
|
LOG("Updating chat unread count, unread messages" << unreadCount << ", last read message ID:" << lastReadInboxMessageId);
|
||||||
this->chatInformation.insert("unread_count", unreadCount);
|
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);
|
emit unreadCountUpdated(unreadCount, lastReadInboxMessageId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -299,11 +318,16 @@ void ChatModel::insertMessages()
|
||||||
endResetModel();
|
endResetModel();
|
||||||
} else {
|
} else {
|
||||||
// There is only an append or a prepend, tertium non datur! (probably ;))
|
// 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
|
// Append
|
||||||
|
LOG("Appending new messages...");
|
||||||
this->insertRows(rowCount(QModelIndex()), this->messagesToBeAdded.size());
|
this->insertRows(rowCount(QModelIndex()), this->messagesToBeAdded.size());
|
||||||
} else {
|
} else {
|
||||||
// Prepend
|
// Prepend
|
||||||
|
LOG("Prepending new messages...");
|
||||||
this->insertRows(0, this->messagesToBeAdded.size());
|
this->insertRows(0, this->messagesToBeAdded.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -343,7 +367,7 @@ QVariantMap ChatModel::enhanceMessage(const QVariantMap &message)
|
||||||
int ChatModel::calculateLastKnownMessageId()
|
int ChatModel::calculateLastKnownMessageId()
|
||||||
{
|
{
|
||||||
LOG("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("lastKnownMessageId" << lastKnownMessageId);
|
||||||
LOG("size messageIndexMap" << messageIndexMap.size());
|
LOG("size messageIndexMap" << messageIndexMap.size());
|
||||||
LOG("contains ID?" << messageIndexMap.contains(lastKnownMessageId));
|
LOG("contains ID?" << messageIndexMap.contains(lastKnownMessageId));
|
||||||
|
|
|
@ -41,8 +41,10 @@ public:
|
||||||
|
|
||||||
Q_INVOKABLE void initialize(const QVariantMap &chatInformation);
|
Q_INVOKABLE void initialize(const QVariantMap &chatInformation);
|
||||||
Q_INVOKABLE void triggerLoadMoreHistory();
|
Q_INVOKABLE void triggerLoadMoreHistory();
|
||||||
|
Q_INVOKABLE void triggerLoadMoreFuture();
|
||||||
Q_INVOKABLE QVariantMap getChatInformation();
|
Q_INVOKABLE QVariantMap getChatInformation();
|
||||||
Q_INVOKABLE QVariantMap getMessage(int index);
|
Q_INVOKABLE QVariantMap getMessage(int index);
|
||||||
|
Q_INVOKABLE int getLastReadMessageIndex();
|
||||||
QVariantMap smallPhoto() const;
|
QVariantMap smallPhoto() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
|
@ -321,14 +321,12 @@
|
||||||
<source>%n Messages deleted</source>
|
<source>%n Messages deleted</source>
|
||||||
<translation type="unfinished">
|
<translation type="unfinished">
|
||||||
<numerusform></numerusform>
|
<numerusform></numerusform>
|
||||||
<numerusform></numerusform>
|
|
||||||
</translation>
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
<message numerus="yes">
|
<message numerus="yes">
|
||||||
<source>%n messages have been copied</source>
|
<source>%n messages have been copied</source>
|
||||||
<translation type="unfinished">
|
<translation type="unfinished">
|
||||||
<numerusform></numerusform>
|
<numerusform></numerusform>
|
||||||
<numerusform></numerusform>
|
|
||||||
</translation>
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
<message numerus="yes">
|
<message numerus="yes">
|
||||||
|
@ -336,7 +334,6 @@
|
||||||
<comment>number of messages selected</comment>
|
<comment>number of messages selected</comment>
|
||||||
<translation type="unfinished">
|
<translation type="unfinished">
|
||||||
<numerusform></numerusform>
|
<numerusform></numerusform>
|
||||||
<numerusform></numerusform>
|
|
||||||
</translation>
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
<message numerus="yes">
|
<message numerus="yes">
|
||||||
|
@ -344,7 +341,6 @@
|
||||||
<comment>dialog header</comment>
|
<comment>dialog header</comment>
|
||||||
<translation type="unfinished">
|
<translation type="unfinished">
|
||||||
<numerusform></numerusform>
|
<numerusform></numerusform>
|
||||||
<numerusform></numerusform>
|
|
||||||
</translation>
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
@ -941,7 +937,6 @@
|
||||||
<source>Question (%n1 characters left)</source>
|
<source>Question (%n1 characters left)</source>
|
||||||
<translation type="unfinished">
|
<translation type="unfinished">
|
||||||
<numerusform></numerusform>
|
<numerusform></numerusform>
|
||||||
<numerusform></numerusform>
|
|
||||||
</translation>
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
|
@ -957,7 +952,6 @@
|
||||||
<source>Answer (%n1 characters left)</source>
|
<source>Answer (%n1 characters left)</source>
|
||||||
<translation type="unfinished">
|
<translation type="unfinished">
|
||||||
<numerusform></numerusform>
|
<numerusform></numerusform>
|
||||||
<numerusform></numerusform>
|
|
||||||
</translation>
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
|
@ -1006,7 +1000,6 @@
|
||||||
<comment>number of total votes</comment>
|
<comment>number of total votes</comment>
|
||||||
<translation type="unfinished">
|
<translation type="unfinished">
|
||||||
<numerusform></numerusform>
|
<numerusform></numerusform>
|
||||||
<numerusform></numerusform>
|
|
||||||
</translation>
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
|
@ -1033,7 +1026,6 @@
|
||||||
<comment>number of total votes</comment>
|
<comment>number of total votes</comment>
|
||||||
<translation type="unfinished">
|
<translation type="unfinished">
|
||||||
<numerusform></numerusform>
|
<numerusform></numerusform>
|
||||||
<numerusform></numerusform>
|
|
||||||
</translation>
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
|
@ -1051,7 +1043,6 @@
|
||||||
<comment>number of votes for option</comment>
|
<comment>number of votes for option</comment>
|
||||||
<translation type="unfinished">
|
<translation type="unfinished">
|
||||||
<numerusform></numerusform>
|
<numerusform></numerusform>
|
||||||
<numerusform></numerusform>
|
|
||||||
</translation>
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
|
@ -1069,7 +1060,6 @@
|
||||||
<comment>number of votes for option</comment>
|
<comment>number of votes for option</comment>
|
||||||
<translation type="unfinished">
|
<translation type="unfinished">
|
||||||
<numerusform></numerusform>
|
<numerusform></numerusform>
|
||||||
<numerusform></numerusform>
|
|
||||||
</translation>
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
|
Loading…
Reference in a new issue