Skip to content

Commit a88c422

Browse files
author
Justin McPherson
committed
Further work on image loader
1 parent 4d3822a commit a88c422

2 files changed

Lines changed: 47 additions & 6 deletions

File tree

ReactUbuntu/runtime/src/reactimageloader.cpp

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,44 @@
11

2+
#include <QMap>
3+
#include <QCryptographicHash>
24
#include <QNetworkRequest>
35
#include <QNetworkReply>
6+
#include <QNetworkDiskCache>
7+
#include <QQuickImageProvider>
48

59
#include "reactimageloader.h"
610
#include "reactbridge.h"
711

812

9-
class ReactImageLoaderPrivate {
13+
class ReactImageLoaderPrivate : public QQuickImageProvider {
1014
public:
15+
ReactImageLoaderPrivate():QQuickImageProvider(QQuickImageProvider::Image)
16+
{}
17+
void markCached(const QUrl& source) {
18+
cacheIds.insert(source, QCryptographicHash::hash(source.toEncoded(), QCryptographicHash::Sha1));
19+
}
20+
bool isCached(const QUrl& source) {
21+
return cacheIds.contains(source);
22+
}
23+
QUrl cachedUrl(const QUrl& source) {
24+
return QUrl("image://react/" + cacheIds.value(source));
25+
}
26+
QImage requestImage(const QString& id, QSize* size, const QSize& requestedSize) {
27+
qDebug() << __PRETTY_FUNCTION__ << id;
28+
auto cache = qobject_cast<QNetworkDiskCache*>(bridge->networkAccessManager()->cache());
29+
auto idev = cache->data(cacheIds.key(id.toLocal8Bit()));
30+
if (idev == nullptr) {
31+
qWarning() << __PRETTY_FUNCTION__ << "Could not obtain cache entry for" << id;
32+
return QImage();
33+
}
34+
idev->deleteLater();
35+
QImage image = QImage::fromData(idev->readAll());
36+
if (size != nullptr)
37+
*size = image.size();
38+
qDebug() << __PRETTY_FUNCTION__ << image;;
39+
return image;
40+
}
41+
QMap<QUrl, QByteArray> cacheIds;
1142
ReactBridge* bridge = nullptr;
1243
};
1344

@@ -28,6 +59,7 @@ void ReactImageLoader::prefetchImage(
2859
reject(d->bridge, QVariantList{QVariantMap{{"code", reply->errorString()}}});
2960
return;
3061
}
62+
d->markCached(url);
3163
resolve(d->bridge, QVariantList{true});
3264
});
3365
}
@@ -45,7 +77,9 @@ ReactImageLoader::~ReactImageLoader()
4577

4678
void ReactImageLoader::setBridge(ReactBridge* bridge)
4779
{
48-
d_func()->bridge = bridge;
80+
Q_D(ReactImageLoader);
81+
d->bridge = bridge;
82+
d->bridge->qmlEngine()->addImageProvider("react", d);
4983
}
5084

5185
QString ReactImageLoader::moduleName()
@@ -65,5 +99,9 @@ QVariantMap ReactImageLoader::constantsToExport()
6599

66100
QUrl ReactImageLoader::provideUriFromSourceUrl(const QUrl& source)
67101
{
102+
Q_D(ReactImageLoader);
103+
if (d->isCached(source))
104+
return d->cachedUrl(source);
105+
68106
return source;
69107
}

ReactUbuntu/runtime/src/reactimagemanager.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,9 @@ class ImagePropertyHandler : public ReactPropertyHandler {
2727

2828
public:
2929
enum FillMode { Stretch, PreserveAspectFit, PreserveAspectCrop, Tile, TileVertically, TileHorizontally, Pad };
30-
ImagePropertyHandler(QObject* object)
31-
: ReactPropertyHandler(object) {
30+
ImagePropertyHandler(QObject* object, ReactBridge* bridge)
31+
: ReactPropertyHandler(object)
32+
, m_bridge(bridge) {
3233
}
3334
QString resizeMode() const;
3435
void setResizeMode(const QString& resizeMode);
@@ -50,6 +51,8 @@ class ImagePropertyHandler : public ReactPropertyHandler {
5051
void setBorderColor(const QColor& borderColor);
5152
QUrl source() const;
5253
void setSource(const QUrl& source);
54+
private:
55+
ReactBridge* m_bridge;
5356
};
5457

5558
QColor ImagePropertyHandler::backgroundColor() const
@@ -101,7 +104,7 @@ QUrl ImagePropertyHandler::source() const
101104

102105
void ImagePropertyHandler::setSource(const QUrl& source)
103106
{
104-
m_object->setProperty("source", source);
107+
m_object->setProperty("source", m_bridge->imageLoader()->provideUriFromSourceUrl(source));
105108
}
106109

107110
QColor ImagePropertyHandler::tintColor() const
@@ -187,7 +190,7 @@ ReactViewManager* ReactImageManager::viewManager()
187190

188191
ReactPropertyHandler* ReactImageManager::propertyHandler(QObject* object)
189192
{
190-
return new ImagePropertyHandler(object);
193+
return new ImagePropertyHandler(object, m_bridge);
191194
}
192195

193196
QString ReactImageManager::moduleName()

0 commit comments

Comments
 (0)