Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F140497
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
36 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/src/contents/ui/Bubble.qml b/src/contents/ui/Bubble.qml
index aa66045..43146e7 100644
--- a/src/contents/ui/Bubble.qml
+++ b/src/contents/ui/Bubble.qml
@@ -1,51 +1,35 @@
/*
* 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.2
import QtQuick.Layouts 1.15
import QtQuick.Controls 2.15
import org.kde.kirigami 2.13 as Kirigami
import '.' as Kazv
Kirigami.AbstractCard {
id: upper
default property var children
- property var kazvIO
- property var url
-
readonly property var bubbleSpacing: leftPadding + rightPadding
Layout.fillWidth: false
contentItem: RowLayout {
anchors.left: parent.left
anchors.right: parent.right
property var encryptedIcon: Kirigami.Icon {
source: 'emblem-encrypted-locked'
Layout.preferredHeight: inlineBadgeSize
Layout.preferredWidth: inlineBadgeSize
}
data: [
...(event && event.encrypted ? [encryptedIcon] : []),
...(Array.isArray(upper.children) ? upper.children :
upper.children ? [upper.children] : [])
]
}
-
- property var menu: Kazv.MediaFileMenu {
- kazvIO: upper.kazvIO
- serverUrl: upper.url
-
- onStartDownload: {
- progressBar.show()
- }
- }
-
- property var progressBar: Kazv.ProgressBar {
- kazvIO: upper.kazvIO
- }
}
diff --git a/src/contents/ui/MediaFileMenu.qml b/src/contents/ui/MediaFileMenu.qml
index d175138..2f639dc 100644
--- a/src/contents/ui/MediaFileMenu.qml
+++ b/src/contents/ui/MediaFileMenu.qml
@@ -1,58 +1,60 @@
/*
* This file is part of kazv.
* SPDX-FileCopyrightText: 2022 nannanko <nannanko@kazv.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import QtQuick 2.15
import QtQuick.Controls 2.15
import Qt.labs.platform 1.1 as Platform
import org.kde.kirigami 2.13 as Kirigami
import '.' as Types
TapHandler {
- property var kazvIO
- property var serverUrl
+ id: mediaFileMenu
+
+ required property var kazvIO
+ required property var serverUrl
+ required property var jobId
signal startDownload
acceptedButtons: Qt.LeftButton | Qt.RightButton
onSingleTapped: {
if (eventPoint.event.button === Qt.RightButton) {
optionMenu.popup(parent)
}
if (eventPoint.event.button === Qt.LeftButton) {
// TODO: Open with default program
}
}
onLongPressed: {
optionMenu.popup(parent)
}
property var optionMenu: Menu {
Kirigami.Action {
text: l10n.get('media-file-menu-option-view')
// shortcut: StandardKey.Open
// TODO: open with default program
}
Kirigami.Action {
text: l10n.get('media-file-menu-option-save-as')
// Can't think of a suitable shortcut key
// shortcut: StandardKey.Save
onTriggered: {
fileDialog.open()
}
}
}
property var fileDialog: Platform.FileDialog {
acceptLabel: l10n.get('media-file-menu-option-save-as')
fileMode: Platform.FileDialog.SaveFile
onAccepted: {
- kazvIO.localFileUrl = file
- kazvIO.download()
+ kazvIO.job = root.kazvIOManager.startNewDownloadJob(mediaFileMenu.serverUrl, file, mediaFileMenu.jobId)
startDownload()
}
}
}
diff --git a/src/contents/ui/ProgressBar.qml b/src/contents/ui/ProgressBar.qml
index d8a1b9c..23402e4 100644
--- a/src/contents/ui/ProgressBar.qml
+++ b/src/contents/ui/ProgressBar.qml
@@ -1,97 +1,98 @@
/*
* This file is part of kazv.
* SPDX-FileCopyrightText: 2022 nannanko <nannanko@kazv.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import org.kde.kirigami 2.13 as Kirigami
import moe.kazv.mxc.kazv 0.0 as MK
ColumnLayout {
property var kazvIO
+ property var jobId
visible: false
RowLayout {
id: progressBarLayout
Layout.preferredWidth: parent.width
ProgressBar {
id: progressBar
Layout.fillWidth: true
}
Kirigami.Action {
id: pauseAction
iconName: suspended ? "media-playback-start" : "media-playback-pause"
property var suspended: false
onTriggered: {
if (pauseAction.suspended) {
kazvIO.resume()
} else {
kazvIO.suspend()
}
suspended = !suspended
}
}
Kirigami.Action {
id: cancelAction
iconName: "dialog-cancel"
onTriggered: {
pauseAction.suspended = false
kazvIO.cancel()
}
}
RoundButton {
id: pauseBtn
Accessible.name: pauseAction.suspended ? l10n.get('media-file-download-resume') : l10n.get('media-file-download-pause')
icon.name: pauseAction.suspended ? "media-playback-start" : "media-playback-pause"
onClicked: pauseAction.trigger()
}
RoundButton {
icon.name: "dialog-cancel"
Accessible.name: l10n.get('media-file-download-cancel')
onClicked: cancelAction.trigger()
}
}
RowLayout {
id: promptMsgLayout
Text {
id: promptMsg
}
Button {
text: l10n.get('media-file-download-prompt-close')
onClicked: {
- kazvIOManager.deleteDownloadJob(kazvIO.eventId)
+ kazvIOManager.deleteDownloadJob(jobId)
close()
}
}
}
function show() {
progressBar.value = Qt.binding(function() { return kazvIO.progress })
visible = true
progressBarLayout.visible = true
promptMsgLayout.visible = false
}
function close() {
visible = false
}
function switchToPause() {
pauseAction.suspended = true
}
function showSuccMsg() {
progressBarLayout.visible = false
promptMsg.text = l10n.get('media-file-download-success-prompt')
promptMsgLayout.visible = true
}
function showFailMsg() {
progressBarLayout.visible = false
promptMsg.text = l10n.get('media-file-download-failure-prompt')
promptMsgLayout.visible = true
}
}
diff --git a/src/contents/ui/SendMessageBox.qml b/src/contents/ui/SendMessageBox.qml
index 3503636..1431caa 100644
--- a/src/contents/ui/SendMessageBox.qml
+++ b/src/contents/ui/SendMessageBox.qml
@@ -1,85 +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
- manager: kazvIOManager
- roomId: room.roomId
- serverUrl: matrixSdk.serverUrl
- token: matrixSdk.token
-
- onMxcUriChanged: {
- room.sendMediaFileMessage(kazvIO.localFileUrl, kazvIO.mxcUri)
- }
}
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-menu-option-save-as')
fileMode: Platform.FileDialog.SaveFile
onAccepted: {
- kazvIO.localFileUrl = file
- kazvIO.upload()
+// kazvIO.localFileUrl = file
+// kazvIO.upload()
}
}
ToolButton {
icon.name: "document-send-symbolic"
onClicked: sendMediaFileAction.trigger()
}
ToolButton {
icon.name: "document-send"
onClicked: sendAction.trigger()
}
}
diff --git a/src/contents/ui/event-types/Audio.qml b/src/contents/ui/event-types/Audio.qml
index 50a02e7..ea50c0a 100644
--- a/src/contents/ui/event-types/Audio.qml
+++ b/src/contents/ui/event-types/Audio.qml
@@ -1,87 +1,69 @@
/*
* 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 moe.kazv.mxc.kazv 0.0 as MK
import QtMultimedia 5.15
import org.kde.kirigami 2.13 as Kirigami
-import '..' as Kazv
+import '.' as Types
Simple {
id: upper
property var gender: 'neutral'
property var body: event.content.body
property var mxcUri: event.content.url
property var audioUri: matrixSdk.mxcUriToHttp(mxcUri)
property var innerContentWidth: upper.contentMaxWidth - bubble.bubbleSpacing
- property var kazvIO: MK.KazvIO {
- manager: root.kazvIOManager
- eventId: event.eventId
- serverUrl: audioUri
- job: kazvIOManager.getDownloadJob(event.eventId)
- onSuccess: {
- bubble.progressBar.showSuccMsg()
- }
- onFailure: {
- bubble.progressBar.showFailMsg()
- }
- onProcessing: {
- bubble.progressBar.show()
- }
- onSuspended: {
- bubble.progressBar.switchToPause()
- }
- }
-
- Kazv.Bubble {
+ Types.MediaBubble {
id: bubble
- kazvIO: upper.kazvIO
- url: upper.imageUri
+
+ eventId: event.eventId
+ serverUrl: upper.audioUri
ColumnLayout {
property var msgLabel: Label {
Layout.fillWidth: false
Layout.maximumWidth: innerContentWidth
wrapMode: Text.Wrap
text: l10n.get('event-message-audio-sent', { gender, body })
}
property var audio: Audio {
id: audio
source: audioUri
autoLoad: false
autoPlay: false
}
property var playLabel: Label {
Layout.fillWidth: true
Layout.maximumWidth: innerContentWidth
wrapMode: Text.Wrap
text: l10n.get('event-message-audio-play-audio')
TapHandler {
onSingleTapped: {
audio.play()
}
}
}
data: [
msgLabel,
audio,
playLabel,
- bubble.menu,
+ bubble.mediaFileMenu,
bubble.progressBar
]
}
}
}
diff --git a/src/contents/ui/event-types/File.qml b/src/contents/ui/event-types/File.qml
index 6735a85..d7a2480 100644
--- a/src/contents/ui/event-types/File.qml
+++ b/src/contents/ui/event-types/File.qml
@@ -1,72 +1,54 @@
/*
* 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.2
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 Kazv
+import '.' as Types
Simple {
id: upper
property var gender: 'neutral'
property var body: event.content.body
property var mxcUri: event.content.url
property var fileUri: matrixSdk.mxcUriToHttp(mxcUri)
property var innerContentWidth: upper.contentMaxWidth - bubble.bubbleSpacing
- property var kazvIO: MK.KazvIO {
- manager: root.kazvIOManager
- roomId: roomId
- serverUrl: fileUri
- job: kazvIOManager.getDownloadJob(event.eventId)
- onSuccess: {
- bubble.progressBar.showSuccMsg()
- }
- onFailure: {
- bubble.progressBar.showFailMsg()
- }
- onProcessing: {
- bubble.progressBar.show()
- }
- onSuspended: {
- bubble.progressBar.switchToPause()
- }
- }
-
- Kazv.Bubble {
+ Types.MediaBubble {
id: bubble
- kazvIO: upper.kazvIO
- url: upper.fileUri
+
+ eventId: event.eventId
+ serverUrl: upper.fileUri
ColumnLayout {
property var msgLabel: Label {
Layout.fillWidth: false
Layout.maximumWidth: innerContentWidth
wrapMode: Text.Wrap
text: l10n.get('event-message-file-sent', { gender, body })
}
property var uriLabel: Label {
Layout.fillWidth: false
Layout.maximumWidth: innerContentWidth
wrapMode: Text.Wrap
text: fileUri
}
data: [
msgLabel,
uriLabel,
- bubble.menu,
+ bubble.mediaFileMenu,
bubble.progressBar
]
}
}
}
diff --git a/src/contents/ui/event-types/Image.qml b/src/contents/ui/event-types/Image.qml
index 54d5476..e27454f 100644
--- a/src/contents/ui/event-types/Image.qml
+++ b/src/contents/ui/event-types/Image.qml
@@ -1,79 +1,62 @@
/*
* 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 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 mxcUri: event.content.url
property var imageUri: matrixSdk.mxcUriToHttp(mxcUri)
property var imageInfo: 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
- property var kazvIO: MK.KazvIO {
- manager: root.kazvIOManager
- eventId: event.eventId
- serverUrl: imageUri
- job: kazvIOManager.getDownloadJob(event.eventId)
- onSuccess: {
- bubble.progressBar.showSuccMsg()
- }
- onFailure: {
- bubble.progressBar.showFailMsg()
- }
- onProcessing: {
- bubble.progressBar.show()
- }
- onSuspended: {
- bubble.progressBar.switchToPause()
- }
- }
-
- Kazv.Bubble {
+ Types.MediaBubble {
id: bubble
- kazvIO: upper.kazvIO
- url: upper.imageUri
+
+ eventId: event.eventId
+ serverUrl: upper.imageUri
property var label: Label {
Layout.fillWidth: false
Layout.maximumWidth: innerContentWidth
wrapMode: Text.Wrap
text: l10n.get('event-message-image-sent', { gender, body })
}
property var image: Image {
id: image
source: imageUri
Layout.maximumWidth: innerContentWidth
Layout.preferredWidth: imageWidth
Layout.preferredHeight: imageHeight / imageWidth * width
fillMode: Image.PreserveAspectFit
- data: [bubble.menu]
+ data: [bubble.mediaFileMenu]
}
ColumnLayout {
id: layout
data: [
bubble.label,
bubble.image,
bubble.progressBar
]
}
}
}
diff --git a/src/contents/ui/event-types/MediaBubble.qml b/src/contents/ui/event-types/MediaBubble.qml
new file mode 100644
index 0000000..cd64fb5
--- /dev/null
+++ b/src/contents/ui/event-types/MediaBubble.qml
@@ -0,0 +1,43 @@
+/*
+ * This file is part of kazv.
+ * SPDX-FileCopyrightText: 2022 nannanko <nannanko@kazv.moe>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+import moe.kazv.mxc.kazv 0.0 as MK
+
+import '..' as Kazv
+
+Kazv.Bubble {
+ id: bubble
+
+ required property var eventId
+ required property var serverUrl
+
+ property var kazvIO: MK.KazvIO {
+ job: root.kazvIOManager.getDownloadJob(bubble.eventId)
+ onSuccess: {
+ bubble.progressBar.showSuccMsg()
+ }
+ onFailure: {
+ bubble.progressBar.showFailMsg()
+ }
+ onProcessing: {
+ bubble.progressBar.show()
+ }
+ onSuspended: {
+ bubble.progressBar.switchToPause()
+ }
+ }
+
+ property var mediaFileMenu: Kazv.MediaFileMenu {
+ kazvIO: bubble.kazvIO
+ serverUrl: bubble.serverUrl
+ jobId: bubble.eventId
+ }
+
+ property var progressBar: Kazv.ProgressBar {
+ kazvIO: bubble.kazvIO
+ jobId: bubble.eventId
+ }
+}
diff --git a/src/contents/ui/event-types/Video.qml b/src/contents/ui/event-types/Video.qml
index a662eb5..cb3cc40 100644
--- a/src/contents/ui/event-types/Video.qml
+++ b/src/contents/ui/event-types/Video.qml
@@ -1,134 +1,116 @@
/*
* 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 moe.kazv.mxc.kazv 0.0 as MK
import QtMultimedia 5.15
import org.kde.kirigami 2.13 as Kirigami
-import '..' as Kazv
+import '.' as Types
Simple {
id: upper
property var gender: 'neutral'
property var body: event.content.body
property var mxcUri: event.content.url
property var videoUri: matrixSdk.mxcUriToHttp(mxcUri)
property var videoInfo: event.content.info || {}
property var videoResolution: video.metaData.resolution
property var videoWidth: videoResolution && videoResolution.width || (videoInfo.w || 1)
property var videoHeight: videoResolution && videoResolution.height || (videoInfo.h || 1)
property var thumbnailInfo: videoInfo.thumbnail_info || {}
property var thumbnailMxcUri: videoInfo.thumbnail_url
property var thumbnailUri: matrixSdk.mxcUriToHttp(thumbnailMxcUri)
property var hasThumbnail: !! thumbnailMxcUri
property var innerContentWidth: upper.contentMaxWidth - bubble.bubbleSpacing
- property var kazvIO: MK.KazvIO {
- manager: root.kazvIOManager
- roomId: room.roomId
- serverUrl: videoUri
- job: kazvIOManager.getDownloadJob(event.eventId)
- onSuccess: {
- bubble.progressBar.showSuccMsg()
- }
- onFailure: {
- bubble.progressBar.showFailMsg()
- }
- onProcessing: {
- bubble.progressBar.show()
- }
- onSuspended: {
- bubble.progressBar.switchToPause()
- }
- }
-
- Kazv.Bubble {
+ Types.MediaBubble {
id: bubble
- kazvIO: upper.kazvIO
- url: videoUri
+
+ eventId: event.eventId
+ serverUrl: upper.videoUri
ColumnLayout {
id: layout
property var label: Label {
Layout.fillWidth: false
Layout.maximumWidth: innerContentWidth
wrapMode: Text.Wrap
text: l10n.get('event-message-video-sent', { gender, body })
}
property var video: Video {
id: video
source: videoUri
autoLoad: false
autoPlay: false
loops: MediaPlayer.Infinite
Layout.minimumHeight: Kirigami.Units.gridUnit * 10
Layout.minimumWidth: Kirigami.Units.gridUnit * 10
Layout.maximumWidth: innerContentWidth
Layout.preferredWidth: videoWidth
Layout.preferredHeight: videoHeight / videoWidth * width
fillMode: VideoOutput.PreserveAspectFit
TapHandler {
onSingleTapped: {
video.playOrPause();
}
}
Image {
anchors.fill: parent
source: thumbnailUri
visible: video.playbackState == MediaPlayer.StoppedState && hasThumbnail
fillMode: Image.PreserveAspectFit
+ data: [bubble.mediaFileMenu]
}
Rectangle {
anchors.fill: parent
color: Kirigami.Theme.negativeBackgroundColor //Kirigami.ColorUtils.tintWithAlpha(color, Kirigami.Theme.textColor, 0.15)
visible: {
video.playbackState == MediaPlayer.StoppedState &&
! hasThumbnail
}
}
onStatusChanged: {
console.log('status = ', video.status);
}
onPlaybackStateChanged: {
console.log('playback state = ', video.playbackState);
}
function playOrPause() {
console.log('playback state ==', video.playbackState);
if (video.playbackState == MediaPlayer.PlayingState) {
video.pause();
} else {
if (video.playbackState == MediaPlayer.StoppedState) {
video.seek(0);
}
video.play();
}
}
}
data: [
label,
video,
- bubble.menu,
bubble.progressBar
]
}
}
}
diff --git a/src/kazv-io-manager.cpp b/src/kazv-io-manager.cpp
index 16eb421..e7f929e 100644
--- a/src/kazv-io-manager.cpp
+++ b/src/kazv-io-manager.cpp
@@ -1,72 +1,72 @@
/*
* 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 <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;
-QPointer<KazvIODownloadJob> KazvIOManager::startNewDownloadJob(const QUrl &serverUrl, const QString &localFileName, const QString &jobId)
+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(localFileName)));
+ downloadJob->setFile(QSharedPointer<QSaveFile>(new QSaveFile(localFileUrl.path())));
m_d->downloadJobs[jobId] = downloadJob;
return downloadJob.data();
}
QPointer<KazvIOUploadJob> KazvIOManager::startNewUploadJob(const QUrl &serverUrl, const QString &localFileName, const QString &token, const QString &jobId)
{
auto uploadJob = QSharedPointer<KazvIOUploadJob>(new KazvIOUploadJob());
uploadJob->setFile(QSharedPointer<QFile>(new QFile(localFileName)));
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(localFileName).name());
uploadJob->job()->addMetaData("customHTTPHeader", QString("Authorization: ").append(kazvUploadJob.requestHeader()->at("Authorization").data()));
uploadJob->job()->addMetaData("PropagateHttpHeader", "true");
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 b80bbf3..668ea92 100644
--- a/src/kazv-io-manager.hpp
+++ b/src/kazv-io-manager.hpp
@@ -1,35 +1,35 @@
/*
* 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 <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;
- QPointer<KazvIODownloadJob> startNewDownloadJob(const QUrl &serverUrl, const QString &localFileName, const QString &jobId);
- QPointer<KazvIOUploadJob> startNewUploadJob(const QUrl &serverUrl, const QString &localFileName, const QString &token, const QString &jobId);
+ Q_INVOKABLE KazvIOBaseJob *startNewDownloadJob(const QUrl &serverUrl, const QUrl &localFileName, const QString &jobId);
+ Q_INVOKABLE QPointer<KazvIOUploadJob> startNewUploadJob(const QUrl &serverUrl, const QString &localFileName, const QString &token, const QString &jobId);
Q_INVOKABLE KazvIOBaseJob *getDownloadJob(const QString &jobId);
Q_INVOKABLE void deleteDownloadJob(const QString &jobId);
};
diff --git a/src/kazv-io.cpp b/src/kazv-io.cpp
index 5bfe6d8..408fb31 100644
--- a/src/kazv-io.cpp
+++ b/src/kazv-io.cpp
@@ -1,223 +1,116 @@
/*
* This file is part of kazv.
* SPDX-FileCopyrightText: 2022 nannanko <nannanko@kazv.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
#include "kazv-io.hpp"
#include "kazv-io-manager.hpp"
#include "kazv-io-job.hpp"
#include <QUrl>
#include <QObject>
struct KazvIOPrivate {
- QPointer<KazvIOManager> manager;
- QString roomId;
- QString eventId;
- QUrl localFileUrl;
- QString serverUrl;
- QString token;
- QString mxcUri;
float progress;
QPointer<KazvIOBaseJob> kazvIOJob;
};
KazvIO::KazvIO(QObject *parent)
: QObject(parent)
, m_d(new KazvIOPrivate)
{
connect(this, &KazvIO::jobChanged, this, &KazvIO::checkJob);
connect(this, &KazvIO::success, this, &KazvIO::result);
connect(this, &KazvIO::failure, this, &KazvIO::result);
connect(this, &KazvIO::result, this, &KazvIO::clearPercent);
}
KazvIO::~KazvIO() = default;
void KazvIO::connectJob()
{
connect(m_d->kazvIOJob->job(), &KJob::percentChanged, this, &KazvIO::updateProgress);
connect(m_d->kazvIOJob, &KazvIOBaseJob::result, this, &KazvIO::checkResult);
}
-/*
- * This function is only applicable to a single thread,
- * if the manager is located in other threads, please modify this function appropriately
- */
-void KazvIO::download()
-{
- m_d->kazvIOJob = m_d->manager->startNewDownloadJob(m_d->serverUrl, m_d->localFileUrl.path(), m_d->eventId);
- connectJob();
- m_d->kazvIOJob->job()->start();
-}
-
-/*
- * This function is only applicable to a single thread,
- * if the manager is located in other threads, please modify this function appropriately
- */
-void KazvIO::upload()
-{
- m_d->kazvIOJob = m_d->manager->startNewUploadJob(m_d->serverUrl, m_d->localFileUrl.path(), m_d->token, m_d->roomId);
- connectJob();
- connect(m_d->kazvIOJob->job(), &KJob::result, this, &KazvIO::setMxcUri);
- m_d->kazvIOJob->job()->start();
-}
-
/*
* This function is only applicable to a single thread,
* if the manager is located in other threads, please modify this function appropriately
*/
void KazvIO::suspend()
{
m_d->kazvIOJob->job()->suspend();
}
/*
* This function is only applicable to a single thread,
* if the manager is located in other threads, please modify this function appropriately
*/
void KazvIO::resume()
{
m_d->kazvIOJob->job()->resume();
}
/*
* This function is only applicable to a single thread,
* if the manager is located in other threads, please modify this function appropriately
*/
void KazvIO::cancel()
{
m_d->kazvIOJob->job()->kill();
Q_EMIT failure();
}
void KazvIO::checkJob()
{
if (m_d->kazvIOJob.isNull()) {
return;
}
Q_EMIT processing();
if (m_d->kazvIOJob->success().has_value()) {
checkResult();
return;
}
updateProgress(m_d->kazvIOJob->job(), m_d->kazvIOJob->job()->percent());
if (m_d->kazvIOJob->job()->isSuspended()) {
Q_EMIT suspended();
}
connectJob();
}
-KazvIOManager *KazvIO::manager()
-{
- return m_d->manager;
-}
-
-void KazvIO::setManager(KazvIOManager *manager)
-{
- m_d->manager = manager;
- Q_EMIT managerChanged();
-}
-
-QString KazvIO::roomId()
-{
- return m_d->roomId;
-}
-
-void KazvIO::setRoomId(QString roomId)
-{
- m_d->roomId = roomId;
- Q_EMIT roomIdChanged();
-}
-
-QString KazvIO::eventId()
-{
- return m_d->eventId;
-}
-
-void KazvIO::setEventId(QString eventId)
-{
- m_d->eventId = eventId;
- Q_EMIT eventIdChanged();
-}
-
-QUrl KazvIO::localFileUrl()
-{
- return m_d->localFileUrl;
-}
-
-void KazvIO::setLocalFileUrl(QUrl localFileUrl)
-{
- m_d->localFileUrl = localFileUrl;
- Q_EMIT localFileUrlChanged();
-}
-
-QString KazvIO::serverUrl()
-{
- return m_d->serverUrl;
-}
-
-void KazvIO::setServerUrl(QString serverUrl)
-{
- m_d->serverUrl = serverUrl;
- Q_EMIT serverUrlChanged();
-}
-
-QString KazvIO::mxcUri()
-{
- return m_d->mxcUri;
-}
-
float KazvIO::progress()
{
return m_d->progress;
}
void KazvIO::updateProgress(KJob * /* job */, unsigned long percent)
{
m_d->progress = 1.0 * percent / 100;
Q_EMIT progressChanged();
}
void KazvIO::checkResult()
{
if (m_d->kazvIOJob->error().value()) {
Q_EMIT failure();
} else {
Q_EMIT success();
}
}
void KazvIO::clearPercent()
{
m_d->progress = 0;
Q_EMIT progressChanged();
}
-void KazvIO::setMxcUri(KJob * /* job */)
-{
- auto uploadJob = qobject_cast<KazvIOUploadJob*>(m_d->kazvIOJob);
- // TODO: Get MxcUri from response
-}
-
KazvIOBaseJob *KazvIO::job()
{
return m_d->kazvIOJob;
}
void KazvIO::setJob(KazvIOBaseJob *job)
{
m_d->kazvIOJob = job;
Q_EMIT jobChanged();
}
-
-QString KazvIO::token()
-{
- return m_d->token;
-}
-
-void KazvIO::setToken(QString token)
-{
- m_d->token = token;
- Q_EMIT tokenChanged();
-}
diff --git a/src/kazv-io.hpp b/src/kazv-io.hpp
index aa4e438..f1de754 100644
--- a/src/kazv-io.hpp
+++ b/src/kazv-io.hpp
@@ -1,127 +1,91 @@
/*
* 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-manager.hpp"
#include "kazv-io-job.hpp"
#include <KIO/Job>
#include <QObject>
#include <QUrl>
#include <QtQml>
#include <memory>
struct KazvIOPrivate;
class KazvIO : public QObject {
Q_OBJECT
QML_ELEMENT
- /**
- * Global manager for kazvIO.
- */
- Q_PROPERTY(KazvIOManager *manager READ manager WRITE setManager NOTIFY managerChanged)
- Q_PROPERTY(QString roomId READ roomId WRITE setRoomId NOTIFY roomIdChanged)
- Q_PROPERTY(QString eventId READ roomId WRITE setEventId NOTIFY eventIdChanged)
- Q_PROPERTY(QUrl localFileUrl READ localFileUrl WRITE setLocalFileUrl NOTIFY localFileUrlChanged)
- Q_PROPERTY(QString serverUrl READ serverUrl WRITE setServerUrl NOTIFY serverUrlChanged)
- Q_PROPERTY(QString token READ token WRITE setToken NOTIFY tokenChanged)
- Q_PROPERTY(QString mxcUri READ mxcUri NOTIFY mxcUriChanged)
/**
* From zero to one
*/
Q_PROPERTY(float progress READ progress NOTIFY progressChanged)
Q_PROPERTY(KazvIOBaseJob *job READ job WRITE setJob NOTIFY jobChanged)
private:
std::unique_ptr<KazvIOPrivate> m_d;
+ /**
+ * connect some signal for job, such as progress.
+ */
void connectJob();
public:
explicit KazvIO(QObject *parent = 0);
~KazvIO() override;
- /**
- * QML should call this function to initiate a download.
- */
- Q_INVOKABLE void download();
- /**
- * Upload file to server
- */
- Q_INVOKABLE void upload();
/**
* Pause the job.
*/
Q_INVOKABLE void suspend();
/**
* Resume the job.
*/
Q_INVOKABLE void resume();
/**
* Cancel the job.
*/
Q_INVOKABLE void cancel();
- KazvIOManager *manager();
- void setManager(KazvIOManager *manager);
- QString roomId();
- void setRoomId(QString roomId);
- QString eventId();
- void setEventId(QString eventId);
- QUrl localFileUrl();
- void setLocalFileUrl(QUrl localFileUrl);
- QString serverUrl();
- void setServerUrl(QString serverUrl);
- QString token();
- void setToken(QString token);
- QString mxcUri();
float progress();
KazvIOBaseJob *job();
void setJob(KazvIOBaseJob *job);
Q_SIGNALS:
/**
* Sending this signal means that the job has been destroyed and the download or upload task has ended.
* This signal is always emitted once, whether it is a normal exit or an error.
*/
void result();
void success();
void failure();
/**
* When KazvIO is created, it will check if the url it manages is being downloaded or uploading,
* and if it is, then it will send this signal.
*/
void processing();
/**
* This signal is emitted if the upload or download tasks it manages have been paused when KazvIO was created
*/
void suspended();
- void managerChanged();
- void roomIdChanged();
- void eventIdChanged();
- void localFileUrlChanged();
- void serverUrlChanged();
- void tokenChanged();
- void mxcUriChanged();
void progressChanged();
void jobChanged();
private Q_SLOTS:
void updateProgress(KJob *job, unsigned long percent);
void checkResult();
void clearPercent();
- void setMxcUri(KJob *job);
/**
* Check if a download/upload task is in progress
*/
void checkJob();
};
diff --git a/src/resources.qrc b/src/resources.qrc
index 124631a..5f62f0c 100644
--- a/src/resources.qrc
+++ b/src/resources.qrc
@@ -1,41 +1,43 @@
<RCC>
<qresource prefix="/">
<file alias="main.qml">contents/ui/main.qml</file>
<file alias="LoginPage.qml">contents/ui/LoginPage.qml</file>
<file alias="MainPage.qml">contents/ui/MainPage.qml</file>
<file alias="TabView.qml">contents/ui/TabView.qml</file>
<file alias="Tab.qml">contents/ui/Tab.qml</file>
<file alias="RoomListView.qml">contents/ui/RoomListView.qml</file>
<file alias="RoomPage.qml">contents/ui/RoomPage.qml</file>
<file alias="RoomTimelineView.qml">contents/ui/RoomTimelineView.qml</file>
<file alias="SendMessageBox.qml">contents/ui/SendMessageBox.qml</file>
<file alias="EventView.qml">contents/ui/EventView.qml</file>
<file alias="Bubble.qml">contents/ui/Bubble.qml</file>
<file alias="MediaFileMenu.qml">contents/ui/MediaFileMenu.qml</file>
<file alias="ProgressBar.qml">contents/ui/ProgressBar.qml</file>
<file alias="event-types/Simple.qml">contents/ui/event-types/Simple.qml</file>
<file alias="event-types/Text.qml">contents/ui/event-types/Text.qml</file>
<file alias="event-types/Emote.qml">contents/ui/event-types/Emote.qml</file>
<file alias="event-types/Notice.qml">contents/ui/event-types/Notice.qml</file>
<file alias="event-types/State.qml">contents/ui/event-types/State.qml</file>
<file alias="event-types/TextTemplate.qml">contents/ui/event-types/TextTemplate.qml</file>
<file alias="event-types/Image.qml">contents/ui/event-types/Image.qml</file>
<file alias="event-types/File.qml">contents/ui/event-types/File.qml</file>
<file alias="event-types/Video.qml">contents/ui/event-types/Video.qml</file>
<file alias="event-types/Audio.qml">contents/ui/event-types/Audio.qml</file>
+ <file alias="event-types/MediaBubble.qml">contents/ui/event-types/MediaBubble.qml</file>
+
<file alias="ActionSettingsPage.qml">contents/ui/ActionSettingsPage.qml</file>
<file alias="shortcuts/ActionCollection.qml">contents/ui/shortcuts/ActionCollection.qml</file>
<file alias="shortcuts/ActionItem.qml">contents/ui/shortcuts/ActionItem.qml</file>
<file alias="shortcuts/ActionSettings.qml">contents/ui/shortcuts/ActionSettings.qml</file>
<file alias="shortcuts/ShortcutInput.qml">contents/ui/shortcuts/ShortcutInput.qml</file>
<file alias="l10n.js">js/l10n.js</file>
<file alias="fluent-bundle.js">js/transformed-libs/fluent-bundle.js</file>
<file alias="fluent-sequence.js">js/transformed-libs/fluent-sequence.js</file>
<file alias="fluent-langneg.js">js/transformed-libs/fluent-langneg.js</file>
<file alias="bundled-deps.js">js/transformed-libs/bundled-deps.js</file>
<file alias="global-this.js">js/global-this.js</file>
<file alias="matrix-helpers.js">js/matrix-helpers.js</file>
</qresource>
</RCC>
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sun, Jan 19, 11:14 PM (1 d, 20 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
55497
Default Alt Text
(36 KB)
Attached To
Mode
rK kazv
Attached
Detach File
Event Timeline
Log In to Comment