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,31 +16,40 @@ 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 {
spacing: 0
MobileForm.FormCardHeader {
title: i18n("Room Information")
}
MobileForm.AbstractFormDelegate {
Layout.fillWidth: true
background: Item {}
contentItem: RowLayout {
Item {
Layout.fillWidth: true
}
Kirigami.Avatar { Kirigami.Avatar {
Layout.bottomMargin: Kirigami.Units.largeSpacing id: avatar
Layout.alignment: Qt.AlignRight
name: room.name name: room.name
source: room.avatarMediaId ? ("image://mxc/" + room.avatarMediaId) : "" 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
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: { onClicked: {
const fileDialog = openFileDialog.createObject(QQC2.ApplicationWindow.overlay) const fileDialog = openFileDialog.createObject(QQC2.ApplicationWindow.overlay)
@@ -50,140 +61,52 @@ Kirigami.ScrollablePage {
fileDialog.open() fileDialog.open()
} }
}
}
QQC2.TextField {
id: roomNameField
text: room.name
Kirigami.FormData.label: i18n("Room Name:")
enabled: canChangeName
}
QQC2.TextArea { 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 id: roomTopicField
Layout.fillWidth: true Layout.fillWidth: true
text: room.topic enabled: room.canSendState("m.room.topic")
Kirigami.FormData.label: i18n("Room topic:") background: Item {}
enabled: canChangeTopic contentItem: ColumnLayout {
}
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
spacing: 0
Repeater {
model: room.altAliases
delegate: RowLayout {
Layout.maximumWidth: parent.width
QQC2.Label { QQC2.Label {
text: modelData id: roomTopicLabel
} text: i18n("Room topic:")
QQC2.ToolButton {
icon.name: ""
onClicked: room.removeLocalAlias(modelData)
}
}
}
}
}
}
Kirigami.Separator {
Layout.fillWidth: true Layout.fillWidth: true
visible: next.visible || prev.visible
} }
QQC2.TextArea {
QQC2.Control { Accessible.description: roomTopicLabel.text
id: next
Layout.fillWidth: true Layout.fillWidth: true
text: room.topic
visible: room.predecessorId && room.connection.room(room.predecessorId) onTextChanged: roomTopicField.text = text
padding: Kirigami.Units.largeSpacing
contentItem: Kirigami.InlineMessage {
text: i18n("This room continues another conversation.")
actions: Kirigami.Action {
text: i18n("See older messages...")
onTriggered: {
roomListForm.enteredRoom = Controller.activeConnection.room(room.predecessorId)
root.close()
} }
} }
} }
} MobileForm.AbstractFormDelegate {
QQC2.Control {
id: prev
Layout.fillWidth: true Layout.fillWidth: true
background: Item {}
visible: room.successorId && room.connection.room(room.successorId)
padding: Kirigami.Units.largeSpacing
contentItem: Kirigami.InlineMessage {
text: i18n("This room has been replaced.")
actions: Kirigami.Action {
text: i18n("See new room...")
onTriggered: {
roomListForm.enteredRoom = Controller.activeConnection.room(room.successorId)
root.close()
}
}
}
}
Component {
id: openFileDialog
OpenFileDialog {}
}
}
footer: QQC2.ToolBar {
contentItem: RowLayout { contentItem: RowLayout {
Item { Item {
Layout.fillWidth: true Layout.fillWidth: true
} }
QQC2.Button { QQC2.Button {
Layout.alignment: Qt.AlignRight Layout.bottomMargin: Kirigami.Units.smallSpacing
Layout.topMargin: Kirigami.Units.smallSpacing
enabled: room.name !== roomNameField.text || room.topic !== roomTopicField.text enabled: room.name !== roomNameField.text || room.topic !== roomTopicField.text
text: i18n("Apply") text: i18n("Save")
onClicked: { onClicked: {
if (room.name != roomNameField.text) { if (room.name != roomNameField.text) {
room.setName(roomNameField.text) room.setName(roomNameField.text)
@@ -196,5 +119,142 @@ Kirigami.ScrollablePage {
} }
} }
} }
}
}
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 {
id: setCanonicalAliasButton
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
}
}
}
}
}
}
Kirigami.InlineMessage {
Layout.fillWidth: true
Layout.maximumWidth: Kirigami.Units.gridUnit * 30
Layout.alignment: Qt.AlignHCenter
text: i18n("This room continues another conversation.")
type: Kirigami.MessageType.Information
visible: room.predecessorId && room.connection.room(room.predecessorId)
actions: Kirigami.Action {
text: i18n("See older messages…")
onTriggered: {
RoomManager.enterRoom(Controller.activeConnection.room(room.predecessorId));
root.close();
}
}
}
Kirigami.InlineMessage {
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)
actions: Kirigami.Action {
text: i18n("See new room…")
onTriggered: {
RoomManager.enterRoom(Controller.activeConnection.room(room.successorId));
root.close();
}
}
}
Component {
id: openFileDialog
OpenFileDialog {}
}
}
} }