[multimedia/kasts] src: Replace image loading and caching with normal qml image loading and QNetworkDiskCache

Bart De Vries <[email protected]> Tue, 4 Aug 2026 12:39:01 +0000 (UTC)
Newsgroups gmane.comp.kde.cvs
Message-ID <[email protected]>
Git commit c2bcbb8e1e79d8c4a438cd965d2161302de8b564 by Bart De Vries, on behalf of Tobias Fella.
Committed on 04/08/2026 at 07:43.
Pushed by bdevries into branch 'master'.

Replace image loading and caching with normal qml image loading and QNetworkDiskCache

M  +1    -1    src/audiomanager.cpp
M  +1    -24   src/chapter.cpp
M  +0    -3    src/chapter.h
M  +0    -1    src/enclosure.cpp
M  +0    -28   src/entry.cpp
M  +0    -3    src/entry.h
M  +0    -12   src/feed.cpp
M  +0    -3    src/feed.h
M  +0    -48   src/fetcher.cpp
M  +0    -1    src/fetcher.h
M  +22   -0    src/main.cpp
M  +1    -1    src/qml/ChapterListDelegate.qml
M  +2    -2    src/qml/Desktop/HeaderBar.qml
M  +1    -1    src/qml/EntryPage.qml
M  +1    -1    src/qml/FeedDetailsPage.qml
M  +1    -1    src/qml/FeedListDelegate.qml
M  +1    -1    src/qml/GenericEntryDelegate.qml
M  +1    -1    src/qml/GlobalSearchField.qml
M  +11   -3    src/qml/ImageWithFallback.qml
M  +1    -1    src/qml/Mobile/FooterBar.qml
M  +1    -1    src/qml/Mobile/MinimizedPlayerControls.qml
M  +2    -2    src/qml/Mobile/MobilePlayerControls.qml

https://invent.kde.org/multimedia/kasts/-/commit/c2bcbb8e1e79d8c4a438cd965d2161302de8b564

diff --git a/src/audiomanager.cpp b/src/audiomanager.cpp
index c2389d00..8d303995 100644
--- a/src/audiomanager.cpp
+++ b/src/audiomanager.cpp
@@ -807,7 +807,7 @@ void AudioManager::updateMetaData()
         d->m_player.metaData()->setArtist(d->m_entry->authors());
     }
     if (!d->m_entry->image().isEmpty()) {
-        d->m_player.metaData()->setArtworkUrl(QUrl(d->m_entry->cachedImage()));
+        d->m_player.metaData()->setArtworkUrl(QUrl(d->m_entry->image()));
     }
 }
 
diff --git a/src/chapter.cpp b/src/chapter.cpp
index 951e566b..3128562e 100644
--- a/src/chapter.cpp
+++ b/src/chapter.cpp
@@ -18,12 +18,6 @@ Chapter::Chapter(Entry *entry, const QString &title, const QString &link, const
     , m_start(start)
 {
     qCDebug(kastsObjects) << "Chapter object constructed: entryuid" << m_entry->entryuid() << ", chapter start" << m_start;
-    connect(&Fetcher::instance(), &Fetcher::downloadFinished, this, [this](QString url) {
-        if (url == m_image) {
-            Q_EMIT imageChanged(url);
-            Q_EMIT cachedImageChanged(cachedImage());
-        }
-    });
 }
 
 Chapter::~Chapter()
@@ -53,24 +47,8 @@ QString Chapter::image() const
     } else if (m_entry) {
         // fall back to entry image
         return m_entry->image();
-    } else {
-        return QStringLiteral("no-image");
     }
-}
-
-QString Chapter::cachedImage() const
-{
-    // First check for the feed image, fall back if needed
-    QString image = m_image;
-    if (image.isEmpty()) {
-        if (m_entry) {
-            return m_entry->cachedImage();
-        } else {
-            return QStringLiteral("no-image");
-        }
-    }
-
-    return Fetcher::instance().image(image);
+    return {};
 }
 
 int Chapter::start() const
