Migrate room general settings to mobileform

![image](/uploads/98b895cbbf59ef9215b2085e120e5db5/image.png)
This commit is contained in:
James Graham
2022-11-29 23:27:30 +00:00
committed by Tobias Fella
parent e270a46a36
commit 6acb847843
3 changed files with 260 additions and 145 deletions

View File

@@ -17,6 +17,7 @@
#include <qcoro/task.h> #include <qcoro/task.h>
#include <connection.h> #include <connection.h>
#include <csapi/directory.h>
#include <csapi/pushrules.h> #include <csapi/pushrules.h>
#include <csapi/redaction.h> #include <csapi/redaction.h>
#include <csapi/report_content.h> #include <csapi/report_content.h>
@@ -1324,3 +1325,46 @@ void NeoChatRoom::download(const QString &eventId, const QUrl &localFilename)
job->start(); job->start();
#endif #endif
} }
void NeoChatRoom::mapAlias(const QString &alias)
{
auto getLocalAliasesJob = connection()->callApi<GetLocalAliasesJob>(id());
connect(getLocalAliasesJob, &BaseJob::success, this, [this, getLocalAliasesJob, alias] {
if (getLocalAliasesJob->aliases().contains(alias)) {
return;
} else {
auto setRoomAliasJob = connection()->callApi<SetRoomAliasJob>(alias, id());
connect(setRoomAliasJob, &BaseJob::success, this, [this, alias] {
auto newAltAliases = altAliases();
newAltAliases.append(alias);
setLocalAliases(newAltAliases);
});
}
});
}
void NeoChatRoom::unmapAlias(const QString &alias)
{
connection()->callApi<DeleteRoomAliasJob>(alias);
}
void NeoChatRoom::setCanonicalAlias(const QString &newAlias)
{
QString oldCanonicalAlias = canonicalAlias();
Room::setCanonicalAlias(newAlias);
connect(this, &Room::namesChanged, this, [this, newAlias, oldCanonicalAlias] {
if (canonicalAlias() == newAlias) {
// If the new canonical alias is already a published alt alias remove it otherwise it will be in both lists.
// The server doesn't prevent this so we need to handle it.
auto newAltAliases = altAliases();
if (!oldCanonicalAlias.isEmpty()) {
newAltAliases.append(oldCanonicalAlias);
}
if (newAltAliases.contains(newAlias)) {
newAltAliases.removeAll(newAlias);
Room::setLocalAliases(newAltAliases);
}
}
});
}

View File

@@ -3,6 +3,7 @@
#pragma once #pragma once
#include <qobjectdefs.h>
#include <room.h> #include <room.h>
#include <QCache> #include <QCache>
@@ -201,6 +202,16 @@ public:
Q_INVOKABLE bool downloadTempFile(const QString &eventId); Q_INVOKABLE bool downloadTempFile(const QString &eventId);
/*
* Map an alias to the room
*
* Note: this is different to setLocalAliases as that can only
* get the room to publish and alias that is already mapped.
*/
Q_INVOKABLE void mapAlias(const QString &alias);
Q_INVOKABLE void unmapAlias(const QString &alias);
Q_INVOKABLE void setCanonicalAlias(const QString &newAlias);
#ifdef QUOTIENT_07 #ifdef QUOTIENT_07
Q_INVOKABLE PollHandler *poll(const QString &eventId); Q_INVOKABLE PollHandler *poll(const QString &eventId);
#endif #endif

View File

