Primitive timeline background support.

This commit is contained in:
Black Hat
2019-05-23 22:50:38 +08:00
parent 6072cb0c23
commit 97db902dc5
7 changed files with 122 additions and 57 deletions

View File

@@ -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()

View File

@@ -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()

View File

@@ -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"
} }

View File

@@ -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"
} }

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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 = "");