diff --git a/qml/pages/BookDetailPage.qml b/qml/pages/BookDetailPage.qml index 35b93ae..eba658d 100644 --- a/qml/pages/BookDetailPage.qml +++ b/qml/pages/BookDetailPage.qml @@ -172,13 +172,14 @@ Page { Component.onCompleted: { if (bookData.coverUrl && bookData.coverUrl.length > 0) - apiClient.fetchImage(bookData.coverUrl, "detail:" + bookData.id) + apiClient.fetchImage(bookData.coverUrl, "detailcover") } Connections { target: apiClient - onImageReady: { - if (id === "detail:" + bookData.id) + // nota: parametro rinominato (imageId) — "id" è parola chiave QML e rompe il confronto + onImageReady: function(imageId, localPath) { + if (imageId === "detailcover") page.coverSource = localPath } } diff --git a/qml/pages/FeedPage.qml b/qml/pages/FeedPage.qml index 428354b..c5c7861 100644 --- a/qml/pages/FeedPage.qml +++ b/qml/pages/FeedPage.qml @@ -175,9 +175,9 @@ Page { page.loadingMore = false page.errorMessage = message } - onImageReady: { + onImageReady: function(imageId, localPath) { for (var i = 0; i < feedModel.count; i++) { - if (feedModel.get(i).coverId === id) { + if (feedModel.get(i).coverId === imageId) { feedModel.setProperty(i, "coverSource", localPath) break } diff --git a/src/apiclient.cpp b/src/apiclient.cpp index 0c93168..2aebdc3 100644 --- a/src/apiclient.cpp +++ b/src/apiclient.cpp @@ -127,6 +127,13 @@ void ApiClient::getFeed(const QString &url) }); } +static bool looksLikeImage(const QByteArray &data) +{ + // sniff dei magic byte per PNG/JPEG/GIF/WebP senza dipendere da QtGui + return data.startsWith("\x89PNG") || data.startsWith("\xFF\xD8") + || data.startsWith("GIF8") || data.startsWith("RIFF"); +} + void ApiClient::fetchImage(const QString &url, const QString &id) { if (url.isEmpty()) { @@ -150,16 +157,27 @@ void ApiClient::fetchImage(const QString &url, const QString &id) } QNetworkReply *reply = startGet(imageUrl); - connect(reply, &QNetworkReply::finished, this, [this, reply, id, localPath]() { + connect(reply, &QNetworkReply::finished, this, [this, reply, id, localPath, imageUrl]() { reply->deleteLater(); const int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); if (reply->error() != QNetworkReply::NoError || status >= 400) { emit imageReady(id, QString()); return; } + const QByteArray body = reply->readAll(); + const QByteArray contentType = reply->header( + QNetworkRequest::ContentTypeHeader).toByteArray(); + // non cachare risposte che non sono immagini (es. pagine HTML di errore 200) + const bool isImage = contentType.startsWith("image/") + || (contentType.isEmpty() && looksLikeImage(body)); + if (!isImage) { + qDebug() << "fetchImage: risposta non immagine scartata" << imageUrl; + emit imageReady(id, QString()); + return; + } QFile file(localPath); if (file.open(QIODevice::WriteOnly)) { - file.write(reply->readAll()); + file.write(body); file.close(); emit imageReady(id, localPath); } else {