Implement Enclosure::PartiallyDownloaded status

Still to be done:
- Update Download Page to show partial downloads.
- Connect signals to Download Page to update whenever an enclosure
  changes status.  This is broken by this commit because
  downloadCountChanged has been removed.
This commit is contained in:
Bart De Vries 2021-06-23 21:11:04 +02:00
parent 03081edc66
commit f197e6ab02
11 changed files with 164 additions and 105 deletions

View File

@ -44,6 +44,8 @@ bool Database::migrate()
TRUE_OR_RETURN(migrateTo1()); TRUE_OR_RETURN(migrateTo1());
if (dbversion < 2) if (dbversion < 2)
TRUE_OR_RETURN(migrateTo2()); TRUE_OR_RETURN(migrateTo2());
if (dbversion < 3)
TRUE_OR_RETURN(migrateTo3());
return true; return true;
} }
@ -75,6 +77,17 @@ bool Database::migrateTo2()
return true; return true;
} }
bool Database::migrateTo3()
{
qDebug() << "Migrating database to version 3";
TRUE_OR_RETURN(execute(QStringLiteral("ALTER TABLE Enclosures RENAME COLUMN downloaded TO downloaded_temp;")));
TRUE_OR_RETURN(execute(QStringLiteral("ALTER TABLE Enclosures ADD COLUMN downloaded INTEGER DEFAULT 0;")));
TRUE_OR_RETURN(execute(QStringLiteral("UPDATE Enclosures SET downloaded=3 where downloaded_temp=1;")));
TRUE_OR_RETURN(execute(QStringLiteral("ALTER TABLE Enclosures DROP COLUMN downloaded_temp;")));
TRUE_OR_RETURN(execute(QStringLiteral("PRAGMA user_version = 3;")));
return true;
}
bool Database::execute(const QString &query) bool Database::execute(const QString &query)
{ {
QSqlQuery q; QSqlQuery q;

View File

@ -29,5 +29,6 @@ private:
bool migrate(); bool migrate();
bool migrateTo1(); bool migrateTo1();
bool migrateTo2(); bool migrateTo2();
bool migrateTo3();
void cleanup(); void cleanup();
}; };

View File

