diff --git a/qml/pages/OverviewPage.qml b/qml/pages/OverviewPage.qml index 5d8739e..43fde30 100644 --- a/qml/pages/OverviewPage.qml +++ b/qml/pages/OverviewPage.qml @@ -48,6 +48,16 @@ Page { running: overviewPage.loading } + Timer { + id: chatListSorterTimer + interval: 1000 + running: false + repeat: false + onTriggered: { + chatListModel.updateSorting(); + } + } + function setPageStatus() { switch (overviewPage.connectionState) { case TelegramAPI.WaitingForNetwork: @@ -117,6 +127,10 @@ Page { onOwnUserIdFound: { overviewPage.ownUserId = ownUserId; } + onChatOrderUpdated: { + chatListSorterTimer.stop(); + chatListSorterTimer.start(); + } } Component.onCompleted: { diff --git a/src/chatlistmodel.cpp b/src/chatlistmodel.cpp index 2b665ed..bad3d51 100644 --- a/src/chatlistmodel.cpp +++ b/src/chatlistmodel.cpp @@ -6,7 +6,7 @@ ChatListModel::ChatListModel(TDLibWrapper *tdLibWrapper) this->tdLibWrapper = tdLibWrapper; connect(this->tdLibWrapper, SIGNAL(newChatDiscovered(QString, QVariantMap)), this, SLOT(handleChatDiscovered(QString, QVariantMap))); connect(this->tdLibWrapper, SIGNAL(chatLastMessageUpdated(QString, QVariantMap)), this, SLOT(handleChatLastMessageUpdated(QString, QVariantMap))); - // connect(this->tdLibWrapper, SIGNAL(chatOrderUpdated(QString, QString)), this, SLOT(handleChatOrderUpdated(QString, QString))); + connect(this->tdLibWrapper, SIGNAL(chatOrderUpdated(QString, QString)), this, SLOT(handleChatOrderUpdated(QString, QString))); } ChatListModel::~ChatListModel() @@ -37,46 +37,68 @@ bool ChatListModel::insertRows(int row, int count, const QModelIndex &parent) return true; } +bool compareChats(const QVariant &chat1, const QVariant &chat2) +{ + QVariantMap chatMap1 = chat1.toMap(); + QVariantMap chatMap2 = chat2.toMap(); + // Order comes first... + if (chatMap1.value("order").toLongLong() > chatMap2.value("order").toLongLong()) { + return true; + } + // ID comes next... + if (chatMap1.value("order").toLongLong() == chatMap2.value("order").toLongLong() && chatMap1.value("id").toLongLong() > chatMap2.value("id").toLongLong()) { + return true; + } else { + return false; + } +} + +void ChatListModel::updateSorting() +{ + this->chatListMutex.lock(); + qDebug() << "[ChatListModel] List sorting will be updated..."; + + beginResetModel(); + 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); + } + endResetModel(); + this->chatListMutex.unlock(); +} + void ChatListModel::handleChatDiscovered(const QString &chatId, const QVariantMap &chatInformation) { + this->chatListMutex.lock(); qDebug() << "[ChatListModel] Adding new chat " << chatId; this->chatToBeAdded = chatInformation; insertRows(rowCount(QModelIndex()), 1); + this->chatListMutex.unlock(); } void ChatListModel::handleChatLastMessageUpdated(const QString &chatId, const QVariantMap &lastMessage) { + this->chatListMutex.lock(); int chatIndex = this->chatIndexMap.value(chatId).toInt(); qDebug() << "[ChatListModel] Updating last message for chat " << chatId << " at index " << chatIndex; QVariantMap currentChat = this->chatList.value(chatIndex).toMap(); currentChat.insert("last_message", lastMessage); this->chatList.replace(chatIndex, currentChat); emit dataChanged(this->index(chatIndex), this->index(chatIndex)); + this->chatListMutex.unlock(); } void ChatListModel::handleChatOrderUpdated(const QString &chatId, const QString &order) { - qDebug() << "[ChatListModel] Updating chat order because of " << chatId << " , new order " << order; + this->chatListMutex.lock(); + qDebug() << "[ChatListModel] Updating chat order because of " << chatId << " new order " << order; int currentChatIndex = this->chatIndexMap.value(chatId).toInt(); - int otherChatIndex = 0; - QListIterator currentChatIterator(this->chatList); - while (currentChatIterator.hasNext()) { - QVariantMap otherChat = currentChatIterator.next().toMap(); - QString otherOrder = otherChat.value("order").toString(); - if (otherOrder < order) { - // Our chat gets reordered to the position of the other chat - otherChatIndex = this->chatIndexMap.value(otherChat.value("id").toString()).toInt(); - qDebug() << "[ChatListModel] Old position: " << currentChatIndex << "- new position " << otherChatIndex; - break; - } - } - this->chatList.move(currentChatIndex, otherChatIndex); - this->chatIndexMap.clear(); - QListIterator newChatIterator(this->chatList); - int currentIndex = 0; - while (newChatIterator.hasNext()) { - QVariantMap currentChat = newChatIterator.next().toMap(); - this->chatIndexMap.insert(currentChat.value("id").toString(), currentIndex); - currentIndex++; - } + QVariantMap currentChat = this->chatList.at(currentChatIndex).toMap(); + currentChat.insert("order", order); + this->chatList.replace(currentChatIndex, currentChat); + emit dataChanged(this->index(currentChatIndex), this->index(currentChatIndex)); + this->chatListMutex.unlock(); } diff --git a/src/chatlistmodel.h b/src/chatlistmodel.h index 8a0e9ae..60ce5b8 100644 --- a/src/chatlistmodel.h +++ b/src/chatlistmodel.h @@ -3,6 +3,7 @@ #include #include +#include #include "tdlibwrapper.h" class ChatListModel : public QAbstractListModel @@ -16,6 +17,8 @@ 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 QVariantMap &lastMessage); @@ -26,6 +29,8 @@ private: QVariantList chatList; QVariantMap chatToBeAdded; QVariantMap chatIndexMap; + QMutex chatListMutex; + }; #endif // CHATLISTMODEL_H