diff --git a/imports/Spectral/Dialog/AccountDetailDialog.qml b/imports/Spectral/Dialog/AccountDetailDialog.qml index 959c9ec75..95c782de6 100644 --- a/imports/Spectral/Dialog/AccountDetailDialog.qml +++ b/imports/Spectral/Dialog/AccountDetailDialog.qml @@ -299,46 +299,6 @@ Dialog { onPrimaryClicked: fontFamilyDialog.createObject(ApplicationWindow.overlay).open() } } - - Control { - width: parent.width - - contentItem: RowLayout { - MaterialIcon { - Layout.preferredWidth: 48 - Layout.preferredHeight: 48 - - color: MPalette.foreground - icon: "\ue8aa" - } - - Label { - Layout.fillWidth: true - - color: MPalette.foreground - text: "Chat Background" - } - } - - RippleEffect { - anchors.fill: parent - - onPrimaryClicked: { - var fileDialog = chatBackgroundDialog.createObject(ApplicationWindow.overlay) - - fileDialog.chosen.connect(function(path) { - if (!path) return - - MSettings.timelineBackground = path - }) - fileDialog.rejected.connect(function(path) { - MSettings.timelineBackground = "" - }) - - fileDialog.open() - } - } - } } onClosed: destroy() diff --git a/imports/Spectral/Dialog/RoomSettingsDialog.qml b/imports/Spectral/Dialog/RoomSettingsDialog.qml index c71db94e8..0888ea85f 100644 --- a/imports/Spectral/Dialog/RoomSettingsDialog.qml +++ b/imports/Spectral/Dialog/RoomSettingsDialog.qml @@ -211,6 +211,48 @@ Dialog { } } } + + MenuSeparator { + Layout.fillWidth: true + } + + RowLayout { + Layout.fillWidth: true + + Button { + Layout.fillWidth: true + + flat: true + text: "Set background image" + + onClicked: { + var fileDialog = chatBackgroundDialog.createObject(ApplicationWindow.overlay) + + fileDialog.chosen.connect(function(path) { + if (!path) return + + room.setBackgroundFromLocalFile(path) + }) + + fileDialog.open() + } + } + + Button { + Layout.fillWidth: true + + flat: true + text: "Clear background image" + + onClicked: room.clearBackground() + } + } + } + + Component { + id: chatBackgroundDialog + + OpenFileDialog {} } onClosed: destroy() diff --git a/imports/Spectral/Panel/RoomPanel.qml b/imports/Spectral/Panel/RoomPanel.qml index e435ec807..29e6131d5 100644 --- a/imports/Spectral/Panel/RoomPanel.qml +++ b/imports/Spectral/Panel/RoomPanel.qml @@ -4,6 +4,7 @@ import QtQuick.Layouts 1.12 import QtQuick.Controls.Material 2.12 import Qt.labs.qmlmodels 1.0 import Qt.labs.platform 1.0 +import QtGraphicalEffects 1.0 import Spectral.Component 2.0 import Spectral.Component.Emoji 2.0 @@ -126,7 +127,7 @@ Item { background: RippleEffect { onClicked: { var localPath = StandardPaths.writableLocation(StandardPaths.CacheLocation) + "/screenshots/" + (new Date()).getTime() + ".png" - if (!imageClipboard.saveImage(localPath)) return + if (!imageClipboard.saveImage(localPath)) return roomPanelInput.attach(localPath) attachDialog.close() } @@ -172,19 +173,24 @@ Item { } Image { + readonly property int sourceDim: (Math.ceil(Math.max(width, height) / 360) + 1) * 360 + anchors.fill: parent - visible: currentRoom && MSettings.timelineBackground + visible: currentRoom && currentRoom.backgroundMediaId + + sourceSize.width: sourceDim + sourceSize.height: sourceDim - source: MSettings.timelineBackground fillMode: Image.PreserveAspectCrop + + source: currentRoom && currentRoom.backgroundMediaId ? "image://mxc/" + currentRoom.backgroundMediaId : "" } Rectangle { anchors.fill: parent - visible: currentRoom && !MSettings.timelineBackground - + visible: currentRoom && !currentRoom.backgroundMediaId color: MSettings.darkTheme ? "#242424" : "#EBEFF2" } diff --git a/imports/Spectral/Setting/Setting.qml b/imports/Spectral/Setting/Setting.qml index f5c0e7529..3dd86287b 100644 --- a/imports/Spectral/Setting/Setting.qml +++ b/imports/Spectral/Setting/Setting.qml @@ -9,7 +9,5 @@ Settings { property bool darkTheme - property string timelineBackground - property string fontFamily: "Roboto,Noto Sans,Noto Color Emoji" } diff --git a/qml/main.qml b/qml/main.qml index e28743dba..ff51639a7 100644 --- a/qml/main.qml +++ b/qml/main.qml @@ -113,12 +113,6 @@ ApplicationWindow { FontFamilyDialog {} } - Component { - id: chatBackgroundDialog - - OpenFileDialog {} - } - Drawer { width: Math.min((inPortrait ? 0.67 : 0.3) * window.width, 360) height: window.height diff --git a/src/spectralroom.cpp b/src/spectralroom.cpp index bcd37d9dc..08de261ae 100644 --- a/src/spectralroom.cpp +++ b/src/spectralroom.cpp @@ -3,6 +3,7 @@ #include "connection.h" #include "user.h" +#include "csapi/account-data.h" #include "csapi/content-repo.h" #include "csapi/leaving.h" #include "csapi/typing.h" @@ -33,6 +34,10 @@ SpectralRoom::SpectralRoom(Connection* connection, setFileUploadingProgress(0); setHasFileUploading(false); }); + connect(this, &Room::accountDataChanged, this, [=](QString type) { + if (type == backgroundEventType) + emit backgroundChanged(); + }); } inline QString getMIME(const QUrl& fileUrl) { @@ -48,17 +53,17 @@ void SpectralRoom::uploadFile(const QUrl& url, const QString& body) { if (url.isEmpty()) return; - QString txnID = postFile(body.isEmpty() ? url.fileName() : body, url, false); + QString txnId = postFile(body.isEmpty() ? url.fileName() : body, url, false); setHasFileUploading(true); connect(this, &Room::fileTransferCompleted, [=](QString id, QUrl localFile, QUrl mxcUrl) { - if (id == txnID) { + if (id == txnId) { setFileUploadingProgress(0); setHasFileUploading(false); } }); connect(this, &Room::fileTransferFailed, [=](QString id, QString error) { - if (id == txnID) { + if (id == txnId) { setFileUploadingProgress(0); setHasFileUploading(false); } @@ -66,7 +71,7 @@ void SpectralRoom::uploadFile(const QUrl& url, const QString& body) { connect( this, &Room::fileTransferProgress, [=](QString id, qint64 progress, qint64 total) { - if (id == txnID) { + if (id == txnId) { qDebug() << "Progress:" << progress << total; setFileUploadingProgress(int(float(progress) / float(total) * 100)); } @@ -253,3 +258,49 @@ QString SpectralRoom::postMarkdownText(const QString& markdown) { QUrl SpectralRoom::urlToMxcUrl(QUrl mxcUrl) { return DownloadFileJob::makeRequestUrl(connection()->homeserver(), mxcUrl); } + +QUrl SpectralRoom::backgroundUrl() { + return hasAccountData(backgroundEventType) + ? QUrl(accountData(backgroundEventType) + .get() + ->contentJson()["url"] + .toString()) + : QUrl(); +} + +void SpectralRoom::setBackgroundUrl(QUrl url) { + if (url.isEmpty() || url == backgroundUrl()) + return; + + connection()->callApi( + localUser()->id(), id(), backgroundEventType, + QJsonObject{{"url", url.toString()}}); +} + +void SpectralRoom::setBackgroundFromLocalFile(QUrl url) { + if (url.isEmpty()) + return; + + auto txnId = connection()->generateTxnId(); + Room::uploadFile(txnId, url); + + connect(this, &Room::fileTransferCompleted, + [=](QString id, QUrl localFile, QUrl mxcUrl) { + if (id == txnId) { + setBackgroundUrl(mxcUrl); + } + }); +} + +void SpectralRoom::clearBackground() { + connection()->callApi( + localUser()->id(), id(), backgroundEventType, QJsonObject{}); +} + +QString SpectralRoom::backgroundMediaId() { + if (!hasAccountData(backgroundEventType)) + return {}; + + auto url = backgroundUrl(); + return url.authority() + url.path(); +} diff --git a/src/spectralroom.h b/src/spectralroom.h index b681a9771..10a412462 100644 --- a/src/spectralroom.h +++ b/src/spectralroom.h @@ -28,6 +28,10 @@ class SpectralRoom : public Room { Q_PROPERTY(int fileUploadingProgress READ fileUploadingProgress NOTIFY fileUploadingProgressChanged) Q_PROPERTY(bool busy READ busy NOTIFY busyChanged) + Q_PROPERTY(QUrl backgroundUrl READ backgroundUrl WRITE setBackgroundUrl NOTIFY + backgroundChanged) + Q_PROPERTY( + QString backgroundMediaId READ backgroundMediaId NOTIFY backgroundChanged) public: explicit SpectralRoom(Connection* connection, @@ -86,6 +90,13 @@ class SpectralRoom : public Room { Q_INVOKABLE QUrl urlToMxcUrl(QUrl mxcUrl); + QUrl backgroundUrl(); + Q_INVOKABLE void setBackgroundUrl(QUrl url); + Q_INVOKABLE void clearBackground(); + Q_INVOKABLE void setBackgroundFromLocalFile(QUrl url); + + QString backgroundMediaId(); + template QString eventToString(const BaseEventT& evt, Qt::TextFormat format = Qt::PlainText) { @@ -231,6 +242,8 @@ class SpectralRoom : public Room { } private: + const QString backgroundEventType = "org.eu.encom.spectral.background"; + QString m_cachedInput; QSet highlights; @@ -252,6 +265,7 @@ class SpectralRoom : public Room { void busyChanged(); void hasFileUploadingChanged(); void fileUploadingProgressChanged(); + void backgroundChanged(); public slots: void uploadFile(const QUrl& url, const QString& body = "");