@ -157,11 +157,16 @@ Entry *DataManager::getEntry(const EpisodeModel::Type type, const int entry_inde
entryQuery.bindValue(QStringLiteral(":read"), false); entryQuery.bindValue(QStringLiteral(":read"), false);
} else if (type == EpisodeModel::All) { } else if (type == EpisodeModel::All) {
entryQuery.prepare(QStringLiteral("SELECT id FROM Entries ORDER BY updated DESC LIMIT 1 OFFSET :index;")); entryQuery.prepare(QStringLiteral("SELECT id FROM Entries ORDER BY updated DESC LIMIT 1 OFFSET :index;"));
} else { // i.e. EpisodeModel::Downloaded } else if (type == EpisodeModel::Downloaded) {
entryQuery.prepare( entryQuery.prepare(
QStringLiteral("SELECT * FROM Enclosures INNER JOIN Entries ON Enclosures.id = Entries.id WHERE downloaded=:downloaded ORDER BY updated DESC " QStringLiteral("SELECT * FROM Enclosures INNER JOIN Entries ON Enclosures.id = Entries.id WHERE downloaded=:downloaded ORDER BY updated DESC "
"LIMIT 1 OFFSET :index;")); "LIMIT 1 OFFSET :index;"));
entryQuery.bindValue(QStringLiteral(":downloaded"), true); entryQuery.bindValue(QStringLiteral(":downloaded"), Enclosure::statusToDb(Enclosure::Downloaded));
} else { // i.e. EpisodeModel::PartiallyDownloaded
entryQuery.prepare(
QStringLiteral("SELECT * FROM Enclosures INNER JOIN Entries ON Enclosures.id = Entries.id WHERE downloaded=:downloaded ORDER BY updated DESC "
"LIMIT 1 OFFSET :index;"));
entryQuery.bindValue(QStringLiteral(":downloaded"), Enclosure::statusToDb(Enclosure::PartiallyDownloaded));
} }
entryQuery.bindValue(QStringLiteral(":index"), entry_index); entryQuery.bindValue(QStringLiteral(":index"), entry_index);
Database::instance().execute(entryQuery); Database::instance().execute(entryQuery);
@ -202,9 +207,12 @@ int DataManager::entryCount(const EpisodeModel::Type type) const
query.bindValue(QStringLiteral(":read"), false); query.bindValue(QStringLiteral(":read"), false);
} else if (type == EpisodeModel::All) { } else if (type == EpisodeModel::All) {
query.prepare(QStringLiteral("SELECT COUNT (id) FROM Entries;")); query.prepare(QStringLiteral("SELECT COUNT (id) FROM Entries;"));
} else { // i.e. EpisodeModel::Downloaded } else if (type == EpisodeModel::Downloaded) {
query.prepare(QStringLiteral("SELECT COUNT (id) FROM Enclosures WHERE downloaded=:downloaded;")); query.prepare(QStringLiteral("SELECT COUNT (id) FROM Enclosures WHERE downloaded=:downloaded;"));
query.bindValue(QStringLiteral(":downloaded"), true); query.bindValue(QStringLiteral(":downloaded"), Enclosure::statusToDb(Enclosure::Downloaded));
} else { // i.e. EpisodeModel::PartiallyDownloaded
query.prepare(QStringLiteral("SELECT COUNT (id) FROM Enclosures WHERE downloaded=:downloaded;"));
query.bindValue(QStringLiteral(":downloaded"), Enclosure::statusToDb(Enclosure::PartiallyDownloaded));
} }
Database::instance().execute(query); Database::instance().execute(query);
if (!query.next()) if (!query.next())
@ -577,4 +585,4 @@ void DataManager::updateQueueListnrs() const
query.bindValue(QStringLiteral(":id"), m_queuemap[i]); query.bindValue(QStringLiteral(":id"), m_queuemap[i]);
Database::instance().execute(query); Database::instance().execute(query);
} }
} }

View File

@ -74,7 +74,6 @@ Q_SIGNALS:
void unreadEntryCountChanged(const QString &url); void unreadEntryCountChanged(const QString &url);
void newEntryCountChanged(const QString &url); void newEntryCountChanged(const QString &url);
void downloadCountChanged(const QString &url);
private: private:
DataManager(); DataManager();

View File

