diff --git a/resources/qml/Completer.qml b/resources/qml/Completer.qml
index 333fb11d..00fc3216 100644
--- a/resources/qml/Completer.qml
+++ b/resources/qml/Completer.qml
@@ -70,7 +70,7 @@ Popup {
onCompleterNameChanged: {
if (completerName) {
if (completerName == "user")
- completer = TimelineManager.completerFor(completerName, room.roomId());
+ completer = TimelineManager.completerFor(completerName, room.roomId);
else
completer = TimelineManager.completerFor(completerName);
completer.setSearchString("");
diff --git a/resources/qml/InviteDialog.qml b/resources/qml/InviteDialog.qml
new file mode 100644
index 00000000..dbe8bb07
--- /dev/null
+++ b/resources/qml/InviteDialog.qml
@@ -0,0 +1,158 @@
+// SPDX-FileCopyrightText: 2021 Nheko Contributors
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+import QtQuick 2.12
+import QtQuick.Controls 2.12
+import QtQuick.Layouts 1.12
+import im.nheko 1.0
+
+ApplicationWindow {
+ id: inviteDialogRoot
+
+ property string roomId
+ property string plainRoomName
+ property InviteesModel invitees
+
+ function addInvite() {
+ if (inviteeEntry.isValidMxid) {
+ invitees.addUser(inviteeEntry.text);
+ inviteeEntry.clear();
+ }
+ }
+
+ function cleanUpAndClose() {
+ if (inviteeEntry.isValidMxid)
+ addInvite();
+
+ invitees.accept();
+ close();
+ }
+
+ title: qsTr("Invite users to ") + plainRoomName
+ x: MainWindow.x + (MainWindow.width / 2) - (width / 2)
+ y: MainWindow.y + (MainWindow.height / 2) - (height / 2)
+ height: 380
+ width: 340
+ palette: Nheko.colors
+ color: Nheko.colors.window
+
+ Shortcut {
+ sequence: "Ctrl+Enter"
+ onActivated: cleanUpAndClose()
+ }
+
+ Shortcut {
+ sequence: StandardKey.Cancel
+ onActivated: inviteDialogRoot.close()
+ }
+
+ ColumnLayout {
+ anchors.fill: parent
+ anchors.margins: Nheko.paddingMedium
+ spacing: Nheko.paddingMedium
+
+ Label {
+ text: qsTr("User ID to invite")
+ Layout.fillWidth: true
+ }
+
+ RowLayout {
+ spacing: Nheko.paddingMedium
+
+ MatrixTextField {
+ id: inviteeEntry
+
+ property bool isValidMxid: text.match("@.+?:.{3,}")
+
+ backgroundColor: Nheko.colors.window
+ placeholderText: qsTr("@joe:matrix.org", "Example user id. The name 'joe' can be localized however you want.")
+ Layout.fillWidth: true
+ onAccepted: {
+ if (isValidMxid)
+ addInvite();
+
+ }
+ Component.onCompleted: forceActiveFocus()
+ Keys.onShortcutOverride: event.accepted = ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && (event.modifiers & Qt.ControlModifier))
+ Keys.onPressed: {
+ if ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && (event.modifiers === Qt.ControlModifier))
+ cleanUpAndClose();
+
+ }
+ }
+
+ Button {
+ text: qsTr("Add")
+ enabled: inviteeEntry.isValidMxid
+ onClicked: addInvite()
+ }
+
+ }
+
+ ListView {
+ id: inviteesList
+
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ model: invitees
+
+ delegate: RowLayout {
+ spacing: Nheko.paddingMedium
+
+ Avatar {
+ width: Nheko.avatarSize
+ height: Nheko.avatarSize
+ userid: model.mxid
+ url: model.avatarUrl.replace("mxc://", "image://MxcImage/")
+ displayName: model.displayName
+ onClicked: Rooms.currentRoom.openUserProfile(model.mxid)
+ }
+
+ ColumnLayout {
+ spacing: Nheko.paddingSmall
+
+ Label {
+ text: model.displayName
+ color: TimelineManager.userColor(model ? model.mxid : "", Nheko.colors.window)
+ font.pointSize: fontMetrics.font.pointSize
+ }
+
+ Label {
+ text: model.mxid
+ color: Nheko.colors.buttonText
+ font.pointSize: fontMetrics.font.pointSize * 0.9
+ }
+
+ Item {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+ footer: DialogButtonBox {
+ id: buttons
+
+ Button {
+ text: qsTr("Invite")
+ DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole
+ enabled: invitees.count > 0
+ onClicked: cleanUpAndClose()
+ }
+
+ Button {
+ text: qsTr("Cancel")
+ DialogButtonBox.buttonRole: DialogButtonBox.DestructiveRole
+ onClicked: inviteDialogRoot.close()
+ }
+
+ }
+
+}
diff --git a/resources/qml/MatrixTextField.qml b/resources/qml/MatrixTextField.qml
index 3c660bac..80732b27 100644
--- a/resources/qml/MatrixTextField.qml
+++ b/resources/qml/MatrixTextField.qml
@@ -10,6 +10,8 @@ import im.nheko 1.0
TextField {
id: input
+ property alias backgroundColor: backgroundRect.color
+
palette: Nheko.colors
color: Nheko.colors.text
@@ -62,6 +64,8 @@ TextField {
}
background: Rectangle {
+ id: backgroundRect
+
color: Nheko.colors.base
}
diff --git a/resources/qml/MessageInput.qml b/resources/qml/MessageInput.qml
index 415d67a7..c135aff9 100644
--- a/resources/qml/MessageInput.qml
+++ b/resources/qml/MessageInput.qml
@@ -331,7 +331,7 @@ Rectangle {
image: ":/icons/icons/ui/sticky-note-solid.svg"
ToolTip.visible: hovered
ToolTip.text: qsTr("Stickers")
- onClicked: stickerPopup.visible ? stickerPopup.close() : stickerPopup.show(stickerButton, room.roomId(), function(row) {
+ onClicked: stickerPopup.visible ? stickerPopup.close() : stickerPopup.show(stickerButton, room.roomId, function(row) {
room.input.sticker(stickerPopup.model.sourceModel, row);
TimelineManager.focusMessageInput();
})
diff --git a/resources/qml/RoomList.qml b/resources/qml/RoomList.qml
index a1ce8d7e..9dac5830 100644
--- a/resources/qml/RoomList.qml
+++ b/resources/qml/RoomList.qml
@@ -33,8 +33,8 @@ Page {
Connections {
onActiveTimelineChanged: {
- roomlist.positionViewAtIndex(Rooms.roomidToIndex(Rooms.currentRoom.roomId()), ListView.Contain);
- console.log("Test" + Rooms.currentRoom.roomId() + " " + Rooms.roomidToIndex(Rooms.currentRoom.roomId()));
+ roomlist.positionViewAtIndex(Rooms.roomidToIndex(Rooms.currentRoom.roomId), ListView.Contain);
+ console.log("Test" + Rooms.currentRoom.roomId + " " + Rooms.roomidToIndex(Rooms.currentRoom.roomId));
}
target: TimelineManager
}
@@ -133,7 +133,7 @@ Page {
states: [
State {
name: "highlight"
- when: hovered.hovered && !((Rooms.currentRoom && roomId == Rooms.currentRoom.roomId()) || Rooms.currentRoomPreview.roomid == roomId)
+ when: hovered.hovered && !((Rooms.currentRoom && roomId == Rooms.currentRoom.roomId) || Rooms.currentRoomPreview.roomid == roomId)
PropertyChanges {
target: roomItem
@@ -147,7 +147,7 @@ Page {
},
State {
name: "selected"
- when: (Rooms.currentRoom && roomId == Rooms.currentRoom.roomId()) || Rooms.currentRoomPreview.roomid == roomId
+ when: (Rooms.currentRoom && roomId == Rooms.currentRoom.roomId) || Rooms.currentRoomPreview.roomid == roomId
PropertyChanges {
target: roomItem
diff --git a/resources/qml/RoomMembers.qml b/resources/qml/RoomMembers.qml
new file mode 100644
index 00000000..3758cb0b
--- /dev/null
+++ b/resources/qml/RoomMembers.qml
@@ -0,0 +1,149 @@
+// SPDX-FileCopyrightText: 2021 Nheko Contributors
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+import "./ui"
+import QtQuick 2.12
+import QtQuick.Controls 2.12
+import QtQuick.Layouts 1.12
+import QtQuick.Window 2.12
+import im.nheko 1.0
+
+ApplicationWindow {
+ id: roomMembersRoot
+
+ property MemberList members
+
+ title: qsTr("Members of ") + members.roomName
+ x: MainWindow.x + (MainWindow.width / 2) - (width / 2)
+ y: MainWindow.y + (MainWindow.height / 2) - (height / 2)
+ height: 650
+ width: 420
+ minimumHeight: 420
+ palette: Nheko.colors
+ color: Nheko.colors.window
+
+ Shortcut {
+ sequence: StandardKey.Cancel
+ onActivated: roomMembersRoot.close()
+ }
+
+ ColumnLayout {
+ anchors.fill: parent
+ anchors.margins: Nheko.paddingMedium
+ spacing: Nheko.paddingMedium
+
+ Avatar {
+ id: roomAvatar
+
+ width: 130
+ height: width
+ displayName: members.roomName
+ Layout.alignment: Qt.AlignHCenter
+ url: members.avatarUrl.replace("mxc://", "image://MxcImage/")
+ onClicked: Rooms.currentRoom.openRoomSettings(members.roomId)
+ }
+
+ ElidedLabel {
+ font.pixelSize: fontMetrics.font.pixelSize * 2
+ fullText: members.memberCount + (members.memberCount === 1 ? qsTr(" person in ") : qsTr(" people in ")) + members.roomName
+ Layout.alignment: Qt.AlignHCenter
+ elideWidth: parent.width - Nheko.paddingMedium
+ }
+
+ ImageButton {
+ Layout.alignment: Qt.AlignHCenter
+ image: ":/icons/icons/ui/add-square-button.png"
+ hoverEnabled: true
+ ToolTip.visible: hovered
+ ToolTip.text: qsTr("Invite more people")
+ onClicked: Rooms.currentRoom.openInviteUsers()
+ }
+
+ ScrollView {
+ palette: Nheko.colors
+ padding: Nheko.paddingMedium
+ ScrollBar.horizontal.visible: false
+ Layout.fillHeight: true
+ Layout.minimumHeight: 200
+ Layout.fillWidth: true
+
+ ListView {
+ id: memberList
+
+ clip: true
+ spacing: Nheko.paddingMedium
+ boundsBehavior: Flickable.StopAtBounds
+ model: members
+
+ ScrollHelper {
+ flickable: parent
+ anchors.fill: parent
+ enabled: !Settings.mobileMode
+ }
+
+ delegate: RowLayout {
+ spacing: Nheko.paddingMedium
+
+ Avatar {
+ width: Nheko.avatarSize
+ height: Nheko.avatarSize
+ userid: model.mxid
+ url: model.avatarUrl.replace("mxc://", "image://MxcImage/")
+ displayName: model.displayName
+ onClicked: Rooms.currentRoom.openUserProfile(model.mxid)
+ }
+
+ ColumnLayout {
+ spacing: Nheko.paddingSmall
+
+ Label {
+ text: model.displayName
+ color: TimelineManager.userColor(model ? model.mxid : "", Nheko.colors.window)
+ font.pointSize: fontMetrics.font.pointSize
+ }
+
+ Label {
+ text: model.mxid
+ color: Nheko.colors.buttonText
+ font.pointSize: fontMetrics.font.pointSize * 0.9
+ }
+
+ Item {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ }
+
+ }
+
+ }
+
+ footer: Item {
+ width: parent.width
+ visible: (members.numUsersLoaded < members.memberCount) && members.loadingMoreMembers
+
+ // use the default height if it's visible, otherwise no height at all
+ height: membersLoadingSpinner.height
+ anchors.margins: Nheko.paddingMedium
+
+ Spinner {
+ id: membersLoadingSpinner
+
+ anchors.centerIn: parent
+ height: visible ? 35 : 0
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+ footer: DialogButtonBox {
+ standardButtons: DialogButtonBox.Ok
+ onAccepted: roomMembersRoot.close()
+ }
+
+}
diff --git a/resources/qml/RoomSettings.qml b/resources/qml/RoomSettings.qml
index c852b837..2701edf9 100644
--- a/resources/qml/RoomSettings.qml
+++ b/resources/qml/RoomSettings.qml
@@ -98,7 +98,7 @@ ApplicationWindow {
MatrixText {
text: roomSettings.roomName
- font.pixelSize: 24
+ font.pixelSize: fontMetrics.font.pixelSize * 2
Layout.alignment: Qt.AlignHCenter
}
@@ -264,7 +264,7 @@ ApplicationWindow {
MatrixText {
text: roomSettings.roomId
- font.pixelSize: 14
+ font.pixelSize: fontMetrics.font.pixelSize * 1.2
Layout.alignment: Qt.AlignRight
}
@@ -274,16 +274,16 @@ ApplicationWindow {
MatrixText {
text: roomSettings.roomVersion
- font.pixelSize: 14
+ font.pixelSize: fontMetrics.font.pixelSize * 1.2
Layout.alignment: Qt.AlignRight
}
}
- Button {
- Layout.alignment: Qt.AlignRight
- text: qsTr("OK")
- onClicked: close()
+ DialogButtonBox {
+ Layout.fillWidth: true
+ standardButtons: DialogButtonBox.Ok
+ onAccepted: close()
}
}
diff --git a/resources/qml/Root.qml b/resources/qml/Root.qml
index 5316e20d..f71c18e2 100644
--- a/resources/qml/Root.qml
+++ b/resources/qml/Root.qml
@@ -48,6 +48,14 @@ Page {
}
Component {
+ id: roomMembersComponent
+
+ RoomMembers {
+ }
+
+ }
+
+ Component {
id: mobileCallInviteDialog
CallInvite {
@@ -63,6 +71,22 @@ Page {
}
+ Component {
+ id: deviceVerificationDialog
+
+ DeviceVerification {
+ }
+
+ }
+
+ Component {
+ id: inviteDialog
+
+ InviteDialog {
+ }
+
+ }
+
Shortcut {
sequence: "Ctrl+K"
onActivated: {
@@ -82,14 +106,6 @@ Page {
onActivated: Rooms.previousRoom()
}
- Component {
- id: deviceVerificationDialog
-
- DeviceVerification {
- }
-
- }
-
Connections {
target: TimelineManager
onNewDeviceVerificationRequest: {
@@ -116,6 +132,31 @@ Page {
}
}
+ Connections {
+ target: Rooms.currentRoom
+ onOpenRoomMembersDialog: {
+ var membersDialog = roomMembersComponent.createObject(timelineRoot, {
+ "members": members,
+ "roomName": Rooms.currentRoom.roomName
+ });
+ membersDialog.show();
+ }
+ onOpenRoomSettingsDialog: {
+ var roomSettings = roomSettingsComponent.createObject(timelineRoot, {
+ "roomSettings": settings
+ });
+ roomSettings.show();
+ }
+ onOpenInviteUsersDialog: {
+ var dialog = inviteDialog.createObject(timelineRoot, {
+ "roomId": Rooms.currentRoom.roomId,
+ "plainRoomName": Rooms.currentRoom.plainRoomName,
+ "invitees": invitees
+ });
+ dialog.show();
+ }
+ }
+
ChatPage {
anchors.fill: parent
}
diff --git a/resources/qml/TimelineView.qml b/resources/qml/TimelineView.qml
index 148a5817..c5cc69a6 100644
--- a/resources/qml/TimelineView.qml
+++ b/resources/qml/TimelineView.qml
@@ -246,17 +246,7 @@ Item {
NhekoDropArea {
anchors.fill: parent
- roomid: room ? room.roomId() : ""
- }
-
- Connections {
- target: room
- onOpenRoomSettingsDialog: {
- var roomSettings = roomSettingsComponent.createObject(timelineRoot, {
- "roomSettings": settings
- });
- roomSettings.show();
- }
+ roomid: room ? room.roomId : ""
}
}
diff --git a/resources/qml/TopBar.qml b/resources/qml/TopBar.qml
index 58aba0c7..48491f84 100644
--- a/resources/qml/TopBar.qml
+++ b/resources/qml/TopBar.qml
@@ -111,17 +111,17 @@ Rectangle {
Platform.MenuItem {
visible: room ? room.permissions.canInvite() : false
text: qsTr("Invite users")
- onTriggered: TimelineManager.openInviteUsersDialog()
+ onTriggered: Rooms.currentRoom.openInviteUsers()
}
Platform.MenuItem {
text: qsTr("Members")
- onTriggered: TimelineManager.openMemberListDialog(room.roomId())
+ onTriggered: Rooms.currentRoom.openRoomMembers()
}
Platform.MenuItem {
text: qsTr("Leave room")
- onTriggered: TimelineManager.openLeaveRoomDialog(room.roomId())
+ onTriggered: TimelineManager.openLeaveRoomDialog(room.roomId)
}
Platform.MenuItem {
diff --git a/resources/qml/delegates/MessageDelegate.qml b/resources/qml/delegates/MessageDelegate.qml
index c64ae887..a98c2a8b 100644
--- a/resources/qml/delegates/MessageDelegate.qml
+++ b/resources/qml/delegates/MessageDelegate.qml
@@ -232,7 +232,7 @@ Item {
body: formatted
isOnlyEmoji: false
isReply: d.isReply
- formatted: qsTr("%1 created and configured room: %2").arg(d.userName).arg(room.roomId())
+ formatted: qsTr("%1 created and configured room: %2").arg(d.userName).arg(room.roomId)
}
}
diff --git a/resources/qml/voip/PlaceCall.qml b/resources/qml/voip/PlaceCall.qml
index 5f564853..97932cc9 100644
--- a/resources/qml/voip/PlaceCall.qml
+++ b/resources/qml/voip/PlaceCall.qml
@@ -88,7 +88,7 @@ Popup {
onClicked: {
if (buttonLayout.validateMic()) {
Settings.microphone = micCombo.currentText;
- CallManager.sendInvite(room.roomId(), CallType.VOICE);
+ CallManager.sendInvite(room.roomId, CallType.VOICE);
close();
}
}
@@ -102,7 +102,7 @@ Popup {
if (buttonLayout.validateMic()) {
Settings.microphone = micCombo.currentText;
Settings.camera = cameraCombo.currentText;
- CallManager.sendInvite(room.roomId(), CallType.VIDEO);
+ CallManager.sendInvite(room.roomId, CallType.VIDEO);
close();
}
}
diff --git a/resources/qml/voip/ScreenShare.qml b/resources/qml/voip/ScreenShare.qml
index a10057b2..8cd43b1c 100644
--- a/resources/qml/voip/ScreenShare.qml
+++ b/resources/qml/voip/ScreenShare.qml
@@ -136,7 +136,7 @@ Popup {
Settings.screenSharePiP = pipCheckBox.checked;
Settings.screenShareRemoteVideo = remoteVideoCheckBox.checked;
Settings.screenShareHideCursor = hideCursorCheckBox.checked;
- CallManager.sendInvite(room.roomId(), CallType.SCREEN, windowCombo.currentIndex);
+ CallManager.sendInvite(room.roomId, CallType.SCREEN, windowCombo.currentIndex);
close();
}
}
diff --git a/resources/res.qrc b/resources/res.qrc
index e9479e57..f8c040e4 100644
--- a/resources/res.qrc
+++ b/resources/res.qrc
@@ -9,7 +9,6 @@
<file>icons/ui/do-not-disturb-rounded-sign@2x.png</file>
<file>icons/ui/round-remove-button.png</file>
<file>icons/ui/round-remove-button@2x.png</file>
-
<file>icons/ui/double-tick-indicator.png</file>
<file>icons/ui/double-tick-indicator@2x.png</file>
<file>icons/ui/lock.png</file>
@@ -55,22 +54,17 @@
<file>icons/ui/pause-symbol@2x.png</file>
<file>icons/ui/remove-symbol.png</file>
<file>icons/ui/remove-symbol@2x.png</file>
-
<file>icons/ui/world.png</file>
<file>icons/ui/world@2x.png</file>
-
<file>icons/ui/tag.png</file>
<file>icons/ui/tag@2x.png</file>
<file>icons/ui/star.png</file>
<file>icons/ui/star@2x.png</file>
<file>icons/ui/lowprio.png</file>
<file>icons/ui/lowprio@2x.png</file>
-
<file>icons/ui/edit.png</file>
<file>icons/ui/edit@2x.png</file>
-
<file>icons/ui/mail-reply.png</file>
-
<file>icons/ui/place-call.png</file>
<file>icons/ui/end-call.png</file>
<file>icons/ui/microphone-mute.png</file>
@@ -78,7 +72,6 @@
<file>icons/ui/screen-share.png</file>
<file>icons/ui/toggle-camera-view.png</file>
<file>icons/ui/video-call.png</file>
-
<file>icons/emoji-categories/people.png</file>
<file>icons/emoji-categories/people@2x.png</file>
<file>icons/emoji-categories/nature.png</file>
@@ -99,16 +92,12 @@
<qresource prefix="/logos">
<file>nheko.png</file>
<file>nheko.svg</file>
-
<file>splash.png</file>
<file>splash@2x.png</file>
-
<file>register.png</file>
<file>register@2x.png</file>
-
<file>login.png</file>
<file>login@2x.png</file>
-
<file>nheko-512.png</file>
<file>nheko-256.png</file>
<file>nheko-128.png</file>
@@ -185,6 +174,8 @@
<file>qml/components/AdaptiveLayout.qml</file>
<file>qml/components/AdaptiveLayoutElement.qml</file>
<file>qml/components/FlatButton.qml</file>
+ <file>qml/RoomMembers.qml</file>
+ <file>qml/InviteDialog.qml</file>
</qresource>
<qresource prefix="/media">
<file>media/ring.ogg</file>
|