@@ -5,7 +5,9 @@
import QtQuick 2.15 import QtQuick 2.15
import QtQuick.Controls 2.15 as QQC2 import QtQuick.Controls 2.15 as QQC2
import QtQuick.Layouts 1.15 import QtQuick.Layouts 1.15
import org.kde.kirigami 2.15 as Kirigami import org.kde.kirigami 2.15 as Kirigami
import org.kde.kirigamiaddons.labs.mobileform 0.1 as MobileForm
import org.kde.neochat 1.0 import org.kde.neochat 1.0
@@ -14,108 +16,202 @@ Kirigami.ScrollablePage {
property var room property var room
readonly property bool canChangeAvatar: room.canSendState("m.room.avatar")
readonly property bool canChangeName: room.canSendState("m.room.name")
readonly property bool canChangeTopic: room.canSendState("m.room.topic")
readonly property bool canChangeCanonicalAlias: room.canSendState("m.room.canonical_alias")
title: i18n("General") title: i18n("General")
leftPadding: 0
rightPadding: 0
ColumnLayout { ColumnLayout {
Kirigami.FormLayout { MobileForm.FormCard {
Layout.fillWidth: true Layout.fillWidth: true
contentItem: ColumnLayout {
Kirigami.Avatar { spacing: 0
Layout.bottomMargin: Kirigami.Units.largeSpacing MobileForm.FormCardHeader {
title: i18n("Room Information")
name: room.name
source: room.avatarMediaId ? ("image://mxc/" + room.avatarMediaId) : ""
QQC2.RoundButton {
anchors.right: parent.right
anchors.bottom: parent.bottom
height: Kirigami.Units.gridUnits
width: Kirigami.Units.gridUnits
icon.name: 'cloud-upload'
Accessible.name: i18n("Update avatar")
enabled: canChangeAvatar
onClicked: {
const fileDialog = openFileDialog.createObject(QQC2.ApplicationWindow.overlay)
fileDialog.chosen.connect(function(path) {
if (!path) return
room.changeAvatar(path)
})
fileDialog.open()
}
} }
} MobileForm.AbstractFormDelegate {
QQC2.TextField {
id: roomNameField
text: room.name
Kirigami.FormData.label: i18n("Room Name:")
enabled: canChangeName
}
QQC2.TextArea {
id: roomTopicField
Layout.fillWidth: true
text: room.topic
Kirigami.FormData.label: i18n("Room topic:")
enabled: canChangeTopic
}
Kirigami.Separator {
Layout.fillWidth: true
visible: canonicalAliasComboBox.visible || altAlias.visible
}
QQC2.ComboBox {
id: canonicalAliasComboBox
visible: room.aliases && room.aliases.length
Kirigami.FormData.label: i18n("Canonical Alias:")
popup.z: 999; // HACK This is an absolute hack, but combos inside OverlaySheets have their popups show up underneath, because of fun z ordering stuff
enabled: canChangeCanonicalAlias
model: room.aliases
currentIndex: room.aliases.indexOf(room.canonicalAlias)
onCurrentIndexChanged: {
if (room.canonicalAlias != room.aliases[currentIndex]) {
room.setCanonicalAlias(room.aliases[currentIndex])
}
}
}
RowLayout {
id: altAlias
Kirigami.FormData.label: i18n("Other Aliases:")
Layout.fillWidth: true
visible: room.altAliases && room.altAliases.length
ColumnLayout {
Layout.fillWidth: true Layout.fillWidth: true
background: Item {}
contentItem: RowLayout {
Item {
Layout.fillWidth: true
}
Kirigami.Avatar {
id: avatar
Layout.alignment: Qt.AlignRight
name: room.name
source: room.avatarMediaId ? ("image://mxc/" + room.avatarMediaId) : ""
}
QQC2.Button {
Layout.alignment: Qt.AlignLeft
enabled: room.canSendState("m.room.avatar")
visible: enabled
icon.name: "cloud-upload"
text: i18n("Update avatar")
display: QQC2.AbstractButton.IconOnly
spacing: 0 onClicked: {
const fileDialog = openFileDialog.createObject(QQC2.ApplicationWindow.overlay)
Repeater { fileDialog.chosen.connect(function(path) {
model: room.altAliases if (!path) return
delegate: RowLayout { room.changeAvatar(path)
Layout.maximumWidth: parent.width })
QQC2.Label { fileDialog.open()
text: modelData
} }
QQC2.ToolTip.text: text
QQC2.ToolTip.visible: hovered
}
Item {
Layout.fillWidth: true
}
}
}
MobileForm.FormTextFieldDelegate {
id: roomNameField
label: i18n("Room name:")
text: room.name
enabled: room.canSendState("m.room.name")
}
MobileForm.AbstractFormDelegate {
id: roomTopicField
Layout.fillWidth: true
enabled: room.canSendState("m.room.topic")
background: Item {}
contentItem: ColumnLayout {
QQC2.Label {
id: roomTopicLabel
text: i18n("Room topic:")
Layout.fillWidth: true
}
QQC2.TextArea {
Accessible.description: roomTopicLabel.text
Layout.fillWidth: true
text: room.topic
onTextChanged: roomTopicField.text = text
}
}
}
MobileForm.AbstractFormDelegate {
Layout.fillWidth: true
background: Item {}
contentItem: RowLayout {
Item {
Layout.fillWidth: true
}
QQC2.Button {
Layout.bottomMargin: Kirigami.Units.smallSpacing
Layout.topMargin: Kirigami.Units.smallSpacing
enabled: room.name !== roomNameField.text || room.topic !== roomTopicField.text
text: i18n("Save")
onClicked: {
if (room.name != roomNameField.text) {
room.setName(roomNameField.text)
}
if (room.topic != roomTopicField.text) {
room.setTopic(roomTopicField.text)
}
}
}
}
}
}
}
MobileForm.FormCard {
Layout.fillWidth: true
contentItem: ColumnLayout {
spacing: 0
MobileForm.FormCardHeader {
title: i18n("Aliases")
}
MobileForm.FormTextDelegate {
visible: room.aliases.length <= 0
text: i18n("No canonical alias set")
}
Repeater {
id: altAliasRepeater
model: room.aliases.slice().reverse()
delegate: MobileForm.FormTextDelegate {
text: modelData
description: room.canonicalAlias.length > 0 && modelData === room.canonicalAlias ? "Canonical alias" : ""
contentItem.children: [
QQC2.ToolButton { QQC2.ToolButton {
icon.name: "" id: setCanonicalAliasButton
onClicked: room.removeLocalAlias(modelData) visible: modelData !== room.canonicalAlias && room.canSendState("m.room.canonical_alias")
text: i18n("Make this alias the room's canonical alias")
icon.name: "checkmark"
display: QQC2.AbstractButton.IconOnly
onClicked: {
room.setCanonicalAlias(modelData)
}
QQC2.ToolTip {
text: setCanonicalAliasButton.text
delay: Kirigami.Units.toolTipDelay
}
},
QQC2.ToolButton {
id: deleteButton
visible: room.canSendState("m.room.canonical_alias")
text: i18n("Delete alias")
icon.name: "edit-delete-remove"
display: QQC2.AbstractButton.IconOnly
onClicked: {
room.unmapAlias(modelData)
}
QQC2.ToolTip {
text: deleteButton.text
delay: Kirigami.Units.toolTipDelay
}
}
]
}
}
MobileForm.AbstractFormDelegate {
Layout.fillWidth: true
contentItem : RowLayout {
Kirigami.ActionTextField {
id: aliasAddField
Layout.fillWidth: true
placeholderText: i18n("#new_alias:server.org")
rightActions: Kirigami.Action {
icon.name: "edit-clear"
visible: aliasAddField.text.length > 0
onTriggered: {
aliasAddField.text = ""
}
}
onAccepted: {
room.mapAlias(aliasAddField.text)
}
}
QQC2.Button {
id: addButton
text: i18n("Add keyword")
Accessible.name: text
icon.name: "list-add"
display: QQC2.AbstractButton.IconOnly
onClicked: {
room.mapAlias(aliasAddField.text)
}
QQC2.ToolTip {
text: addButton.text
delay: Kirigami.Units.toolTipDelay
} }
} }
} }
@@ -123,47 +219,33 @@ Kirigami.ScrollablePage {
} }
} }
Kirigami.Separator { Kirigami.InlineMessage {
Layout.fillWidth: true Layout.fillWidth: true
visible: next.visible || prev.visible Layout.maximumWidth: Kirigami.Units.gridUnit * 30
} Layout.alignment: Qt.AlignHCenter
text: i18n("This room continues another conversation.")
QQC2.Control { type: Kirigami.MessageType.Information
id: next
Layout.fillWidth: true
visible: room.predecessorId && room.connection.room(room.predecessorId) visible: room.predecessorId && room.connection.room(room.predecessorId)
actions: Kirigami.Action {
padding: Kirigami.Units.largeSpacing text: i18n("See older messages…")
onTriggered: {
contentItem: Kirigami.InlineMessage { RoomManager.enterRoom(Controller.activeConnection.room(room.predecessorId));
text: i18n("This room continues another conversation.") root.close();
actions: Kirigami.Action {
text: i18n("See older messages...")
onTriggered: {
roomListForm.enteredRoom = Controller.activeConnection.room(room.predecessorId)
root.close()
}
} }
} }
} }
Kirigami.InlineMessage {
QQC2.Control {
id: prev
Layout.fillWidth: true Layout.fillWidth: true
Layout.maximumWidth: Kirigami.Units.gridUnit * 30
Layout.alignment: Qt.AlignHCenter
text: i18n("This room has been replaced.")
type: Kirigami.MessageType.Information
visible: room.successorId && room.connection.room(room.successorId) visible: room.successorId && room.connection.room(room.successorId)
actions: Kirigami.Action {
padding: Kirigami.Units.largeSpacing text: i18n("See new room…")
onTriggered: {
contentItem: Kirigami.InlineMessage { RoomManager.enterRoom(Controller.activeConnection.room(room.successorId));
text: i18n("This room has been replaced.") root.close();
actions: Kirigami.Action {
text: i18n("See new room...")
onTriggered: {
roomListForm.enteredRoom = Controller.activeConnection.room(room.successorId)
root.close()
}
} }
} }
} }
@@ -174,27 +256,5 @@ Kirigami.ScrollablePage {
OpenFileDialog {} OpenFileDialog {}
} }
} }
footer: QQC2.ToolBar {
contentItem: RowLayout {
Item {
Layout.fillWidth: true
}
QQC2.Button {
Layout.alignment: Qt.AlignRight
enabled: room.name !== roomNameField.text || room.topic !== roomTopicField.text
text: i18n("Apply")
onClicked: {
if (room.name != roomNameField.text) {
room.setName(roomNameField.text)
}
if (room.topic != roomTopicField.text) {
room.setTopic(roomTopicField.text)
}
}
}
}
}
} }