Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F140011
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
10 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/src/contents/ui/event-types/Image.qml b/src/contents/ui/event-types/Image.qml
index 932dfac..99714d7 100644
--- a/src/contents/ui/event-types/Image.qml
+++ b/src/contents/ui/event-types/Image.qml
@@ -1,73 +1,73 @@
/*
* This file is part of kazv.
* SPDX-FileCopyrightText: 2020-2023 Tusooa Zhu <tusooa@kazv.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Controls 2.15
import moe.kazv.mxc.kazv 0.0 as MK
import org.kde.kirigami 2.13 as Kirigami
import '.' as Types
import '..' as Kazv
Simple {
id: upper
property var gender: 'neutral'
property var body: event.content.body
property var key: event.content.file.key.k || ""
- property var iv: event.content.file.key.iv || ""
+ property var iv: event.content.file.iv || ""
property var thumbnailMxcUri: event.encrypted ? event.content.info.thumbnail_file.url : event.content.info.thumbnail_url
property var imageMxcUri: event.encrypted ? event.content.file.url : event.content.url
property var kazvIOJob: thumbnailUri ? kazvIOManager.getDownloadJob(event.eventId) : (imageUri ? kazvIOManager.getDownloadJob(event.eventId) : null)
property var thumbnailUri: thumbnailMxcUri ? kazvIOManager.cacheFile(matrixSdk.mxcUriToHttp(thumbnailMxcUri), event.eventId) : undefined
property var imageUri: thumbnailMxcUri ? matrixSdk.mxcUriToHttp(imageMxcUri) : kazvIOManager.cacheFile(matrixSdk.mxcUriToHttp(imageMxcUri), event.eventId)
property var imageInfo: thumbnailUri ? (event.content.info.thumbnail_info || {}) : (event.content.info || {})
property var imageWidth: image.implicitWidth || imageInfo.w || 1 // lest we divide by 0
property var imageHeight: image.implicitHeight || imageInfo.h || 1
property var innerContentWidth: upper.contentMaxWidth - bubble.bubbleSpacing
Types.MediaBubble {
id: bubble
eventId: event.eventId
serverUrl: upper.imageUri
fileName: body
key: upper.key
iv: upper.iv
property var label: Label {
// Layout.fillWidth: false
// Layout.maximumWidth: innerContentWidth
width: contentWidth > innerContentWidth ? innerContentWidth : contentWidth
wrapMode: Text.Wrap
text: l10n.get('event-message-image-sent', { gender, body })
}
property var image: Image {
id: image
source: kazvIOJob ? null : (thumbnailMxcUri ? thumbnailUri : imageUri)
// Layout.maximumWidth: innerContentWidth
// Layout.preferredWidth: imageWidth
// Layout.preferredHeight: imageHeight / imageWidth * width
width: sourceSize.width > innerContentWidth ? innerContentWidth : source.width
fillMode: Image.PreserveAspectFit
}
Column {
id: layout
width: childrenRect.width > innerContentWidth ? innerContentWidth : childrenRect.width
data: [
bubble.mediaFileMenu,
bubble.label,
bubble.image,
bubble.progressBar
]
}
}
}
diff --git a/src/kazv-io-job.cpp b/src/kazv-io-job.cpp
index 8269133..c938c86 100644
--- a/src/kazv-io-job.cpp
+++ b/src/kazv-io-job.cpp
@@ -1,307 +1,307 @@
/*
* This file is part of kazv.
* SPDX-FileCopyrightText: 2022-2023 nannanko <nannanko@kazv.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
#include "kazv-io-job.hpp"
#include "matrix-room.hpp"
#include <QObject>
#include <QPointer>
#include <QSharedPointer>
#include <QSaveFile>
#include <QFile>
#include <QString>
#include <QMimeDatabase>
#include <KJob>
#include <KIO/TransferJob>
#include <nlohmann/json.hpp>
#include <optional>
#include <string>
struct KazvIOBaseJobPrivate
{
QPointer<KIO::TransferJob> job;
std::optional<KazvIOBaseJob::ErrorCode> result = std::nullopt;
std::optional<Kazv::AES256CTRDesc> aes = std::nullopt;
};
KazvIOBaseJob::KazvIOBaseJob(std::optional<Kazv::AES256CTRDesc> aes, QObject *parent)
: QObject(parent)
, m_d(new KazvIOBaseJobPrivate)
{
m_d->aes = aes;
connect(this, &KazvIOBaseJob::jobChanged, this, &KazvIOBaseJob::connectJob);
}
KazvIOBaseJob::~KazvIOBaseJob() = default;
float KazvIOBaseJob::progress() {
if (m_d->job.isNull()) {
return 0;
}
return static_cast<float>(m_d->job->percent()) / 100;
}
void KazvIOBaseJob::suspend()
{
if (m_d->job.isNull()) {
emitResult(KazvError);
return;
}
m_d->job->suspend();
}
void KazvIOBaseJob::resume()
{
if (m_d->job.isNull()) {
emitResult(KazvError);
return;
}
m_d->job->resume();
}
void KazvIOBaseJob::cancel()
{
if (m_d->job.isNull()) {
emitResult(KazvError);
return;
}
emitResult(UserCancel);
m_d->job->kill();
}
bool KazvIOBaseJob::isSuspended()
{
if (m_d->job.isNull()) {
return false;
}
return m_d->job->isSuspended();
}
bool KazvIOBaseJob::isResulted()
{
return m_d->result.has_value();
}
KazvIOBaseJob::ErrorCode KazvIOBaseJob::error()
{
if (m_d->result.has_value()) {
return m_d->result.value();
}
// Shouldn't call this function before result are emited
return NoError;
}
void KazvIOBaseJob::connectJob()
{
connect(m_d->job, &KJob::result, this, [this](KJob *job) {
if (job->error()) {
emitResult(KIOError);
}
});
connect(m_d->job, &KJob::percentChanged, this,
[this](KJob * /* job */, unsigned long /* percent */) { Q_EMIT progressChanged(); });
}
QPointer<KIO::TransferJob> KazvIOBaseJob::job()
{
return m_d->job;
}
void KazvIOBaseJob::setJob(QPointer<KIO::TransferJob> job)
{
m_d->job = job;
Q_EMIT jobChanged();
}
void KazvIOBaseJob::emitResult(ErrorCode ec, QString data)
{
if (m_d->result.has_value()) {
return;
}
m_d->result = ec;
Q_EMIT result(m_d->result.value(), data);
}
std::optional<Kazv::AES256CTRDesc> KazvIOBaseJob::aes()
{
return m_d->aes;
}
void KazvIOBaseJob::setAes(Kazv::AES256CTRDesc aes)
{
m_d->aes = aes;
}
struct KazvIODownloadJobPrivate
{
QSharedPointer<QSaveFile> file;
};
KazvIODownloadJob::KazvIODownloadJob(std::optional<Kazv::AES256CTRDesc> aes, QObject *parent)
: KazvIOBaseJob(aes, parent)
, m_d(new KazvIODownloadJobPrivate)
{
}
KazvIODownloadJob::KazvIODownloadJob(QString fileName, QUrl serverUrl,
std::optional<Kazv::AES256CTRDesc> aes, QObject *parent)
: KazvIOBaseJob(aes, parent)
, m_d(new KazvIODownloadJobPrivate)
{
if (setFile(fileName)) {
setJob(KIO::get(serverUrl));
}
}
KazvIODownloadJob::~KazvIODownloadJob() = default;
QString KazvIODownloadJob::fileName() {
if (m_d->file.isNull()) {
return QStringLiteral("");
}
return m_d->file->fileName();
}
void KazvIODownloadJob::connectJob()
{
KazvIOBaseJob::connectJob();
connect(this->job(), &KIO::TransferJob::data, this, &KazvIODownloadJob::writeFile);
connect(this->job(), &KJob::result, this, &KazvIODownloadJob::closeFile);
}
bool KazvIODownloadJob::setFile(QString fileName)
{
m_d->file.reset(new QSaveFile(fileName));
if (m_d->file->open(QIODevice::WriteOnly)) {
return true;
}
emitResult(KazvIOBaseJob::OpenFileError);
return false;
}
void KazvIODownloadJob::writeFile(KJob *job, const QByteArray &data)
{
if (m_d->file.isNull() || !m_d->file->isOpen()) {
emitResult(KazvError);
job->kill();
return;
}
QByteArray plainData = data;
if (this->aes() != std::nullopt) {
// auto result = this->aes().value().process(data.toStdString());
- // plainData = result.second
+ // plainData = QByteArray::fromStdString(result.second);
// this->setAes(result.first);
}
auto len = m_d->file->write(plainData);
if (len == -1) {
KazvIOBaseJob::emitResult(WriteFileError);
job->kill();
}
}
void KazvIODownloadJob::closeFile(KJob *job)
{
if (m_d->file.isNull()) {
emitResult(KazvError);
return;
}
if (job->error()) {
m_d->file->cancelWriting();
return;
}
m_d->file->commit();
emitResult(NoError);
}
struct KazvIOUploadJobPrivate
{
QSharedPointer<QFile> file;
QString response;
QSharedPointer<MatrixRoom> room;
QString mimeType;
QString mxcUri;
};
KazvIOUploadJob::KazvIOUploadJob(std::optional<Kazv::AES256CTRDesc> aes, QObject *parent)
: KazvIOBaseJob(aes, parent)
, m_d(new KazvIOUploadJobPrivate)
{
}
KazvIOUploadJob::KazvIOUploadJob(const QString fileName, const QUrl serverUrl,
MatrixRoomList *roomList, const QString &roomId, const QString token,
std::optional<Kazv::AES256CTRDesc> aes, QObject *parent)
: KazvIOBaseJob(aes, parent)
, m_d(new KazvIOUploadJobPrivate)
{
if (setFile(fileName)) {
auto kazvUploadJob = Kazv::Api::UploadContentJob(serverUrl.toString().toStdString(),
token.toStdString(), Kazv::FileDesc(std::string()));
auto job = KIO::http_post(QString(kazvUploadJob.url().data()), m_d->file.data());
job->addMetaData("customHTTPHeader", QStringLiteral("Authorization: ")
.append(kazvUploadJob.requestHeader()->at("Authorization").data()));
job->addMetaData("PropagateHttpHeader", "true");
setJob(job);
if (roomList) {
m_d->room.reset(roomList->room(roomId));
}
}
}
KazvIOUploadJob::~KazvIOUploadJob() = default;
QString KazvIOUploadJob::fileName()
{
if (m_d->file.isNull()) {
return QStringLiteral("");
}
return m_d->file->fileName();
}
void KazvIOUploadJob::connectJob()
{
KazvIOBaseJob::connectJob();
connect(this->job(), &KIO::TransferJob::data, this,
[this](KJob * /* job */, const QByteArray &data) { m_d->response.append(data); });
connect(this->job(), &KJob::result, this, &KazvIOUploadJob::handleResult);
connect(this->job(), &KIO::TransferJob::mimeTypeFound, this,
[this](KJob * /* job */, const QString &mimeType) { m_d->mimeType = mimeType; });
}
void KazvIOUploadJob::handleResult(KJob *job)
{
if (m_d->file.isNull()) {
emitResult(KazvError);
return;
}
m_d->file->close();
if (job->error()) {
return;
}
auto j = nlohmann::json::parse(m_d->response.toStdString());
auto mxcUri = QString::fromStdString(j["content_uri"].get<std::string>());
auto shouldSendMessage = !!m_d->room;
if (shouldSendMessage) {
m_d->room->sendMediaFileMessage(QUrl::fromLocalFile(m_d->file->fileName()).fileName(),
QMimeDatabase().mimeTypeForData(m_d->file.data()).name(), m_d->file->size(), mxcUri);
}
KazvIOBaseJob::emitResult(NoError, mxcUri);
}
bool KazvIOUploadJob::setFile(const QString fileName)
{
m_d->file.reset(new QFile(fileName));
if (m_d->file->open(QIODevice::ReadOnly)) {
return true;
}
emitResult(KazvIOBaseJob::OpenFileError);
return false;
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sun, Jan 19, 9:49 AM (2 h, 23 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
55092
Default Alt Text
(10 KB)
Attached To
Mode
rK kazv
Attached
Detach File
Event Timeline
Log In to Comment