Add capability to monitor ongoing downloads

This commit is contained in:
Bart De Vries 2021-04-21 23:09:19 +02:00
parent 8c32389b65
commit a50c8bf001
8 changed files with 123 additions and 13 deletions

View File

@ -11,6 +11,7 @@ add_executable(alligator
enclosuredownloadjob.cpp enclosuredownloadjob.cpp
queuemodel.cpp queuemodel.cpp
episodemodel.cpp episodemodel.cpp
downloadprogressmodel.cpp
datamanager.cpp datamanager.cpp
audiomanager.cpp audiomanager.cpp
powermanagementinterface.cpp powermanagementinterface.cpp

View File

@ -0,0 +1,53 @@
/**
* SPDX-FileCopyrightText: 2021 Bart De Vries <bart@mogwai.be>
*
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
#include "downloadprogressmodel.h"
#include "datamanager.h"
DownloadProgressModel::DownloadProgressModel()
: QAbstractListModel(nullptr)
{
m_entries.clear();
}
QVariant DownloadProgressModel::data(const QModelIndex &index, int role) const
{
if (role != 0)
return QVariant();
return QVariant::fromValue(DataManager::instance().getEntry(m_entries[index.row()]));
}
QHash<int, QByteArray> DownloadProgressModel::roleNames() const
{
QHash<int, QByteArray> roleNames;
roleNames[0] = "entry";
return roleNames;
}
int DownloadProgressModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return m_entries.count();
}
void DownloadProgressModel::monitorDownloadProgress(Entry* entry, Enclosure::Status status)
{
qDebug() << "download status changed:" << entry->title() << status;
if (status == Enclosure::Downloading && !m_entries.contains(entry->id())) {
qDebug() << "inserting dowloading entry" << entry->id() << "in position" << m_entries.count();
beginInsertRows(QModelIndex(), m_entries.count(), m_entries.count());
m_entries += entry->id();
endInsertRows();
}
if (status != Enclosure::Downloading && m_entries.contains(entry->id())) {
int index = m_entries.indexOf(entry->id());
qDebug() << "removing dowloading entry" << entry->id() << "in position" << index;
beginRemoveRows(QModelIndex(), index, index);
m_entries.removeAt(index);
endRemoveRows();
}
}

View File

@ -0,0 +1,38 @@
/**
* SPDX-FileCopyrightText: 2021 Bart De Vries <bart@mogwai.be>
*
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
#pragma once
#include <QAbstractListModel>
#include <QHash>
#include <QObject>
#include <QVariant>
#include "entry.h"
#include "enclosure.h"
class DownloadProgressModel : public QAbstractListModel
{
Q_OBJECT
public:
static DownloadProgressModel &instance()
{
static DownloadProgressModel _instance;
return _instance;
}
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
QHash<int, QByteArray> roleNames() const override;
int rowCount(const QModelIndex &parent) const override;
public Q_SLOTS:
void monitorDownloadProgress(Entry* entry, Enclosure::Status status);
private:
explicit DownloadProgressModel();
QStringList m_entries;
};

View File

@ -16,11 +16,18 @@
#include "enclosuredownloadjob.h" #include "enclosuredownloadjob.h"
#include "entry.h" #include "entry.h"
#include "fetcher.h" #include "fetcher.h"
#include "downloadprogressmodel.h"
Enclosure::Enclosure(Entry *entry) Enclosure::Enclosure(Entry *entry)
: QObject(entry) : QObject(entry)
, m_entry(entry) , m_entry(entry)
{ {
// Set up signals to make DownloadProgressModel aware of ongoing downloads
connect(this, &Enclosure::statusChanged, this, [this]() {
Q_EMIT downloadStatusChanged(m_entry, m_status);
});
connect(this, &Enclosure::downloadStatusChanged, &DownloadProgressModel::instance(), &DownloadProgressModel::monitorDownloadProgress);
QSqlQuery query; QSqlQuery query;
query.prepare(QStringLiteral("SELECT * FROM Enclosures WHERE id=:id")); query.prepare(QStringLiteral("SELECT * FROM Enclosures WHERE id=:id"));
query.bindValue(QStringLiteral(":id"), entry->id()); query.bindValue(QStringLiteral(":id"), entry->id());

View File

@ -59,6 +59,7 @@ Q_SIGNALS:
void playPositionChanged(); void playPositionChanged();
void durationChanged(); void durationChanged();
void sizeChanged(); void sizeChanged();
void downloadStatusChanged(Entry* entry, Status status);
private: private:

View File

@ -30,6 +30,7 @@
#include "fetcher.h" #include "fetcher.h"
#include "queuemodel.h" #include "queuemodel.h"
#include "episodemodel.h" #include "episodemodel.h"
#include "downloadprogressmodel.h"
#include "datamanager.h" #include "datamanager.h"
#include "audiomanager.h" #include "audiomanager.h"
#include "mpris2/mpris2.h" #include "mpris2/mpris2.h"
@ -71,10 +72,10 @@ int main(int argc, char *argv[])
engine->setObjectOwnership(SettingsManager::self(), QQmlEngine::CppOwnership); engine->setObjectOwnership(SettingsManager::self(), QQmlEngine::CppOwnership);
return SettingsManager::self(); return SettingsManager::self();
}); });
/*qmlRegisterSingletonType<AudioManager>("org.kde.alligator", 1, 0, "AudioManager", [](QQmlEngine *engine, QJSEngine *) -> QObject * { qmlRegisterSingletonType<DownloadProgressModel>("org.kde.alligator", 1, 0, "DownloadProgressModel", [](QQmlEngine *engine, QJSEngine *) -> QObject * {
engine->setObjectOwnership(&AudioManager::instance(), QQmlEngine::CppOwnership); engine->setObjectOwnership(&DownloadProgressModel::instance(), QQmlEngine::CppOwnership);
return &AudioManager::instance(); return &DownloadProgressModel::instance();
});*/ });
qmlRegisterType<AudioManager>("org.kde.alligator", 1, 0, "AudioManager"); qmlRegisterType<AudioManager>("org.kde.alligator", 1, 0, "AudioManager");
qmlRegisterType<Mpris2>("org.kde.alligator", 1, 0, "Mpris2"); qmlRegisterType<Mpris2>("org.kde.alligator", 1, 0, "Mpris2");
@ -104,7 +105,7 @@ int main(int argc, char *argv[])
DataManager::instance(); DataManager::instance();
//AudioManager::instance(); DownloadProgressModel::instance();
engine.load(QUrl(QStringLiteral("qrc:///main.qml"))); engine.load(QUrl(QStringLiteral("qrc:///main.qml")));

