Page MenuHomePhorge

No OneTemporary

Size
36 KB
Referenced Files
None
Subscribers
None
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

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)

Event Timeline