diff --git a/linphone-app/src/components/chat-room/ChatRoomModel.cpp b/linphone-app/src/components/chat-room/ChatRoomModel.cpp index fa6e60b02..2e67c30d8 100644 --- a/linphone-app/src/components/chat-room/ChatRoomModel.cpp +++ b/linphone-app/src/components/chat-room/ChatRoomModel.cpp @@ -638,10 +638,10 @@ void ChatRoomModel::initEntries(){ if(!mIsInitialized){ QList > entries; // Get chat messages - for (auto &message : mChatRoom->getHistory(0)) + for (auto &message : mChatRoom->getHistory(mLastEntriesCount)) entries << ChatMessageModel::create(message, this); // Get events - for(auto &eventLog : mChatRoom->getHistoryEvents(0)){ + for(auto &eventLog : mChatRoom->getHistoryEvents(mLastEntriesCount)){ auto entry = ChatNoticeModel::create(eventLog, this); if(entry) entries << entry; @@ -666,6 +666,43 @@ void ChatRoomModel::initEntries(){ } } +void ChatRoomModel::loadMoreEntries(){ + mLastEntriesCount += mLastEntriesStep; +// Messages + QList> messagesToAdd; + for (auto &message : mChatRoom->getHistory(mLastEntriesCount)){ + auto itEntries = mEntries.begin(); + bool haveEntry = false; + while(!haveEntry && itEntries != mEntries.end()){ + auto entry = dynamic_cast(itEntries->get()); + haveEntry = (entry && entry->getChatMessage() == message); + ++itEntries; + } + if(!haveEntry) + messagesToAdd << message; + } + +// Notices + QList> noticesToAdd; + for (auto &eventLog : mChatRoom->getHistoryEvents(mLastEntriesCount)){ + auto itEntries = mEntries.begin(); + bool haveEntry = false; + while(!haveEntry && itEntries != mEntries.end()){ + auto entry = dynamic_cast(itEntries->get()); + haveEntry = (entry && entry->getEventLog() == eventLog); + ++itEntries; + } + if(!haveEntry) + noticesToAdd << eventLog; + } + if(messagesToAdd.size() > 0) + insertMessages(messagesToAdd); + if(noticesToAdd.size() > 0) + insertNotices(noticesToAdd); + if( messagesToAdd.size() == 0 && noticesToAdd.size() == 0) + mLastEntriesCount = mEntries.size(); // We reset last antries count to current events size to avoid overflow count +} + // ----------------------------------------------------------------------------- @@ -704,9 +741,27 @@ void ChatRoomModel::insertMessageAtEnd (const shared_ptr } } -void ChatRoomModel::insertNotice (const std::shared_ptr &enventLog) { +void ChatRoomModel::insertMessages (const QList > &messages) { if(mIsInitialized){ - std::shared_ptr model = ChatNoticeModel::create(enventLog, this); + QList > entries; + for(auto message : messages) { + std::shared_ptr model = ChatMessageModel::create(message, this); + if(model) + entries << model; + } + if(entries.size() > 0){ + setUnreadMessagesCount(mChatRoom->getUnreadMessagesCount()); + beginInsertRows(QModelIndex(), 0, entries.size()-1); + entries << mEntries; + mEntries = entries; + endInsertRows(); + } + } +} + +void ChatRoomModel::insertNotice (const std::shared_ptr &eventLog) { + if(mIsInitialized){ + std::shared_ptr model = ChatNoticeModel::create(eventLog, this); if(model){ int row = mEntries.count(); beginInsertRows(QModelIndex(), row, row); @@ -716,6 +771,24 @@ void ChatRoomModel::insertNotice (const std::shared_ptr &env } } +void ChatRoomModel::insertNotices (const QList> &eventLogs) { + if(mIsInitialized){ + QList > entries; + + for(auto eventLog : eventLogs) { + std::shared_ptr model = ChatNoticeModel::create(eventLog, this); + if(model) + entries << model; + } + + if(entries.size() > 0){ + beginInsertRows(QModelIndex(), 0, entries.size()-1); + entries << mEntries; + mEntries = entries; + endInsertRows(); + } + } +} // ----------------------------------------------------------------------------- void ChatRoomModel::handleCallStateChanged (const shared_ptr &call, linphone::Call::State state) { diff --git a/linphone-app/src/components/chat-room/ChatRoomModel.hpp b/linphone-app/src/components/chat-room/ChatRoomModel.hpp index 2d334ccb7..8e4581f5d 100644 --- a/linphone-app/src/components/chat-room/ChatRoomModel.hpp +++ b/linphone-app/src/components/chat-room/ChatRoomModel.hpp @@ -212,13 +212,16 @@ public: void compose (); void resetMessageCount (); Q_INVOKABLE void initEntries(); + Q_INVOKABLE void loadMoreEntries(); QDateTime mLastUpdateTime; int mUnreadMessagesCount = 0; int mMissedCallsCount = 0; bool mIsInitialized = false; - bool mDeleteChatRoom = false; // Use as workaround because of core->deleteChatRoom() that call destructor without takking account of count ref : call it in ChatRoomModel destructor + bool mDeleteChatRoom = false; // Use as workaround because of core->deleteChatRoom() that call destructor without takking account of count ref : call it in ChatRoomModel destructor + int mLastEntriesCount = 50; // Retrieve a part of the history to avoid too much processing + int mLastEntriesStep = 50; // Message loading Step //-------------------- CHAT ROOM HANDLER @@ -302,7 +305,9 @@ signals: private: void insertCall (const std::shared_ptr &callLog); void insertMessageAtEnd (const std::shared_ptr &message); + void insertMessages (const QList > &messages); void insertNotice (const std::shared_ptr &enventLog); + void insertNotices (const QList> &eventLogs); void handleCallStateChanged (const std::shared_ptr &call, linphone::Call::State state); void handleCallCreated(const std::shared_ptr &call);// Count an event call diff --git a/linphone-app/src/components/chat-room/ChatRoomProxyModel.cpp b/linphone-app/src/components/chat-room/ChatRoomProxyModel.cpp index 782649849..8848fea6b 100644 --- a/linphone-app/src/components/chat-room/ChatRoomProxyModel.cpp +++ b/linphone-app/src/components/chat-room/ChatRoomProxyModel.cpp @@ -142,19 +142,15 @@ void ChatRoomProxyModel::compose (const QString& text) { void ChatRoomProxyModel::loadMoreEntries () { int count = rowCount(); int parentCount = sourceModel()->rowCount(); - - if (count < parentCount) { - // Do not increase `mMaxDisplayedEntries` if it's not necessary... - // Limit qml calls. - if (count == mMaxDisplayedEntries) + if (count == mMaxDisplayedEntries) mMaxDisplayedEntries += EntriesChunkSize; - - invalidateFilter(); - - count = rowCount() - count; + + if (count + 10 >= parentCount) // Magic number : try to load more entries if near to max event count + mChatRoomModel->loadMoreEntries(); + invalidateFilter(); + count = rowCount() - count; if (count > 0) emit moreEntriesLoaded(count); - } } void ChatRoomProxyModel::setEntryTypeFilter (int type) {