Primitive timeline background support.
This commit is contained in:
@@ -299,46 +299,6 @@ Dialog {
|
|||||||
onPrimaryClicked: fontFamilyDialog.createObject(ApplicationWindow.overlay).open()
|
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()
|
onClosed: destroy()
|
||||||
|
|||||||
@@ -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()
|
onClosed: destroy()
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import QtQuick.Layouts 1.12
|
|||||||
import QtQuick.Controls.Material 2.12
|
import QtQuick.Controls.Material 2.12
|
||||||
import Qt.labs.qmlmodels 1.0
|
import Qt.labs.qmlmodels 1.0
|
||||||
import Qt.labs.platform 1.0
|
import Qt.labs.platform 1.0
|
||||||
|
import QtGraphicalEffects 1.0
|
||||||
|
|
||||||
import Spectral.Component 2.0
|
import Spectral.Component 2.0
|
||||||
import Spectral.Component.Emoji 2.0
|
import Spectral.Component.Emoji 2.0
|
||||||
@@ -126,7 +127,7 @@ Item {
|
|||||||
background: RippleEffect {
|
background: RippleEffect {
|
||||||
onClicked: {
|
onClicked: {
|
||||||
var localPath = StandardPaths.writableLocation(StandardPaths.CacheLocation) + "/screenshots/" + (new Date()).getTime() + ".png"
|
var localPath = StandardPaths.writableLocation(StandardPaths.CacheLocation) + "/screenshots/" + (new Date()).getTime() + ".png"
|
||||||
if (!imageClipboard.saveImage(localPath)) return
|
if (!imageClipboard.saveImage(localPath)) return
|
||||||
roomPanelInput.attach(localPath)
|
roomPanelInput.attach(localPath)
|
||||||
attachDialog.close()
|
attachDialog.close()
|
||||||
}
|
}
|
||||||
@@ -172,19 +173,24 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
|
readonly property int sourceDim: (Math.ceil(Math.max(width, height) / 360) + 1) * 360
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
visible: currentRoom && MSettings.timelineBackground
|
visible: currentRoom && currentRoom.backgroundMediaId
|
||||||
|
|
||||||
|
sourceSize.width: sourceDim
|
||||||
|
sourceSize.height: sourceDim
|
||||||
|
|
||||||
source: MSettings.timelineBackground
|
|
||||||
fillMode: Image.PreserveAspectCrop
|
fillMode: Image.PreserveAspectCrop
|
||||||
|
|
||||||
|
source: currentRoom && currentRoom.backgroundMediaId ? "image://mxc/" + currentRoom.backgroundMediaId : ""
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
visible: currentRoom && !MSettings.timelineBackground
|
visible: currentRoom && !currentRoom.backgroundMediaId
|
||||||
|
|
||||||
color: MSettings.darkTheme ? "#242424" : "#EBEFF2"
|
color: MSettings.darkTheme ? "#242424" : "#EBEFF2"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,5 @@ Settings {
|
|||||||
|
|
||||||
property bool darkTheme
|
property bool darkTheme
|
||||||
|
|
||||||
property string timelineBackground
|
|
||||||
|
|
||||||
property string fontFamily: "Roboto,Noto Sans,Noto Color Emoji"
|
property string fontFamily: "Roboto,Noto Sans,Noto Color Emoji"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,12 +113,6 @@ ApplicationWindow {
|
|||||||
FontFamilyDialog {}
|
FontFamilyDialog {}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
|
||||||
id: chatBackgroundDialog
|
|
||||||
|
|
||||||
OpenFileDialog {}
|
|
||||||
}
|
|
||||||
|
|
||||||
Drawer {
|
Drawer {
|
||||||
width: Math.min((inPortrait ? 0.67 : 0.3) * window.width, 360)
|
width: Math.min((inPortrait ? 0.67 : 0.3) * window.width, 360)
|
||||||
height: window.height
|
height: window.height
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "connection.h"
|
#include "connection.h"
|
||||||
#include "user.h"
|
#include "user.h"
|
||||||
|
|
||||||
|
#include "csapi/account-data.h"
|
||||||
#include "csapi/content-repo.h"
|
#include "csapi/content-repo.h"
|
||||||
#include "csapi/leaving.h"
|
#include "csapi/leaving.h"
|
||||||
#include "csapi/typing.h"
|
#include "csapi/typing.h"
|
||||||
@@ -33,6 +34,10 @@ SpectralRoom::SpectralRoom(Connection* connection,
|
|||||||
setFileUploadingProgress(0);
|
setFileUploadingProgress(0);
|
||||||
setHasFileUploading(false);
|
setHasFileUploading(false);
|
||||||
});
|
});
|
||||||
|
connect(this, &Room::accountDataChanged, this, [=](QString type) {
|
||||||
|
if (type == backgroundEventType)
|
||||||
|
emit backgroundChanged();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
inline QString getMIME(const QUrl& fileUrl) {
|
inline QString getMIME(const QUrl& fileUrl) {
|
||||||
@@ -48,17 +53,17 @@ void SpectralRoom::uploadFile(const QUrl& url, const QString& body) {
|
|||||||
if (url.isEmpty())
|
if (url.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QString txnID = postFile(body.isEmpty() ? url.fileName() : body, url, false);
|
QString txnId = postFile(body.isEmpty() ? url.fileName() : body, url, false);
|
||||||
setHasFileUploading(true);
|
setHasFileUploading(true);
|
||||||
connect(this, &Room::fileTransferCompleted,
|
connect(this, &Room::fileTransferCompleted,
|
||||||
[=](QString id, QUrl localFile, QUrl mxcUrl) {
|
[=](QString id, QUrl localFile, QUrl mxcUrl) {
|
||||||
if (id == txnID) {
|
if (id == txnId) {
|
||||||
setFileUploadingProgress(0);
|
setFileUploadingProgress(0);
|
||||||
setHasFileUploading(false);
|
setHasFileUploading(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
connect(this, &Room::fileTransferFailed, [=](QString id, QString error) {
|
connect(this, &Room::fileTransferFailed, [=](QString id, QString error) {
|
||||||
if (id == txnID) {
|
if (id == txnId) {
|
||||||
setFileUploadingProgress(0);
|
setFileUploadingProgress(0);
|
||||||
setHasFileUploading(false);
|
setHasFileUploading(false);
|
||||||
}
|
}
|
||||||
@@ -66,7 +71,7 @@ void SpectralRoom::uploadFile(const QUrl& url, const QString& body) {
|
|||||||
connect(
|
connect(
|
||||||
this, &Room::fileTransferProgress,
|
this, &Room::fileTransferProgress,
|
||||||
[=](QString id, qint64 progress, qint64 total) {
|
[=](QString id, qint64 progress, qint64 total) {
|
||||||
if (id == txnID) {
|
if (id == txnId) {
|
||||||
qDebug() << "Progress:" << progress << total;
|
qDebug() << "Progress:" << progress << total;
|
||||||
setFileUploadingProgress(int(float(progress) / float(total) * 100));
|
setFileUploadingProgress(int(float(progress) / float(total) * 100));
|
||||||
}
|
}
|
||||||
@@ -253,3 +258,49 @@ QString SpectralRoom::postMarkdownText(const QString& markdown) {
|
|||||||
QUrl SpectralRoom::urlToMxcUrl(QUrl mxcUrl) {
|
QUrl SpectralRoom::urlToMxcUrl(QUrl mxcUrl) {
|
||||||
return DownloadFileJob::makeRequestUrl(connection()->homeserver(), 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<SetAccountDataPerRoomJob>(
|
||||||
|
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<SetAccountDataPerRoomJob>(
|
||||||
|
localUser()->id(), id(), backgroundEventType, QJsonObject{});
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SpectralRoom::backgroundMediaId() {
|
||||||
|
if (!hasAccountData(backgroundEventType))
|
||||||
|
return {};
|
||||||
|
|
||||||
|
auto url = backgroundUrl();
|
||||||
|
return url.authority() + url.path();
|
||||||
|
}
|
||||||
|
|||||||
@@ -28,6 +28,10 @@ class SpectralRoom : public Room {
|
|||||||
Q_PROPERTY(int fileUploadingProgress READ fileUploadingProgress NOTIFY
|
Q_PROPERTY(int fileUploadingProgress READ fileUploadingProgress NOTIFY
|
||||||
fileUploadingProgressChanged)
|
fileUploadingProgressChanged)
|
||||||
Q_PROPERTY(bool busy READ busy NOTIFY busyChanged)
|
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:
|
public:
|
||||||
explicit SpectralRoom(Connection* connection,
|
explicit SpectralRoom(Connection* connection,
|
||||||
@@ -86,6 +90,13 @@ class SpectralRoom : public Room {
|
|||||||
|
|
||||||
Q_INVOKABLE QUrl urlToMxcUrl(QUrl mxcUrl);
|
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 <typename BaseEventT>
|
template <typename BaseEventT>
|
||||||
QString eventToString(const BaseEventT& evt,
|
QString eventToString(const BaseEventT& evt,
|
||||||
Qt::TextFormat format = Qt::PlainText) {
|
Qt::TextFormat format = Qt::PlainText) {
|
||||||
@@ -231,6 +242,8 @@ class SpectralRoom : public Room {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
const QString backgroundEventType = "org.eu.encom.spectral.background";
|
||||||
|
|
||||||
QString m_cachedInput;
|
QString m_cachedInput;
|
||||||
QSet<const QMatrixClient::RoomEvent*> highlights;
|
QSet<const QMatrixClient::RoomEvent*> highlights;
|
||||||
|
|
||||||
@@ -252,6 +265,7 @@ class SpectralRoom : public Room {
|
|||||||
void busyChanged();
|
void busyChanged();
|
||||||
void hasFileUploadingChanged();
|
void hasFileUploadingChanged();
|
||||||
void fileUploadingProgressChanged();
|
void fileUploadingProgressChanged();
|
||||||
|
void backgroundChanged();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void uploadFile(const QUrl& url, const QString& body = "");
|
void uploadFile(const QUrl& url, const QString& body = "");
|
||||||
|
|||||||
Reference in New Issue
Block a user