@@ -104,7 +82,6 @@ void Chapter::setImage(const QString &image, bool emitSignal)
         m_image = image;
         if (emitSignal) {
             Q_EMIT imageChanged(m_image);
-            Q_EMIT cachedImageChanged(cachedImage());
         }
     }
 }
diff --git a/src/chapter.h b/src/chapter.h
index 3c7dbb06..6cdca065 100644
--- a/src/chapter.h
+++ b/src/chapter.h
@@ -23,7 +23,6 @@ class Chapter : public QObject
     Q_PROPERTY(QString title READ title NOTIFY titleChanged)
     Q_PROPERTY(QString link READ link NOTIFY linkChanged)
     Q_PROPERTY(QString image READ image NOTIFY imageChanged)
-    Q_PROPERTY(QString cachedImage READ cachedImage NOTIFY cachedImageChanged)
     Q_PROPERTY(int start READ start NOTIFY startChanged)
 
 public:
@@ -34,7 +33,6 @@ public:
     QString title() const;
     QString link() const;
     QString image() const;
-    QString cachedImage() const;
     int start() const;
 
     void setTitle(const QString &title, bool emitSignal = true);
@@ -46,7 +44,6 @@ Q_SIGNALS:
     void titleChanged(const QString &title);
     void linkChanged(const QString &link);
     void imageChanged(const QString &url);
-    void cachedImageChanged(const QString &imagePath);
     void startChanged(const int &start);
 
 private:
diff --git a/src/enclosure.cpp b/src/enclosure.cpp
index 206535ad..d0a6616b 100644
--- a/src/enclosure.cpp
+++ b/src/enclosure.cpp
@@ -311,7 +311,6 @@ void Enclosure::processDownloadedFile()
 
     // Trigger update of image since the downloaded file can have an embedded image
     Q_EMIT m_entry->imageChanged(m_entry->image());
-    Q_EMIT m_entry->cachedImageChanged(m_entry->cachedImage());
 }
 
 void Enclosure::deleteFile()
diff --git a/src/entry.cpp b/src/entry.cpp
index 91d9784e..99f858a0 100644
--- a/src/entry.cpp
+++ b/src/entry.cpp
@@ -52,15 +52,6 @@ Entry::Entry(const qint64 entryuid, QObject *parent)
             Q_EMIT queueStatusChanged(state);
         }
     });
-    connect(&Fetcher::instance(), &Fetcher::downloadFinished, this, [this](const QString url) {
-        if (url == m_image) {
-            Q_EMIT imageChanged(url);
-            Q_EMIT cachedImageChanged(cachedImage());
-        } else if (m_image.isEmpty() && url == m_feed->image()) {
-            Q_EMIT imageChanged(url);
-            Q_EMIT cachedImageChanged(cachedImage());
-        }
-    });
     connect(&Fetcher::instance(), &Fetcher::entryUpdated, this, [this](const qint64 entryuid) {
         if (m_entryuid == entryuid) {
             updateFromDb();
@@ -292,7 +283,6 @@ void Entry::setImage(const QString &image, bool emitSignal)
         m_image = image;
         if (emitSignal) {
             Q_EMIT imageChanged(m_image);
-            Q_EMIT cachedImageChanged(cachedImage());
         }
     }
 }
@@ -442,24 +432,6 @@ QString Entry::image() const
     }
 }
 
