Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F85832455
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Authored By
Unknown
Size
13 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/src/contents/ui/SendMessageBox.qml b/src/contents/ui/SendMessageBox.qml
index f1503f0..5199e98 100644
--- a/src/contents/ui/SendMessageBox.qml
+++ b/src/contents/ui/SendMessageBox.qml
@@ -1,77 +1,77 @@
/*
* This file is part of kazv.
* SPDX-FileCopyrightText: 2020-2021 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 Qt.labs.platform 1.1 as Platform
import org.kde.kirigami 2.13 as Kirigami
import moe.kazv.mxc.kazv 0.0 as MK
import '.' as Kazv
RowLayout {
property var room
property var kazvIO: MK.KazvIO {
id: kazvIO
}
onRoomChanged: {
textArea.text = room.localDraft
}
TextArea {
id: textArea
property var shortcutList: ["Ctrl+Return", "Ctrl+Enter"]
placeholderText: l10n.get('send-message-box-input-placeholder')
Layout.fillWidth: true
wrapMode: TextEdit.Wrap
onTextChanged: {
room.localDraft = text
}
// Shortcut keys for sending messages (TODO: Shortcut keys customized by the user)
Shortcut {
sequences: textArea.shortcutList
onActivated: {
sendAction.trigger()
}
}
}
Kirigami.Action {
id: sendAction
iconName: "document-send"
onTriggered: {
room.sendTextMessage(textArea.text)
textArea.text = ""
}
}
Kirigami.Action {
id:sendMediaFileAction
iconName: "document-send-symbolic"
onTriggered: {
fileDialog.open()
}
}
property var fileDialog: Platform.FileDialog {
acceptLabel: l10n.get('media-file-send-select')
fileMode: Platform.FileDialog.SaveFile // When set OpenFile, file will be selected whithout user press "Select" button. Maybe it is a bug of Qt?
- option: Platform.FileDialog.DontConfirmOverwrite
+ options: Platform.FileDialog.DontConfirmOverwrite
onAccepted: {
- kazvIO.job = root.kazvIOManager.startNewUploadJob(matrixSdk.serverUrl, file, matrixSdk.token, room.roomId)
+ kazvIO.job = root.kazvIOManager.startNewUploadJob(matrixSdk.serverUrl, file, matrixSdk.token, room)
}
}
ToolButton {
icon.name: "document-send-symbolic"
onClicked: sendMediaFileAction.trigger()
}
ToolButton {
icon.name: "document-send"
onClicked: sendAction.trigger()
}
}
diff --git a/src/kazv-io-job.cpp b/src/kazv-io-job.cpp
index a84f85d..28493f8 100644
--- a/src/kazv-io-job.cpp
+++ b/src/kazv-io-job.cpp
@@ -1,152 +1,186 @@
#include "kazv-io-job.hpp"
+#include "matrix-room.hpp"
#include <QObject>
#include <QPointer>
#include <QSharedPointer>
#include <QSaveFile>
#include <QFile>
#include <QByteArray>
#include <QIODevice>
#include <QString>
#include <KJob>
#include <KIO/TransferJob>
+#include <nlohmann/json.hpp>
+
#include <optional>
+#include <string>
+
+using json = nlohmann::json;
struct KazvIOBaseJobPrivate {
QPointer<KIO::TransferJob> job;
std::optional<bool> result = std::nullopt;
};
KazvIOBaseJob::KazvIOBaseJob(QObject *parent)
: QObject(parent)
, m_d(new KazvIOBaseJobPrivate)
{
connect(this, &KazvIOBaseJob::jobChanged, this, &KazvIOBaseJob::connectJob);
}
KazvIOBaseJob::~KazvIOBaseJob() = default;
QPointer<KIO::TransferJob> KazvIOBaseJob::job()
{
return m_d->job;
}
void KazvIOBaseJob::setJob(QPointer<KIO::TransferJob> job)
{
m_d->job = job;
Q_EMIT jobChanged();
}
std::optional<bool> KazvIOBaseJob::success()
{
return m_d->result;
}
std::optional<bool> KazvIOBaseJob::error()
{
if (m_d->result.has_value()) {
return !m_d->result.value();
}
return std::nullopt;
}
void KazvIOBaseJob::connectJob()
{
connect(m_d->job, &KJob::result, this, [this](KJob *job) {
if (job->error()) {
m_d->result = false;
} else {
m_d->result = true;
}
Q_EMIT result();
});
}
struct KazvIODownloadJobPrivate {
QSharedPointer<QSaveFile> file;
};
KazvIODownloadJob::KazvIODownloadJob(QObject *parent)
: KazvIOBaseJob(parent)
, m_d(new KazvIODownloadJobPrivate)
{
}
KazvIODownloadJob::~KazvIODownloadJob() = default;
QSharedPointer<QSaveFile> KazvIODownloadJob::file()
{
return m_d->file;
}
void KazvIODownloadJob::setFile(QSharedPointer<QSaveFile> file)
{
if (!file->isOpen()) {
file->open(QIODevice::WriteOnly);
}
m_d->file = file;
Q_EMIT fileChanged();
}
void KazvIODownloadJob::connectJob()
{
KazvIOBaseJob::connectJob();
connect(this->job(), &KIO::TransferJob::data, this, [this](KJob * /* job */, const QByteArray &data) {
m_d->file->write(data);
});
connect(this->job(), &KJob::result, this, [this](KJob *job) {
if (job->error()) {
m_d->file->cancelWriting();
}
m_d->file->commit();
});
}
struct KazvIOUploadJobPrivate {
QSharedPointer<QFile> file;
QString response;
+ QPointer<MatrixRoom> room;
+ QUrl localFileUrl; // For send media file message
};
KazvIOUploadJob::KazvIOUploadJob(QObject *parent)
: KazvIOBaseJob(parent)
, m_d(new KazvIOUploadJobPrivate)
{
}
KazvIOUploadJob::~KazvIOUploadJob() = default;
QSharedPointer<QFile> KazvIOUploadJob::file()
{
return m_d->file;
}
void KazvIOUploadJob::setFile(QSharedPointer<QFile> file)
{
if (!file->isOpen()) {
file->open(QIODevice::ReadOnly);
}
m_d->file = file;
Q_EMIT fileChanged();
}
QString KazvIOUploadJob::response()
{
return m_d->response;
}
+QPointer<MatrixRoom> KazvIOUploadJob::room()
+{
+ return m_d->room;
+}
+
+void KazvIOUploadJob::setRoom(QPointer<MatrixRoom> room)
+{
+ m_d->room = room;
+ Q_EMIT roomChanged();
+}
+
+QUrl KazvIOUploadJob::localFileUrl()
+{
+ return m_d->localFileUrl;
+}
+
+void KazvIOUploadJob::setLocalFileUrl(QUrl localFileUrl)
+{
+ m_d->localFileUrl = localFileUrl;
+ Q_EMIT localFileUrlChanged();
+}
+
void KazvIOUploadJob::connectJob()
{
KazvIOBaseJob::connectJob();
connect(this->job(), &KIO::TransferJob::data, this, [this](KJob * /* job */, const QByteArray &data) {
m_d->response.append(data);
Q_EMIT responseChanged();
});
connect(this->job(), &KJob::result, this, [this](KJob *job) {
if (job->error()) {
m_d->response.clear();
}
+ json j = json::parse(m_d->response.toStdString());
+ auto mxcUri = j["content_uri"].get<std::string>();
+ m_d->room->sendMediaFileMessage(m_d->localFileUrl, QString(mxcUri.data()));
m_d->file->close();
+ Q_EMIT result();
});
}
diff --git a/src/kazv-io-job.hpp b/src/kazv-io-job.hpp
index 6a41aea..00ae7db 100644
--- a/src/kazv-io-job.hpp
+++ b/src/kazv-io-job.hpp
@@ -1,98 +1,110 @@
/*
* This file is part of kazv.
* SPDX-FileCopyrightText: 2022 nannanko <nannanko@kazv.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
#pragma once
+#include "matrix-room.hpp"
+
#include <QObject>
#include <QPointer>
#include <QSharedPointer>
#include <QSaveFile>
#include <QFile>
#include <QString>
#include <QByteArray>
+#include <QUrl>
#include <KIO/TransferJob>
#include <memory>
#include <optional>
struct KazvIOBaseJobPrivate;
class KazvIOBaseJob : public QObject {
Q_OBJECT
Q_PROPERTY(QPointer<KIO::TransferJob> job READ job WRITE setJob NOTIFY jobChanged)
std::unique_ptr<KazvIOBaseJobPrivate> m_d;
public:
KazvIOBaseJob(QObject *parent = 0);
~KazvIOBaseJob();
QPointer<KIO::TransferJob> job();
void setJob(QPointer<KIO::TransferJob> job);
/**
* return std::nullopt when job is not completed
*/
std::optional<bool> success();
/**
* return std::nullopt when job is not completed
*/
std::optional<bool> error();
Q_SIGNALS:
void jobChanged();
void result();
protected Q_SLOTS:
virtual void connectJob();
};
struct KazvIODownloadJobPrivate;
class KazvIODownloadJob : public KazvIOBaseJob {
Q_OBJECT
Q_PROPERTY(QSharedPointer<QSaveFile> file READ file WRITE setFile NOTIFY fileChanged)
std::unique_ptr<KazvIODownloadJobPrivate> m_d;
public:
KazvIODownloadJob(QObject *parent = 0);
~KazvIODownloadJob();
QSharedPointer<QSaveFile> file();
void setFile(QSharedPointer<QSaveFile> file);
Q_SIGNALS:
void fileChanged();
protected Q_SLOTS:
void connectJob() override;
};
struct KazvIOUploadJobPrivate;
class KazvIOUploadJob : public KazvIOBaseJob {
Q_OBJECT
Q_PROPERTY(QSharedPointer<QFile> file READ file WRITE setFile NOTIFY fileChanged)
Q_PROPERTY(QString response READ response NOTIFY responseChanged)
+ Q_PROPERTY(QPointer<MatrixRoom> room READ room WRITE setRoom NOTIFY roomChanged)
+ Q_PROPERTY(QUrl localFileUrl READ localFileUrl WRITE setLocalFileUrl NOTIFY localFileUrlChanged)
std::unique_ptr<KazvIOUploadJobPrivate> m_d;
public:
KazvIOUploadJob(QObject *parent = 0);
~KazvIOUploadJob();
QSharedPointer<QFile> file();
void setFile(QSharedPointer<QFile> file);
QString response();
+ QPointer<MatrixRoom> room();
+ void setRoom(QPointer<MatrixRoom> room);
+ QUrl localFileUrl();
+ void setLocalFileUrl(QUrl localFileUrl);
Q_SIGNALS:
void fileChanged();
void responseChanged();
+ void roomChanged();
+ void localFileUrlChanged();
+ void result();
protected Q_SLOTS:
void connectJob() override;
};
diff --git a/src/kazv-io-manager.cpp b/src/kazv-io-manager.cpp
index d377cfc..d0d0462 100644
--- a/src/kazv-io-manager.cpp
+++ b/src/kazv-io-manager.cpp
@@ -1,72 +1,79 @@
/*
* This file is part of kazv.
* SPDX-FileCopyrightText: 2022 nannanko <nannanko@kazv.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
#include "kazv-io-manager.hpp"
#include "kazv-io-job.hpp"
+#include "matrix-room.hpp"
#include <api/csapi/content-repo.hpp>
#include <file-desc.hpp>
#include <QObject>
#include <QIODevice>
#include <QFile>
#include <QSaveFile>
#include <QPointer>
#include <QSharedPointer>
#include <QUrl>
#include <QMap>
#include <QMultiMap>
#include <string>
struct KazvIOManagerPrivate {
QMap<QString, QSharedPointer<KazvIODownloadJob>> downloadJobs;
QMultiMap<QString, QSharedPointer<KazvIOUploadJob>> uploadJobs;
};
KazvIOManager::KazvIOManager(QObject *parent)
: QObject(parent)
, m_d(new KazvIOManagerPrivate)
{
}
KazvIOManager::~KazvIOManager() = default;
KazvIOBaseJob *KazvIOManager::startNewDownloadJob(const QUrl &serverUrl, const QUrl &localFileUrl, const QString &jobId)
{
auto downloadJob = QSharedPointer<KazvIODownloadJob>(new KazvIODownloadJob());
downloadJob->setJob(KIO::get(serverUrl));
downloadJob->setFile(QSharedPointer<QSaveFile>(new QSaveFile(localFileUrl.path())));
m_d->downloadJobs[jobId] = downloadJob;
return downloadJob.data();
}
-KazvIOBaseJob *KazvIOManager::startNewUploadJob(const QUrl &serverUrl, const QUrl &localFileUrl, const QString &token, const QString &jobId)
+KazvIOBaseJob *KazvIOManager::startNewUploadJob(const QUrl &serverUrl, const QUrl &localFileUrl, const QString &token, MatrixRoom *room)
{
auto uploadJob = QSharedPointer<KazvIOUploadJob>(new KazvIOUploadJob());
uploadJob->setFile(QSharedPointer<QFile>(new QFile(localFileUrl.path())));
auto kazvUploadJob = Kazv::Api::UploadContentJob(serverUrl.toString().toStdString(), token.toStdString(), Kazv::FileDesc(std::string()));
uploadJob->setJob(KIO::http_post(QString(kazvUploadJob.url().data()), uploadJob->file().data()));
uploadJob->job()->addMetaData(QString("content-type") , QMimeDatabase().mimeTypeForFile(localFileUrl.path()).name());
uploadJob->job()->addMetaData("customHTTPHeader", QString("Authorization: ").append(kazvUploadJob.requestHeader()->at("Authorization").data()));
uploadJob->job()->addMetaData("PropagateHttpHeader", "true");
+ uploadJob->setRoom(room);
+ uploadJob->setLocalFileUrl(localFileUrl);
+ auto jobId = room->roomId();
+ connect(uploadJob.data(), &KazvIOUploadJob::result, this, [this, jobId, uploadJob]() {
+ m_d->uploadJobs.remove(jobId, uploadJob);
+ });
m_d->uploadJobs.insert(jobId, uploadJob);
return uploadJob.data();
}
KazvIOBaseJob *KazvIOManager::getDownloadJob(const QString &jobId)
{
auto targetJob = m_d->downloadJobs.find(jobId);
if (targetJob == m_d->downloadJobs.end()) {
return nullptr;
}
return targetJob.value().data();
}
void KazvIOManager::deleteDownloadJob(const QString &jobId)
{
m_d->downloadJobs.remove(jobId);
}
diff --git a/src/kazv-io-manager.hpp b/src/kazv-io-manager.hpp
index 8b092a2..78f96d2 100644
--- a/src/kazv-io-manager.hpp
+++ b/src/kazv-io-manager.hpp
@@ -1,35 +1,36 @@
/*
* This file is part of kazv.
* SPDX-FileCopyrightText: 2022 nannanko <nannanko@kazv.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
#pragma once
#include "kazv-io-job.hpp"
+#include "matrix-room.hpp"
#include <QObject>
#include <QtQml>
#include <QUrl>
#include <QString>
#include <KIO/TransferJob>
#include <QPointer>
#include <memory>
struct KazvIOManagerPrivate;
class KazvIOManager : public QObject {
Q_OBJECT
QML_ELEMENT
std::unique_ptr<KazvIOManagerPrivate> m_d;
public:
explicit KazvIOManager(QObject *parent = 0);
~KazvIOManager() override;
Q_INVOKABLE KazvIOBaseJob *startNewDownloadJob(const QUrl &serverUrl, const QUrl &localFileName, const QString &jobId);
- Q_INVOKABLE KazvIOBaseJob *startNewUploadJob(const QUrl &serverUrl, const QUrl &localFileName, const QString &token, const QString &jobId);
+ Q_INVOKABLE KazvIOBaseJob *startNewUploadJob(const QUrl &serverUrl, const QUrl &localFileName, const QString &token, MatrixRoom *room);
Q_INVOKABLE KazvIOBaseJob *getDownloadJob(const QString &jobId);
Q_INVOKABLE void deleteDownloadJob(const QString &jobId);
};
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Mon, Nov 2, 8:24 AM (3 h, 34 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1803820
Default Alt Text
(13 KB)
Attached To
Mode
rK kazv
Attached
Detach File
Event Timeline