@ -33,6 +33,9 @@ Enclosure::Enclosure(Entry *entry)
// reported. Other times only the remaining part. // reported. Other times only the remaining part.
// Sometimes the value is rubbish (e.g. 2) // Sometimes the value is rubbish (e.g. 2)
// We assume that the value when starting a new download is correct. // We assume that the value when starting a new download is correct.
if (fileSize < resumedAt) {
fileSize += resumedAt;
}
qDebug() << "Correct filesize for enclosure" << url << "from" << m_size << "to" << fileSize; qDebug() << "Correct filesize for enclosure" << url << "from" << m_size << "to" << fileSize;
setSize(fileSize); setSize(fileSize);
} }
@ -53,7 +56,7 @@ Enclosure::Enclosure(Entry *entry)
m_type = query.value(QStringLiteral("type")).toString(); m_type = query.value(QStringLiteral("type")).toString();
m_url = query.value(QStringLiteral("url")).toString(); m_url = query.value(QStringLiteral("url")).toString();
m_playposition = query.value(QStringLiteral("playposition")).toLongLong(); m_playposition = query.value(QStringLiteral("playposition")).toLongLong();
m_status = query.value(QStringLiteral("downloaded")).toBool() ? Downloaded : Downloadable; m_status = dbToStatus(query.value(QStringLiteral("downloaded")).toInt());
m_playposition_dbsave = m_playposition; m_playposition_dbsave = m_playposition;
// In principle the database contains this status, we check anyway in case // In principle the database contains this status, we check anyway in case
@ -61,38 +64,53 @@ Enclosure::Enclosure(Entry *entry)
QFile file(path()); QFile file(path());
if (file.exists()) { if (file.exists()) {
if (file.size() == m_size && file.size() > 0) { if (file.size() == m_size && file.size() > 0) {
if (m_status == Downloadable) { // file is on disk and has correct size, write to database if it
// file is on disk, but was not expected, write to database // wasn't already registered so
// this should, in principle, never happen unless the db was deleted // this should, in principle, never happen unless the db was deleted
m_status = Downloaded; setStatus(Downloaded);
query.prepare(QStringLiteral("UPDATE Enclosures SET downloaded=:downloaded WHERE id=:id;")); } else if (file.size() > 0) {
query.bindValue(QStringLiteral(":id"), entry->id()); // file was downloaded, but there is a size mismatch
query.bindValue(QStringLiteral(":downloaded"), true); // set to PartiallyDownloaded such that download can be resumed
Database::instance().execute(query); setStatus(PartiallyDownloaded);
}
} else { } else {
if (m_status == Downloaded) { // file is empty
// file was downloaded, but there is a size mismatch or file is empty setStatus(Downloadable);
// update status in database
// don't actually delete the file such that the download can be resumed
m_status = Downloadable;
query.prepare(QStringLiteral("UPDATE Enclosures SET downloaded=:downloaded WHERE id=:id;"));
query.bindValue(QStringLiteral(":id"), entry->id());
query.bindValue(QStringLiteral(":downloaded"), false);
Database::instance().execute(query);
}
} }
} else { } else {
if (m_status == Downloaded) { // file does not exist
// file was supposed to be on disk, but isn't there setStatus(Downloadable);
// update status and write to the database }
file.remove(); }
m_status = Downloadable;
query.prepare(QStringLiteral("UPDATE Enclosures SET downloaded=:downloaded WHERE id=:id;")); int Enclosure::statusToDb(Enclosure::Status status)
query.bindValue(QStringLiteral(":id"), entry->id()); {
query.bindValue(QStringLiteral(":downloaded"), false); switch (status) {
Database::instance().execute(query); case Enclosure::Status::Downloadable:
} return 0;
case Enclosure::Status::Downloading:
return 1;
case Enclosure::Status::PartiallyDownloaded:
return 2;
case Enclosure::Status::Downloaded:
return 3;
default:
return -1;
}
}
Enclosure::Status Enclosure::dbToStatus(int value)
{
switch (value) {
case 0:
return Enclosure::Status::Downloadable;
case 1:
return Enclosure::Status::Downloading;
case 2:
return Enclosure::Status::PartiallyDownloaded;
case 3:
return Enclosure::Status::Downloaded;
default:
return Enclosure::Status::Error;
} }
} }
@ -111,7 +129,12 @@ void Enclosure::download()
if (downloadJob->error() == 0) { if (downloadJob->error() == 0) {
processDownloadedFile(); processDownloadedFile();
} else { } else {
m_status = Downloadable; QFile file(path());
if (file.exists() && file.size() > 0) {
setStatus(PartiallyDownloaded);
} else {
setStatus(Downloadable);
}
if (downloadJob->error() != QNetworkReply::OperationCanceledError) { if (downloadJob->error() != QNetworkReply::OperationCanceledError) {
m_entry->feed()->setErrorId(downloadJob->error()); m_entry->feed()->setErrorId(downloadJob->error());
m_entry->feed()->setErrorString(downloadJob->errorString()); m_entry->feed()->setErrorString(downloadJob->errorString());
@ -124,9 +147,12 @@ void Enclosure::download()
connect(this, &Enclosure::cancelDownload, this, [this, downloadJob]() { connect(this, &Enclosure::cancelDownload, this, [this, downloadJob]() {
downloadJob->doKill(); downloadJob->doKill();
m_status = Downloadable; QFile file(path());
Q_EMIT statusChanged(m_entry, m_status); if (file.exists() && file.size() > 0) {
Q_EMIT DataManager::instance().downloadCountChanged(m_entry->feed()->url()); setStatus(PartiallyDownloaded);
} else {
setStatus(Downloadable);
}
disconnect(this, &Enclosure::cancelDownload, this, nullptr); disconnect(this, &Enclosure::cancelDownload, this, nullptr);
}); });
@ -135,8 +161,7 @@ void Enclosure::download()
Q_EMIT downloadProgressChanged(); Q_EMIT downloadProgressChanged();
}); });
m_status = Downloading; setStatus(Downloading);
Q_EMIT statusChanged(m_entry, m_status);
} }
void Enclosure::processDownloadedFile() void Enclosure::processDownloadedFile()
@ -159,17 +184,10 @@ void Enclosure::processDownloadedFile()
setSize(file.size()); setSize(file.size());
} }
m_status = Downloaded; setStatus(Downloaded);
QSqlQuery query;
query.prepare(QStringLiteral("UPDATE Enclosures SET downloaded=:downloaded WHERE id=:id;"));
query.bindValue(QStringLiteral(":id"), m_entry->id());
query.bindValue(QStringLiteral(":downloaded"), true);
Database::instance().execute(query);
// Unset "new" status of item // Unset "new" status of item
if (m_entry->getNew()) if (m_entry->getNew())
m_entry->setNew(false); m_entry->setNew(false);
Q_EMIT DataManager::instance().downloadCountChanged(m_entry->feed()->url());
} }
void Enclosure::deleteFile() void Enclosure::deleteFile()
@ -179,14 +197,7 @@ void Enclosure::deleteFile()
if (QFile(path()).exists()) if (QFile(path()).exists())
QFile(path()).remove(); QFile(path()).remove();
// If file disappeared unexpectedly, then still change status to downloadable // If file disappeared unexpectedly, then still change status to downloadable
m_status = Downloadable; setStatus(Downloadable);
QSqlQuery query;
query.prepare(QStringLiteral("UPDATE Enclosures SET downloaded=:downloaded WHERE id=:id;"));
query.bindValue(QStringLiteral(":id"), m_entry->id());
query.bindValue(QStringLiteral(":downloaded"), false);
Database::instance().execute(query);
Q_EMIT statusChanged(m_entry, m_status);
Q_EMIT DataManager::instance().downloadCountChanged(m_entry->feed()->url());
} }
QString Enclosure::path() const QString Enclosure::path() const
@ -214,52 +225,77 @@ int Enclosure::size() const
return m_size; return m_size;
} }
void Enclosure::setPlayPosition(const qint64 &position) void Enclosure::setStatus(Enclosure::Status status)
{ {
m_playposition = position; if (m_status != status) {
qCDebug(kastsEnclosure) << "save playPosition" << position << m_entry->title(); m_status = status;
Q_EMIT playPositionChanged();
// let's only save the play position to the database every 15 seconds
if ((abs(m_playposition - m_playposition_dbsave) > 15000) || position == 0) {
qCDebug(kastsEnclosure) << "save playPosition to database" << position << m_entry->title();
QSqlQuery query; QSqlQuery query;
query.prepare(QStringLiteral("UPDATE Enclosures SET playposition=:playposition WHERE id=:id AND feed=:feed")); query.prepare(QStringLiteral("UPDATE Enclosures SET downloaded=:downloaded WHERE id=:id AND feed=:feed;"));
query.bindValue(QStringLiteral(":id"), m_entry->id()); query.bindValue(QStringLiteral(":id"), m_entry->id());
query.bindValue(QStringLiteral(":feed"), m_entry->feed()->url()); query.bindValue(QStringLiteral(":feed"), m_entry->feed()->url());
query.bindValue(QStringLiteral(":playposition"), m_playposition); query.bindValue(QStringLiteral(":downloaded"), statusToDb(m_status));
Database::instance().execute(query); Database::instance().execute(query);
m_playposition_dbsave = m_playposition;
Q_EMIT statusChanged(m_entry, m_status);
}
}
void Enclosure::setPlayPosition(const qint64 &position)
{
if (m_playposition != position) {
m_playposition = position;
qCDebug(kastsEnclosure) << "save playPosition" << position << m_entry->title();
// let's only save the play position to the database every 15 seconds
if ((abs(m_playposition - m_playposition_dbsave) > 15000) || position == 0) {
qCDebug(kastsEnclosure) << "save playPosition to database" << position << m_entry->title();
QSqlQuery query;
query.prepare(QStringLiteral("UPDATE Enclosures SET playposition=:playposition WHERE id=:id AND feed=:feed"));
query.bindValue(QStringLiteral(":id"), m_entry->id());
query.bindValue(QStringLiteral(":feed"), m_entry->feed()->url());
query.bindValue(QStringLiteral(":playposition"), m_playposition);
Database::instance().execute(query);
m_playposition_dbsave = m_playposition;
}
Q_EMIT playPositionChanged();
} }
} }
void Enclosure::setDuration(const qint64 &duration) void Enclosure::setDuration(const qint64 &duration)
{ {
m_duration = duration; if (m_duration != duration) {
Q_EMIT durationChanged(); m_duration = duration;
// also save to database // also save to database
qCDebug(kastsEnclosure) << "updating entry duration" << duration << m_entry->title(); qCDebug(kastsEnclosure) << "updating entry duration" << duration << m_entry->title();
QSqlQuery query; QSqlQuery query;
query.prepare(QStringLiteral("UPDATE Enclosures SET duration=:duration WHERE id=:id AND feed=:feed")); query.prepare(QStringLiteral("UPDATE Enclosures SET duration=:duration WHERE id=:id AND feed=:feed"));
query.bindValue(QStringLiteral(":id"), m_entry->id()); query.bindValue(QStringLiteral(":id"), m_entry->id());
query.bindValue(QStringLiteral(":feed"), m_entry->feed()->url()); query.bindValue(QStringLiteral(":feed"), m_entry->feed()->url());
query.bindValue(QStringLiteral(":duration"), m_duration); query.bindValue(QStringLiteral(":duration"), m_duration);
Database::instance().execute(query); Database::instance().execute(query);
Q_EMIT durationChanged();
}
} }
void Enclosure::setSize(const int &size) void Enclosure::setSize(const int &size)
{ {
m_size = size; if (m_size != size) {
Q_EMIT sizeChanged(); m_size = size;
// also save to database // also save to database
QSqlQuery query; QSqlQuery query;
query.prepare(QStringLiteral("UPDATE Enclosures SET size=:size WHERE id=:id AND feed=:feed")); query.prepare(QStringLiteral("UPDATE Enclosures SET size=:size WHERE id=:id AND feed=:feed"));
query.bindValue(QStringLiteral(":id"), m_entry->id()); query.bindValue(QStringLiteral(":id"), m_entry->id());
query.bindValue(QStringLiteral(":feed"), m_entry->feed()->url()); query.bindValue(QStringLiteral(":feed"), m_entry->feed()->url());
query.bindValue(QStringLiteral(":size"), m_size); query.bindValue(QStringLiteral(":size"), m_size);
Database::instance().execute(query); Database::instance().execute(query);
Q_EMIT sizeChanged();
}
} }
QString Enclosure::formattedSize() const QString Enclosure::formattedSize() const