-QString Entry::cachedImage() const
-{
-    // First check for an image in the downloaded file
-    if (m_hasenclosure && !m_enclosure->cachedEmbeddedImage().isEmpty()) {
-        // use embedded image if available
-        return m_enclosure->cachedEmbeddedImage();
-    }
-
-    // Then check for the entry image, fall back if needed to feed image
-    QString image = m_image;
-    if (image.isEmpty()) {
-        // else fall back to feed image
-        image = m_feed->image();
-    }
-
-    return Fetcher::instance().image(image);
-}
-
 bool Entry::queueStatus() const
 {
     return QueueModel::instance().entryInQueue(m_entryuid);
diff --git a/src/entry.h b/src/entry.h
index 84337001..9ab5816f 100644
--- a/src/entry.h
+++ b/src/entry.h
@@ -40,7 +40,6 @@ class Entry : public QObject
     Q_PROPERTY(Enclosure *enclosure READ enclosure CONSTANT)
     Q_PROPERTY(bool hasEnclosure READ hasEnclosure NOTIFY hasEnclosureChanged)
     Q_PROPERTY(QString image READ image NOTIFY imageChanged)
-    Q_PROPERTY(QString cachedImage READ cachedImage NOTIFY cachedImageChanged)
     Q_PROPERTY(bool queueStatus READ queueStatus WRITE setQueueStatus NOTIFY queueStatusChanged)
 
 public:
@@ -63,7 +62,6 @@ public:
     Enclosure *enclosure() const;
     bool hasEnclosure() const;
     QString image() const;
-    QString cachedImage() const;
     bool queueStatus() const;
     Feed *feed() const;
 
@@ -90,7 +88,6 @@ Q_SIGNALS:
     void removedChanged(bool removed);
     void hasEnclosureChanged(bool hasEnclosure);
     void imageChanged(const QString &url);
-    void cachedImageChanged(const QString &imagePath);
     void queueStatusChanged(bool queueStatus);
 
 private:
diff --git a/src/feed.cpp b/src/feed.cpp
index 2761a831..452baaad 100644
--- a/src/feed.cpp
+++ b/src/feed.cpp
@@ -105,12 +105,6 @@ Feed::Feed(const qint64 feeduid, QObject *parent)
                     setRefreshing(false);
                 }
             });
-    connect(&Fetcher::instance(), &Fetcher::downloadFinished, this, [this](QString url) {
-        if (url == m_image) {
-            Q_EMIT imageChanged(url);
-            Q_EMIT cachedImageChanged(cachedImage());
-        }
-    });
 
     m_entries = new EntriesProxyModel(m_feeduid, this);
 
@@ -257,11 +251,6 @@ QString Feed::image() const
     return m_image;
 }
 
-QString Feed::cachedImage() const
-{
-    return Fetcher::instance().image(m_image);
-}
-
 QString Feed::link() const
 {
     return m_link;
@@ -340,7 +329,6 @@ void Feed::setImage(const QString &image)
     if (image != m_image) {
         m_image = image;
         Q_EMIT imageChanged(m_image);
-        Q_EMIT cachedImageChanged(cachedImage());
     }
 }
 
diff --git a/src/feed.h b/src/feed.h
index 1a561062..cf708f7e 100644
--- a/src/feed.h
+++ b/src/feed.h
@@ -25,7 +25,6 @@ class Feed : public QObject
     Q_PROPERTY(QString url READ url CONSTANT)
     Q_PROPERTY(QString name READ name NOTIFY nameChanged)
     Q_PROPERTY(QString image READ image NOTIFY imageChanged)
-    Q_PROPERTY(QString cachedImage READ cachedImage NOTIFY cachedImageChanged)
     Q_PROPERTY(QString link READ link NOTIFY linkChanged)
     Q_PROPERTY(QString description READ description NOTIFY descriptionChanged)
     Q_PROPERTY(QString authors READ authors NOTIFY authorsChanged)
@@ -50,7 +49,6 @@ public:
     QString url() const;
     QString name() const;
     QString image() const;
-    QString cachedImage() const;
     QString link() const;
     QString description() const;
     QString authors() const;
@@ -82,7 +80,6 @@ public:
 Q_SIGNALS:
     void nameChanged(const QString &name);
     void imageChanged(const QString &image);