View File

@ -44,7 +44,7 @@ Kirigami.Page {
Controls.TabButton { Controls.TabButton {
width: parent.parent.width/parent.count width: parent.parent.width/parent.count
height: tabBarHeight height: tabBarHeight
text: i18n("Running") text: i18n("In Progress")
} }
Controls.TabButton { Controls.TabButton {
width: parent.parent.width/parent.count width: parent.parent.width/parent.count
@ -60,7 +60,7 @@ Kirigami.Page {
currentIndex: Kirigami.Settings.isMobile ? footerLoader.item.currentIndex : headerLoader.item.currentIndex currentIndex: Kirigami.Settings.isMobile ? footerLoader.item.currentIndex : headerLoader.item.currentIndex
EpisodeListPage { EpisodeListPage {
title: i18n("Running") title: i18n("In Progress")
episodeType: EpisodeModel.Downloading episodeType: EpisodeModel.Downloading
} }

View File

@ -34,10 +34,12 @@ Kirigami.ScrollablePage {
width: Kirigami.Units.gridUnit * 20 width: Kirigami.Units.gridUnit * 20
anchors.centerIn: parent anchors.centerIn: parent
text: i18n("No %1 available", episodeType === EpisodeModel.All ? i18n("episodes") text: i18n(episodeType === EpisodeModel.All ? i18n("No episodes available")
: episodeType === EpisodeModel.New ? i18n("new episodes") : episodeType === EpisodeModel.New ? i18n("No new episodes")
: episodeType === EpisodeModel.Unread ? i18n("unread episodes") : episodeType === EpisodeModel.Unread ? i18n("No unread episodes")
: i18n("episodes")) : episodeType === EpisodeModel.Downloaded ? i18n("No downloaded episodes")
: episodeType === EpisodeModel.Downloading ? i18n("No downloads in progress")
: i18n("No episodes available"))
} }
Component { Component {
id: episodeListDelegate id: episodeListDelegate
@ -46,14 +48,21 @@ Kirigami.ScrollablePage {
isDownloads: episodeType == EpisodeModel.Downloaded || episodeType == EpisodeModel.Downloading isDownloads: episodeType == EpisodeModel.Downloaded || episodeType == EpisodeModel.Downloading
} }
} }
EpisodeModel {
id: episodeModel
type: episodeType
}
ListView { ListView {
anchors.fill: parent anchors.fill: parent
id: episodeList id: episodeList
visible: count !== 0 visible: count !== 0
model: EpisodeModel { type: episodeType } model: episodeType === EpisodeModel.Downloading ? DownloadProgressModel
: episodeModel
delegate: Kirigami.DelegateRecycler { delegate: Kirigami.DelegateRecycler {
width: episodeList.width width: episodeList.width
sourceComponent: episodeListDelegate sourceComponent: episodeListDelegate
} }
} }