Implement FeedDetailsPage
This commit is contained in:
parent
bef7760151
commit
a5a449c08b
@ -57,8 +57,8 @@ bool Database::migrate()
|
|||||||
bool Database::migrateTo1()
|
bool Database::migrateTo1()
|
||||||
{
|
{
|
||||||
qDebug() << "Migrating database to version 1";
|
qDebug() << "Migrating database to version 1";
|
||||||
TRUE_OR_RETURN(execute(QStringLiteral("CREATE TABLE IF NOT EXISTS Feeds (name TEXT, url TEXT, image TEXT, link TEXT, description TEXT);")));
|
TRUE_OR_RETURN(execute(QStringLiteral("CREATE TABLE IF NOT EXISTS Feeds (name TEXT, url TEXT, image TEXT, link TEXT, description TEXT, deleteAfterCount INTEGER, deleteAfterType INTEGER, subscribed INTEGER, lastUpdated INTEGER, autoUpdateCount INTEGER, autoUpdateType INTEGER, notify BOOL);")));
|
||||||
TRUE_OR_RETURN(execute(QStringLiteral("CREATE TABLE IF NOT EXISTS Entries (feed TEXT, id TEXT UNIQUE, title TEXT, content TEXT, created INTEGER, updated INTEGER, link TEXT);")));
|
TRUE_OR_RETURN(execute(QStringLiteral("CREATE TABLE IF NOT EXISTS Entries (feed TEXT, id TEXT UNIQUE, title TEXT, content TEXT, created INTEGER, updated INTEGER, link TEXT, read bool);")));
|
||||||
TRUE_OR_RETURN(execute(QStringLiteral("CREATE TABLE IF NOT EXISTS Authors (feed TEXT, id TEXT, name TEXT, uri TEXT, email TEXT);")));
|
TRUE_OR_RETURN(execute(QStringLiteral("CREATE TABLE IF NOT EXISTS Authors (feed TEXT, id TEXT, name TEXT, uri TEXT, email TEXT);")));
|
||||||
TRUE_OR_RETURN(execute(QStringLiteral("CREATE TABLE IF NOT EXISTS Enclosures (feed TEXT, id TEXT, duration INTEGER, size INTEGER, title TEXT, type STRING, url STRING);")));
|
TRUE_OR_RETURN(execute(QStringLiteral("CREATE TABLE IF NOT EXISTS Enclosures (feed TEXT, id TEXT, duration INTEGER, size INTEGER, title TEXT, type STRING, url STRING);")));
|
||||||
TRUE_OR_RETURN(execute(QStringLiteral("PRAGMA user_version = 1;")));
|
TRUE_OR_RETURN(execute(QStringLiteral("PRAGMA user_version = 1;")));
|
||||||
@ -106,7 +106,7 @@ void Database::cleanup()
|
|||||||
int count = settings.deleteAfterCount();
|
int count = settings.deleteAfterCount();
|
||||||
int type = settings.deleteAfterType();
|
int type = settings.deleteAfterType();
|
||||||
|
|
||||||
if(type == 0) { //Never delete Entries
|
if (type == 0) { // Never delete Entries
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,12 +149,19 @@ void Database::addFeed(QString url)
|
|||||||
qDebug() << "Feed does not yet exist";
|
qDebug() << "Feed does not yet exist";
|
||||||
|
|
||||||
QSqlQuery query;
|
QSqlQuery query;
|
||||||
query.prepare(QStringLiteral("INSERT INTO Feeds VALUES (:name, :url, :image, :link, :description);"));
|
query.prepare(QStringLiteral("INSERT INTO Feeds VALUES (:name, :url, :image, :link, :description, :deleteAfterCount, :deleteAfterType, :subscribed, :lastUpdated, :autoUpdateCount, :autoUpdateType, :notify);"));
|
||||||
query.bindValue(QStringLiteral(":name"), url);
|
query.bindValue(QStringLiteral(":name"), url);
|
||||||
query.bindValue(QStringLiteral(":url"), url);
|
query.bindValue(QStringLiteral(":url"), url);
|
||||||
query.bindValue(QStringLiteral(":image"), QLatin1String(""));
|
query.bindValue(QStringLiteral(":image"), QLatin1String(""));
|
||||||
query.bindValue(QStringLiteral(":link"), QLatin1String(""));
|
query.bindValue(QStringLiteral(":link"), QLatin1String(""));
|
||||||
query.bindValue(QStringLiteral(":description"), QLatin1String(""));
|
query.bindValue(QStringLiteral(":description"), QLatin1String(""));
|
||||||
|
query.bindValue(QStringLiteral(":deleteAfterCount"), 0);
|
||||||
|
query.bindValue(QStringLiteral(":deleteAfterType"), 0);
|
||||||
|
query.bindValue(QStringLiteral(":subscribed"), QDateTime::currentDateTime().toSecsSinceEpoch());
|
||||||
|
query.bindValue(QStringLiteral(":lastUpdated"), 0);
|
||||||
|
query.bindValue(QStringLiteral(":autoUpdateCount"), 0);
|
||||||
|
query.bindValue(QStringLiteral(":autoUpdateType"), 0);
|
||||||
|
query.bindValue(QStringLiteral(":notify"), false);
|
||||||
execute(query);
|
execute(query);
|
||||||
|
|
||||||
Q_EMIT feedAdded(url);
|
Q_EMIT feedAdded(url);
|
||||||
|
@ -19,16 +19,23 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "entry.h"
|
#include "entry.h"
|
||||||
|
|
||||||
|
#include <QSqlQuery>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
|
||||||
Entry::Entry(QString title, QString content, QVector<Author *> authors, QDateTime created, QDateTime updated, QString link, QObject *parent)
|
#include "database.h"
|
||||||
|
|
||||||
|
Entry::Entry(Feed *feed, QString id, QString title, QString content, QVector<Author *> authors, QDateTime created, QDateTime updated, QString link, bool read, QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
|
, m_feed(feed)
|
||||||
|
, m_id(id)
|
||||||
, m_title(title)
|
, m_title(title)
|
||||||
, m_content(content)
|
, m_content(content)
|
||||||
, m_authors(authors)
|
, m_authors(authors)
|
||||||
, m_created(created)
|
, m_created(created)
|
||||||
, m_updated(updated)
|
, m_updated(updated)
|
||||||
, m_link(link)
|
, m_link(link)
|
||||||
|
, m_read(read)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,6 +43,11 @@ Entry::~Entry()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString Entry::id() const
|
||||||
|
{
|
||||||
|
return m_id;
|
||||||
|
}
|
||||||
|
|
||||||
QString Entry::title() const
|
QString Entry::title() const
|
||||||
{
|
{
|
||||||
return m_title;
|
return m_title;
|
||||||
@ -66,7 +78,24 @@ QString Entry::link() const
|
|||||||
return m_link;
|
return m_link;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Entry::read() const
|
||||||
|
{
|
||||||
|
return m_read;
|
||||||
|
}
|
||||||
|
|
||||||
QString Entry::baseUrl() const
|
QString Entry::baseUrl() const
|
||||||
{
|
{
|
||||||
return QUrl(m_link).adjusted(QUrl::RemovePath).toString();
|
return QUrl(m_link).adjusted(QUrl::RemovePath).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Entry::setRead(bool read)
|
||||||
|
{
|
||||||
|
m_read = read;
|
||||||
|
Q_EMIT readChanged(m_read);
|
||||||
|
QSqlQuery query;
|
||||||
|
query.prepare(QStringLiteral("UPDATE Entries SET read=:read WHERE id=:id AND feed=:feed"));
|
||||||
|
query.bindValue(QStringLiteral(":id"), m_id);
|
||||||
|
query.bindValue(QStringLiteral(":feed"), m_feed->url());
|
||||||
|
query.bindValue(QStringLiteral(":read"), m_read);
|
||||||
|
Database::instance().execute(query);
|
||||||
|
}
|
||||||
|
14
src/entry.h
14
src/entry.h
@ -34,6 +34,7 @@ class Entry : public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_PROPERTY(QString id READ id CONSTANT)
|
||||||
Q_PROPERTY(QString title READ title CONSTANT)
|
Q_PROPERTY(QString title READ title CONSTANT)
|
||||||
Q_PROPERTY(QString content READ content CONSTANT)
|
Q_PROPERTY(QString content READ content CONSTANT)
|
||||||
Q_PROPERTY(QVector<Author *> authors READ authors CONSTANT)
|
Q_PROPERTY(QVector<Author *> authors READ authors CONSTANT)
|
||||||
@ -41,27 +42,38 @@ class Entry : public QObject
|
|||||||
Q_PROPERTY(QDateTime updated READ updated CONSTANT)
|
Q_PROPERTY(QDateTime updated READ updated CONSTANT)
|
||||||
Q_PROPERTY(QString link READ link CONSTANT)
|
Q_PROPERTY(QString link READ link CONSTANT)
|
||||||
Q_PROPERTY(QString baseUrl READ baseUrl CONSTANT)
|
Q_PROPERTY(QString baseUrl READ baseUrl CONSTANT)
|
||||||
|
Q_PROPERTY(bool read READ read WRITE setRead NOTIFY readChanged);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Entry(QString title, QString content, QVector<Author *> authors, QDateTime created, QDateTime updated, QString link, QObject *parent = nullptr);
|
Entry(Feed *feed, QString id, QString title, QString content, QVector<Author *> authors, QDateTime created, QDateTime updated, QString link, bool read, QObject *parent = nullptr);
|
||||||
~Entry();
|
~Entry();
|
||||||
|
|
||||||
|
QString id() const;
|
||||||
QString title() const;
|
QString title() const;
|
||||||
QString content() const;
|
QString content() const;
|
||||||
QVector<Author *> authors() const;
|
QVector<Author *> authors() const;
|
||||||
QDateTime created() const;
|
QDateTime created() const;
|
||||||
QDateTime updated() const;
|
QDateTime updated() const;
|
||||||
QString link() const;
|
QString link() const;
|
||||||
|
bool read() const;
|
||||||
|
|
||||||
QString baseUrl() const;
|
QString baseUrl() const;
|
||||||
|
|
||||||
|
void setRead(bool read);
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void readChanged(bool read);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Feed *m_feed;
|
Feed *m_feed;
|
||||||
|
QString m_id;
|
||||||
QString m_title;
|
QString m_title;
|
||||||
QString m_content;
|
QString m_content;
|
||||||
QVector<Author *> m_authors;
|
QVector<Author *> m_authors;
|
||||||
QDateTime m_created;
|
QDateTime m_created;
|
||||||
QDateTime m_updated;
|
QDateTime m_updated;
|
||||||
QString m_link;
|
QString m_link;
|
||||||
|
bool m_read;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ENTRY_H
|
#endif // ENTRY_H
|
||||||
|
@ -94,7 +94,16 @@ void EntryListModel::loadEntry(int index) const
|
|||||||
QDateTime updated;
|
QDateTime updated;
|
||||||
updated.setSecsSinceEpoch(entryQuery.value(QStringLiteral("updated")).toInt());
|
updated.setSecsSinceEpoch(entryQuery.value(QStringLiteral("updated")).toInt());
|
||||||
|
|
||||||
Entry *entry = new Entry(entryQuery.value(QStringLiteral("title")).toString(), entryQuery.value(QStringLiteral("content")).toString(), authors, created, updated, entryQuery.value(QStringLiteral("link")).toString(), nullptr);
|
Entry *entry = new Entry(m_feed,
|
||||||
|
entryQuery.value(QStringLiteral("id")).toString(),
|
||||||
|
entryQuery.value(QStringLiteral("title")).toString(),
|
||||||
|
entryQuery.value(QStringLiteral("content")).toString(),
|
||||||
|
authors,
|
||||||
|
created,
|
||||||
|
updated,
|
||||||
|
entryQuery.value(QStringLiteral("link")).toString(),
|
||||||
|
entryQuery.value(QStringLiteral("read")).toBool(),
|
||||||
|
nullptr);
|
||||||
m_entries[index] = entry;
|
m_entries[index] = entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
125
src/feed.cpp
125
src/feed.cpp
@ -24,7 +24,20 @@
|
|||||||
#include "feed.h"
|
#include "feed.h"
|
||||||
#include "fetcher.h"
|
#include "fetcher.h"
|
||||||
|
|
||||||
Feed::Feed(QString url, QString name, QString image, QString link, QString description, QVector<Author *> authors, QObject *parent)
|
Feed::Feed(QString url,
|
||||||
|
QString name,
|
||||||
|
QString image,
|
||||||
|
QString link,
|
||||||
|
QString description,
|
||||||
|
QVector<Author *> authors,
|
||||||
|
int deleteAfterCount,
|
||||||
|
int deleteAfterType,
|
||||||
|
QDateTime subscribed,
|
||||||
|
QDateTime lastUpdated,
|
||||||
|
int autoUpdateCount,
|
||||||
|
int autoUpdateType,
|
||||||
|
bool notify,
|
||||||
|
QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
, m_url(url)
|
, m_url(url)
|
||||||
, m_name(name)
|
, m_name(name)
|
||||||
@ -32,15 +45,24 @@ Feed::Feed(QString url, QString name, QString image, QString link, QString descr
|
|||||||
, m_link(link)
|
, m_link(link)
|
||||||
, m_description(description)
|
, m_description(description)
|
||||||
, m_authors(authors)
|
, m_authors(authors)
|
||||||
|
, m_deleteAfterCount(deleteAfterCount)
|
||||||
|
, m_deleteAfterType(deleteAfterType)
|
||||||
|
, m_subscribed(subscribed)
|
||||||
|
, m_lastUpdated(lastUpdated)
|
||||||
|
, m_autoUpdateCount(autoUpdateCount)
|
||||||
|
, m_autoUpdateType(autoUpdateType)
|
||||||
|
, m_notify(notify)
|
||||||
{
|
{
|
||||||
connect(&Fetcher::instance(), &Fetcher::startedFetchingFeed, this, [this] (QString url) {
|
connect(&Fetcher::instance(), &Fetcher::startedFetchingFeed, this, [this](QString url) {
|
||||||
if(url == m_url) {
|
if (url == m_url) {
|
||||||
setRefreshing(true);
|
setRefreshing(true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
connect(&Fetcher::instance(), &Fetcher::feedUpdated, this, [this] (QString url) {
|
connect(&Fetcher::instance(), &Fetcher::feedUpdated, this, [this](QString url) {
|
||||||
if(url == m_url) {
|
if (url == m_url) {
|
||||||
setRefreshing(false);
|
setRefreshing(false);
|
||||||
|
emit entryCountChanged();
|
||||||
|
emit unreadEntryCountChanged();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -79,6 +101,63 @@ QVector<Author *> Feed::authors() const
|
|||||||
return m_authors;
|
return m_authors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Feed::deleteAfterCount() const
|
||||||
|
{
|
||||||
|
return m_deleteAfterCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Feed::deleteAfterType() const
|
||||||
|
{
|
||||||
|
return m_deleteAfterType;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDateTime Feed::subscribed() const
|
||||||
|
{
|
||||||
|
return m_subscribed;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDateTime Feed::lastUpdated() const
|
||||||
|
{
|
||||||
|
return m_lastUpdated;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Feed::autoUpdateCount() const
|
||||||
|
{
|
||||||
|
return m_autoUpdateCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Feed::autoUpdateType() const
|
||||||
|
{
|
||||||
|
return m_autoUpdateType;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Feed::notify() const
|
||||||
|
{
|
||||||
|
return m_notify;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Feed::entryCount() const
|
||||||
|
{
|
||||||
|
QSqlQuery query;
|
||||||
|
query.prepare(QStringLiteral("SELECT COUNT (id) FROM Entries where feed=:feed;"));
|
||||||
|
query.bindValue(QStringLiteral(":feed"), m_url);
|
||||||
|
Database::instance().execute(query);
|
||||||
|
if (!query.next())
|
||||||
|
return -1;
|
||||||
|
return query.value(0).toInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Feed::unreadEntryCount() const
|
||||||
|
{
|
||||||
|
QSqlQuery query;
|
||||||
|
query.prepare(QStringLiteral("SELECT COUNT (id) FROM Entries where feed=:feed AND read=false;"));
|
||||||
|
query.bindValue(QStringLiteral(":feed"), m_url);
|
||||||
|
Database::instance().execute(query);
|
||||||
|
if (!query.next())
|
||||||
|
return -1;
|
||||||
|
return query.value(0).toInt();
|
||||||
|
}
|
||||||
|
|
||||||
bool Feed::refreshing() const
|
bool Feed::refreshing() const
|
||||||
{
|
{
|
||||||
return m_refreshing;
|
return m_refreshing;
|
||||||
@ -114,6 +193,42 @@ void Feed::setAuthors(QVector<Author *> authors)
|
|||||||
Q_EMIT authorsChanged(m_authors);
|
Q_EMIT authorsChanged(m_authors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Feed::setDeleteAfterCount(int count)
|
||||||
|
{
|
||||||
|
m_deleteAfterCount = count;
|
||||||
|
Q_EMIT deleteAfterCountChanged(m_deleteAfterCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Feed::setDeleteAfterType(int type)
|
||||||
|
{
|
||||||
|
m_deleteAfterType = type;
|
||||||
|
Q_EMIT deleteAfterTypeChanged(m_deleteAfterType);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Feed::setLastUpdated(QDateTime lastUpdated)
|
||||||
|
{
|
||||||
|
m_lastUpdated = lastUpdated;
|
||||||
|
Q_EMIT lastUpdatedChanged(m_lastUpdated);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Feed::setAutoUpdateCount(int count)
|
||||||
|
{
|
||||||
|
m_autoUpdateCount = count;
|
||||||
|
Q_EMIT autoUpdateCountChanged(m_autoUpdateCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Feed::setAutoUpdateType(int type)
|
||||||
|
{
|
||||||
|
m_autoUpdateType = type;
|
||||||
|
Q_EMIT autoUpdateTypeChanged(m_autoUpdateType);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Feed::setNotify(bool notify)
|
||||||
|
{
|
||||||
|
m_notify = notify;
|
||||||
|
Q_EMIT notifyChanged(m_notify);
|
||||||
|
}
|
||||||
|
|
||||||
void Feed::setRefreshing(bool refreshing)
|
void Feed::setRefreshing(bool refreshing)
|
||||||
{
|
{
|
||||||
m_refreshing = refreshing;
|
m_refreshing = refreshing;
|
||||||
|
59
src/feed.h
59
src/feed.h
@ -21,6 +21,7 @@
|
|||||||
#ifndef FEED_H
|
#ifndef FEED_H
|
||||||
#define FEED_H
|
#define FEED_H
|
||||||
|
|
||||||
|
#include <QDateTime>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
#include "author.h"
|
#include "author.h"
|
||||||
@ -36,9 +37,31 @@ class Feed : public QObject
|
|||||||
Q_PROPERTY(QString description READ description WRITE setDescription NOTIFY descriptionChanged)
|
Q_PROPERTY(QString description READ description WRITE setDescription NOTIFY descriptionChanged)
|
||||||
Q_PROPERTY(QVector<Author *> authors READ authors WRITE setAuthors NOTIFY authorsChanged)
|
Q_PROPERTY(QVector<Author *> authors READ authors WRITE setAuthors NOTIFY authorsChanged)
|
||||||
Q_PROPERTY(bool refreshing READ refreshing WRITE setRefreshing NOTIFY refreshingChanged)
|
Q_PROPERTY(bool refreshing READ refreshing WRITE setRefreshing NOTIFY refreshingChanged)
|
||||||
|
Q_PROPERTY(int deleteAfterCount READ deleteAfterCount WRITE setDeleteAfterCount NOTIFY deleteAfterCountChanged)
|
||||||
|
Q_PROPERTY(int deleteAfterType READ deleteAfterType WRITE setDeleteAfterType NOTIFY deleteAfterTypeChanged)
|
||||||
|
Q_PROPERTY(QDateTime subscribed READ subscribed CONSTANT)
|
||||||
|
Q_PROPERTY(QDateTime lastUpdated READ lastUpdated WRITE setLastUpdated NOTIFY lastUpdatedChanged)
|
||||||
|
Q_PROPERTY(int autoUpdateCount READ autoUpdateCount WRITE setAutoUpdateCount NOTIFY autoUpdateCountChanged)
|
||||||
|
Q_PROPERTY(int autoUpdateType READ autoUpdateType WRITE setAutoUpdateType NOTIFY autoUpdateCountChanged)
|
||||||
|
Q_PROPERTY(bool notify READ notify WRITE setNotify NOTIFY notifyChanged)
|
||||||
|
Q_PROPERTY(int entryCount READ entryCount NOTIFY entryCountChanged)
|
||||||
|
Q_PROPERTY(int unreadEntryCount READ unreadEntryCount NOTIFY unreadEntryCountChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Feed(QString url, QString name, QString image, QString link, QString description, QVector<Author *> authors, QObject *parent = nullptr);
|
Feed(QString url,
|
||||||
|
QString name,
|
||||||
|
QString image,
|
||||||
|
QString link,
|
||||||
|
QString description,
|
||||||
|
QVector<Author *> authors,
|
||||||
|
int deleteAfterCount,
|
||||||
|
int deleteAfterType,
|
||||||
|
QDateTime subscribed,
|
||||||
|
QDateTime lastUpdated,
|
||||||
|
int autoUpdateCount,
|
||||||
|
int autoUpdateType,
|
||||||
|
bool notify,
|
||||||
|
QObject *parent = nullptr);
|
||||||
|
|
||||||
~Feed();
|
~Feed();
|
||||||
|
|
||||||
@ -48,6 +71,17 @@ public:
|
|||||||
QString link() const;
|
QString link() const;
|
||||||
QString description() const;
|
QString description() const;
|
||||||
QVector<Author *> authors() const;
|
QVector<Author *> authors() const;
|
||||||
|
int deleteAfterCount() const;
|
||||||
|
int deleteAfterType() const;
|
||||||
|
QDateTime subscribed() const;
|
||||||
|
QDateTime lastUpdated() const;
|
||||||
|
int autoUpdateCount() const;
|
||||||
|
int autoUpdateType() const;
|
||||||
|
bool notify() const;
|
||||||
|
int entryCount() const;
|
||||||
|
int unreadEntryCount() const;
|
||||||
|
bool read() const;
|
||||||
|
|
||||||
bool refreshing() const;
|
bool refreshing() const;
|
||||||
|
|
||||||
void setName(QString name);
|
void setName(QString name);
|
||||||
@ -55,6 +89,12 @@ public:
|
|||||||
void setLink(QString link);
|
void setLink(QString link);
|
||||||
void setDescription(QString description);
|
void setDescription(QString description);
|
||||||
void setAuthors(QVector<Author *> authors);
|
void setAuthors(QVector<Author *> authors);
|
||||||
|
void setDeleteAfterCount(int count);
|
||||||
|
void setDeleteAfterType(int type);
|
||||||
|
void setLastUpdated(QDateTime lastUpdated);
|
||||||
|
void setAutoUpdateCount(int count);
|
||||||
|
void setAutoUpdateType(int type);
|
||||||
|
void setNotify(bool notify);
|
||||||
void setRefreshing(bool refreshing);
|
void setRefreshing(bool refreshing);
|
||||||
|
|
||||||
Q_INVOKABLE void refresh();
|
Q_INVOKABLE void refresh();
|
||||||
@ -66,6 +106,15 @@ Q_SIGNALS:
|
|||||||
void linkChanged(QString &link);
|
void linkChanged(QString &link);
|
||||||
void descriptionChanged(QString &description);
|
void descriptionChanged(QString &description);
|
||||||
void authorsChanged(QVector<Author *> &authors);
|
void authorsChanged(QVector<Author *> &authors);
|
||||||
|
void deleteAfterCountChanged(int count);
|
||||||
|
void deleteAfterTypeChanged(int type);
|
||||||
|
void lastUpdatedChanged(QDateTime lastUpdated);
|
||||||
|
void autoUpdateCountChanged(int count);
|
||||||
|
void autoUpdateTypeChanged(int type);
|
||||||
|
void notifyChanged(bool notify);
|
||||||
|
void entryCountChanged();
|
||||||
|
void unreadEntryCountChanged();
|
||||||
|
|
||||||
void refreshingChanged(bool refreshing);
|
void refreshingChanged(bool refreshing);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -75,6 +124,14 @@ private:
|
|||||||
QString m_link;
|
QString m_link;
|
||||||
QString m_description;
|
QString m_description;
|
||||||
QVector<Author *> m_authors;
|
QVector<Author *> m_authors;
|
||||||
|
int m_deleteAfterCount;
|
||||||
|
int m_deleteAfterType;
|
||||||
|
QDateTime m_subscribed;
|
||||||
|
QDateTime m_lastUpdated;
|
||||||
|
int m_autoUpdateCount;
|
||||||
|
int m_autoUpdateType;
|
||||||
|
bool m_notify;
|
||||||
|
|
||||||
bool m_refreshing = false;
|
bool m_refreshing = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -35,13 +35,14 @@ FeedListModel::FeedListModel(QObject *parent)
|
|||||||
beginInsertRows(QModelIndex(), rowCount(QModelIndex()) - 1, rowCount(QModelIndex()) - 1);
|
beginInsertRows(QModelIndex(), rowCount(QModelIndex()) - 1, rowCount(QModelIndex()) - 1);
|
||||||
endInsertRows();
|
endInsertRows();
|
||||||
});
|
});
|
||||||
connect(&Fetcher::instance(), &Fetcher::feedDetailsUpdated, this, [this](QString url, QString name, QString image, QString link, QString description) {
|
connect(&Fetcher::instance(), &Fetcher::feedDetailsUpdated, this, [this](QString url, QString name, QString image, QString link, QString description, QDateTime lastUpdated) {
|
||||||
for (int i = rowCount(QModelIndex()) - 1; i >= 0; i--) {
|
for (int i = rowCount(QModelIndex()) - 1; i >= 0; i--) {
|
||||||
if (m_feeds[i]->url() == url) {
|
if (m_feeds[i]->url() == url) {
|
||||||
m_feeds[i]->setName(name);
|
m_feeds[i]->setName(name);
|
||||||
m_feeds[i]->setImage(image);
|
m_feeds[i]->setImage(image);
|
||||||
m_feeds[i]->setLink(link);
|
m_feeds[i]->setLink(link);
|
||||||
m_feeds[i]->setDescription(description);
|
m_feeds[i]->setDescription(description);
|
||||||
|
m_feeds[i]->setLastUpdated(lastUpdated);
|
||||||
Q_EMIT dataChanged(createIndex(i, 0), createIndex(i, 0));
|
Q_EMIT dataChanged(createIndex(i, 0), createIndex(i, 0));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -94,7 +95,26 @@ void FeedListModel::loadFeed(int index) const
|
|||||||
authors += new Author(authorQuery.value(QStringLiteral("name")).toString(), authorQuery.value(QStringLiteral("email")).toString(), authorQuery.value(QStringLiteral("uri")).toString(), nullptr);
|
authors += new Author(authorQuery.value(QStringLiteral("name")).toString(), authorQuery.value(QStringLiteral("email")).toString(), authorQuery.value(QStringLiteral("uri")).toString(), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
Feed *feed = new Feed(query.value(QStringLiteral("url")).toString(), query.value(QStringLiteral("name")).toString(), query.value(QStringLiteral("image")).toString(), query.value(QStringLiteral("link")).toString(), query.value(QStringLiteral("description")).toString(), authors, nullptr);
|
QDateTime subscribed;
|
||||||
|
subscribed.setSecsSinceEpoch(query.value(QStringLiteral("subscribed")).toInt());
|
||||||
|
|
||||||
|
QDateTime lastUpdated;
|
||||||
|
lastUpdated.setSecsSinceEpoch(query.value(QStringLiteral("lastUpdated")).toInt());
|
||||||
|
|
||||||
|
Feed *feed = new Feed(query.value(QStringLiteral("url")).toString(),
|
||||||
|
query.value(QStringLiteral("name")).toString(),
|
||||||
|
query.value(QStringLiteral("image")).toString(),
|
||||||
|
query.value(QStringLiteral("link")).toString(),
|
||||||
|
query.value(QStringLiteral("description")).toString(),
|
||||||
|
authors,
|
||||||
|
query.value(QStringLiteral("deleteAfterCount")).toInt(),
|
||||||
|
query.value(QStringLiteral("deleteAfterType")).toInt(),
|
||||||
|
subscribed,
|
||||||
|
lastUpdated,
|
||||||
|
query.value(QStringLiteral("autoUpdateCount")).toInt(),
|
||||||
|
query.value(QStringLiteral("autoUpdateType")).toInt(),
|
||||||
|
query.value(QStringLiteral("notify")).toBool(),
|
||||||
|
nullptr);
|
||||||
m_feeds[index] = feed;
|
m_feeds[index] = feed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,7 +130,7 @@ void FeedListModel::removeFeed(int index)
|
|||||||
|
|
||||||
void FeedListModel::refreshAll()
|
void FeedListModel::refreshAll()
|
||||||
{
|
{
|
||||||
for(auto &feed : m_feeds) {
|
for (auto &feed : m_feeds) {
|
||||||
feed->refresh();
|
feed->refresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -18,6 +18,7 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <QDateTime>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QNetworkAccessManager>
|
#include <QNetworkAccessManager>
|
||||||
@ -62,7 +63,7 @@ void Fetcher::fetchAll()
|
|||||||
QSqlQuery query;
|
QSqlQuery query;
|
||||||
query.prepare(QStringLiteral("SELECT url FROM Feeds;"));
|
query.prepare(QStringLiteral("SELECT url FROM Feeds;"));
|
||||||
Database::instance().execute(query);
|
Database::instance().execute(query);
|
||||||
while(query.next()) {
|
while (query.next()) {
|
||||||
fetch(query.value(0).toString());
|
fetch(query.value(0).toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -73,13 +74,16 @@ void Fetcher::processFeed(Syndication::FeedPtr feed, QString url)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
QSqlQuery query;
|
QSqlQuery query;
|
||||||
query.prepare(QStringLiteral("UPDATE Feeds SET name=:name, image=:image, link=:link, description=:description WHERE url=:url;"));
|
query.prepare(QStringLiteral("UPDATE Feeds SET name=:name, image=:image, link=:link, description=:description, lastUpdated=:lastUpdated WHERE url=:url;"));
|
||||||
query.bindValue(QStringLiteral(":name"), feed->title());
|
query.bindValue(QStringLiteral(":name"), feed->title());
|
||||||
query.bindValue(QStringLiteral(":url"), url);
|
query.bindValue(QStringLiteral(":url"), url);
|
||||||
query.bindValue(QStringLiteral(":link"), feed->link());
|
query.bindValue(QStringLiteral(":link"), feed->link());
|
||||||
query.bindValue(QStringLiteral(":description"), feed->description());
|
query.bindValue(QStringLiteral(":description"), feed->description());
|
||||||
|
|
||||||
for(auto &author : feed->authors()) {
|
QDateTime current = QDateTime::currentDateTime();
|
||||||
|
query.bindValue(QStringLiteral(":lastUpdated"), current.toSecsSinceEpoch());
|
||||||
|
|
||||||
|
for (auto &author : feed->authors()) {
|
||||||
processAuthor(author, QLatin1String(""), url);
|
processAuthor(author, QLatin1String(""), url);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,7 +97,7 @@ void Fetcher::processFeed(Syndication::FeedPtr feed, QString url)
|
|||||||
|
|
||||||
qDebug() << "Updated feed title:" << feed->title();
|
qDebug() << "Updated feed title:" << feed->title();
|
||||||
|
|
||||||
Q_EMIT feedDetailsUpdated(url, feed->title(), image, feed->link(), feed->description());
|
Q_EMIT feedDetailsUpdated(url, feed->title(), image, feed->link(), feed->description(), current);
|
||||||
|
|
||||||
for (const auto &entry : feed->items()) {
|
for (const auto &entry : feed->items()) {
|
||||||
processEntry(entry, url);
|
processEntry(entry, url);
|
||||||
@ -114,7 +118,7 @@ void Fetcher::processEntry(Syndication::ItemPtr entry, QString url)
|
|||||||
if (query.value(0).toInt() != 0)
|
if (query.value(0).toInt() != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
query.prepare(QStringLiteral("INSERT INTO Entries VALUES (:feed, :id, :title, :content, :created, :updated, :link);"));
|
query.prepare(QStringLiteral("INSERT INTO Entries VALUES (:feed, :id, :title, :content, :created, :updated, :link, false);"));
|
||||||
query.bindValue(QStringLiteral(":feed"), url);
|
query.bindValue(QStringLiteral(":feed"), url);
|
||||||
query.bindValue(QStringLiteral(":id"), entry->id());
|
query.bindValue(QStringLiteral(":id"), entry->id());
|
||||||
query.bindValue(QStringLiteral(":title"), QTextDocumentFragment::fromHtml(entry->title()).toPlainText());
|
query.bindValue(QStringLiteral(":title"), QTextDocumentFragment::fromHtml(entry->title()).toPlainText());
|
||||||
|
@ -54,5 +54,5 @@ private:
|
|||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void startedFetchingFeed(QString url);
|
void startedFetchingFeed(QString url);
|
||||||
void feedUpdated(QString url);
|
void feedUpdated(QString url);
|
||||||
void feedDetailsUpdated(QString url, QString name, QString image, QString link, QString description);
|
void feedDetailsUpdated(QString url, QString name, QString image, QString link, QString description, QDateTime lastUpdated);
|
||||||
};
|
};
|
||||||
|
@ -36,6 +36,7 @@ Kirigami.SwipeListItem {
|
|||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
opacity: 1
|
opacity: 1
|
||||||
|
color: model.entry.read ? Kirigami.Theme.disabledTextColor : Kirigami.Theme.textColor
|
||||||
}
|
}
|
||||||
Controls.Label {
|
Controls.Label {
|
||||||
id: subtitleItem
|
id: subtitleItem
|
||||||
@ -45,10 +46,12 @@ Kirigami.SwipeListItem {
|
|||||||
font: Kirigami.Theme.smallFont
|
font: Kirigami.Theme.smallFont
|
||||||
opacity: 0.6
|
opacity: 0.6
|
||||||
visible: text.length > 0
|
visible: text.length > 0
|
||||||
|
color: model.entry.read ? Kirigami.Theme.disabledTextColor : Kirigami.Theme.textColor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
model.entry.read = true
|
||||||
pageStack.push("qrc:/EntryPage.qml", {"entry": model.entry})
|
pageStack.push("qrc:/EntryPage.qml", {"entry": model.entry})
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -44,7 +44,7 @@ Kirigami.ScrollablePage {
|
|||||||
Kirigami.Action {
|
Kirigami.Action {
|
||||||
iconName: "help-about-symbolic"
|
iconName: "help-about-symbolic"
|
||||||
text: i18n("Details")
|
text: i18n("Details")
|
||||||
onTriggered: pageStack.push("qrc:/FeedDetailsPage.qml")
|
onTriggered: pageStack.push("qrc:/FeedDetailsPage.qml", {"feed": feed})
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -24,7 +24,44 @@ import QtQuick.Layouts 1.14
|
|||||||
|
|
||||||
import org.kde.kirigami 2.12 as Kirigami
|
import org.kde.kirigami 2.12 as Kirigami
|
||||||
|
|
||||||
|
import org.kde.alligator 1.0
|
||||||
|
|
||||||
Kirigami.Page {
|
Kirigami.ScrollablePage {
|
||||||
|
id: detailsPage
|
||||||
|
|
||||||
|
property QtObject feed;
|
||||||
|
|
||||||
|
title: i18nc("<Feed Name> - Details", "%1 - Details", feed.name)
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Kirigami.Icon {
|
||||||
|
source: Fetcher.image(feed.image)
|
||||||
|
height: 200
|
||||||
|
width: height
|
||||||
|
}
|
||||||
|
Kirigami.Heading {
|
||||||
|
text: feed.name
|
||||||
|
}
|
||||||
|
Kirigami.Heading {
|
||||||
|
text: feed.description;
|
||||||
|
level: 3
|
||||||
|
}
|
||||||
|
Controls.Label {
|
||||||
|
text: i18nc("by <author(s)>", "by %1", feed.authors[0].name)
|
||||||
|
visible: feed.authors.length !== 0
|
||||||
|
}
|
||||||
|
Controls.Label {
|
||||||
|
text: "<a href='%1'>%1</a>".arg(feed.link)
|
||||||
|
onLinkActivated: Qt.openUrlExternally(link)
|
||||||
|
}
|
||||||
|
Controls.Label {
|
||||||
|
text: i18n("Subscribed since: %1", feed.subscribed.toLocaleString(Qt.locale(), Locale.ShortFormat))
|
||||||
|
}
|
||||||
|
Controls.Label {
|
||||||
|
text: i18n("last updated: %1", feed.lastUpdated.toLocaleString(Qt.locale(), Locale.ShortFormat))
|
||||||
|
}
|
||||||
|
Controls.Label {
|
||||||
|
text: i18n("%1 posts, %2 unread", feed.entryCount, feed.unreadEntryCount)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user