diff --git a/qml/pages/OverviewPage.qml b/qml/pages/OverviewPage.qml index f4cb319..548beda 100644 --- a/qml/pages/OverviewPage.qml +++ b/qml/pages/OverviewPage.qml @@ -48,16 +48,6 @@ Page { running: overviewPage.loading } - Timer { - id: chatListSorterTimer - interval: 100 - running: false - repeat: false - onTriggered: { - chatListModel.updateSorting(); - } - } - function setPageStatus() { switch (overviewPage.connectionState) { case TelegramAPI.WaitingForNetwork: @@ -131,10 +121,6 @@ Page { chatListSorterTimer.stop(); chatListSorterTimer.start(); } - onChatLastMessageUpdated: { - chatListSorterTimer.stop(); - chatListSorterTimer.start(); - } } Component.onCompleted: { diff --git a/src/chatlistmodel.cpp b/src/chatlistmodel.cpp index 6e27101..ab6a151 100644 --- a/src/chatlistmodel.cpp +++ b/src/chatlistmodel.cpp @@ -53,23 +53,6 @@ bool compareChats(const QVariant &chat1, const QVariant &chat2) } } -void ChatListModel::updateSorting() -{ - this->chatListMutex.lock(); - qDebug() << "[ChatListModel] List sorting will be updated..."; - - emit layoutAboutToBeChanged(); - std::sort(this->chatList.begin(), this->chatList.end(), compareChats); - - this->chatIndexMap.clear(); - for (int i = 0; i < this->chatList.length(); i++) { - QString currentChatId = this->chatList.at(i).toMap().value("id").toString(); - this->chatIndexMap.insert(currentChatId, i); - } - emit layoutChanged(); - this->chatListMutex.unlock(); -} - void ChatListModel::handleChatDiscovered(const QString &chatId, const QVariantMap &chatInformation) { this->chatListMutex.lock(); @@ -79,6 +62,8 @@ void ChatListModel::handleChatDiscovered(const QString &chatId, const QVariantMa this->chatListMutex.unlock(); } + + void ChatListModel::handleChatLastMessageUpdated(const QString &chatId, const QString &order, const QVariantMap &lastMessage) { this->chatListMutex.lock(); @@ -89,6 +74,9 @@ void ChatListModel::handleChatLastMessageUpdated(const QString &chatId, const QS currentChat.insert("order", order); this->chatList.replace(chatIndex, currentChat); emit dataChanged(this->index(chatIndex), this->index(chatIndex)); + + this->updateChatOrder(chatIndex, currentChat); + this->chatListMutex.unlock(); } @@ -96,10 +84,40 @@ void ChatListModel::handleChatOrderUpdated(const QString &chatId, const QString { this->chatListMutex.lock(); qDebug() << "[ChatListModel] Updating chat order because of " << chatId << " new order " << order; - int currentChatIndex = this->chatIndexMap.value(chatId).toInt(); - QVariantMap currentChat = this->chatList.at(currentChatIndex).toMap(); + int chatIndex = this->chatIndexMap.value(chatId).toInt(); + QVariantMap currentChat = this->chatList.at(chatIndex).toMap(); currentChat.insert("order", order); - this->chatList.replace(currentChatIndex, currentChat); - emit dataChanged(this->index(currentChatIndex), this->index(currentChatIndex)); + this->chatList.replace(chatIndex, currentChat); + emit dataChanged(this->index(chatIndex), this->index(chatIndex)); + + this->updateChatOrder(chatIndex, currentChat); + this->chatListMutex.unlock(); } + +void ChatListModel::updateChatOrder(const int ¤tChatIndex, const QVariantMap &updatedChat) +{ + // Finding the new position manually as information is needed by beginMoveRows() + // This seems to be the most convenient way of persisting the list position while changing the items + // Other alternative layoutChanged() after sorting resets the index position - there we would need to calculate the new position as well + // If somebody has a better solution - go for it ;) + int newChatIndex = 0; + for (int i = 0; i < this->chatList.length(); i++) { + QVariantMap otherChat = this->chatList.at(i).toMap(); + if (compareChats(updatedChat, otherChat)) { + newChatIndex = i; + break; + } + } + if (newChatIndex != currentChatIndex) { + // The updated chat now needs to go to the position of the other chat + qDebug() << "[ChatListModel] Chat " << updatedChat.value("id").toString() << " will be moved from position " << currentChatIndex << " to " << newChatIndex; + beginMoveRows(QModelIndex(), currentChatIndex, currentChatIndex, QModelIndex(), (( newChatIndex < currentChatIndex ) ? newChatIndex : ( newChatIndex + 1 ))); + std::sort(this->chatList.begin(), this->chatList.end(), compareChats); + this->chatIndexMap.clear(); + for (int i = 0; i < this->chatList.length(); i++) { + this->chatIndexMap.insert(this->chatList.at(i).toMap().value("id").toString(), i); + } + endMoveRows(); + } +} diff --git a/src/chatlistmodel.h b/src/chatlistmodel.h index b83fc1a..c029223 100644 --- a/src/chatlistmodel.h +++ b/src/chatlistmodel.h @@ -17,8 +17,6 @@ public: virtual QVariant data(const QModelIndex &index, int role) const override; virtual bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; - Q_INVOKABLE void updateSorting(); - public slots: void handleChatDiscovered(const QString &chatId, const QVariantMap &chatInformation); void handleChatLastMessageUpdated(const QString &chatId, const QString &order, const QVariantMap &lastMessage); @@ -31,6 +29,8 @@ private: QVariantMap chatIndexMap; QMutex chatListMutex; + void updateChatOrder(const int ¤tChatIndex, const QVariantMap &updatedChat); + }; #endif // CHATLISTMODEL_H