diff --git a/src/MxcImageProvider.cpp b/src/MxcImageProvider.cpp
new file mode 100644
index 00000000..305439fc
--- /dev/null
+++ b/src/MxcImageProvider.cpp
@@ -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();
+ });
+ }
+}
diff --git a/src/MxcImageProvider.h b/src/MxcImageProvider.h
new file mode 100644
index 00000000..8710171c
--- /dev/null
+++ b/src/MxcImageProvider.h
@@ -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;
+};
+
diff --git a/src/RoomInfoListItem.cpp b/src/RoomInfoListItem.cpp
index 8aadbea2..f135451c 100644
--- a/src/RoomInfoListItem.cpp
+++ b/src/RoomInfoListItem.cpp
@@ -142,7 +142,7 @@ RoomInfoListItem::resizeEvent(QResizeEvent *)
void
RoomInfoListItem::paintEvent(QPaintEvent *event)
{
- bool rounded = QSettings().value("user/avatar/circles", true).toBool();
+ bool rounded = QSettings().value("user/avatar_circles", true).toBool();
Q_UNUSED(event);
diff --git a/src/UserSettingsPage.cpp b/src/UserSettingsPage.cpp
index 9fd033e9..1caea449 100644
--- a/src/UserSettingsPage.cpp
+++ b/src/UserSettingsPage.cpp
@@ -53,7 +53,7 @@ UserSettings::load()
isReadReceiptsEnabled_ = settings.value("user/read_receipts", true).toBool();
theme_ = settings.value("user/theme", defaultTheme_).toString();
font_ = settings.value("user/font_family", "default").toString();
- avatarCircles_ = settings.value("user/avatar/circles", true).toBool();
+ avatarCircles_ = settings.value("user/avatar_circles", true).toBool();
emojiFont_ = settings.value("user/emoji_font_family", "default").toString();
baseFontSize_ = settings.value("user/font_size", QFont().pointSizeF()).toDouble();
@@ -119,9 +119,7 @@ UserSettings::save()
settings.setValue("start_in_tray", isStartInTrayEnabled_);
settings.endGroup();
- settings.beginGroup("avatar");
- settings.setValue("circles", avatarCircles_);
- settings.endGroup();
+ settings.setValue("avatar_circles", avatarCircles_);
settings.setValue("font_size", baseFontSize_);
settings.setValue("typing_notifications", isTypingNotificationsEnabled_);
diff --git a/src/timeline2/TimelineModel.cpp b/src/timeline2/TimelineModel.cpp
index 28820205..310494b4 100644
--- a/src/timeline2/TimelineModel.cpp
+++ b/src/timeline2/TimelineModel.cpp
@@ -326,6 +326,12 @@ TimelineModel::displayName(QString id) const
}
QString
+TimelineModel::avatarUrl(QString id) const
+{
+ return Cache::avatarUrl(room_id_, id);
+}
+
+QString
TimelineModel::formatDateSeparator(QDate date) const
{
auto now = QDateTime::currentDateTime();
diff --git a/src/timeline2/TimelineModel.h b/src/timeline2/TimelineModel.h
index e37c6542..954da5eb 100644
--- a/src/timeline2/TimelineModel.h
+++ b/src/timeline2/TimelineModel.h
@@ -90,6 +90,7 @@ public:
Q_INVOKABLE QColor userColor(QString id, QColor background);
Q_INVOKABLE QString displayName(QString id) const;
+ Q_INVOKABLE QString avatarUrl(QString id) const;
Q_INVOKABLE QString formatDateSeparator(QDate date) const;
Q_INVOKABLE QString escapeEmoji(QString str) const;
diff --git a/src/timeline2/TimelineViewManager.cpp b/src/timeline2/TimelineViewManager.cpp
index 0e0e74e4..eb9bea54 100644
--- a/src/timeline2/TimelineViewManager.cpp
+++ b/src/timeline2/TimelineViewManager.cpp
@@ -4,6 +4,7 @@
#include <QQmlContext>
#include "Logging.h"
+#include "MxcImageProvider.h"
TimelineViewManager::TimelineViewManager(QWidget *parent)
{
@@ -18,6 +19,7 @@ TimelineViewManager::TimelineViewManager(QWidget *parent)
container = QWidget::createWindowContainer(view, parent);
container->setMinimumSize(200, 200);
view->rootContext()->setContextProperty("timelineManager", this);
+ view->engine()->addImageProvider("MxcImage", new MxcImageProvider());
view->setSource(QUrl("qrc:///qml/TimelineView.qml"));
}
diff --git a/src/ui/Avatar.cpp b/src/ui/Avatar.cpp
index 501a8968..e4a90f81 100644
--- a/src/ui/Avatar.cpp
+++ b/src/ui/Avatar.cpp
@@ -101,7 +101,7 @@ Avatar::setIcon(const QIcon &icon)
void
Avatar::paintEvent(QPaintEvent *)
{
- bool rounded = QSettings().value("user/avatar/circles", true).toBool();
+ bool rounded = QSettings().value("user/avatar_circles", true).toBool();
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
|