Use fetchMore for native lazy loading of item model data

This commit is contained in:
Nicolas Werner 2020-01-06 16:42:56 +01:00
parent 946ab4d0f2
commit 5af6f6528b
3 changed files with 48 additions and 37 deletions

View File

@ -93,13 +93,9 @@ Item {
currentIndex = newIndex currentIndex = newIndex
model.currentIndex = newIndex model.currentIndex = newIndex
} }
if (contentHeight < height && model) {
model.fetchHistory();
}
} }
onAtYBeginningChanged: if (atYBeginning) { chat.model.currentIndex = 0; chat.currentIndex = 0; model.fetchHistory(); } onAtYBeginningChanged: if (atYBeginning) { chat.model.currentIndex = 0; chat.currentIndex = 0; }
function updatePosition() { function updatePosition() {
for (var y = chat.contentY + chat.height; y > chat.height; y -= 9) { for (var y = chat.contentY + chat.height; y > chat.height; y -= 9) {

View File

@ -349,6 +349,50 @@ TimelineModel::data(const QModelIndex &index, int role) const
} }
} }
bool
TimelineModel::canFetchMore(const QModelIndex &) const
{
if (eventOrder.empty())
return true;
if (!std::holds_alternative<mtx::events::StateEvent<mtx::events::state::Create>>(
events[eventOrder.back()]))
return true;
else
return false;
}
void
TimelineModel::fetchMore(const QModelIndex &)
{
if (paginationInProgress) {
nhlog::ui()->warn("Already loading older messages");
return;
}
paginationInProgress = true;
mtx::http::MessagesOpts opts;
opts.room_id = room_id_.toStdString();
opts.from = prev_batch_token_.toStdString();
nhlog::ui()->debug("Paginationg room {}", opts.room_id);
http::client()->messages(
opts, [this, opts](const mtx::responses::Messages &res, mtx::http::RequestErr err) {
if (err) {
nhlog::net()->error("failed to call /messages ({}): {} - {}",
opts.room_id,
mtx::errors::to_string(err->matrix_error.errcode),
err->matrix_error.error);
paginationInProgress = false;
return;
}
emit oldMessagesRetrieved(std::move(res));
paginationInProgress = false;
});
}
void void
TimelineModel::addEvents(const mtx::responses::Timeline &timeline) TimelineModel::addEvents(const mtx::responses::Timeline &timeline)
{ {
@ -465,37 +509,6 @@ TimelineModel::internalAddEvents(
return ids; return ids;
} }
void
TimelineModel::fetchHistory()
{
if (paginationInProgress) {
nhlog::ui()->warn("Already loading older messages");
return;
}
paginationInProgress = true;
mtx::http::MessagesOpts opts;
opts.room_id = room_id_.toStdString();
opts.from = prev_batch_token_.toStdString();
nhlog::ui()->info("Paginationg room {}", opts.room_id);
http::client()->messages(
opts, [this, opts](const mtx::responses::Messages &res, mtx::http::RequestErr err) {
if (err) {
nhlog::net()->error("failed to call /messages ({}): {} - {}",
opts.room_id,
mtx::errors::to_string(err->matrix_error.errcode),
err->matrix_error.error);
paginationInProgress = false;
return;
}
emit oldMessagesRetrieved(std::move(res));
paginationInProgress = false;
});
}
void void
TimelineModel::setCurrentIndex(int index) TimelineModel::setCurrentIndex(int index)
{ {

View File

@ -154,6 +154,9 @@ public:
int rowCount(const QModelIndex &parent = QModelIndex()) const override; int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
bool canFetchMore(const QModelIndex &) const override;
void fetchMore(const QModelIndex &) override;
Q_INVOKABLE QColor userColor(QString id, QColor background); Q_INVOKABLE QColor userColor(QString id, QColor background);
Q_INVOKABLE QString displayName(QString id) const; Q_INVOKABLE QString displayName(QString id) const;
Q_INVOKABLE QString avatarUrl(QString id) const; Q_INVOKABLE QString avatarUrl(QString id) const;
@ -175,7 +178,6 @@ public:
void sendMessage(const T &msg); void sendMessage(const T &msg);
public slots: public slots:
void fetchHistory();
void setCurrentIndex(int index); void setCurrentIndex(int index);
int currentIndex() const { return idToIndex(currentId); } int currentIndex() const { return idToIndex(currentId); }
void markEventsAsRead(const std::vector<QString> &event_ids); void markEventsAsRead(const std::vector<QString> &event_ids);