From b8f6e4ce6462f074c34a8b7a286cbabe0e2897aa Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Tue, 3 Dec 2019 02:26:41 +0100 Subject: Add encrypted file download --- src/timeline/TimelineViewManager.cpp | 154 ++++------------------------------- 1 file changed, 15 insertions(+), 139 deletions(-) (limited to 'src/timeline/TimelineViewManager.cpp') diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index 2a88c882..6430a426 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -1,11 +1,8 @@ #include "TimelineViewManager.h" -#include #include -#include #include #include -#include #include "ChatPage.h" #include "ColorImageProvider.h" @@ -124,146 +121,24 @@ TimelineViewManager::setHistoryView(const QString &room_id) } void -TimelineViewManager::openImageOverlay(QString mxcUrl, - QString originalFilename, - QString mimeType, - qml_mtx_events::EventType eventType) const +TimelineViewManager::openImageOverlay(QString mxcUrl, QString eventId) const { QQuickImageResponse *imgResponse = imgProvider->requestImageResponse(mxcUrl.remove("mxc://"), QSize()); - connect(imgResponse, - &QQuickImageResponse::finished, - this, - [this, mxcUrl, originalFilename, mimeType, eventType, imgResponse]() { - if (!imgResponse->errorString().isEmpty()) { - nhlog::ui()->error("Error when retrieving image for overlay: {}", - imgResponse->errorString().toStdString()); - return; - } - auto pixmap = QPixmap::fromImage(imgResponse->textureFactory()->image()); - - auto imgDialog = new dialogs::ImageOverlay(pixmap); - imgDialog->show(); - connect(imgDialog, - &dialogs::ImageOverlay::saving, - this, - [this, mxcUrl, originalFilename, mimeType, eventType]() { - saveMedia(mxcUrl, originalFilename, mimeType, eventType); - }); - }); -} - -void -TimelineViewManager::saveMedia(QString mxcUrl, - QString originalFilename, - QString mimeType, - qml_mtx_events::EventType eventType) const -{ - QString dialogTitle; - if (eventType == qml_mtx_events::EventType::ImageMessage) { - dialogTitle = tr("Save image"); - } else if (eventType == qml_mtx_events::EventType::VideoMessage) { - dialogTitle = tr("Save video"); - } else if (eventType == qml_mtx_events::EventType::AudioMessage) { - dialogTitle = tr("Save audio"); - } else { - dialogTitle = tr("Save file"); - } - - QString filterString = QMimeDatabase().mimeTypeForName(mimeType).filterString(); - - auto filename = - QFileDialog::getSaveFileName(container, dialogTitle, originalFilename, filterString); - - if (filename.isEmpty()) - return; - - const auto url = mxcUrl.toStdString(); - - http::client()->download( - url, - [filename, url](const std::string &data, - const std::string &, - const std::string &, - mtx::http::RequestErr err) { - if (err) { - nhlog::net()->warn("failed to retrieve image {}: {} {}", - url, - err->matrix_error.error, - static_cast(err->status_code)); - return; - } - - try { - QFile file(filename); - - if (!file.open(QIODevice::WriteOnly)) - return; - - file.write(QByteArray(data.data(), (int)data.size())); - file.close(); - } catch (const std::exception &e) { - nhlog::ui()->warn("Error while saving file to: {}", e.what()); - } - }); -} - -void -TimelineViewManager::cacheMedia(QString mxcUrl, QString mimeType) -{ - // If the message is a link to a non mxcUrl, don't download it - if (!mxcUrl.startsWith("mxc://")) { - emit mediaCached(mxcUrl, mxcUrl); - return; - } - - QString suffix = QMimeDatabase().mimeTypeForName(mimeType).preferredSuffix(); - - const auto url = mxcUrl.toStdString(); - QFileInfo filename(QString("%1/media_cache/%2.%3") - .arg(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)) - .arg(QString(mxcUrl).remove("mxc://")) - .arg(suffix)); - if (QDir::cleanPath(filename.path()) != filename.path()) { - nhlog::net()->warn("mxcUrl '{}' is not safe, not downloading file", url); - return; - } - - QDir().mkpath(filename.path()); - - if (filename.isReadable()) { - emit mediaCached(mxcUrl, filename.filePath()); - return; - } + connect(imgResponse, &QQuickImageResponse::finished, this, [this, eventId, imgResponse]() { + if (!imgResponse->errorString().isEmpty()) { + nhlog::ui()->error("Error when retrieving image for overlay: {}", + imgResponse->errorString().toStdString()); + return; + } + auto pixmap = QPixmap::fromImage(imgResponse->textureFactory()->image()); - http::client()->download( - url, - [this, mxcUrl, filename, url](const std::string &data, - const std::string &, - const std::string &, - mtx::http::RequestErr err) { - if (err) { - nhlog::net()->warn("failed to retrieve image {}: {} {}", - url, - err->matrix_error.error, - static_cast(err->status_code)); - return; - } - - try { - QFile file(filename.filePath()); - - if (!file.open(QIODevice::WriteOnly)) - return; - - file.write(QByteArray(data.data(), data.size())); - file.close(); - } catch (const std::exception &e) { - nhlog::ui()->warn("Error while saving file to: {}", e.what()); - } - - emit mediaCached(mxcUrl, filename.filePath()); - }); + auto imgDialog = new dialogs::ImageOverlay(pixmap); + imgDialog->show(); + connect(imgDialog, &dialogs::ImageOverlay::saving, timeline_, [this, eventId]() { + timeline_->saveMedia(eventId); + }); + }); } void @@ -401,3 +276,4 @@ TimelineViewManager::queueVideoMessage(const QString &roomid, video.url = url.toStdString(); models.value(roomid)->sendMessage(video); } + -- cgit 1.5.1 From a689118d71000adba36de19e8ad022ec69695627 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Tue, 3 Dec 2019 19:49:56 +0100 Subject: lint --- src/timeline/TimelineViewManager.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/timeline/TimelineViewManager.cpp') diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index 6430a426..c44bcbbf 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -276,4 +276,3 @@ TimelineViewManager::queueVideoMessage(const QString &roomid, video.url = url.toStdString(); models.value(roomid)->sendMessage(video); } - -- cgit 1.5.1 From 5bfdaff7780bc4299c3edab85c688eebf21f7d4e Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Tue, 3 Dec 2019 23:34:16 +0100 Subject: Implement decryption of images It is a bit of a hack, but it works... --- CMakeLists.txt | 1 + src/MxcImageProvider.cpp | 9 +++++++-- src/MxcImageProvider.h | 30 ++++++++++++++++++++++++++---- src/timeline/TimelineModel.cpp | 13 +++++++++++++ src/timeline/TimelineModel.h | 2 ++ src/timeline/TimelineViewManager.cpp | 11 ++++++++--- 6 files changed, 57 insertions(+), 9 deletions(-) (limited to 'src/timeline/TimelineViewManager.cpp') diff --git a/CMakeLists.txt b/CMakeLists.txt index c918d834..67a1dfb0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -365,6 +365,7 @@ qt5_wrap_cpp(MOC_HEADERS src/CommunitiesList.h src/LoginPage.h src/MainWindow.h + src/MxcImageProvider.h src/InviteeItem.h src/QuickSwitcher.h src/RegisterPage.h diff --git a/src/MxcImageProvider.cpp b/src/MxcImageProvider.cpp index 556b019b..edf6ceb5 100644 --- a/src/MxcImageProvider.cpp +++ b/src/MxcImageProvider.cpp @@ -5,7 +5,7 @@ void MxcImageResponse::run() { - if (m_requestedSize.isValid()) { + if (m_requestedSize.isValid() && !m_encryptionInfo) { QString fileName = QString("%1_%2x%3_crop") .arg(m_id) .arg(m_requestedSize.width()) @@ -65,7 +65,12 @@ MxcImageResponse::run() return; } - auto data = QByteArray(res.data(), res.size()); + auto temp = res; + if (m_encryptionInfo) + temp = mtx::crypto::to_string( + mtx::crypto::decrypt_file(temp, m_encryptionInfo.value())); + + auto data = QByteArray(temp.data(), temp.size()); m_image.loadFromData(data); m_image.setText("original filename", QString::fromStdString(originalFilename)); diff --git a/src/MxcImageProvider.h b/src/MxcImageProvider.h index 19d8a74e..2c197a13 100644 --- a/src/MxcImageProvider.h +++ b/src/MxcImageProvider.h @@ -6,14 +6,21 @@ #include #include +#include + +#include + class MxcImageResponse : public QQuickImageResponse , public QRunnable { public: - MxcImageResponse(const QString &id, const QSize &requestedSize) + MxcImageResponse(const QString &id, + const QSize &requestedSize, + boost::optional encryptionInfo) : m_id(id) , m_requestedSize(requestedSize) + , m_encryptionInfo(encryptionInfo) { setAutoDelete(false); } @@ -29,19 +36,34 @@ public: QString m_id, m_error; QSize m_requestedSize; QImage m_image; + boost::optional m_encryptionInfo; }; -class MxcImageProvider : public QQuickAsyncImageProvider +class MxcImageProvider + : public QObject + , public QQuickAsyncImageProvider { -public: + Q_OBJECT +public slots: QQuickImageResponse *requestImageResponse(const QString &id, const QSize &requestedSize) override { - MxcImageResponse *response = new MxcImageResponse(id, requestedSize); + boost::optional info; + auto temp = infos.find("mxc://" + id); + if (temp != infos.end()) + info = *temp; + + MxcImageResponse *response = new MxcImageResponse(id, requestedSize, info); pool.start(response); return response; } + void addEncryptionInfo(mtx::crypto::EncryptedFile info) + { + infos.insert(QString::fromStdString(info.url), info); + } + private: QThreadPool pool; + QHash infos; }; diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp index f606b603..2c58e2f5 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp @@ -673,6 +673,19 @@ TimelineModel::internalAddEvents( continue; // don't insert redaction into timeline } + if (auto event = + boost::get>(&e)) { + auto temp = decryptEvent(*event).event; + auto encInfo = boost::apply_visitor( + [](const auto &ev) -> boost::optional { + return eventEncryptionInfo(ev); + }, + temp); + + if (encInfo) + emit newEncryptedImage(encInfo.value()); + } + this->events.insert(id, e); ids.push_back(id); } diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h index f52091e6..06c64acf 100644 --- a/src/timeline/TimelineModel.h +++ b/src/timeline/TimelineModel.h @@ -6,6 +6,7 @@ #include #include +#include #include #include "Cache.h" @@ -188,6 +189,7 @@ signals: void nextPendingMessage(); void newMessageToSend(mtx::events::collections::TimelineEvents event); void mediaCached(QString mxcUrl, QString cacheUrl); + void newEncryptedImage(mtx::crypto::EncryptedFile encryptionInfo); private: DecryptionResult decryptEvent( diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index c44bcbbf..25f72a6d 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -102,9 +102,14 @@ TimelineViewManager::sync(const mtx::responses::Rooms &rooms) void TimelineViewManager::addRoom(const QString &room_id) { - if (!models.contains(room_id)) - models.insert(room_id, - QSharedPointer(new TimelineModel(this, room_id))); + if (!models.contains(room_id)) { + QSharedPointer newRoom(new TimelineModel(this, room_id)); + connect(newRoom.data(), + &TimelineModel::newEncryptedImage, + imgProvider, + &MxcImageProvider::addEncryptionInfo); + models.insert(room_id, std::move(newRoom)); + } } void -- cgit 1.5.1 From 43d7fe0d358edd1983257350817f7e76132c8dc8 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Thu, 5 Dec 2019 15:31:53 +0100 Subject: Implement sending encrypted files --- src/ChatPage.cpp | 206 ++++++++--------------------------- src/ChatPage.h | 21 +--- src/TextInputWidget.cpp | 28 ++--- src/TextInputWidget.h | 12 +- src/timeline/TimelineViewManager.cpp | 19 +++- src/timeline/TimelineViewManager.h | 5 + 6 files changed, 79 insertions(+), 212 deletions(-) (limited to 'src/timeline/TimelineViewManager.cpp') diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp index 091a9fa0..d6f6940b 100644 --- a/src/ChatPage.cpp +++ b/src/ChatPage.cpp @@ -54,6 +54,8 @@ constexpr int CHECK_CONNECTIVITY_INTERVAL = 15'000; constexpr int RETRY_TIMEOUT = 5'000; constexpr size_t MAX_ONETIME_KEYS = 50; +Q_DECLARE_METATYPE(boost::optional) + ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) : QWidget(parent) , isConnected_(true) @@ -62,6 +64,9 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) { setObjectName("chatPage"); + qRegisterMetaType>( + "boost::optional"); + topLayout_ = new QHBoxLayout(this); topLayout_->setSpacing(0); topLayout_->setMargin(0); @@ -299,9 +304,9 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) connect( text_input_, - &TextInputWidget::uploadImage, + &TextInputWidget::uploadMedia, this, - [this](QSharedPointer dev, const QString &fn) { + [this](QSharedPointer dev, QString mimeClass, const QString &fn) { QMimeDatabase db; QMimeType mime = db.mimeTypeForData(dev.data()); @@ -311,9 +316,18 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) return; } - auto bin = dev->peek(dev->size()); - auto payload = std::string(bin.data(), bin.size()); - auto dimensions = QImageReader(dev.data()).size(); + auto bin = dev->peek(dev->size()); + auto payload = std::string(bin.data(), bin.size()); + boost::optional encryptedFile; + if (cache::client()->isRoomEncrypted(current_room_.toStdString())) { + mtx::crypto::BinaryBuf buf; + std::tie(buf, encryptedFile) = mtx::crypto::encrypt_file(payload); + payload = mtx::crypto::to_string(buf); + } + + QSize dimensions; + if (mimeClass == "image") + dimensions = QImageReader(dev.data()).size(); http::client()->upload( payload, @@ -322,193 +336,61 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) [this, room_id = current_room_, filename = fn, - mime = mime.name(), - size = payload.size(), + encryptedFile, + mimeClass, + mime = mime.name(), + size = payload.size(), dimensions](const mtx::responses::ContentURI &res, mtx::http::RequestErr err) { if (err) { emit uploadFailed( - tr("Failed to upload image. Please try again.")); - nhlog::net()->warn("failed to upload image: {} {} ({})", + tr("Failed to upload media. Please try again.")); + nhlog::net()->warn("failed to upload media: {} {} ({})", err->matrix_error.error, to_string(err->matrix_error.errcode), static_cast(err->status_code)); return; } - emit imageUploaded(room_id, + emit mediaUploaded(room_id, filename, + encryptedFile, QString::fromStdString(res.content_uri), + mimeClass, mime, size, dimensions); }); }); - connect(text_input_, - &TextInputWidget::uploadFile, - this, - [this](QSharedPointer dev, const QString &fn) { - QMimeDatabase db; - QMimeType mime = db.mimeTypeForData(dev.data()); - - if (!dev->open(QIODevice::ReadOnly)) { - emit uploadFailed( - QString("Error while reading media: %1").arg(dev->errorString())); - return; - } - - auto bin = dev->readAll(); - auto payload = std::string(bin.data(), bin.size()); - - http::client()->upload( - payload, - mime.name().toStdString(), - QFileInfo(fn).fileName().toStdString(), - [this, - room_id = current_room_, - filename = fn, - mime = mime.name(), - size = payload.size()](const mtx::responses::ContentURI &res, - mtx::http::RequestErr err) { - if (err) { - emit uploadFailed( - tr("Failed to upload file. Please try again.")); - nhlog::net()->warn("failed to upload file: {} ({})", - err->matrix_error.error, - static_cast(err->status_code)); - return; - } - - emit fileUploaded(room_id, - filename, - QString::fromStdString(res.content_uri), - mime, - size); - }); - }); - - connect(text_input_, - &TextInputWidget::uploadAudio, - this, - [this](QSharedPointer dev, const QString &fn) { - QMimeDatabase db; - QMimeType mime = db.mimeTypeForData(dev.data()); - - if (!dev->open(QIODevice::ReadOnly)) { - emit uploadFailed( - QString("Error while reading media: %1").arg(dev->errorString())); - return; - } - - auto bin = dev->readAll(); - auto payload = std::string(bin.data(), bin.size()); - - http::client()->upload( - payload, - mime.name().toStdString(), - QFileInfo(fn).fileName().toStdString(), - [this, - room_id = current_room_, - filename = fn, - mime = mime.name(), - size = payload.size()](const mtx::responses::ContentURI &res, - mtx::http::RequestErr err) { - if (err) { - emit uploadFailed( - tr("Failed to upload audio. Please try again.")); - nhlog::net()->warn("failed to upload audio: {} ({})", - err->matrix_error.error, - static_cast(err->status_code)); - return; - } - - emit audioUploaded(room_id, - filename, - QString::fromStdString(res.content_uri), - mime, - size); - }); - }); - connect(text_input_, - &TextInputWidget::uploadVideo, - this, - [this](QSharedPointer dev, const QString &fn) { - QMimeDatabase db; - QMimeType mime = db.mimeTypeForData(dev.data()); - - if (!dev->open(QIODevice::ReadOnly)) { - emit uploadFailed( - QString("Error while reading media: %1").arg(dev->errorString())); - return; - } - - auto bin = dev->readAll(); - auto payload = std::string(bin.data(), bin.size()); - - http::client()->upload( - payload, - mime.name().toStdString(), - QFileInfo(fn).fileName().toStdString(), - [this, - room_id = current_room_, - filename = fn, - mime = mime.name(), - size = payload.size()](const mtx::responses::ContentURI &res, - mtx::http::RequestErr err) { - if (err) { - emit uploadFailed( - tr("Failed to upload video. Please try again.")); - nhlog::net()->warn("failed to upload video: {} ({})", - err->matrix_error.error, - static_cast(err->status_code)); - return; - } - - emit videoUploaded(room_id, - filename, - QString::fromStdString(res.content_uri), - mime, - size); - }); - }); - connect(this, &ChatPage::uploadFailed, this, [this](const QString &msg) { text_input_->hideUploadSpinner(); emit showNotification(msg); }); connect(this, - &ChatPage::imageUploaded, + &ChatPage::mediaUploaded, this, [this](QString roomid, QString filename, + boost::optional encryptedFile, QString url, + QString mimeClass, QString mime, qint64 dsize, QSize dimensions) { text_input_->hideUploadSpinner(); - view_manager_->queueImageMessage( - roomid, filename, url, mime, dsize, dimensions); - }); - connect(this, - &ChatPage::fileUploaded, - this, - [this](QString roomid, QString filename, QString url, QString mime, qint64 dsize) { - text_input_->hideUploadSpinner(); - view_manager_->queueFileMessage(roomid, filename, url, mime, dsize); - }); - connect(this, - &ChatPage::audioUploaded, - this, - [this](QString roomid, QString filename, QString url, QString mime, qint64 dsize) { - text_input_->hideUploadSpinner(); - view_manager_->queueAudioMessage(roomid, filename, url, mime, dsize); - }); - connect(this, - &ChatPage::videoUploaded, - this, - [this](QString roomid, QString filename, QString url, QString mime, qint64 dsize) { - text_input_->hideUploadSpinner(); - view_manager_->queueVideoMessage(roomid, filename, url, mime, dsize); + + if (mimeClass == "image") + view_manager_->queueImageMessage( + roomid, filename, encryptedFile, url, mime, dsize, dimensions); + else if (mimeClass == "audio") + view_manager_->queueAudioMessage( + roomid, filename, encryptedFile, url, mime, dsize); + else if (mimeClass == "video") + view_manager_->queueVideoMessage( + roomid, filename, encryptedFile, url, mime, dsize); + else + view_manager_->queueFileMessage( + roomid, filename, encryptedFile, url, mime, dsize); }); connect(room_list_, &RoomList::roomAvatarChanged, this, &ChatPage::updateTopBarAvatar); diff --git a/src/ChatPage.h b/src/ChatPage.h index 1898f1a7..20e156af 100644 --- a/src/ChatPage.h +++ b/src/ChatPage.h @@ -18,7 +18,9 @@ #pragma once #include +#include #include +#include #include #include @@ -94,27 +96,14 @@ signals: const QPoint widgetPos); void uploadFailed(const QString &msg); - void imageUploaded(const QString &roomid, + void mediaUploaded(const QString &roomid, const QString &filename, + const boost::optional &file, const QString &url, + const QString &mimeClass, const QString &mime, qint64 dsize, const QSize &dimensions); - void fileUploaded(const QString &roomid, - const QString &filename, - const QString &url, - const QString &mime, - qint64 dsize); - void audioUploaded(const QString &roomid, - const QString &filename, - const QString &url, - const QString &mime, - qint64 dsize); - void videoUploaded(const QString &roomid, - const QString &filename, - const QString &url, - const QString &mime, - qint64 dsize); void contentLoaded(); void closing(); diff --git a/src/TextInputWidget.cpp b/src/TextInputWidget.cpp index f723c01a..66700dbc 100644 --- a/src/TextInputWidget.cpp +++ b/src/TextInputWidget.cpp @@ -458,21 +458,16 @@ FilteredTextEdit::textChanged() } void -FilteredTextEdit::uploadData(const QByteArray data, const QString &media, const QString &filename) +FilteredTextEdit::uploadData(const QByteArray data, + const QString &mediaType, + const QString &filename) { QSharedPointer buffer{new QBuffer{this}}; buffer->setData(data); emit startedUpload(); - if (media == "image") - emit image(buffer, filename); - else if (media == "audio") - emit audio(buffer, filename); - else if (media == "video") - emit video(buffer, filename); - else - emit file(buffer, filename); + emit media(buffer, mediaType, filename); } void @@ -580,10 +575,7 @@ TextInputWidget::TextInputWidget(QWidget *parent) connect(input_, &FilteredTextEdit::message, this, &TextInputWidget::sendTextMessage); connect(input_, &FilteredTextEdit::reply, this, &TextInputWidget::sendReplyMessage); connect(input_, &FilteredTextEdit::command, this, &TextInputWidget::command); - connect(input_, &FilteredTextEdit::image, this, &TextInputWidget::uploadImage); - connect(input_, &FilteredTextEdit::audio, this, &TextInputWidget::uploadAudio); - connect(input_, &FilteredTextEdit::video, this, &TextInputWidget::uploadVideo); - connect(input_, &FilteredTextEdit::file, this, &TextInputWidget::uploadFile); + connect(input_, &FilteredTextEdit::media, this, &TextInputWidget::uploadMedia); connect(emojiBtn_, SIGNAL(emojiSelected(const QString &)), this, @@ -642,14 +634,8 @@ TextInputWidget::openFileSelection() const auto format = mime.name().split("/")[0]; QSharedPointer file{new QFile{fileName, this}}; - if (format == "image") - emit uploadImage(file, fileName); - else if (format == "audio") - emit uploadAudio(file, fileName); - else if (format == "video") - emit uploadVideo(file, fileName); - else - emit uploadFile(file, fileName); + + emit uploadMedia(file, format, fileName); showUploadSpinner(); } diff --git a/src/TextInputWidget.h b/src/TextInputWidget.h index 71f794d1..d498be72 100644 --- a/src/TextInputWidget.h +++ b/src/TextInputWidget.h @@ -63,10 +63,7 @@ signals: void message(QString); void reply(QString, const RelatedInfo &); void command(QString name, QString args); - void image(QSharedPointer data, const QString &filename); - void audio(QSharedPointer data, const QString &filename); - void video(QSharedPointer data, const QString &filename); - void file(QSharedPointer data, const QString &filename); + void media(QSharedPointer data, QString mimeClass, const QString &filename); //! Trigger the suggestion popup. void showSuggestions(const QString &query); @@ -179,10 +176,9 @@ signals: void sendEmoteMessage(QString msg); void heightChanged(int height); - void uploadImage(const QSharedPointer data, const QString &filename); - void uploadFile(const QSharedPointer data, const QString &filename); - void uploadAudio(const QSharedPointer data, const QString &filename); - void uploadVideo(const QSharedPointer data, const QString &filename); + void uploadMedia(const QSharedPointer data, + QString mimeClass, + const QString &filename); void sendJoinRoomRequest(const QString &room); diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index 25f72a6d..6e18d111 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -222,6 +222,7 @@ TimelineViewManager::queueEmoteMessage(const QString &msg) void TimelineViewManager::queueImageMessage(const QString &roomid, const QString &filename, + const boost::optional &file, const QString &url, const QString &mime, uint64_t dsize, @@ -234,27 +235,32 @@ TimelineViewManager::queueImageMessage(const QString &roomid, image.url = url.toStdString(); image.info.h = dimensions.height(); image.info.w = dimensions.width(); + image.file = file; models.value(roomid)->sendMessage(image); } void -TimelineViewManager::queueFileMessage(const QString &roomid, - const QString &filename, - const QString &url, - const QString &mime, - uint64_t dsize) +TimelineViewManager::queueFileMessage( + const QString &roomid, + const QString &filename, + const boost::optional &encryptedFile, + const QString &url, + const QString &mime, + uint64_t dsize) { mtx::events::msg::File file; file.info.mimetype = mime.toStdString(); file.info.size = dsize; file.body = filename.toStdString(); file.url = url.toStdString(); + file.file = encryptedFile; models.value(roomid)->sendMessage(file); } void TimelineViewManager::queueAudioMessage(const QString &roomid, const QString &filename, + const boost::optional &file, const QString &url, const QString &mime, uint64_t dsize) @@ -264,12 +270,14 @@ TimelineViewManager::queueAudioMessage(const QString &roomid, audio.info.size = dsize; audio.body = filename.toStdString(); audio.url = url.toStdString(); + audio.file = file; models.value(roomid)->sendMessage(audio); } void TimelineViewManager::queueVideoMessage(const QString &roomid, const QString &filename, + const boost::optional &file, const QString &url, const QString &mime, uint64_t dsize) @@ -279,5 +287,6 @@ TimelineViewManager::queueVideoMessage(const QString &roomid, video.info.size = dsize; video.body = filename.toStdString(); video.url = url.toStdString(); + video.file = file; models.value(roomid)->sendMessage(video); } diff --git a/src/timeline/TimelineViewManager.h b/src/timeline/TimelineViewManager.h index 1cb0de44..9e8de616 100644 --- a/src/timeline/TimelineViewManager.h +++ b/src/timeline/TimelineViewManager.h @@ -5,6 +5,7 @@ #include #include +#include #include #include "Cache.h" @@ -55,22 +56,26 @@ public slots: void queueEmoteMessage(const QString &msg); void queueImageMessage(const QString &roomid, const QString &filename, + const boost::optional &file, const QString &url, const QString &mime, uint64_t dsize, const QSize &dimensions); void queueFileMessage(const QString &roomid, const QString &filename, + const boost::optional &file, const QString &url, const QString &mime, uint64_t dsize); void queueAudioMessage(const QString &roomid, const QString &filename, + const boost::optional &file, const QString &url, const QString &mime, uint64_t dsize); void queueVideoMessage(const QString &roomid, const QString &filename, + const boost::optional &file, const QString &url, const QString &mime, uint64_t dsize); -- cgit 1.5.1