mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-24 03:58:49 +03:00
588 lines
22 KiB
QML
588 lines
22 KiB
QML
// SPDX-FileCopyrightText: Nheko Contributors
|
|
//
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
import ".."
|
|
import "../ui"
|
|
import Qt.labs.platform 1.1 as Platform
|
|
import QtQuick 2.15
|
|
import QtQuick.Controls 2.3
|
|
import QtQuick.Layouts 1.2
|
|
import QtQuick.Window 2.13
|
|
import im.nheko 1.0
|
|
|
|
ApplicationWindow {
|
|
id: roomSettingsDialog
|
|
|
|
property var roomSettings
|
|
|
|
minimumWidth: 340
|
|
minimumHeight: 450
|
|
width: 450
|
|
height: 680
|
|
color: palette.window
|
|
modality: Qt.NonModal
|
|
flags: Qt.Dialog | Qt.WindowCloseButtonHint | Qt.WindowTitleHint
|
|
title: qsTr("Room Settings")
|
|
|
|
Shortcut {
|
|
sequence: StandardKey.Cancel
|
|
onActivated: roomSettingsDialog.close()
|
|
}
|
|
|
|
Flickable {
|
|
id: flickable
|
|
boundsBehavior: Flickable.StopAtBounds
|
|
anchors.fill: parent
|
|
clip: true
|
|
flickableDirection: Flickable.VerticalFlick
|
|
contentWidth: roomSettingsDialog.width
|
|
contentHeight: contentLayout1.height
|
|
ColumnLayout {
|
|
id: contentLayout1
|
|
width: parent.width
|
|
spacing: Nheko.paddingMedium
|
|
|
|
Avatar {
|
|
id: displayAvatar
|
|
|
|
Layout.topMargin: Nheko.paddingMedium
|
|
url: roomSettings.roomAvatarUrl.replace("mxc://", "image://MxcImage/")
|
|
roomid: roomSettings.roomId
|
|
displayName: roomSettings.roomName
|
|
height: 130
|
|
width: 130
|
|
Layout.alignment: Qt.AlignHCenter
|
|
onClicked: TimelineManager.openImageOverlay(null, roomSettings.roomAvatarUrl, "", 0, 0)
|
|
|
|
ImageButton {
|
|
hoverEnabled: true
|
|
ToolTip.visible: hovered
|
|
ToolTip.text: qsTr("Change room avatar.")
|
|
anchors.left: displayAvatar.left
|
|
anchors.top: displayAvatar.top
|
|
anchors.leftMargin: Nheko.paddingMedium
|
|
anchors.topMargin: Nheko.paddingMedium
|
|
visible: roomSettings.canChangeAvatar
|
|
image: ":/icons/icons/ui/edit.svg"
|
|
onClicked: {
|
|
roomSettings.updateAvatar();
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
Spinner {
|
|
Layout.alignment: Qt.AlignHCenter
|
|
visible: roomSettings.isLoading
|
|
foreground: palette.mid
|
|
running: roomSettings.isLoading
|
|
}
|
|
|
|
Text {
|
|
id: errorText
|
|
|
|
color: "red"
|
|
visible: opacity > 0
|
|
opacity: 0
|
|
Layout.alignment: Qt.AlignHCenter
|
|
wrapMode: Text.Wrap // somehow still doesn't wrap
|
|
Layout.fillWidth: true
|
|
}
|
|
|
|
SequentialAnimation {
|
|
id: hideErrorAnimation
|
|
|
|
running: false
|
|
|
|
PauseAnimation {
|
|
duration: 4000
|
|
}
|
|
|
|
NumberAnimation {
|
|
target: errorText
|
|
property: 'opacity'
|
|
to: 0
|
|
duration: 1000
|
|
}
|
|
|
|
}
|
|
|
|
Connections {
|
|
target: roomSettings
|
|
function onDisplayError(errorMessage) {
|
|
errorText.text = errorMessage;
|
|
errorText.opacity = 1;
|
|
hideErrorAnimation.restart();
|
|
}
|
|
}
|
|
|
|
TextEdit {
|
|
id: roomName
|
|
|
|
property bool isNameEditingAllowed: false
|
|
|
|
readOnly: !isNameEditingAllowed
|
|
textFormat: isNameEditingAllowed ? TextEdit.PlainText : TextEdit.RichText
|
|
text: isNameEditingAllowed ? roomSettings.plainRoomName : roomSettings.roomName
|
|
font.pixelSize: fontMetrics.font.pixelSize * 2
|
|
color: palette.text
|
|
|
|
Layout.alignment: Qt.AlignHCenter
|
|
Layout.maximumWidth: parent.width - (Nheko.paddingSmall * 2) - nameChangeButton.anchors.leftMargin - (nameChangeButton.width * 2)
|
|
horizontalAlignment: TextEdit.AlignHCenter
|
|
wrapMode: TextEdit.Wrap
|
|
selectByMouse: true
|
|
|
|
Keys.onShortcutOverride: event.key === Qt.Key_Enter
|
|
Keys.onPressed: {
|
|
if (event.matches(StandardKey.InsertLineSeparator) || event.matches(StandardKey.InsertParagraphSeparator)) {
|
|
roomSettings.changeName(roomName.text);
|
|
roomName.isNameEditingAllowed = false;
|
|
event.accepted = true;
|
|
}
|
|
}
|
|
|
|
ImageButton {
|
|
id: nameChangeButton
|
|
visible: roomSettings.canChangeName
|
|
anchors.leftMargin: Nheko.paddingSmall
|
|
anchors.left: roomName.right
|
|
anchors.verticalCenter: roomName.verticalCenter
|
|
hoverEnabled: true
|
|
ToolTip.visible: hovered
|
|
ToolTip.text: qsTr("Change name of this room")
|
|
ToolTip.delay: Nheko.tooltipDelay
|
|
image: roomName.isNameEditingAllowed ? ":/icons/icons/ui/checkmark.svg" : ":/icons/icons/ui/edit.svg"
|
|
onClicked: {
|
|
if (roomName.isNameEditingAllowed) {
|
|
roomSettings.changeName(roomName.text);
|
|
roomName.isNameEditingAllowed = false;
|
|
} else {
|
|
roomName.isNameEditingAllowed = true;
|
|
roomName.focus = true;
|
|
roomName.selectAll();
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
RowLayout {
|
|
spacing: Nheko.paddingMedium
|
|
Layout.alignment: Qt.AlignHCenter
|
|
|
|
Label {
|
|
text: qsTr("%n member(s)", "", roomSettings.memberCount)
|
|
color: palette.text
|
|
}
|
|
|
|
ImageButton {
|
|
image: ":/icons/icons/ui/people.svg"
|
|
hoverEnabled: true
|
|
ToolTip.visible: hovered
|
|
ToolTip.text: qsTr("View members of %1").arg(roomSettings.roomName)
|
|
onClicked: TimelineManager.openRoomMembers(Rooms.getRoomById(roomSettings.roomId))
|
|
}
|
|
|
|
}
|
|
|
|
TextArea {
|
|
id: roomTopic
|
|
property bool cut: implicitHeight > 100
|
|
property bool showMore: false
|
|
clip: true
|
|
Layout.maximumHeight: showMore? Number.POSITIVE_INFINITY : 100
|
|
Layout.preferredHeight: implicitHeight
|
|
Layout.alignment: Qt.AlignHCenter
|
|
Layout.fillWidth: true
|
|
Layout.leftMargin: Nheko.paddingLarge
|
|
Layout.rightMargin: Nheko.paddingLarge
|
|
|
|
property bool isTopicEditingAllowed: false
|
|
|
|
readOnly: !isTopicEditingAllowed
|
|
textFormat: isTopicEditingAllowed ? TextEdit.PlainText : TextEdit.RichText
|
|
text: isTopicEditingAllowed
|
|
? roomSettings.plainRoomTopic
|
|
: (roomSettings.plainRoomTopic === "" ? ("<i>" + qsTr("No topic set") + "</i>") : roomSettings.roomTopic)
|
|
wrapMode: TextEdit.WordWrap
|
|
background: null
|
|
selectByMouse: !Settings.mobileMode
|
|
color: palette.text
|
|
horizontalAlignment: TextEdit.AlignHCenter
|
|
onLinkActivated: Nheko.openLink(link)
|
|
|
|
NhekoCursorShape {
|
|
anchors.fill: parent
|
|
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
|
|
}
|
|
|
|
}
|
|
|
|
ImageButton {
|
|
id: topicChangeButton
|
|
Layout.alignment: Qt.AlignHCenter
|
|
visible: roomSettings.canChangeTopic
|
|
hoverEnabled: true
|
|
ToolTip.visible: hovered
|
|
ToolTip.text: qsTr("Change topic of this room")
|
|
ToolTip.delay: Nheko.tooltipDelay
|
|
image: roomTopic.isTopicEditingAllowed ? ":/icons/icons/ui/checkmark.svg" : ":/icons/icons/ui/edit.svg"
|
|
onClicked: {
|
|
if (roomTopic.isTopicEditingAllowed) {
|
|
roomSettings.changeTopic(roomTopic.text);
|
|
roomTopic.isTopicEditingAllowed = false;
|
|
} else {
|
|
roomTopic.isTopicEditingAllowed = true;
|
|
roomTopic.showMore = true;
|
|
roomTopic.focus = true;
|
|
//roomTopic.selectAll();
|
|
}
|
|
}
|
|
}
|
|
|
|
Item {
|
|
Layout.alignment: Qt.AlignHCenter
|
|
id: showMorePlaceholder
|
|
Layout.preferredHeight: showMoreButton.height
|
|
Layout.preferredWidth: showMoreButton.width
|
|
visible: roomTopic.cut
|
|
}
|
|
|
|
GridLayout {
|
|
columns: 2
|
|
rowSpacing: Nheko.paddingMedium
|
|
Layout.margins: Nheko.paddingMedium
|
|
Layout.fillWidth: true
|
|
|
|
Label {
|
|
text: qsTr("SETTINGS")
|
|
font.bold: true
|
|
color: palette.text
|
|
}
|
|
|
|
Item {
|
|
Layout.fillWidth: true
|
|
}
|
|
|
|
Label {
|
|
text: qsTr("Notifications")
|
|
Layout.fillWidth: true
|
|
color: palette.text
|
|
}
|
|
|
|
ComboBox {
|
|
model: [qsTr("Muted"), qsTr("Mentions only"), qsTr("All messages")]
|
|
currentIndex: roomSettings.notifications
|
|
onActivated: {
|
|
roomSettings.changeNotifications(index);
|
|
}
|
|
Layout.fillWidth: true
|
|
WheelHandler{} // suppress scrolling changing values
|
|
}
|
|
|
|
Label {
|
|
text: qsTr("Anyone can join")
|
|
Layout.fillWidth: true
|
|
color: palette.text
|
|
}
|
|
|
|
ToggleButton {
|
|
id: publicRoomButton
|
|
|
|
enabled: roomSettings.canChangeJoinRules
|
|
checked: !roomSettings.privateAccess
|
|
Layout.alignment: Qt.AlignRight
|
|
}
|
|
|
|
Label {
|
|
text: qsTr("Allow knocking")
|
|
Layout.fillWidth: true
|
|
color: palette.text
|
|
visible: knockingButton.visible
|
|
}
|
|
|
|
ToggleButton {
|
|
id: knockingButton
|
|
|
|
visible: !publicRoomButton.checked
|
|
enabled: roomSettings.canChangeJoinRules && roomSettings.supportsKnocking
|
|
checked: roomSettings.knockingEnabled
|
|
onCheckedChanged: {
|
|
if (checked && !roomSettings.supportsKnockRestricted) restrictedButton.checked = false;
|
|
}
|
|
Layout.alignment: Qt.AlignRight
|
|
}
|
|
|
|
Label {
|
|
text: qsTr("Allow joining via other rooms")
|
|
Layout.fillWidth: true
|
|
color: palette.text
|
|
visible: restrictedButton.visible
|
|
}
|
|
|
|
ToggleButton {
|
|
id: restrictedButton
|
|
|
|
visible: !publicRoomButton.checked
|
|
enabled: roomSettings.canChangeJoinRules && roomSettings.supportsRestricted
|
|
checked: roomSettings.restrictedEnabled
|
|
onCheckedChanged: {
|
|
if (checked && !roomSettings.supportsKnockRestricted) knockingButton.checked = false;
|
|
}
|
|
Layout.alignment: Qt.AlignRight
|
|
}
|
|
|
|
Label {
|
|
text: qsTr("Rooms to join via")
|
|
Layout.fillWidth: true
|
|
color: palette.text
|
|
visible: allowedRoomsButton.visible
|
|
}
|
|
|
|
Button {
|
|
id: allowedRoomsButton
|
|
|
|
visible: restrictedButton.checked && restrictedButton.visible
|
|
enabled: roomSettings.canChangeJoinRules && roomSettings.supportsRestricted
|
|
|
|
text: qsTr("Change")
|
|
ToolTip.text: qsTr("Change the list of rooms users can join this room via. Usually this is the official community of this room.")
|
|
onClicked: timelineRoot.showAllowedRoomsEditor(roomSettings)
|
|
Layout.alignment: Qt.AlignRight
|
|
}
|
|
|
|
Label {
|
|
text: qsTr("Allow guests to join")
|
|
Layout.fillWidth: true
|
|
color: palette.text
|
|
}
|
|
|
|
ToggleButton {
|
|
id: guestAccessButton
|
|
|
|
enabled: roomSettings.canChangeJoinRules
|
|
checked: roomSettings.guestAccess
|
|
Layout.alignment: Qt.AlignRight
|
|
}
|
|
|
|
Button {
|
|
visible: publicRoomButton.checked == roomSettings.privateAccess || knockingButton.checked != roomSettings.knockingEnabled || restrictedButton.checked != roomSettings.restrictedEnabled || guestAccessButton.checked != roomSettings.guestAccess || roomSettings.allowedRoomsModified
|
|
enabled: roomSettings.canChangeJoinRules
|
|
|
|
text: qsTr("Apply access rules")
|
|
onClicked: roomSettings.changeAccessRules(!publicRoomButton.checked, guestAccessButton.checked, knockingButton.checked, restrictedButton.checked)
|
|
Layout.columnSpan: 2
|
|
Layout.fillWidth: true
|
|
}
|
|
|
|
Label {
|
|
text: qsTr("History visibility")
|
|
Layout.fillWidth: true
|
|
color: palette.text
|
|
}
|
|
|
|
ComboBox {
|
|
id: visComboBox
|
|
model: [qsTr("Readable to anyone without joining the room"), qsTr("Past messages visible to all current members"), qsTr("Only visible to members who were invited or joined when the message was sent"), qsTr("Only visible to members who were joined when the message was sent")]
|
|
currentIndex: roomSettings.historyVisibility
|
|
onActivated: {
|
|
roomSettings.changeHistoryVisibility(index);
|
|
}
|
|
Layout.fillWidth: true
|
|
WheelHandler{} // suppress scrolling changing values
|
|
enabled: roomSettings.canChangeHistoryVisibility
|
|
|
|
delegate: ItemDelegate {
|
|
text: modelData
|
|
width: implicitWidth
|
|
highlighted: visComboBox.highlightedIndex === index
|
|
ToolTip.text: modelData
|
|
ToolTip.visible: hovered
|
|
ToolTip.delay: Nheko.tooltipDelay
|
|
}
|
|
|
|
ToolTip.text: displayText
|
|
ToolTip.visible: hovered
|
|
ToolTip.delay: Nheko.tooltipDelay
|
|
}
|
|
|
|
Label {
|
|
text: qsTr("Encryption")
|
|
color: palette.text
|
|
}
|
|
|
|
ToggleButton {
|
|
id: encryptionToggle
|
|
|
|
checked: roomSettings.isEncryptionEnabled
|
|
onCheckedChanged: {
|
|
if (roomSettings.isEncryptionEnabled) {
|
|
checked = true;
|
|
return ;
|
|
}
|
|
if (checked === true)
|
|
confirmEncryptionDialog.open();
|
|
}
|
|
Layout.alignment: Qt.AlignRight
|
|
}
|
|
|
|
Platform.MessageDialog {
|
|
id: confirmEncryptionDialog
|
|
|
|
title: qsTr("End-to-End Encryption")
|
|
text: qsTr("Encryption is currently experimental and things might break unexpectedly. <br>
|
|
Please take note that it can't be disabled afterwards.")
|
|
modality: Qt.NonModal
|
|
onAccepted: {
|
|
if (roomSettings.isEncryptionEnabled)
|
|
return ;
|
|
|
|
roomSettings.enableEncryption();
|
|
}
|
|
onRejected: {
|
|
encryptionToggle.checked = false;
|
|
}
|
|
buttons: Platform.MessageDialog.Ok | Platform.MessageDialog.Cancel
|
|
}
|
|
|
|
Label {
|
|
text: qsTr("Permission")
|
|
color: palette.text
|
|
}
|
|
|
|
Button {
|
|
text: qsTr("Configure")
|
|
ToolTip.text: qsTr("View and change the permissions in this room")
|
|
onClicked: timelineRoot.showPLEditor(roomSettings)
|
|
Layout.alignment: Qt.AlignRight
|
|
}
|
|
|
|
Label {
|
|
text: qsTr("Aliases")
|
|
color: palette.text
|
|
}
|
|
|
|
Button {
|
|
text: qsTr("Configure")
|
|
ToolTip.text: qsTr("View and change the addresses/aliases of this room")
|
|
onClicked: timelineRoot.showAliasEditor(roomSettings)
|
|
Layout.alignment: Qt.AlignRight
|
|
}
|
|
|
|
Label {
|
|
text: qsTr("Sticker & Emote Settings")
|
|
color: palette.text
|
|
}
|
|
|
|
Button {
|
|
text: qsTr("Change")
|
|
ToolTip.text: qsTr("Change what packs are enabled, remove packs, or create new ones")
|
|
onClicked: TimelineManager.openImagePackSettings(roomSettings.roomId)
|
|
Layout.alignment: Qt.AlignRight
|
|
}
|
|
|
|
Label {
|
|
text: qsTr("Hidden events")
|
|
color: palette.text
|
|
}
|
|
|
|
HiddenEventsDialog {
|
|
id: hiddenEventsDialog
|
|
roomid: roomSettings.roomId
|
|
roomName: roomSettings.roomName
|
|
}
|
|
|
|
Button {
|
|
text: qsTr("Configure")
|
|
ToolTip.text: qsTr("Select events to hide in this room")
|
|
onClicked: hiddenEventsDialog.show()
|
|
Layout.alignment: Qt.AlignRight
|
|
}
|
|
|
|
Item {
|
|
// for adding extra space between sections
|
|
Layout.fillWidth: true
|
|
}
|
|
|
|
Item {
|
|
// for adding extra space between sections
|
|
Layout.fillWidth: true
|
|
}
|
|
|
|
Label {
|
|
text: qsTr("INFO")
|
|
font.bold: true
|
|
color: palette.text
|
|
}
|
|
|
|
Item {
|
|
Layout.fillWidth: true
|
|
}
|
|
|
|
Label {
|
|
text: qsTr("Internal ID")
|
|
color: palette.text
|
|
}
|
|
|
|
AbstractButton { // AbstractButton does not allow setting text color
|
|
Layout.alignment: Qt.AlignRight
|
|
Layout.fillWidth: true
|
|
Layout.preferredHeight: idLabel.height
|
|
Label { // TextEdit does not trigger onClicked
|
|
id: idLabel
|
|
text: roomSettings.roomId
|
|
font.pixelSize: Math.floor(fontMetrics.font.pixelSize * 0.8)
|
|
color: palette.text
|
|
width: parent.width
|
|
horizontalAlignment: Text.AlignRight
|
|
wrapMode: Text.WrapAnywhere
|
|
ToolTip.text: qsTr("Copied to clipboard")
|
|
ToolTip.visible: toolTipTimer.running
|
|
}
|
|
TextEdit{ // label does not allow selection
|
|
id: textEdit
|
|
visible: false
|
|
text: roomSettings.roomId
|
|
}
|
|
onClicked: {
|
|
textEdit.selectAll()
|
|
textEdit.copy()
|
|
toolTipTimer.start()
|
|
}
|
|
Timer {
|
|
id: toolTipTimer
|
|
}
|
|
}
|
|
|
|
Label {
|
|
text: qsTr("Room Version")
|
|
color: palette.text
|
|
}
|
|
|
|
Label {
|
|
text: roomSettings.roomVersion
|
|
font.pixelSize: fontMetrics.font.pixelSize
|
|
Layout.alignment: Qt.AlignRight
|
|
color: palette.text
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
Button {
|
|
id: showMoreButton
|
|
anchors.horizontalCenter: flickable.horizontalCenter
|
|
y: Math.min(showMorePlaceholder.y+contentLayout1.y-flickable.contentY,flickable.height-height)
|
|
visible: roomTopic.cut
|
|
text: roomTopic.showMore? qsTr("show less") : qsTr("show more")
|
|
onClicked: {roomTopic.showMore = !roomTopic.showMore
|
|
console.log(flickable.visibleArea)
|
|
}
|
|
}
|
|
footer: DialogButtonBox {
|
|
standardButtons: DialogButtonBox.Ok
|
|
onAccepted: close()
|
|
}
|
|
}
|