diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index e640e4ed9..49bc8c02f 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -35,6 +35,7 @@ set(SOURCES
src/app/DefaultTranslator.cpp
src/app/Logger.cpp
src/components/chat/ChatModel.cpp
+ src/components/chat/ChatModelFilter.cpp
src/components/chat/ChatProxyModel.cpp
src/components/contacts/ContactModel.cpp
src/components/contacts/ContactsListModel.cpp
@@ -55,6 +56,7 @@ set(HEADERS
src/app/DefaultTranslator.hpp
src/app/Logger.hpp
src/components/chat/ChatModel.hpp
+ src/components/chat/ChatModelFilter.hpp
src/components/chat/ChatProxyModel.hpp
src/components/contacts/ContactModel.hpp
src/components/contacts/ContactsListModel.hpp
diff --git a/tests/assets/languages/fr.ts b/tests/assets/languages/fr.ts
index ef856f80c..e6dd29cbd 100644
--- a/tests/assets/languages/fr.ts
+++ b/tests/assets/languages/fr.ts
@@ -139,7 +139,7 @@
removeAllEntriesTitle
- Suppression de l'historique
+ Suppression de l'historique
@@ -184,7 +184,7 @@
endedCall
- Fin d'appel
+ Fin d'appel
missedIncomingCall
diff --git a/tests/src/components/chat/ChatModelFilter.cpp b/tests/src/components/chat/ChatModelFilter.cpp
new file mode 100644
index 000000000..5dcb45e17
--- /dev/null
+++ b/tests/src/components/chat/ChatModelFilter.cpp
@@ -0,0 +1,19 @@
+#include "ChatProxyModel.hpp"
+
+// ===================================================================
+
+ChatModelFilter::ChatModelFilter (QObject *parent) : QSortFilterProxyModel(parent) {
+ setSourceModel(&m_chat_model);
+}
+
+bool ChatModelFilter::filterAcceptsRow (int source_row, const QModelIndex &source_parent) const {
+ if (m_entry_type_filter == ChatModel::EntryType::GenericEntry)
+ return true;
+
+ QModelIndex index = sourceModel()->index(source_row, 0, QModelIndex());
+ const QVariantMap &data = qvariant_cast(
+ index.data()
+ );
+
+ return data["type"].toInt() == m_entry_type_filter;
+}
diff --git a/tests/src/components/chat/ChatModelFilter.hpp b/tests/src/components/chat/ChatModelFilter.hpp
new file mode 100644
index 000000000..9dc79acb9
--- /dev/null
+++ b/tests/src/components/chat/ChatModelFilter.hpp
@@ -0,0 +1,35 @@
+#ifndef CHAT_MODEL_FILTER_H_
+#define CHAT_MODEL_FILTER_H_
+
+#include
+
+#include "ChatModel.hpp"
+#include
+
+// ===================================================================
+// Fetch K filtered chat entries.
+// ===================================================================
+
+class ChatModelFilter : public QSortFilterProxyModel {
+ friend class ChatProxyModel;
+
+ Q_OBJECT;
+
+public:
+ ChatModelFilter (QObject *parent = Q_NULLPTR);
+
+protected:
+ bool filterAcceptsRow (int source_row, const QModelIndex &source_parent) const;
+
+private:
+ void setEntryTypeFilter (ChatModel::EntryType type) {
+ m_entry_type_filter = type;
+ invalidateFilter();
+ }
+
+ ChatModel m_chat_model;
+
+ ChatModel::EntryType m_entry_type_filter = ChatModel::EntryType::GenericEntry;
+};
+
+#endif // CHAT_MODEL_FILTER_H_
diff --git a/tests/src/components/chat/ChatProxyModel.cpp b/tests/src/components/chat/ChatProxyModel.cpp
index 6d4e77777..5f81db84f 100644
--- a/tests/src/components/chat/ChatProxyModel.cpp
+++ b/tests/src/components/chat/ChatProxyModel.cpp
@@ -2,25 +2,37 @@
// ===================================================================
+const unsigned int ChatProxyModel::ENTRIES_CHUNK_SIZE = 25;
+
ChatProxyModel::ChatProxyModel (QObject *parent) : QSortFilterProxyModel(parent) {
- m_chat_model.setParent(this);
- setSourceModel(&m_chat_model);
+ setSourceModel(&m_chat_model_filter);
+}
+
+int ChatProxyModel::rowCount (const QModelIndex &parent) const {
+ int size = QSortFilterProxyModel::rowCount(parent);
+ return size < m_n_max_displayed_entries ? size : m_n_max_displayed_entries;
+}
+
+QVariant ChatProxyModel::data (const QModelIndex &index, int role) const {
+ QAbstractItemModel *model = sourceModel();
+
+ return model->data(
+ model->index(
+ mapToSource(index).row() + (model->rowCount() - rowCount()),
+ 0
+ ),
+ role
+ );
+}
+
+void ChatProxyModel::loadMoreEntries () {
+ // TODO.
}
void ChatProxyModel::removeEntry (int id) {
- m_chat_model.removeEntry(
- mapToSource(index(id, 0)).row()
+ QModelIndex source_index = mapToSource(index(id, 0));
+
+ static_cast(m_chat_model_filter.sourceModel())->removeEntry(
+ mapToSource(source_index).row()
);
}
-
-bool ChatProxyModel::filterAcceptsRow (int source_row, const QModelIndex &source_parent) const {
- if (m_entry_type_filter == ChatModel::EntryType::GenericEntry)
- return true;
-
- QModelIndex index = sourceModel()->index(source_row, 0, source_parent);
- const QVariantMap &data = qvariant_cast(
- index.data()
- );
-
- return data["type"].toInt() == m_entry_type_filter;
-}
diff --git a/tests/src/components/chat/ChatProxyModel.hpp b/tests/src/components/chat/ChatProxyModel.hpp
index 78f3a46f9..5a13dbf2c 100644
--- a/tests/src/components/chat/ChatProxyModel.hpp
+++ b/tests/src/components/chat/ChatProxyModel.hpp
@@ -1,10 +1,10 @@
#ifndef CHAT_PROXY_MODEL_H_
#define CHAT_PROXY_MODEL_H_
-#include
-
-#include "ChatModel.hpp"
+#include "ChatModelFilter.hpp"
+// ===================================================================
+// Fetch the L last filtered chat entries.
// ===================================================================
class ChatProxyModel : public QSortFilterProxyModel {
@@ -23,32 +23,38 @@ signals:
public:
ChatProxyModel (QObject *parent = Q_NULLPTR);
+ int rowCount (const QModelIndex &parent = QModelIndex()) const override;
+ QVariant data (const QModelIndex &index, int role) const override;
+
public slots:
+ void loadMoreEntries ();
+
+ void setEntryTypeFilter (ChatModel::EntryType type) {
+ m_chat_model_filter.setEntryTypeFilter(type);
+ }
+
void removeEntry (int id);
void removeAllEntries () {
- m_chat_model.removeAllEntries();
+ static_cast(m_chat_model_filter.sourceModel())->removeAllEntries();
}
- void setEntryTypeFilter (ChatModel::EntryType type) {
- m_entry_type_filter = type;
- invalidateFilter();
- }
-
-protected:
- bool filterAcceptsRow (int source_row, const QModelIndex &source_parent) const;
-
private:
QString getSipAddress () const {
- return m_chat_model.getSipAddress();
+ static_cast(m_chat_model_filter.sourceModel())->getSipAddress();
}
void setSipAddress (const QString &sip_address) {
- m_chat_model.setSipAddress(sip_address);
+ static_cast(m_chat_model_filter.sourceModel())->setSipAddress(
+ sip_address
+ );
}
- ChatModel m_chat_model;
- ChatModel::EntryType m_entry_type_filter = ChatModel::EntryType::GenericEntry;
+ ChatModelFilter m_chat_model_filter;
+
+ unsigned int m_n_max_displayed_entries = ENTRIES_CHUNK_SIZE;
+
+ static const unsigned int ENTRIES_CHUNK_SIZE;
};
#endif // CHAT_PROXY_MODEL_H_
diff --git a/tests/ui/modules/Linphone/Chat/Chat.qml b/tests/ui/modules/Linphone/Chat/Chat.qml
index 8ce0e83da..b0a50e0cf 100644
--- a/tests/ui/modules/Linphone/Chat/Chat.qml
+++ b/tests/ui/modules/Linphone/Chat/Chat.qml
@@ -21,6 +21,18 @@ ColumnLayout {
ScrollableListView {
id: chat
+ property bool _tryToLoadMoreEntries: false
+
+ function _loadMoreEntries () {
+ if (chat.contentY > 500 || _tryToLoadMoreEntries) {
+ return
+ }
+
+ _tryToLoadMoreEntries = true
+
+ proxyModel.loadMoreEntries()
+ }
+
Layout.fillHeight: true
Layout.fillWidth: true
@@ -164,6 +176,8 @@ ColumnLayout {
}
}
}
+
+ onContentYChanged: _loadMoreEntries()
}
// -----------------------------------------------------------------