View File

@ -26,7 +26,7 @@ class Enclosure : public QObject
Q_PROPERTY(QString title MEMBER m_title CONSTANT) Q_PROPERTY(QString title MEMBER m_title CONSTANT)
Q_PROPERTY(QString type MEMBER m_type CONSTANT) Q_PROPERTY(QString type MEMBER m_type CONSTANT)
Q_PROPERTY(QString url MEMBER m_url CONSTANT) Q_PROPERTY(QString url MEMBER m_url CONSTANT)
Q_PROPERTY(Status status READ status NOTIFY statusChanged) Q_PROPERTY(Status status READ status WRITE setStatus NOTIFY statusChanged)
Q_PROPERTY(double downloadProgress MEMBER m_downloadProgress NOTIFY downloadProgressChanged) Q_PROPERTY(double downloadProgress MEMBER m_downloadProgress NOTIFY downloadProgressChanged)
Q_PROPERTY(QString path READ path CONSTANT) Q_PROPERTY(QString path READ path CONSTANT)
Q_PROPERTY(qint64 playPosition READ playPosition WRITE setPlayPosition NOTIFY playPositionChanged) Q_PROPERTY(qint64 playPosition READ playPosition WRITE setPlayPosition NOTIFY playPositionChanged)
@ -40,11 +40,15 @@ public:
enum Status { enum Status {
Downloadable, Downloadable,
Downloading, Downloading,
PartiallyDownloaded,
Downloaded, Downloaded,
Error, Error,
}; };
Q_ENUM(Status) Q_ENUM(Status)
static int statusToDb(Status status); // needed to translate Enclosure::Status values to int for sqlite
static Status dbToStatus(int value); // needed to translate from int to Enclosure::Status values for sqlite
Q_INVOKABLE void download(); Q_INVOKABLE void download();
Q_INVOKABLE void deleteFile(); Q_INVOKABLE void deleteFile();
@ -57,6 +61,7 @@ public:
QString formattedDuration() const; QString formattedDuration() const;
QString formattedPlayPosition() const; QString formattedPlayPosition() const;
void setStatus(Status status);
void setPlayPosition(const qint64 &position); void setPlayPosition(const qint64 &position);
void setDuration(const qint64 &duration); void setDuration(const qint64 &duration);
void setSize(const int &size); void setSize(const int &size);
@ -84,4 +89,4 @@ private:
double m_downloadProgress = 0; double m_downloadProgress = 0;
Status m_status; Status m_status;
KFormat m_kformat; KFormat m_kformat;
}; };

