forked from mirror/nheko
parent
aae295cb02
commit
ebeb1eb772
@ -0,0 +1,45 @@ |
||||
import QtQuick 2.6 |
||||
import QtGraphicalEffects 1.0 |
||||
import Qt.labs.settings 1.0 |
||||
|
||||
Rectangle { |
||||
id: avatar |
||||
width: 48 |
||||
height: 48 |
||||
radius: settings.avatar_circles ? height/2 : 3 |
||||
|
||||
Settings { |
||||
id: settings |
||||
category: "user" |
||||
property bool avatar_circles: true |
||||
} |
||||
|
||||
property alias url: img.source |
||||
property string displayName |
||||
|
||||
Text { |
||||
anchors.fill: parent |
||||
text: String.fromCodePoint(displayName.codePointAt(0)) |
||||
color: colors.text |
||||
font.pixelSize: avatar.height/2 |
||||
verticalAlignment: Text.AlignVCenter |
||||
horizontalAlignment: Text.AlignHCenter |
||||
} |
||||
|
||||
Image { |
||||
id: img |
||||
anchors.fill: parent |
||||
asynchronous: true |
||||
|
||||
layer.enabled: true |
||||
layer.effect: OpacityMask { |
||||
maskSource: Rectangle { |
||||
anchors.fill: parent |
||||
width: avatar.width |
||||
height: avatar.height |
||||
radius: settings.avatar_circles ? height/2 : 3 |
||||
} |
||||
} |
||||
} |
||||
color: colors.dark |
||||
} |
@ -0,0 +1,79 @@ |
||||
#include "MxcImageProvider.h" |
||||
|
||||
#include "Cache.h" |
||||
|
||||
void |
||||
MxcImageResponse::run() |
||||
{ |
||||
if (m_requestedSize.isValid()) { |
||||
QString fileName = QString("%1_%2x%3") |
||||
.arg(m_id) |
||||
.arg(m_requestedSize.width()) |
||||
.arg(m_requestedSize.height()); |
||||
|
||||
auto data = cache::client()->image(fileName); |
||||
if (!data.isNull() && m_image.loadFromData(data)) { |
||||
m_image = m_image.scaled(m_requestedSize, Qt::KeepAspectRatio); |
||||
m_image.setText("mxc url", "mxc://" + m_id); |
||||
emit finished(); |
||||
return; |
||||
} |
||||
|
||||
mtx::http::ThumbOpts opts; |
||||
opts.mxc_url = "mxc://" + m_id.toStdString(); |
||||
opts.width = m_requestedSize.width() > 0 ? m_requestedSize.width() : -1; |
||||
opts.height = m_requestedSize.height() > 0 ? m_requestedSize.height() : -1; |
||||
opts.method = "scale"; |
||||
http::client()->get_thumbnail( |
||||
opts, [this, fileName](const std::string &res, mtx::http::RequestErr err) { |
||||
if (err) { |
||||
nhlog::net()->error("Failed to download image {}", |
||||
m_id.toStdString()); |
||||
m_error = "Failed download"; |
||||
emit finished(); |
||||
|
||||
return; |
||||
} |
||||
|
||||
auto data = QByteArray(res.data(), res.size()); |
||||
cache::client()->saveImage(fileName, data); |
||||
m_image.loadFromData(data); |
||||
m_image = m_image.scaled(m_requestedSize, Qt::KeepAspectRatio); |
||||
m_image.setText("mxc url", "mxc://" + m_id); |
||||
|
||||
emit finished(); |
||||
}); |
||||
} else { |
||||
auto data = cache::client()->image(m_id); |
||||
if (!data.isNull() && m_image.loadFromData(data)) { |
||||
m_image.setText("mxc url", "mxc://" + m_id); |
||||
emit finished(); |
||||
return; |
||||
} |
||||
|
||||
http::client()->download( |
||||
"mxc://" + m_id.toStdString(), |
||||
[this](const std::string &res, |
||||
const std::string &, |
||||
const std::string &originalFilename, |
||||
mtx::http::RequestErr err) { |
||||
if (err) { |
||||
nhlog::net()->error("Failed to download image {}", |
||||
m_id.toStdString()); |
||||
m_error = "Failed download"; |
||||
emit finished(); |
||||
|
||||
return; |
||||
} |
||||
|
||||
auto data = QByteArray(res.data(), res.size()); |
||||
m_image.loadFromData(data); |
||||
m_image.setText("original filename", |
||||
QString::fromStdString(originalFilename)); |
||||
m_image.setText("mxc url", "mxc://" + m_id); |
||||
cache::client()->saveImage(m_id, data); |
||||
|
||||
emit finished(); |
||||
}); |
||||
} |
||||
} |
@ -0,0 +1,48 @@ |
||||
#pragma once |
||||
|
||||
#include <QQuickAsyncImageProvider> |
||||
#include <QQuickImageResponse> |
||||
|
||||
#include <QImage> |
||||
#include <QThreadPool> |
||||
|
||||
class MxcImageResponse |
||||
: public QQuickImageResponse |
||||
, public QRunnable |
||||
{ |
||||
public: |
||||
MxcImageResponse(const QString &id, const QSize &requestedSize) |
||||
: m_id(id) |
||||
, m_requestedSize(requestedSize) |
||||
{ |
||||
setAutoDelete(false); |
||||
} |
||||
|
||||
QQuickTextureFactory *textureFactory() const override |
||||
{ |
||||
return QQuickTextureFactory::textureFactoryForImage(m_image); |
||||
} |
||||
QString errorString() const override { return m_error; } |
||||
|
||||
void run() override; |
||||
|
||||
QString m_id, m_error; |
||||
QSize m_requestedSize; |
||||
QImage m_image; |
||||
}; |
||||
|
||||
class MxcImageProvider : public QQuickAsyncImageProvider |
||||
{ |
||||
public: |
||||
QQuickImageResponse *requestImageResponse(const QString &id, |
||||
const QSize &requestedSize) override |
||||
{ |
||||
MxcImageResponse *response = new MxcImageResponse(id, requestedSize); |
||||
pool.start(response); |
||||
return response; |
||||
} |
||||
|
||||
private: |
||||
QThreadPool pool; |
||||
}; |
||||
|
Loading…
Reference in new issue