mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-22 19:08:58 +03:00
Fix thumbnails for encrypted files and factor upload box out
This commit is contained in:
parent
dbd2bebe6c
commit
a9486ec896
8 changed files with 182 additions and 83 deletions
|
@ -125,75 +125,7 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Page {
|
UploadBox {
|
||||||
id: uploadPopup
|
|
||||||
visible: room && room.input.uploads.length > 0
|
|
||||||
Layout.preferredHeight: 200
|
|
||||||
clip: true
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
padding: Nheko.paddingMedium
|
|
||||||
|
|
||||||
contentItem: ListView {
|
|
||||||
id: uploadsList
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
boundsBehavior: Flickable.StopAtBounds
|
|
||||||
|
|
||||||
orientation: ListView.Horizontal
|
|
||||||
width: Math.min(contentWidth, parent.width)
|
|
||||||
model: room ? room.input.uploads : undefined
|
|
||||||
spacing: Nheko.paddingMedium
|
|
||||||
|
|
||||||
delegate: Pane {
|
|
||||||
padding: Nheko.paddingSmall
|
|
||||||
height: uploadPopup.availableHeight - buttons.height
|
|
||||||
width: uploadPopup.availableHeight - buttons.height
|
|
||||||
|
|
||||||
background: Rectangle {
|
|
||||||
color: Nheko.colors.window
|
|
||||||
radius: Nheko.paddingMedium
|
|
||||||
}
|
|
||||||
contentItem: ColumnLayout {
|
|
||||||
Image {
|
|
||||||
Layout.fillHeight: true
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
sourceSize.height: height
|
|
||||||
sourceSize.width: width
|
|
||||||
|
|
||||||
property string typeStr: switch(modelData.mediaType) {
|
|
||||||
case MediaUpload.Video: return "video-file";
|
|
||||||
case MediaUpload.Audio: return "music";
|
|
||||||
case MediaUpload.Image: return "image";
|
|
||||||
default: return "zip";
|
|
||||||
}
|
|
||||||
source: "image://colorimage/:/icons/icons/ui/"+typeStr+".svg?" + Nheko.colors.buttonText
|
|
||||||
}
|
|
||||||
MatrixTextField {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
text: modelData.filename
|
|
||||||
onTextEdited: modelData.filename = text
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
footer: DialogButtonBox {
|
|
||||||
id: buttons
|
|
||||||
|
|
||||||
standardButtons: DialogButtonBox.Cancel
|
|
||||||
Button {
|
|
||||||
text: qsTr("Upload %n file(s)", "", (room ? room.input.uploads.length : 0))
|
|
||||||
DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole
|
|
||||||
}
|
|
||||||
onAccepted: room.input.acceptUploads()
|
|
||||||
onRejected: room.input.declineUploads()
|
|
||||||
}
|
|
||||||
|
|
||||||
background: Rectangle {
|
|
||||||
color: Nheko.colors.base
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NotificationWarning {
|
NotificationWarning {
|
||||||
|
|
89
resources/qml/UploadBox.qml
Normal file
89
resources/qml/UploadBox.qml
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
// SPDX-FileCopyrightText: 2022 Nheko Contributors
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
import "./components"
|
||||||
|
import "./ui"
|
||||||
|
|
||||||
|
import QtQuick 2.9
|
||||||
|
import QtQuick.Controls 2.5
|
||||||
|
import QtQuick.Layouts 1.3
|
||||||
|
import im.nheko 1.0
|
||||||
|
|
||||||
|
Page {
|
||||||
|
id: uploadPopup
|
||||||
|
visible: room && room.input.uploads.length > 0
|
||||||
|
Layout.preferredHeight: 200
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
padding: Nheko.paddingMedium
|
||||||
|
|
||||||
|
contentItem: ListView {
|
||||||
|
id: uploadsList
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
boundsBehavior: Flickable.StopAtBounds
|
||||||
|
|
||||||
|
ScrollBar.horizontal: ScrollBar {
|
||||||
|
id: scr
|
||||||
|
}
|
||||||
|
|
||||||
|
orientation: ListView.Horizontal
|
||||||
|
width: Math.min(contentWidth, parent.availableWidth)
|
||||||
|
model: room ? room.input.uploads : undefined
|
||||||
|
spacing: Nheko.paddingMedium
|
||||||
|
|
||||||
|
delegate: Pane {
|
||||||
|
padding: Nheko.paddingSmall
|
||||||
|
height: uploadPopup.availableHeight - buttons.height - (scr.visible? scr.height : 0)
|
||||||
|
width: uploadPopup.availableHeight - buttons.height
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
color: Nheko.colors.window
|
||||||
|
radius: Nheko.paddingMedium
|
||||||
|
}
|
||||||
|
contentItem: ColumnLayout {
|
||||||
|
Image {
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
sourceSize.height: height
|
||||||
|
sourceSize.width: width
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
smooth: true
|
||||||
|
mipmap: true
|
||||||
|
|
||||||
|
property string typeStr: switch(modelData.mediaType) {
|
||||||
|
case MediaUpload.Video: return "video-file";
|
||||||
|
case MediaUpload.Audio: return "music";
|
||||||
|
case MediaUpload.Image: return "image";
|
||||||
|
default: return "zip";
|
||||||
|
}
|
||||||
|
source: (modelData.thumbnail != "") ? modelData.thumbnail : ("image://colorimage/:/icons/icons/ui/"+typeStr+".svg?" + Nheko.colors.buttonText)
|
||||||
|
}
|
||||||
|
MatrixTextField {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: modelData.filename
|
||||||
|
onTextEdited: modelData.filename = text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
footer: DialogButtonBox {
|
||||||
|
id: buttons
|
||||||
|
|
||||||
|
standardButtons: DialogButtonBox.Cancel
|
||||||
|
Button {
|
||||||
|
text: qsTr("Upload %n file(s)", "", (room ? room.input.uploads.length : 0))
|
||||||
|
DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole
|
||||||
|
}
|
||||||
|
onAccepted: room.input.acceptUploads()
|
||||||
|
onRejected: room.input.declineUploads()
|
||||||
|
}
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
color: Nheko.colors.base
|
||||||
|
}
|
||||||
|
}
|
|
@ -99,6 +99,7 @@
|
||||||
<file>qml/MatrixText.qml</file>
|
<file>qml/MatrixText.qml</file>
|
||||||
<file>qml/MatrixTextField.qml</file>
|
<file>qml/MatrixTextField.qml</file>
|
||||||
<file>qml/ToggleButton.qml</file>
|
<file>qml/ToggleButton.qml</file>
|
||||||
|
<file>qml/UploadBox.qml</file>
|
||||||
<file>qml/MessageInput.qml</file>
|
<file>qml/MessageInput.qml</file>
|
||||||
<file>qml/MessageView.qml</file>
|
<file>qml/MessageView.qml</file>
|
||||||
<file>qml/NhekoBusyIndicator.qml</file>
|
<file>qml/NhekoBusyIndicator.qml</file>
|
||||||
|
|
|
@ -139,6 +139,19 @@ struct EventFile
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct EventThumbnailFile
|
||||||
|
{
|
||||||
|
template<class Content>
|
||||||
|
using file_t = decltype(Content::info.thumbnail_file);
|
||||||
|
template<class T>
|
||||||
|
std::optional<mtx::crypto::EncryptedFile> operator()(const mtx::events::Event<T> &e)
|
||||||
|
{
|
||||||
|
if constexpr (is_detected<file_t, T>::value)
|
||||||
|
return e.content.info.thumbnail_file;
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct EventUrl
|
struct EventUrl
|
||||||
{
|
{
|
||||||
template<class Content>
|
template<class Content>
|
||||||
|
@ -163,6 +176,8 @@ struct EventThumbnailUrl
|
||||||
std::string operator()(const mtx::events::Event<T> &e)
|
std::string operator()(const mtx::events::Event<T> &e)
|
||||||
{
|
{
|
||||||
if constexpr (is_detected<thumbnail_url_t, T>::value) {
|
if constexpr (is_detected<thumbnail_url_t, T>::value) {
|
||||||
|
if (auto file = EventThumbnailFile{}(e))
|
||||||
|
return file->url;
|
||||||
return e.content.info.thumbnail_url;
|
return e.content.info.thumbnail_url;
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
|
@ -424,6 +439,12 @@ mtx::accessors::file(const mtx::events::collections::TimelineEvents &event)
|
||||||
return std::visit(EventFile{}, event);
|
return std::visit(EventFile{}, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<mtx::crypto::EncryptedFile>
|
||||||
|
mtx::accessors::thumbnail_file(const mtx::events::collections::TimelineEvents &event)
|
||||||
|
{
|
||||||
|
return std::visit(EventThumbnailFile{}, event);
|
||||||
|
}
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
mtx::accessors::url(const mtx::events::collections::TimelineEvents &event)
|
mtx::accessors::url(const mtx::events::collections::TimelineEvents &event)
|
||||||
{
|
{
|
||||||
|
|
|
@ -78,6 +78,8 @@ formattedBodyWithFallback(const mtx::events::collections::TimelineEvents &event)
|
||||||
|
|
||||||
std::optional<mtx::crypto::EncryptedFile>
|
std::optional<mtx::crypto::EncryptedFile>
|
||||||
file(const mtx::events::collections::TimelineEvents &event);
|
file(const mtx::events::collections::TimelineEvents &event);
|
||||||
|
std::optional<mtx::crypto::EncryptedFile>
|
||||||
|
thumbnail_file(const mtx::events::collections::TimelineEvents &event);
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
url(const mtx::events::collections::TimelineEvents &event);
|
url(const mtx::events::collections::TimelineEvents &event);
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
#include <QMimeDatabase>
|
#include <QMimeDatabase>
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
#include <QTextBoundaryFinder>
|
#include <QTextBoundaryFinder>
|
||||||
#include <QUrl>
|
|
||||||
|
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
#include <mtx/responses/common.hpp>
|
#include <mtx/responses/common.hpp>
|
||||||
|
@ -39,6 +38,20 @@
|
||||||
|
|
||||||
static constexpr size_t INPUT_HISTORY_SIZE = 10;
|
static constexpr size_t INPUT_HISTORY_SIZE = 10;
|
||||||
|
|
||||||
|
QUrl
|
||||||
|
MediaUpload::thumbnailDataUrl() const
|
||||||
|
{
|
||||||
|
if (thumbnail_.isNull())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
QByteArray byteArray;
|
||||||
|
QBuffer buffer(&byteArray);
|
||||||
|
buffer.open(QIODevice::WriteOnly);
|
||||||
|
thumbnail_.save(&buffer, "PNG");
|
||||||
|
QString base64 = QString::fromUtf8(byteArray.toBase64());
|
||||||
|
return QString("data:image/png;base64,") + base64;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
InputVideoSurface::present(const QVideoFrame &frame)
|
InputVideoSurface::present(const QVideoFrame &frame)
|
||||||
{
|
{
|
||||||
|
@ -465,6 +478,10 @@ InputBar::image(const QString &filename,
|
||||||
const QString &mime,
|
const QString &mime,
|
||||||
uint64_t dsize,
|
uint64_t dsize,
|
||||||
const QSize &dimensions,
|
const QSize &dimensions,
|
||||||
|
const std::optional<mtx::crypto::EncryptedFile> &thumbnailEncryptedFile,
|
||||||
|
const QString &thumbnailUrl,
|
||||||
|
uint64_t thumbnailSize,
|
||||||
|
const QSize &thumbnailDimensions,
|
||||||
const QString &blurhash)
|
const QString &blurhash)
|
||||||
{
|
{
|
||||||
mtx::events::msg::Image image;
|
mtx::events::msg::Image image;
|
||||||
|
@ -480,6 +497,18 @@ InputBar::image(const QString &filename,
|
||||||
else
|
else
|
||||||
image.url = url.toStdString();
|
image.url = url.toStdString();
|
||||||
|
|
||||||
|
if (!thumbnailUrl.isEmpty()) {
|
||||||
|
if (thumbnailEncryptedFile)
|
||||||
|
image.info.thumbnail_file = thumbnailEncryptedFile;
|
||||||
|
else
|
||||||
|
image.info.thumbnail_url = thumbnailUrl.toStdString();
|
||||||
|
|
||||||
|
image.info.thumbnail_info.h = thumbnailDimensions.height();
|
||||||
|
image.info.thumbnail_info.w = thumbnailDimensions.width();
|
||||||
|
image.info.thumbnail_info.size = thumbnailSize;
|
||||||
|
image.info.thumbnail_info.mimetype = "image/png";
|
||||||
|
}
|
||||||
|
|
||||||
if (!room->reply().isEmpty()) {
|
if (!room->reply().isEmpty()) {
|
||||||
image.relations.relations.push_back(
|
image.relations.relations.push_back(
|
||||||
{mtx::common::RelationType::InReplyTo, room->reply().toStdString()});
|
{mtx::common::RelationType::InReplyTo, room->reply().toStdString()});
|
||||||
|
@ -566,11 +595,13 @@ InputBar::video(const QString &filename,
|
||||||
const std::optional<mtx::crypto::EncryptedFile> &thumbnailEncryptedFile,
|
const std::optional<mtx::crypto::EncryptedFile> &thumbnailEncryptedFile,
|
||||||
const QString &thumbnailUrl,
|
const QString &thumbnailUrl,
|
||||||
uint64_t thumbnailSize,
|
uint64_t thumbnailSize,
|
||||||
const QSize &thumbnailDimensions)
|
const QSize &thumbnailDimensions,
|
||||||
|
const QString &blurhash)
|
||||||
{
|
{
|
||||||
mtx::events::msg::Video video;
|
mtx::events::msg::Video video;
|
||||||
video.info.mimetype = mime.toStdString();
|
video.info.mimetype = mime.toStdString();
|
||||||
video.info.size = dsize;
|
video.info.size = dsize;
|
||||||
|
video.info.blurhash = blurhash.toStdString();
|
||||||
video.body = filename.toStdString();
|
video.body = filename.toStdString();
|
||||||
|
|
||||||
if (duration > 0)
|
if (duration > 0)
|
||||||
|
@ -946,7 +977,17 @@ InputBar::finalizeUpload(MediaUpload *upload, QString url)
|
||||||
auto size = upload->size();
|
auto size = upload->size();
|
||||||
auto encryptedFile = upload->encryptedFile_();
|
auto encryptedFile = upload->encryptedFile_();
|
||||||
if (mimeClass == u"image")
|
if (mimeClass == u"image")
|
||||||
image(filename, encryptedFile, url, mime, size, upload->dimensions(), upload->blurhash());
|
image(filename,
|
||||||
|
encryptedFile,
|
||||||
|
url,
|
||||||
|
mime,
|
||||||
|
size,
|
||||||
|
upload->dimensions(),
|
||||||
|
upload->thumbnailEncryptedFile_(),
|
||||||
|
upload->thumbnailUrl(),
|
||||||
|
upload->thumbnailSize(),
|
||||||
|
upload->thumbnailImg().size(),
|
||||||
|
upload->blurhash());
|
||||||
else if (mimeClass == u"audio")
|
else if (mimeClass == u"audio")
|
||||||
audio(filename, encryptedFile, url, mime, size, upload->duration());
|
audio(filename, encryptedFile, url, mime, size, upload->duration());
|
||||||
else if (mimeClass == u"video")
|
else if (mimeClass == u"video")
|
||||||
|
@ -960,7 +1001,8 @@ InputBar::finalizeUpload(MediaUpload *upload, QString url)
|
||||||
upload->thumbnailEncryptedFile_(),
|
upload->thumbnailEncryptedFile_(),
|
||||||
upload->thumbnailUrl(),
|
upload->thumbnailUrl(),
|
||||||
upload->thumbnailSize(),
|
upload->thumbnailSize(),
|
||||||
upload->thumbnailImg().size());
|
upload->thumbnailImg().size(),
|
||||||
|
upload->blurhash());
|
||||||
else
|
else
|
||||||
file(filename, encryptedFile, url, mime, size);
|
file(filename, encryptedFile, url, mime, size);
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <QSize>
|
#include <QSize>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
#include <QUrl>
|
||||||
#include <QVariantList>
|
#include <QVariantList>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
@ -52,15 +53,11 @@ signals:
|
||||||
class MediaUpload : public QObject
|
class MediaUpload : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
// Q_PROPERTY(bool uploading READ uploading NOTIFY uploadingChanged)
|
|
||||||
Q_PROPERTY(int mediaType READ type NOTIFY mediaTypeChanged)
|
Q_PROPERTY(int mediaType READ type NOTIFY mediaTypeChanged)
|
||||||
// // https://stackoverflow.com/questions/33422265/pass-qimage-to-qml/68554646#68554646
|
// https://stackoverflow.com/questions/33422265/pass-qimage-to-qml/68554646#68554646
|
||||||
// Q_PROPERTY(QUrl thumbnail READ thumbnail NOTIFY thumbnailChanged)
|
Q_PROPERTY(QUrl thumbnail READ thumbnailDataUrl NOTIFY thumbnailChanged)
|
||||||
// Q_PROPERTY(QString humanSize READ humanSize NOTIFY huSizeChanged)
|
// Q_PROPERTY(QString humanSize READ humanSize NOTIFY huSizeChanged)
|
||||||
Q_PROPERTY(QString filename READ filename WRITE setFilename NOTIFY filenameChanged)
|
Q_PROPERTY(QString filename READ filename WRITE setFilename NOTIFY filenameChanged)
|
||||||
// Q_PROPERTY(QString mimetype READ mimetype NOTIFY mimetypeChanged)
|
|
||||||
// Q_PROPERTY(int height READ height NOTIFY heightChanged)
|
|
||||||
// Q_PROPERTY(int width READ width NOTIFY widthChanged)
|
|
||||||
|
|
||||||
// thumbnail video
|
// thumbnail video
|
||||||
// https://stackoverflow.com/questions/26229633/display-on-screen-using-qabstractvideosurface
|
// https://stackoverflow.com/questions/26229633/display-on-screen-using-qabstractvideosurface
|
||||||
|
@ -111,6 +108,7 @@ public:
|
||||||
|
|
||||||
QImage thumbnailImg() const { return thumbnail_; }
|
QImage thumbnailImg() const { return thumbnail_; }
|
||||||
QString thumbnailUrl() const { return thumbnailUrl_; }
|
QString thumbnailUrl() const { return thumbnailUrl_; }
|
||||||
|
QUrl thumbnailDataUrl() const;
|
||||||
[[nodiscard]] uint64_t thumbnailSize() const { return thumbnailSize_; }
|
[[nodiscard]] uint64_t thumbnailSize() const { return thumbnailSize_; }
|
||||||
|
|
||||||
void setFilename(QString fn)
|
void setFilename(QString fn)
|
||||||
|
@ -125,13 +123,18 @@ signals:
|
||||||
void uploadComplete(MediaUpload *self, QString url);
|
void uploadComplete(MediaUpload *self, QString url);
|
||||||
void uploadFailed(MediaUpload *self);
|
void uploadFailed(MediaUpload *self);
|
||||||
void filenameChanged();
|
void filenameChanged();
|
||||||
|
void thumbnailChanged();
|
||||||
void mediaTypeChanged();
|
void mediaTypeChanged();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void startUpload();
|
void startUpload();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void setThumbnail(QImage img) { this->thumbnail_ = std::move(img); }
|
void setThumbnail(QImage img)
|
||||||
|
{
|
||||||
|
this->thumbnail_ = std::move(img);
|
||||||
|
emit thumbnailChanged();
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// void uploadThumbnail(QImage img);
|
// void uploadThumbnail(QImage img);
|
||||||
|
@ -225,6 +228,10 @@ private:
|
||||||
const QString &mime,
|
const QString &mime,
|
||||||
uint64_t dsize,
|
uint64_t dsize,
|
||||||
const QSize &dimensions,
|
const QSize &dimensions,
|
||||||
|
const std::optional<mtx::crypto::EncryptedFile> &thumbnailEncryptedFile,
|
||||||
|
const QString &thumbnailUrl,
|
||||||
|
uint64_t thumbnailSize,
|
||||||
|
const QSize &thumbnailDimensions,
|
||||||
const QString &blurhash);
|
const QString &blurhash);
|
||||||
void file(const QString &filename,
|
void file(const QString &filename,
|
||||||
const std::optional<mtx::crypto::EncryptedFile> &encryptedFile,
|
const std::optional<mtx::crypto::EncryptedFile> &encryptedFile,
|
||||||
|
@ -245,9 +252,10 @@ private:
|
||||||
uint64_t duration,
|
uint64_t duration,
|
||||||
const QSize &dimensions,
|
const QSize &dimensions,
|
||||||
const std::optional<mtx::crypto::EncryptedFile> &thumbnailEncryptedFile,
|
const std::optional<mtx::crypto::EncryptedFile> &thumbnailEncryptedFile,
|
||||||
const QString &thumnailUrl,
|
const QString &thumbnailUrl,
|
||||||
uint64_t thumnailSize,
|
uint64_t thumbnailSize,
|
||||||
const QSize &thumbnailDimensions);
|
const QSize &thumbnailDimensions,
|
||||||
|
const QString &blurhash);
|
||||||
|
|
||||||
void startUploadFromPath(const QString &path);
|
void startUploadFromPath(const QString &path);
|
||||||
void startUploadFromMimeData(const QMimeData &source, const QString &format);
|
void startUploadFromMimeData(const QMimeData &source, const QString &format);
|
||||||
|
|
|
@ -1367,6 +1367,10 @@ struct SendMessageVisitor
|
||||||
if (encInfo)
|
if (encInfo)
|
||||||
emit model_->newEncryptedImage(encInfo.value());
|
emit model_->newEncryptedImage(encInfo.value());
|
||||||
|
|
||||||
|
encInfo = mtx::accessors::thumbnail_file(msg);
|
||||||
|
if (encInfo)
|
||||||
|
emit model_->newEncryptedImage(encInfo.value());
|
||||||
|
|
||||||
model_->sendEncryptedMessage(msg, Event);
|
model_->sendEncryptedMessage(msg, Event);
|
||||||
} else {
|
} else {
|
||||||
msg.type = Event;
|
msg.type = Event;
|
||||||
|
|
Loading…
Reference in a new issue