View File

@ -65,13 +65,5 @@ void EpisodeModel::setType(EpisodeModel::Type type)
beginResetModel(); beginResetModel();
endResetModel(); endResetModel();
}); });
} else if (m_type == EpisodeModel::Downloaded) { // TODO: this needs to be removed !!!!!!
connect(&DataManager::instance(), &DataManager::downloadCountChanged, this, [this](const QString &url) {
Q_UNUSED(url)
// we have to reset the entire model in case entries are removed or added
// because we have no way of knowing where those entries will be added/removed
beginResetModel();
endResetModel();
});
} }
} }

View File

@ -22,6 +22,7 @@ public:
Unread, Unread,
Downloading, Downloading,
Downloaded, Downloaded,
PartiallyDownloaded,
}; };
Q_ENUM(Type) Q_ENUM(Type)

View File

@ -21,6 +21,7 @@
#include <Syndication/Syndication> #include <Syndication/Syndication>
#include "database.h" #include "database.h"
#include "enclosure.h"
#include "fetcher.h" #include "fetcher.h"
#include "fetcherlogging.h" #include "fetcherlogging.h"
#include "settingsmanager.h" #include "settingsmanager.h"
@ -339,7 +340,7 @@ void Fetcher::processEnclosure(Syndication::EnclosurePtr enclosure, Syndication:
query.bindValue(QStringLiteral(":type"), enclosure->type()); query.bindValue(QStringLiteral(":type"), enclosure->type());
query.bindValue(QStringLiteral(":url"), enclosure->url()); query.bindValue(QStringLiteral(":url"), enclosure->url());
query.bindValue(QStringLiteral(":playposition"), 0); query.bindValue(QStringLiteral(":playposition"), 0);
query.bindValue(QStringLiteral(":downloaded"), false); query.bindValue(QStringLiteral(":downloaded"), Enclosure::statusToDb(Enclosure::Downloadable));
Database::instance().execute(query); Database::instance().execute(query);
} }

