From 22e766f214d3c514a2131d0aad8550e7cdc2e418 Mon Sep 17 00:00:00 2001 From: Tobias Fella Date: Sun, 31 May 2020 18:17:25 +0200 Subject: [PATCH] Implement pull-down refreshing in FeedListPage --- src/feed.cpp | 27 +++++++++++++++++++++++++++ src/feed.h | 6 ++++++ src/feedListModel.cpp | 7 +++++++ src/feedListModel.h | 1 + src/fetcher.cpp | 12 ++++++++++++ src/fetcher.h | 2 ++ src/qml/FeedListPage.qml | 28 ++++++++++++++++++++++++++-- 7 files changed, 81 insertions(+), 2 deletions(-) diff --git a/src/feed.cpp b/src/feed.cpp index 2cc78cc3..ef846d7b 100644 --- a/src/feed.cpp +++ b/src/feed.cpp @@ -22,6 +22,7 @@ #include "database.h" #include "feed.h" +#include "fetcher.h" Feed::Feed(QString url, QString name, QString image, QString link, QString description, QVector authors, QObject *parent) : QObject(parent) @@ -32,6 +33,16 @@ Feed::Feed(QString url, QString name, QString image, QString link, QString descr , m_description(description) , m_authors(authors) { + connect(&Fetcher::instance(), &Fetcher::startedFetchingFeed, this, [this] (QString url) { + if(url == m_url) { + setRefreshing(true); + } + }); + connect(&Fetcher::instance(), &Fetcher::feedUpdated, this, [this] (QString url) { + if(url == m_url) { + setRefreshing(false); + } + }); } Feed::~Feed() @@ -68,6 +79,11 @@ QVector Feed::authors() const return m_authors; } +bool Feed::refreshing() const +{ + return m_refreshing; +} + void Feed::setName(QString name) { m_name = name; @@ -98,6 +114,17 @@ void Feed::setAuthors(QVector authors) emit authorsChanged(m_authors); } +void Feed::setRefreshing(bool refreshing) +{ + m_refreshing = refreshing; + emit refreshingChanged(m_refreshing); +} + +void Feed::refresh() +{ + Fetcher::instance().fetch(m_url); +} + void Feed::remove() { // Delete Authors diff --git a/src/feed.h b/src/feed.h index 05665eb4..29a73b77 100644 --- a/src/feed.h +++ b/src/feed.h @@ -35,6 +35,7 @@ class Feed : public QObject Q_PROPERTY(QString link READ link WRITE setLink NOTIFY linkChanged) Q_PROPERTY(QString description READ description WRITE setDescription NOTIFY descriptionChanged) Q_PROPERTY(QVector authors READ authors WRITE setAuthors NOTIFY authorsChanged) + Q_PROPERTY(bool refreshing READ refreshing WRITE setRefreshing NOTIFY refreshingChanged) public: Feed(QString url, QString name, QString image, QString link, QString description, QVector authors, QObject *parent = nullptr); @@ -47,13 +48,16 @@ public: QString link() const; QString description() const; QVector authors() const; + bool refreshing() const; void setName(QString name); void setImage(QString image); void setLink(QString link); void setDescription(QString description); void setAuthors(QVector authors); + void setRefreshing(bool refreshing); + void refresh(); void remove(); Q_SIGNALS: @@ -62,6 +66,7 @@ Q_SIGNALS: void linkChanged(QString &link); void descriptionChanged(QString &description); void authorsChanged(QVector &authors); + void refreshingChanged(bool refreshing); private: QString m_url; @@ -70,6 +75,7 @@ private: QString m_link; QString m_description; QVector m_authors; + bool m_refreshing = false; }; #endif // FEED_H diff --git a/src/feedListModel.cpp b/src/feedListModel.cpp index fbc24690..ec508ba0 100644 --- a/src/feedListModel.cpp +++ b/src/feedListModel.cpp @@ -107,3 +107,10 @@ void FeedListModel::removeFeed(int index) feed->remove(); delete feed; } + +void FeedListModel::refreshAll() +{ + for(auto &feed : m_feeds) { + feed->refresh(); + } +} \ No newline at end of file diff --git a/src/feedListModel.h b/src/feedListModel.h index bdcc88e5..4f66cb9d 100644 --- a/src/feedListModel.h +++ b/src/feedListModel.h @@ -37,6 +37,7 @@ public: QHash roleNames() const override; int rowCount(const QModelIndex &parent) const override; Q_INVOKABLE void removeFeed(int index); + Q_INVOKABLE void refreshAll(); private: void loadFeed(int index) const; diff --git a/src/fetcher.cpp b/src/fetcher.cpp index 5c51e24b..3253d3bb 100644 --- a/src/fetcher.cpp +++ b/src/fetcher.cpp @@ -42,6 +42,8 @@ void Fetcher::fetch(QString url) { qDebug() << "Starting to fetch" << url; + Q_EMIT startedFetchingFeed(url); + QNetworkRequest request((QUrl(url))); QNetworkReply *reply = manager->get(request); connect(reply, &QNetworkReply::finished, this, [this, url, reply]() { @@ -55,6 +57,16 @@ void Fetcher::fetch(QString url) }); } +void Fetcher::fetchAll() +{ + QSqlQuery query; + query.prepare(QStringLiteral("SELECT url FROM Feeds;")); + Database::instance().execute(query); + while(query.next()) { + fetch(query.value(0).toString()); + } +} + void Fetcher::processFeed(Syndication::FeedPtr feed, QString url) { if (feed.isNull()) diff --git a/src/fetcher.h b/src/fetcher.h index d37da468..bb696278 100644 --- a/src/fetcher.h +++ b/src/fetcher.h @@ -35,6 +35,7 @@ public: return _instance; } Q_INVOKABLE void fetch(QString url); + Q_INVOKABLE void fetchAll(); Q_INVOKABLE QString image(QString); void removeImage(QString); Q_INVOKABLE void download(QString url); @@ -51,6 +52,7 @@ private: QNetworkAccessManager *manager; Q_SIGNALS: + void startedFetchingFeed(QString url); void feedUpdated(QString url); void feedDetailsUpdated(QString url, QString name, QString image, QString link, QString description); }; diff --git a/src/qml/FeedListPage.qml b/src/qml/FeedListPage.qml index 28985fa1..5cb08dc3 100644 --- a/src/qml/FeedListPage.qml +++ b/src/qml/FeedListPage.qml @@ -31,6 +31,19 @@ Kirigami.ScrollablePage { property var lastFeed: "" + supportsRefreshing: true + onRefreshingChanged: + if(refreshing) { + timer.running = true + Fetcher.fetchAll() + } + + Timer { + id: timer + interval: 1000 + onTriggered: refreshing = false + } + actions.main: Kirigami.Action { text: i18n("Add feed") iconName: "list-add" @@ -100,11 +113,22 @@ Kirigami.ScrollablePage { height: Kirigami.Units.gridUnit*2 Item { - Kirigami.Icon { + Item { id: icon - source: Fetcher.image(model.feed.image) width: height height: parent.height + Kirigami.Icon { + source: Fetcher.image(model.feed.image) + width: height + height: parent.height + visible: !busy.visible + } + Controls.BusyIndicator { + id: busy + width: height + height: parent.height + visible: model.feed.refreshing + } } Controls.Label {