Autosearch

Make the user search automatically. This includes a timer to ensure that we aren't constantly pinging the server as the user types, the search is started 0.5s after the user stops typing. The `PublicRoomListModel` is upgraded to work in the same manner as it was architected slightly differently.
This commit is contained in:
James Graham
2024-01-21 11:24:40 +00:00
parent 538cfbee8d
commit f48c2a21d9
5 changed files with 63 additions and 23 deletions

View File

@@ -324,6 +324,15 @@ ecm_qt_declare_logging_category(neochat
EXPORT NEOCHAT EXPORT NEOCHAT
) )
ecm_qt_declare_logging_category(neochat
HEADER "publicroomlist_logging.h"
IDENTIFIER "PublicRoomList"
CATEGORY_NAME "org.kde.neochat.publicroomlistmodel"
DESCRIPTION "Neochat: publicroomlistmodel"
DEFAULT_SEVERITY Info
EXPORT NEOCHAT
)
ecm_qt_declare_logging_category(neochat ecm_qt_declare_logging_category(neochat
HEADER "eventhandler_logging.h" HEADER "eventhandler_logging.h"
IDENTIFIER "EventHandling" IDENTIFIER "EventHandling"

View File

@@ -5,6 +5,8 @@
#include <Quotient/connection.h> #include <Quotient/connection.h>
#include "publicroomlist_logging.h"
using namespace Quotient; using namespace Quotient;
PublicRoomListModel::PublicRoomListModel(QObject *parent) PublicRoomListModel::PublicRoomListModel(QObject *parent)
@@ -70,7 +72,6 @@ void PublicRoomListModel::setServer(const QString &value)
nextBatch = QString(); nextBatch = QString();
attempted = false; attempted = false;
rooms.clear(); rooms.clear();
Q_EMIT searchingChanged();
endResetModel(); endResetModel();
@@ -99,26 +100,16 @@ void PublicRoomListModel::setSearchText(const QString &value)
} }
m_searchText = value; m_searchText = value;
Q_EMIT searchTextChanged();
beginResetModel();
nextBatch = QString(); nextBatch = QString();
attempted = false; attempted = false;
rooms.clear();
endResetModel();
if (job) { if (job) {
job->abandon(); job->abandon();
job = nullptr; job = nullptr;
Q_EMIT searchingChanged(); Q_EMIT searchingChanged();
} }
if (m_connection) {
next();
}
Q_EMIT searchTextChanged();
} }
bool PublicRoomListModel::showOnlySpaces() const bool PublicRoomListModel::showOnlySpaces() const
@@ -135,15 +126,28 @@ void PublicRoomListModel::setShowOnlySpaces(bool showOnlySpaces)
Q_EMIT showOnlySpacesChanged(); Q_EMIT showOnlySpacesChanged();
} }
void PublicRoomListModel::next(int count) void PublicRoomListModel::search(int limit)
{ {
if (count < 1) { if (limit < 1 || attempted) {
return; return;
} }
if (job) { if (job) {
qDebug() << "PublicRoomListModel: Other jobs running, ignore"; qCDebug(PublicRoomList) << "Other job running, ignore";
return;
}
next(limit);
}
void PublicRoomListModel::next(int limit)
{
if (m_connection == nullptr || limit < 1) {
return;
}
if (job) {
qCDebug(PublicRoomList) << "Other job running, ignore";
return; return;
} }
@@ -151,11 +155,17 @@ void PublicRoomListModel::next(int count)
if (m_showOnlySpaces) { if (m_showOnlySpaces) {
roomTypes += QLatin1String("m.space"); roomTypes += QLatin1String("m.space");
} }
job = m_connection->callApi<QueryPublicRoomsJob>(m_server, count, nextBatch, QueryPublicRoomsJob::Filter{m_searchText, roomTypes}); job = m_connection->callApi<QueryPublicRoomsJob>(m_server, limit, nextBatch, QueryPublicRoomsJob::Filter{m_searchText, roomTypes});
Q_EMIT searchingChanged(); Q_EMIT searchingChanged();
connect(job, &BaseJob::finished, this, [this] { connect(job, &BaseJob::finished, this, [this] {
attempted = true; if (!attempted) {
beginResetModel();
rooms.clear();
endResetModel();
attempted = true;
}
if (job->status() == BaseJob::Success) { if (job->status() == BaseJob::Success) {
nextBatch = job->nextBatch(); nextBatch = job->nextBatch();
@@ -177,8 +187,7 @@ QVariant PublicRoomListModel::data(const QModelIndex &index, int role) const
} }
if (index.row() >= rooms.count()) { if (index.row() >= rooms.count()) {
qDebug() << "PublicRoomListModel, something's wrong: index.row() >= " qCDebug(PublicRoomList) << "something's wrong: index.row() >= rooms.count()";
"rooms.count()";
return {}; return {};
} }
auto room = rooms.at(index.row()); auto room = rooms.at(index.row());
@@ -267,7 +276,7 @@ int PublicRoomListModel::rowCount(const QModelIndex &parent) const
bool PublicRoomListModel::canFetchMore(const QModelIndex &parent) const bool PublicRoomListModel::canFetchMore(const QModelIndex &parent) const
{ {
Q_UNUSED(parent) Q_UNUSED(parent)
return !(attempted && nextBatch.isEmpty()); return !nextBatch.isEmpty();
} }
void PublicRoomListModel::fetchMore(const QModelIndex &parent) void PublicRoomListModel::fetchMore(const QModelIndex &parent)

View File

@@ -108,6 +108,13 @@ public:
[[nodiscard]] bool searching() const; [[nodiscard]] bool searching() const;
/**
* @brief Search the room directory.
*
* @param limit the maximum number of rooms to load.
*/
Q_INVOKABLE void search(int limit = 50);
private: private:
QPointer<Quotient::Connection> m_connection = nullptr; QPointer<Quotient::Connection> m_connection = nullptr;
QString m_server; QString m_server;
@@ -117,9 +124,9 @@ private:
/** /**
* @brief Load the next set of rooms. * @brief Load the next set of rooms.
* *
* @param count the maximum number of rooms to load. * @param limit the maximum number of rooms to load.
*/ */
void next(int count = 50); void next(int limit = 50);
bool canFetchMore(const QModelIndex &parent) const override; bool canFetchMore(const QModelIndex &parent) const override;
void fetchMore(const QModelIndex &parent) override; void fetchMore(const QModelIndex &parent) override;

View File

@@ -59,6 +59,12 @@ void UserDirectoryListModel::setSearchText(const QString &value)
m_searchText = value; m_searchText = value;
Q_EMIT searchTextChanged(); Q_EMIT searchTextChanged();
if (m_job) {
m_job->abandon();
m_job = nullptr;
Q_EMIT searchingChanged();
}
attempted = false; attempted = false;
} }

View File

@@ -110,6 +110,7 @@ Kirigami.ScrollablePage {
Keys.onEnterPressed: searchButton.clicked() Keys.onEnterPressed: searchButton.clicked()
Keys.onReturnPressed: searchButton.clicked() Keys.onReturnPressed: searchButton.clicked()
onTextChanged: { onTextChanged: {
searchTimer.restart()
if (model) { if (model) {
model.searchText = text; model.searchText = text;
} }
@@ -124,6 +125,14 @@ Kirigami.ScrollablePage {
} }
} }
} }
Timer {
id: searchTimer
interval: 500
running: true
onTriggered: if (typeof model.search === 'function') {
model.search()
}
}
} }
} }
@@ -149,7 +158,7 @@ Kirigami.ScrollablePage {
Kirigami.LoadingPlaceholder { Kirigami.LoadingPlaceholder {
anchors.centerIn: parent anchors.centerIn: parent
visible: root.model.searching visible: searchField.text.length > 0 && listView.count === 0 && root.model.searching
} }
} }
} }