diff --git a/include/MatrixClient.h b/include/MatrixClient.h index a433b095..46d946c7 100644 --- a/include/MatrixClient.h +++ b/include/MatrixClient.h @@ -22,6 +22,15 @@ #include #include +class DownloadMediaProxy : public QObject +{ + Q_OBJECT + +signals: + void imageDownloaded(const QPixmap &data); + void fileDownloaded(const QByteArray &data); +}; + /* * MatrixClient provides the high level API to communicate with * a Matrix homeserver. All the responses are returned through signals. @@ -55,8 +64,8 @@ public: void fetchCommunityAvatar(const QString &communityId, const QUrl &avatarUrl); void fetchCommunityProfile(const QString &communityId); void fetchCommunityRooms(const QString &communityId); - void downloadImage(const QString &event_id, const QUrl &url); - void downloadFile(const QString &event_id, const QUrl &url); + DownloadMediaProxy *downloadImage(const QUrl &url); + DownloadMediaProxy *downloadFile(const QUrl &url); void messages(const QString &room_id, const QString &from_token, int limit = 30) noexcept; void uploadImage(const QString &roomid, const QString &filename, @@ -140,8 +149,6 @@ signals: void communityAvatarRetrieved(const QString &communityId, const QPixmap &img); void communityProfileRetrieved(const QString &communityId, const QJsonObject &profile); void communityRoomsRetrieved(const QString &communityId, const QJsonObject &rooms); - void imageDownloaded(const QString &event_id, const QPixmap &img); - void fileDownloaded(const QString &event_id, const QByteArray &data); // Returned profile data for the user's account. void getOwnProfileResponse(const QUrl &avatar_url, const QString &display_name); diff --git a/include/timeline/widgets/AudioItem.h b/include/timeline/widgets/AudioItem.h index 88e84d0c..b1d47dd5 100644 --- a/include/timeline/widgets/AudioItem.h +++ b/include/timeline/widgets/AudioItem.h @@ -72,11 +72,9 @@ protected: void paintEvent(QPaintEvent *event) override; void mousePressEvent(QMouseEvent *event) override; -private slots: - void fileDownloaded(const QString &event_id, const QByteArray &data); - private: void init(); + void fileDownloaded(const QByteArray &data); enum class AudioState { diff --git a/include/timeline/widgets/FileItem.h b/include/timeline/widgets/FileItem.h index cc6cd2ee..bc75913d 100644 --- a/include/timeline/widgets/FileItem.h +++ b/include/timeline/widgets/FileItem.h @@ -60,12 +60,10 @@ protected: void paintEvent(QPaintEvent *event) override; void mousePressEvent(QMouseEvent *event) override; -private slots: - void fileDownloaded(const QString &event_id, const QByteArray &data); - private: void openUrl(); void init(); + void fileDownloaded(const QByteArray &data); QUrl url_; QString text_; diff --git a/src/MatrixClient.cc b/src/MatrixClient.cc index 5471e410..1e7a5339 100644 --- a/src/MatrixClient.cc +++ b/src/MatrixClient.cc @@ -738,13 +738,14 @@ MatrixClient::fetchUserAvatar(const QUrl &avatarUrl, }); } -void -MatrixClient::downloadImage(const QString &event_id, const QUrl &url) +DownloadMediaProxy * +MatrixClient::downloadImage(const QUrl &url) { QNetworkRequest image_request(url); auto reply = get(image_request); - connect(reply, &QNetworkReply::finished, this, [this, reply, event_id]() { + auto proxy = new DownloadMediaProxy; + connect(reply, &QNetworkReply::finished, this, [this, reply, proxy]() { reply->deleteLater(); int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); @@ -762,17 +763,20 @@ MatrixClient::downloadImage(const QString &event_id, const QUrl &url) QPixmap pixmap; pixmap.loadFromData(img); - emit imageDownloaded(event_id, pixmap); + emit proxy->imageDownloaded(pixmap); }); + + return proxy; } -void -MatrixClient::downloadFile(const QString &event_id, const QUrl &url) +DownloadMediaProxy * +MatrixClient::downloadFile(const QUrl &url) { QNetworkRequest fileRequest(url); auto reply = get(fileRequest); - connect(reply, &QNetworkReply::finished, this, [this, reply, event_id]() { + auto proxy = new DownloadMediaProxy; + connect(reply, &QNetworkReply::finished, this, [this, reply, proxy]() { reply->deleteLater(); int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); @@ -788,8 +792,10 @@ MatrixClient::downloadFile(const QString &event_id, const QUrl &url) if (data.size() == 0) return; - emit fileDownloaded(event_id, data); + emit proxy->fileDownloaded(data); }); + + return proxy; } void diff --git a/src/timeline/widgets/AudioItem.cc b/src/timeline/widgets/AudioItem.cc index f171e78b..9f8b5dd1 100644 --- a/src/timeline/widgets/AudioItem.cc +++ b/src/timeline/widgets/AudioItem.cc @@ -64,7 +64,6 @@ AudioItem::init() player_->setVolume(100); player_->setNotifyInterval(1000); - connect(client_.data(), &MatrixClient::fileDownloaded, this, &AudioItem::fileDownloaded); connect(player_, &QMediaPlayer::stateChanged, this, [this](QMediaPlayer::State state) { if (state == QMediaPlayer::StoppedState) { state_ = AudioState::Play; @@ -135,16 +134,20 @@ AudioItem::mousePressEvent(QMouseEvent *event) if (filenameToSave_.isEmpty()) return; - client_->downloadFile(QString::fromStdString(event_.event_id), url_); + auto proxy = client_->downloadFile(url_); + connect(proxy, + &DownloadMediaProxy::fileDownloaded, + this, + [proxy, this](const QByteArray &data) { + proxy->deleteLater(); + fileDownloaded(data); + }); } } void -AudioItem::fileDownloaded(const QString &event_id, const QByteArray &data) +AudioItem::fileDownloaded(const QByteArray &data) { - if (event_id != QString::fromStdString(event_.event_id)) - return; - try { QFile file(filenameToSave_); diff --git a/src/timeline/widgets/FileItem.cc b/src/timeline/widgets/FileItem.cc index 258536e7..d11ebe91 100644 --- a/src/timeline/widgets/FileItem.cc +++ b/src/timeline/widgets/FileItem.cc @@ -57,8 +57,6 @@ FileItem::init() QString media_params = url_parts[1]; url_ = QString("%1/_matrix/media/r0/download/%2") .arg(client_.data()->getHomeServer().toString(), media_params); - - connect(client_.data(), &MatrixClient::fileDownloaded, this, &FileItem::fileDownloaded); } FileItem::FileItem(QSharedPointer client, @@ -122,18 +120,22 @@ FileItem::mousePressEvent(QMouseEvent *event) if (filenameToSave_.isEmpty()) return; - client_->downloadFile(QString::fromStdString(event_.event_id), url_); + auto proxy = client_->downloadFile(url_); + connect(proxy, + &DownloadMediaProxy::fileDownloaded, + this, + [proxy, this](const QByteArray &data) { + proxy->deleteLater(); + fileDownloaded(data); + }); } else { openUrl(); } } void -FileItem::fileDownloaded(const QString &event_id, const QByteArray &data) +FileItem::fileDownloaded(const QByteArray &data) { - if (event_id != QString::fromStdString(event_.event_id)) - return; - try { QFile file(filenameToSave_); diff --git a/src/timeline/widgets/ImageItem.cc b/src/timeline/widgets/ImageItem.cc index a4f1ca57..2784f386 100644 --- a/src/timeline/widgets/ImageItem.cc +++ b/src/timeline/widgets/ImageItem.cc @@ -53,15 +53,13 @@ ImageItem::ImageItem(QSharedPointer client, url_ = QString("%1/_matrix/media/r0/download/%2") .arg(client_.data()->getHomeServer().toString(), media_params); - client_.data()->downloadImage(QString::fromStdString(event.event_id), url_); + auto proxy = client_.data()->downloadImage(url_); - connect(client_.data(), - &MatrixClient::imageDownloaded, - this, - [this](const QString &id, const QPixmap &img) { - if (id == QString::fromStdString(event_.event_id)) - setImage(img); - }); + connect( + proxy, &DownloadMediaProxy::imageDownloaded, this, [this, proxy](const QPixmap &img) { + proxy->deleteLater(); + setImage(img); + }); } ImageItem::ImageItem(QSharedPointer client, @@ -91,16 +89,13 @@ ImageItem::ImageItem(QSharedPointer client, url_ = QString("%1/_matrix/media/r0/download/%2") .arg(client_.data()->getHomeServer().toString(), media_params); - const auto request_id = QUuid::createUuid().toString(); - client_.data()->downloadImage(request_id, url_); + auto proxy = client_.data()->downloadImage(url_); - connect(client_.data(), - &MatrixClient::imageDownloaded, - this, - [request_id, this](const QString &id, const QPixmap &img) { - if (id == request_id) - setImage(img); - }); + connect( + proxy, &DownloadMediaProxy::imageDownloaded, this, [proxy, this](const QPixmap &img) { + proxy->deleteLater(); + setImage(img); + }); } void