diff --git a/src/downloadmanager.cpp b/src/downloadmanager.cpp index 1b127ce5..7c964f21 100644 --- a/src/downloadmanager.cpp +++ b/src/downloadmanager.cpp @@ -31,7 +31,7 @@ QCoro::QmlTask DownloadManager::downloadSong(const QString &videoId) void DownloadManager::deleteDownload(const QString &videoId) { - QString directory = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) % "/downloads/"; + QString directory = downloadDirectory(); QFile::remove(directory % videoId); auto future = Library::instance().markSongDownloaded(videoId, false); @@ -40,6 +40,11 @@ void DownloadManager::deleteDownload(const QString &videoId) }); } +QString DownloadManager::localPathOf(const QString &videoId) +{ + return downloadDirectory() % "/" % videoId; +} + QCoro::Task<> DownloadManager::download(const QString videoId) { auto info = co_await YTMusicThread::instance()->extractVideoInfo(videoId); @@ -47,7 +52,7 @@ QCoro::Task<> DownloadManager::download(const QString videoId) auto *reply = Library::instance().nam().get(QNetworkRequest(url)); - QString directory = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) % "/downloads"; + QString directory = downloadDirectory(); QDir(directory).mkpath("."); QString location = directory % "/" % videoId; @@ -77,20 +82,22 @@ QCoro::Task<> DownloadManager::download(const QString videoId) Q_EMIT Library::instance().downloadedChanged(videoId); } +QString DownloadManager::downloadDirectory() +{ + return QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) % "/downloads/"; +} + DownloadedWatcher::DownloadedWatcher(QObject *parent) : QObject(parent) { auto update = [this]() { qDebug() << "checking downloaded"; - auto future = Library::instance().database().getResult>( - "select count(*) > 0 from downloaded_songs where video_id = ?", m_videoId); + auto future = Library::instance().songDownloaded(m_videoId); QCoro::connect(std::move(future), this, [this](auto downloaded) { - if (downloaded) { - m_downloaded = downloaded->value; - qDebug() << "downloaded" << m_downloaded; - Q_EMIT downloadedChanged(); - } + m_downloaded = downloaded; + qDebug() << "downloaded" << m_downloaded; + Q_EMIT downloadedChanged(); }); }; diff --git a/src/downloadmanager.h b/src/downloadmanager.h index f380eb80..ed905090 100644 --- a/src/downloadmanager.h +++ b/src/downloadmanager.h @@ -18,8 +18,12 @@ public: Q_INVOKABLE QCoro::QmlTask downloadSong(const QString &videoId); Q_INVOKABLE void deleteDownload(const QString &videoId); + static QString localPathOf(const QString &videoId); + private: QCoro::Task<> download(const QString videoId); + + static QString downloadDirectory(); }; class DownloadedWatcher : public QObject diff --git a/src/library.cpp b/src/library.cpp index 43e1d15a..5844e0e9 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -176,6 +176,18 @@ QFuture Library::markSongDownloaded(const QString &videoId, bool downloade } } +QCoro::Task Library::songDownloaded(const QString &videoId) +{ + auto downloaded = co_await Library::instance().database().getResult>( + "select count(*) > 0 from downloaded_songs where video_id = ?", videoId); + + if (downloaded) { + co_return downloaded->value; + } else { + co_return false; + } +} + PlaybackHistoryModel::PlaybackHistoryModel(QFuture> &&songs, QObject *parent) : QAbstractListModel(parent) { diff --git a/src/library.h b/src/library.h index ca10cf41..0d062e7b 100644 --- a/src/library.h +++ b/src/library.h @@ -181,6 +181,7 @@ public: QFuture addSong(const QString &videoId, const QString &title, const QString &artist, const QString &album); QFuture markSongDownloaded(const QString &videoId, bool downloaded); + QCoro::Task songDownloaded(const QString &videoId); Q_SIGNAL void downloadedChanged(const QString &videoId); diff --git a/src/videoinfoextractor.cpp b/src/videoinfoextractor.cpp index c5e76047..4e48d07f 100644 --- a/src/videoinfoextractor.cpp +++ b/src/videoinfoextractor.cpp @@ -5,6 +5,8 @@ #include "videoinfoextractor.h" #include "asyncytmusic.h" +#include "library.h" +#include "downloadmanager.h" VideoInfoExtractor::VideoInfoExtractor(QObject *parent) : QObject(parent) @@ -18,18 +20,31 @@ VideoInfoExtractor::VideoInfoExtractor(QObject *parent) setLoading(true); - auto future = YTMusicThread::instance()->extractVideoInfo(QString::fromStdString(m_videoId.toStdString())); - QCoro::connect(std::move(future), this, [this](const video_info::VideoInfo &videoInfo) { - m_videoInfo = videoInfo; - setLoading(false); - Q_EMIT songChanged(); + QCoro::connect(Library::instance().songDownloaded(m_videoId), this, [this](bool downloaded) { + m_downloaded = downloaded; + if (downloaded) { + Q_EMIT songChanged(); + } + + auto future = YTMusicThread::instance()->extractVideoInfo(QString::fromStdString(m_videoId.toStdString())); + QCoro::connect(std::move(future), this, [this, downloaded](const video_info::VideoInfo &videoInfo) { + m_videoInfo = videoInfo; + setLoading(false); + if (!downloaded) { + Q_EMIT songChanged(); + } + }); }); }); } QUrl VideoInfoExtractor::audioUrl() const { - return pickAudioUrl(m_videoInfo.formats); + if (m_downloaded) { + return QUrl::fromLocalFile(DownloadManager::localPathOf(m_videoId)); + } else { + return pickAudioUrl(m_videoInfo.formats); + } } QString VideoInfoExtractor::videoId() const diff --git a/src/videoinfoextractor.h b/src/videoinfoextractor.h index 9239e5d4..3a16b132 100644 --- a/src/videoinfoextractor.h +++ b/src/videoinfoextractor.h @@ -47,6 +47,7 @@ public: private: bool m_loading = false; + bool m_downloaded = false; QString m_videoId; video_info::VideoInfo m_videoInfo; };