View File

@ -69,22 +69,25 @@ Kirigami.ScrollablePage {
actions.main: Kirigami.Action { actions.main: Kirigami.Action {
text: !entry.enclosure ? i18n("Open in Browser") : text: !entry.enclosure ? i18n("Open in Browser") :
entry.enclosure.status === Enclosure.Downloadable ? i18n("Download") : (entry.enclosure.status === Enclosure.Downloadable || entry.enclosure.status === Enclosure.PartiallyDownloaded) ? i18n("Download") :
entry.enclosure.status === Enclosure.Downloading ? i18n("Cancel Download") : entry.enclosure.status === Enclosure.Downloading ? i18n("Cancel Download") :
!entry.queueStatus ? i18n("Delete Download") : !entry.queueStatus ? i18n("Delete Download") :
(AudioManager.entry === entry && AudioManager.playbackState === Audio.PlayingState) ? i18n("Pause") : (AudioManager.entry === entry && AudioManager.playbackState === Audio.PlayingState) ? i18n("Pause") :
i18n("Play") i18n("Play")
icon.name: !entry.enclosure ? "globe" : icon.name: !entry.enclosure ? "globe" :
entry.enclosure.status === Enclosure.Downloadable ? "download" : (entry.enclosure.status === Enclosure.Downloadable || entry.enclosure.status === Enclosure.PartiallyDownloaded) ? "download" :
entry.enclosure.status === Enclosure.Downloading ? "edit-delete-remove" : entry.enclosure.status === Enclosure.Downloading ? "edit-delete-remove" :
!entry.queueStatus ? "delete" : !entry.queueStatus ? "delete" :
(AudioManager.entry === entry && AudioManager.playbackState === Audio.PlayingState) ? "media-playback-pause" : (AudioManager.entry === entry && AudioManager.playbackState === Audio.PlayingState) ? "media-playback-pause" :
"media-playback-start" "media-playback-start"
onTriggered: { onTriggered: {
if(!entry.enclosure) Qt.openUrlExternally(entry.link) if (!entry.enclosure) {
else if(entry.enclosure.status === Enclosure.Downloadable) entry.enclosure.download() Qt.openUrlExternally(entry.link)
else if(entry.enclosure.status === Enclosure.Downloading) entry.enclosure.cancelDownload() } else if (entry.enclosure.status === Enclosure.Downloadable || entry.enclosure.status === Enclosure.PartiallyDownloaded) {
else if(!entry.queueStatus) { entry.enclosure.download()
} else if (entry.enclosure.status === Enclosure.Downloading) {
entry.enclosure.cancelDownload()
} else if (!entry.queueStatus) {
entry.enclosure.deleteFile() entry.enclosure.deleteFile()
} else { } else {
if(AudioManager.entry === entry && AudioManager.playbackState === Audio.PlayingState) { if(AudioManager.entry === entry && AudioManager.playbackState === Audio.PlayingState) {

View File

@ -184,7 +184,7 @@ Kirigami.SwipeListItem {
entry.queueStatus = true; entry.queueStatus = true;
entry.enclosure.download(); entry.enclosure.download();
} }
visible: !isDownloads && entry.enclosure && entry.enclosure.status === Enclosure.Downloadable visible: !isDownloads && entry.enclosure && (entry.enclosure.status === Enclosure.Downloadable || entry.enclosure.status === Enclosure.PartiallyDownloaded)
}, },
Kirigami.Action { Kirigami.Action {
text: i18n("Cancel Download") text: i18n("Cancel Download")