-    void cachedImageChanged(const QString &imagePath);
     void linkChanged(const QString &link);
     void descriptionChanged(const QString &description);
     void authorsChanged(const QString &authors);
diff --git a/src/fetcher.cpp b/src/fetcher.cpp
index 336090e7..645d8cef 100644
--- a/src/fetcher.cpp
+++ b/src/fetcher.cpp
@@ -115,54 +115,6 @@ void Fetcher::fetch(const QStringList &urls)
     qCDebug(kastsFetcher) << "end of Fetcher::fetch";
 }
 
-QString Fetcher::image(const QString &url)
-{
-    if (url.isEmpty()) {
-        return QLatin1String("no-image");
-    }
-
-    // if image is already cached, then return the path
-    QString path = StorageManager::instance().imagePath(url);
-    if (QFileInfo::exists(path)) {
-        if (QFileInfo(path).size() != 0) {
-            return QUrl::fromLocalFile(path).toString();
-        }
-    }
-
-    // avoid restarting an image download if it's already running
-    if (m_ongoingImageDownloads.contains(url)) {
-        return QLatin1String("fetching");
-    }
-
-    // if image has not yet been cached, then check for network connectivity if
-    // possible; and download the image
-    if (!NetworkConnectionManager::instance().imageDownloadsAllowed()) {
-        return QLatin1String("no-image");
-    }
-
-    m_ongoingImageDownloads.insert(url);
-    QNetworkRequest request((QUrl(url)));
-    request.setTransferTimeout();
-    QNetworkReply *reply = get(request);
-    connect(reply, &QNetworkReply::finished, this, [this, reply, path, url]() {
-        if (reply->isOpen() && !reply->error()) {
-            QByteArray data = reply->readAll();
-            QFile file(path);
-
-            // TODO: We currently don't handle the case where we can't store the image locally.
-            // Maybe we should emit an error?  But this would probably flood the error log.
-            if (file.open(QIODevice::WriteOnly)) {
-                file.write(data);
-                file.close();
-                Q_EMIT downloadFinished(url);
-            }
-        }
-        m_ongoingImageDownloads.remove(url);
-        reply->deleteLater();
-    });
-    return QLatin1String("fetching");
-}
-
 EnclosureDownloadJob *Fetcher::enqueueEnclosureDownload(const qint64 entryuid, const QString &url, const QString &path, const QString &title)
 {
     QPointer<EnclosureDownloadJob> newDownloadJob = new EnclosureDownloadJob(entryuid, url, path, title);
diff --git a/src/fetcher.h b/src/fetcher.h
index 50ebffad..8be8a9c7 100644
--- a/src/fetcher.h
+++ b/src/fetcher.h
@@ -47,7 +47,6 @@ public:
     Q_INVOKABLE void fetch(const QString &url);
     Q_INVOKABLE void fetch(const QStringList &urls);
     Q_INVOKABLE void fetchAll();
-    Q_INVOKABLE QString image(const QString &url);
 
     EnclosureDownloadJob *enqueueEnclosureDownload(const qint64 entryuid, const QString &url, const QString &path, const QString &title);
     void processEnclosureDownloadQueue();
diff --git a/src/main.cpp b/src/main.cpp
index 0b72f4d7..7785fae1 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -10,9 +10,12 @@
 #include <QFile>
 #include <QIcon>
 #include <QLoggingCategory>
+#include <QNetworkAccessManager>
+#include <QNetworkDiskCache>
 #include <QObject>
 #include <QQmlApplicationEngine>
 #include <QQmlContext>
+#include <QQmlNetworkAccessManagerFactory>
 #include <QQuickStyle>
 #include <QQuickView>
 #include <QSettings>
@@ -63,6 +66,23 @@
 Q_DECL_EXPORT
 #endif
 
+class NetworkAccessManagerFactory : public QQmlNetworkAccessManagerFactory
+{
+public:
+    QNetworkAccessManager *create(QObject *parent) override
+    {
+        static QNetworkAccessManager *manager = nullptr;
+        if (!manager) {
+            manager = new QNetworkAccessManager(parent);
+            auto cache = new QNetworkDiskCache(manager);
+            QString directory = QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + QLatin1StringView("/cacheDir/");
+            cache->setCacheDirectory(directory);
+            manager->setCache(cache);
+        }
+        return manager;
+    }
+};
+
 int main(int argc, char *argv[])
 {
     // Check if we need to force the interface to mobile or desktop, or stick
@@ -138,6 +158,8 @@ int main(int argc, char *argv[])
     }
 
     QQmlApplicationEngine engine;
+    NetworkAccessManagerFactory networkAccessManagerFactory;
+    engine.setNetworkAccessManagerFactory(&networkAccessManagerFactory);
     KLocalization::setupLocalizedContext(&engine);
 
     QCommandLineParser parser;
diff --git a/src/qml/ChapterListDelegate.qml b/src/qml/ChapterListDelegate.qml
index 67352b1f..657eb6ad 100644
--- a/src/qml/ChapterListDelegate.qml
+++ b/src/qml/ChapterListDelegate.qml
@@ -37,7 +37,7 @@ AddonDelegates.RoundedItemDelegate {
 
     contentItem: RowLayout {
         Delegates.IconTitleSubtitle {
-            icon.source: root.chapter ? root.chapter.cachedImage : ""
+            icon.source: root.chapter ? root.chapter.image : ""
             title: root.title
             subtitle: root.formattedStart
             Layout.fillWidth: true
diff --git a/src/qml/Desktop/HeaderBar.qml b/src/qml/Desktop/HeaderBar.qml
index d8b6dd8f..7d615e92 100644
--- a/src/qml/Desktop/HeaderBar.qml
+++ b/src/qml/Desktop/HeaderBar.qml
@@ -29,8 +29,8 @@ FocusScope {
     property int authorCollapseHeight: Kirigami.Units.gridUnit * 4
     property int disappearHeight: Kirigami.Units.gridUnit * 1.0
 
-    property string image: AudioManager.entry ? ((root.desktopPlayerControls.chapterModel.currentChapter && root.desktopPlayerControls.chapterModel.currentChapter !== undefined) ? root.desktopPlayerControls.chapterModel.currentChapter.cachedImage : AudioManager.entry.cachedImage) : "no-image"
-    property string blurredImage: AudioManager.entry ? AudioManager.entry.cachedImage : "no-image"
+    property string image: AudioManager.entry ? ((root.desktopPlayerControls.chapterModel.currentChapter && root.desktopPlayerControls.chapterModel.currentChapter !== undefined) ? root.desktopPlayerControls.chapterModel.currentChapter.image : AudioManager.entry.image) : ""
+    property string blurredImage: AudioManager.entry ? AudioManager.entry.image : ""
     property string title: AudioManager.entry ? AudioManager.entry.title : KI18n.i18n("No Episode Title")
 
     property Item headerMetaData: _headerMetaData
diff --git a/src/qml/EntryPage.qml b/src/qml/EntryPage.qml
index 96b39138..3fd54cb0 100644
--- a/src/qml/EntryPage.qml
+++ b/src/qml/EntryPage.qml
@@ -74,7 +74,7 @@ Kirigami.ScrollablePage {
         GenericHeader {
             id: infoHeader
             Layout.fillWidth: true
-            image: root.entry.cachedImage
+            image: root.entry.image
             title: root.entry.title
             subtitle: root.entry.feed.name
             subtitleClickable: true
diff --git a/src/qml/FeedDetailsPage.qml b/src/qml/FeedDetailsPage.qml
index 92db9c7d..4b532544 100644
--- a/src/qml/FeedDetailsPage.qml
+++ b/src/qml/FeedDetailsPage.qml
@@ -126,7 +126,7 @@ Kirigami.ScrollablePage {
 
                 property string authors: isSubscribed ? feed.authors : feed.author
 
-                image: isSubscribed ? feed.cachedImage : feed.image
+                image: isSubscribed ? feed.image : feed.image
                 title: isSubscribed ? feed.name : feed.title
                 subtitle: authors ? KI18n.i18nc("by <author(s)>", "by %1", authors) : ""
             }
diff --git a/src/qml/FeedListDelegate.qml b/src/qml/FeedListDelegate.qml
index 0402d579..3ba7f1a0 100644
--- a/src/qml/FeedListDelegate.qml
+++ b/src/qml/FeedListDelegate.qml
@@ -166,7 +166,7 @@ Controls.ItemDelegate {
         ImageWithFallback {
             id: img
             anchors.fill: parent
-            imageSource: root.feed.cachedImage
+            imageSource: root.feed.image
             imageTitle: root.feed.name
             imageResize: false // no "stuttering" on resizing the window
             isLoading: root.feed.refreshing
diff --git a/src/qml/GenericEntryDelegate.qml b/src/qml/GenericEntryDelegate.qml
index 01dd18de..3f1b5bc1 100644
--- a/src/qml/GenericEntryDelegate.qml
+++ b/src/qml/GenericEntryDelegate.qml
@@ -200,7 +200,7 @@ AddonDelegates.RoundedItemDelegate {
 
         ImageWithFallback {
             id: img
-            imageSource: root.showFeedImage ? root.entry.feed.cachedImage : root.entry.cachedImage
+            imageSource: root.showFeedImage ? root.entry.feed.image : root.entry.image
             property int size: Kirigami.Units.gridUnit * 3
             Layout.preferredHeight: size
             Layout.preferredWidth: size
diff --git a/src/qml/GlobalSearchField.qml b/src/qml/GlobalSearchField.qml
index 0d06c5d6..804b4069 100644
--- a/src/qml/GlobalSearchField.qml
+++ b/src/qml/GlobalSearchField.qml
@@ -99,7 +99,7 @@ Kirigami.SearchField {
             required property int entryuid
 
             contentItem: Delegates.IconTitleSubtitle {
-                icon.source: albumDelegate.entry.cachedImage
+                icon.source: albumDelegate.entry.image
                 title: albumDelegate.entry.title
                 subtitle: albumDelegate.entry.feed.name
             }
diff --git a/src/qml/ImageWithFallback.qml b/src/qml/ImageWithFallback.qml
index 214a4e7f..21876220 100644
--- a/src/qml/ImageWithFallback.qml
+++ b/src/qml/ImageWithFallback.qml
@@ -17,7 +17,8 @@ import org.kde.kasts
 
 Item {
     id: root
-    property string imageSource: "no-image"
+
+    required property string imageSource
     property real imageOpacity: 1
     property int absoluteRadius: 0
     property real fractionalRadius: 0.0
@@ -30,7 +31,7 @@ Item {
         id: imageLoader
         anchors.fill: parent
         visible: GraphicsInfo.api === GraphicsInfo.Software
-        sourceComponent: (root.imageSource === "no-image" || root.imageSource === "") ? fallbackImg : (root.imageSource === "fetching" ? loaderSymbol : realImg)
+        sourceComponent: root.imageSource === "" ? fallbackImg : realImg
     }
 
     MultiEffect {
@@ -55,6 +56,7 @@ Item {
     Component {
         id: realImg
         Image {
+            id: image
             anchors.fill: parent
             source: root.imageSource
             fillMode: root.imageFillMode
@@ -66,6 +68,12 @@ Item {
             // will ever have (this is mainly the MobilePlayerControls)
             sourceSize.width: root.imageResize ? width * Screen.devicePixelRatio : Kirigami.Units.gridUnit * 40
             sourceSize.height: root.imageResize ? height * Screen.devicePixelRatio : Kirigami.Units.gridUnit * 40
+
+            Loader {
+                active: image.status === Image.Loading
+                anchors.fill: parent
+                sourceComponent: loaderSymbol
+            }
         }
     }
 
@@ -114,7 +122,7 @@ Item {
 
     Loader {
         anchors.fill: parent
-        active: root.imageTitle !== "" && (SettingsManager.alwaysShowFeedTitles ? true : (root.imageSource === "no-image" || root.imageSource === "fetching"))
+        active: root.imageTitle.length > 0 && (SettingsManager.alwaysShowFeedTitles || root.imageSource.length === 0)
         sourceComponent: imageText
     }
 
diff --git a/src/qml/Mobile/FooterBar.qml b/src/qml/Mobile/FooterBar.qml
index 3e907244..b01641cf 100644
--- a/src/qml/Mobile/FooterBar.qml
+++ b/src/qml/Mobile/FooterBar.qml
@@ -142,7 +142,7 @@ Flickable {
 
                 Image {
                     id: backgroundImage
-                    source: AudioManager.entry.cachedImage
+                    source: AudioManager.entry.image
                     asynchronous: true
                     visible: GraphicsInfo.api === GraphicsInfo.Software
                     anchors.fill: parent
diff --git a/src/qml/Mobile/MinimizedPlayerControls.qml b/src/qml/Mobile/MinimizedPlayerControls.qml
index fb75624e..09a7b5d8 100644
--- a/src/qml/Mobile/MinimizedPlayerControls.qml
+++ b/src/qml/Mobile/MinimizedPlayerControls.qml
@@ -62,7 +62,7 @@ Item {
                 anchors.fill: parent
 
                 ImageWithFallback {
-                    imageSource: (AudioManager.entryuid > 0 && AudioManager.entry) ? ((chapterModel.currentChapter && chapterModel.currentChapter !== undefined) ? chapterModel.currentChapter.cachedImage : AudioManager.entry.cachedImage) : "no-image"
+                    imageSource: (AudioManager.entryuid > 0 && AudioManager.entry) ? ((chapterModel.currentChapter && chapterModel.currentChapter !== undefined) ? chapterModel.currentChapter.image : AudioManager.entry.image) : ""
                     Layout.fillHeight: true
                     Layout.preferredWidth: height
                 }
diff --git a/src/qml/Mobile/MobilePlayerControls.qml b/src/qml/Mobile/MobilePlayerControls.qml
index f758327f..6c170c40 100644
--- a/src/qml/Mobile/MobilePlayerControls.qml
+++ b/src/qml/Mobile/MobilePlayerControls.qml
@@ -61,7 +61,7 @@ Kirigami.Page {
 
         Image {
             id: backgroundImage
-            source: AudioManager.entry.cachedImage
+            source: AudioManager.entry.image
             asynchronous: true
             visible: GraphicsInfo.api === GraphicsInfo.Software
             anchors.fill: parent
@@ -120,7 +120,7 @@ Kirigami.Page {
                         width: Utils.isWidescreen ? Math.min(parent.height, parent.width / 2) : Math.min(parent.width, height)
 
                         ImageWithFallback {
-                            imageSource: (AudioManager.entryuid > 0 && AudioManager.entry) ? ((root.chapterModel.currentChapter && root.chapterModel.currentChapter !== undefined) ? root.chapterModel.currentChapter.cachedImage : AudioManager.entry.cachedImage) : "no-image"
+                            imageSource: (AudioManager.entryuid > 0 && AudioManager.entry) ? ((root.chapterModel.currentChapter && root.chapterModel.currentChapter !== undefined) ? root.chapterModel.currentChapter.image : AudioManager.entry.image) : ""
                             imageResize: false // prevent stuttering when resizing
                             imageFillMode: Image.PreserveAspectCrop
                             anchors.centerIn: parent