Newer
Older
// SPDX-FileCopyrightText: Nheko Contributors
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.2
Nicolas Werner
committed
Pane {
property string avatarUrl: room ? room.roomAvatarUrl : ""
property string directChatOtherUserId: room ? room.directChatOtherUserId : ""
property bool isDirect: room ? room.isDirect : false
property bool isEncrypted: room ? room.isEncrypted : false
property string roomId: room ? room.roomId : ""
property string roomName: room ? room.roomName : qsTr("No room selected")
property string roomTopic: room ? room.roomTopic : ""
property bool searchHasFocus: searchField.focus && searchField.enabled
property bool showBackButton: false
property int trustlevel: room ? room.trustlevel : Crypto.Unverified
implicitHeight: topLayout.height + Nheko.paddingMedium * 2
Nicolas Werner
committed
background: Rectangle {
Nicolas Werner
committed
}
contentItem: Item {
GridLayout {
id: topLayout
anchors.left: parent.left
anchors.margins: Nheko.paddingMedium
Nicolas Werner
committed
anchors.verticalCenter: parent.verticalCenter
columnSpacing: Nheko.paddingSmall
rowSpacing: Nheko.paddingSmall
Avatar {
id: communityAvatar
property string avatarUrl: (Settings.groupView && room && room.parentSpace && room.parentSpace.roomAvatarUrl) || ""
property string communityId: (Settings.groupView && room && room.parentSpace && room.parentSpace.roomid) || ""
property string communityName: (Settings.groupView && room && room.parentSpace && room.parentSpace.roomName) || ""
Layout.column: 1
Layout.row: 0
displayName: communityName
enabled: false
height: fontMetrics.lineSpacing
roomid: communityId
url: avatarUrl.replace("mxc://", "image://MxcImage/")
visible: roomid && room.parentSpace.isLoaded && ("space:" + room.parentSpace.roomid != Communities.currentTagId)
width: fontMetrics.lineSpacing
}
Label {
id: communityLabel
Layout.column: 2
Layout.fillWidth: true
maximumLineCount: 1
text: qsTr("In %1").arg(communityAvatar.displayName)
Nicolas Werner
committed
ImageButton {
id: backToRoomsButton
Layout.alignment: Qt.AlignVCenter
Nicolas Werner
committed
Layout.preferredHeight: Nheko.avatarSize - Nheko.paddingMedium
Layout.preferredWidth: Nheko.avatarSize - Nheko.paddingMedium
Nicolas Werner
committed
ToolTip.text: qsTr("Back to room list")
ToolTip.visible: hovered
image: ":/icons/icons/ui/angle-arrow-left.svg"
visible: showBackButton
Nicolas Werner
committed
onClicked: Rooms.resetCurrentRoom()
}
Avatar {
Nicolas Werner
committed
Layout.column: 1
Nicolas Werner
committed
Layout.rowSpan: 2
Nicolas Werner
committed
height: Nheko.avatarSize
roomid: roomId
Nicolas Werner
committed
userid: isDirect ? directChatOtherUserId : ""
Nicolas Werner
committed
}
Label {
Layout.column: 2
Nicolas Werner
committed
maximumLineCount: 1
Nicolas Werner
committed
textFormat: Text.RichText
}
MatrixText {
id: roomTopicC
Nicolas Werner
committed
Layout.column: 2
Nicolas Werner
committed
Layout.maximumHeight: fontMetrics.lineSpacing * 2 // show 2 lines
Nicolas Werner
committed
clip: true
// don't use the disabled color
color: topBar.palette.text
Nicolas Werner
committed
text: roomTopic
}
ImageButton {
id: pinButton
property bool pinsShown: !Settings.hiddenPins.includes(roomId)
Layout.alignment: Qt.AlignVCenter
Nicolas Werner
committed
Layout.preferredHeight: Nheko.avatarSize - Nheko.paddingMedium
Layout.preferredWidth: Nheko.avatarSize - Nheko.paddingMedium
ToolTip.text: qsTr("Show or hide pinned messages")
ToolTip.visible: hovered
image: pinsShown ? ":/icons/icons/ui/pin.svg" : ":/icons/icons/ui/pin-off.svg"
visible: !!room && room.pinnedMessages.length > 0
onClicked: {
var ps = Settings.hiddenPins;
if (pinsShown) {
ps.push(roomId);
} else {
const index = ps.indexOf(roomId);
if (index > -1) {
ps.splice(index, 1);
}
}
Settings.hiddenPins = ps;
}
}
AbstractButton {
Layout.column: 4
Layout.preferredHeight: Nheko.avatarSize - Nheko.paddingMedium
Layout.preferredWidth: Nheko.avatarSize - Nheko.paddingMedium
contentItem: EncryptionIndicator {
ToolTip.delay: Nheko.tooltipDelay
ToolTip.text: {
if (!isEncrypted)
return qsTr("This room contains only verified devices.");
return qsTr("This room contains verified devices and devices which have never changed their master key.");
return qsTr("This room contains unverified devices!");
}
Nicolas Werner
committed
}
enabled: false
encrypted: isEncrypted
hovered: parent.hovered
trust: trustlevel
unencryptedColor: palette.buttonText
unencryptedHoverColor: palette.highlight
unencryptedIcon: ":/icons/icons/ui/people.svg"
onClicked: TimelineManager.openRoomMembers(room)
Nicolas Werner
committed
ImageButton {
Nicolas Werner
committed
Nicolas Werner
committed
Layout.alignment: Qt.AlignVCenter
Nicolas Werner
committed
Layout.preferredHeight: Nheko.avatarSize - Nheko.paddingMedium
Layout.preferredWidth: Nheko.avatarSize - Nheko.paddingMedium
ToolTip.visible: hovered
image: ":/icons/icons/ui/search.svg"
visible: !!room
if (searchActive) {
searchField.forceActiveFocus();
searchField.clear();
topBar.searchString = "";
Nicolas Werner
committed
ImageButton {
id: roomOptionsButton
Layout.alignment: Qt.AlignVCenter
Nicolas Werner
committed
Layout.preferredHeight: Nheko.avatarSize - Nheko.paddingMedium
Layout.preferredWidth: Nheko.avatarSize - Nheko.paddingMedium
Nicolas Werner
committed
ToolTip.text: qsTr("Room options")
ToolTip.visible: hovered
image: ":/icons/icons/ui/options.svg"
visible: !!room
Nicolas Werner
committed
onClicked: roomOptionsMenu.open(roomOptionsButton)
Platform.Menu {
id: roomOptionsMenu
Platform.MenuItem {
text: qsTr("Invite users")
Nicolas Werner
committed
onTriggered: TimelineManager.openInviteUsers(roomId)
}
Platform.MenuItem {
text: qsTr("Members")
Nicolas Werner
committed
onTriggered: TimelineManager.openRoomMembers(room)
}
Platform.MenuItem {
text: qsTr("Leave room")
Nicolas Werner
committed
onTriggered: TimelineManager.openLeaveRoomDialog(roomId)
}
Platform.MenuItem {
text: qsTr("Settings")
Nicolas Werner
committed
onTriggered: TimelineManager.openRoomSettings(roomId)
}
Nicolas Werner
committed
ScrollView {
id: pinnedMessages
Layout.column: 2
Nicolas Werner
committed
Layout.fillWidth: true
Layout.preferredHeight: Math.min(contentHeight, Nheko.avatarSize * 4)
Nicolas Werner
committed
ScrollBar.horizontal.visible: false
clip: true
visible: !!room && room.pinnedMessages.length > 0 && !Settings.hiddenPins.includes(roomId)
Nicolas Werner
committed
ListView {
model: room ? room.pinnedMessages : undefined
Nicolas Werner
committed
delegate: RowLayout {
required property string modelData
height: implicitHeight
Nicolas Werner
committed
Reply {
property var e: room ? room.getDump(modelData, "pins") : {}
//Layout.preferredHeight: height
Nicolas Werner
committed
eventId: e.eventId ?? ""
userColor: TimelineManager.userColor(e.userId, palette.window)
Nicolas Werner
committed
Connections {
function onPinnedMessagesChanged() {
reply.e = room.getDump(modelData, "pins");
}
target: room
}
}
Nicolas Werner
committed
ImageButton {
id: deletePinButton
Nicolas Werner
committed
Layout.preferredHeight: 16
Layout.preferredWidth: 16
Nicolas Werner
committed
hoverEnabled: true
image: ":/icons/icons/ui/dismiss.svg"
Nicolas Werner
committed
onClicked: room.unpin(modelData)
}
}
}
ScrollView {
id: widgets
Layout.column: 2
Layout.fillWidth: true
Layout.preferredHeight: Math.min(contentHeight, Nheko.avatarSize * 1.5)
clip: true
visible: !!room && room.widgetLinks.length > 0 && !Settings.hiddenWidgets.includes(roomId)
ListView {
model: room ? room.widgetLinks : undefined
delegate: MatrixText {
required property var modelData
MatrixTextField {
id: searchField
Layout.column: 2
Layout.columnSpan: 4
Layout.fillWidth: true
placeholderText: qsTr("Enter search query")
onAccepted: topBar.searchString = text
}
anchors.bottomMargin: (pinnedMessages.visible ? pinnedMessages.height : 0) + (widgets.visible ? widgets.height : 0)
Nicolas Werner
committed
cursorShape: Qt.PointingHandCursor
}
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
onRoomIdChanged: {
searchString = "";
searchButton.searchActive = false;
searchField.text = "";
}
// HACK: https://bugreports.qt.io/browse/QTBUG-83972, qtwayland cannot auto hide menu
Connections {
function onHideMenu() {
roomOptionsMenu.close();
}
target: MainWindow
}
Shortcut {
sequence: StandardKey.Find
onActivated: searchButton.searchActive = !searchButton.searchActive
}
TapHandler {
gesturePolicy: TapHandler.ReleaseWithinBounds
onSingleTapped: {
if (eventPoint.position.y > topBar.height - (pinnedMessages.visible ? pinnedMessages.height : 0) - (widgets.visible ? widgets.height : 0)) {
eventPoint.accepted = true;
return;
}
if (showBackButton && eventPoint.position.x < Nheko.paddingMedium + backToRoomsButton.width) {
eventPoint.accepted = true;
return;
}
if (eventPoint.position.x > topBar.width - Nheko.paddingMedium - roomOptionsButton.width) {
eventPoint.accepted = true;
return;
}
if (communityLabel.visible && eventPoint.position.y < communityAvatar.height + Nheko.paddingMedium + Nheko.paddingSmall / 2) {
if (!Communities.trySwitchToSpace(room.parentSpace.roomid))
room.parentSpace.promptJoin();
eventPoint.accepted = true;
return;
}
if (room) {
let p = topBar.mapToItem(roomTopicC, eventPoint.position.x, eventPoint.position.y);
let link = roomTopicC.linkAt(p.x, p.y);
if (link) {
Nheko.openLink(link);
} else {
TimelineManager.openRoomSettings(room.roomId);
}
}
eventPoint.accepted = true;
}
}
HoverHandler {
grabPermissions: PointerHandler.TakeOverForbidden | PointerHandler.CanTakeOverFromAnything
}