diff options
Diffstat (limited to 'resources/qml/TopBar.qml')
-rw-r--r-- | resources/qml/TopBar.qml | 382 |
1 files changed, 175 insertions, 207 deletions
diff --git a/resources/qml/TopBar.qml b/resources/qml/TopBar.qml index a54c5ed7..3f2d8d2a 100644 --- a/resources/qml/TopBar.qml +++ b/resources/qml/TopBar.qml @@ -8,212 +8,142 @@ import QtQuick.Controls 2.15 import QtQuick.Layouts 1.2 import QtQuick.Window 2.15 import im.nheko 1.0 - import "./delegates" Pane { id: topBar - property bool showBackButton: false - property string roomName: room ? room.roomName : qsTr("No room selected") - property string roomId: room ? room.roomId : "" property string avatarUrl: room ? room.roomAvatarUrl : "" - property string roomTopic: room ? room.roomTopic : "" - property bool isEncrypted: room ? room.isEncrypted : false - property int trustlevel: room ? room.trustlevel : Crypto.Unverified - property bool isDirect: room ? room.isDirect : false 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 string searchString: "" - - // HACK: https://bugreports.qt.io/browse/QTBUG-83972, qtwayland cannot auto hide menu - Connections { - function onHideMenu() { - roomOptionsMenu.close() - } - target: MainWindow - } - - onRoomIdChanged: { - searchString = ""; - searchButton.searchActive = false; - searchField.text = "" - } - - Shortcut { - sequence: StandardKey.Find - onActivated: searchButton.searchActive = !searchButton.searchActive - } + property bool showBackButton: false + property int trustlevel: room ? room.trustlevel : Crypto.Unverified Layout.fillWidth: true implicitHeight: topLayout.height + Nheko.paddingMedium * 2 + padding: 0 z: 3 - padding: 0 background: Rectangle { color: palette.window } - - TapHandler { - 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; - } - gesturePolicy: TapHandler.ReleaseWithinBounds - } - - HoverHandler { - grabPermissions: PointerHandler.TakeOverForbidden | PointerHandler.CanTakeOverFromAnything - } - contentItem: Item { GridLayout { id: topLayout anchors.left: parent.left - anchors.right: parent.right anchors.margins: Nheko.paddingMedium + anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter columnSpacing: Nheko.paddingSmall rowSpacing: Nheko.paddingSmall - Avatar { id: communityAvatar - visible: roomid && room.parentSpace.isLoaded && ("space:"+room.parentSpace.roomid != Communities.currentTagId) - 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.alignment: Qt.AlignRight Layout.column: 1 Layout.row: 0 - Layout.alignment: Qt.AlignRight - width: fontMetrics.lineSpacing - height: fontMetrics.lineSpacing - url: avatarUrl.replace("mxc://", "image://MxcImage/") - roomid: communityId 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 - visible: communityAvatar.visible Layout.column: 2 - Layout.row: 0 Layout.fillWidth: true + Layout.row: 0 color: palette.text - text: qsTr("In %1").arg(communityAvatar.displayName) - maximumLineCount: 1 elide: Text.ElideRight + maximumLineCount: 1 + text: qsTr("In %1").arg(communityAvatar.displayName) textFormat: Text.RichText + visible: communityAvatar.visible } - ImageButton { id: backToRoomsButton - Layout.column: 0 - Layout.row: 1 - Layout.rowSpan: 2 Layout.alignment: Qt.AlignVCenter + Layout.column: 0 Layout.preferredHeight: Nheko.avatarSize - Nheko.paddingMedium Layout.preferredWidth: Nheko.avatarSize - Nheko.paddingMedium - visible: showBackButton - image: ":/icons/icons/ui/angle-arrow-left.svg" - ToolTip.visible: hovered + Layout.row: 1 + Layout.rowSpan: 2 ToolTip.text: qsTr("Back to room list") + ToolTip.visible: hovered + image: ":/icons/icons/ui/angle-arrow-left.svg" + visible: showBackButton + onClicked: Rooms.resetCurrentRoom() } - Avatar { + Layout.alignment: Qt.AlignVCenter Layout.column: 1 Layout.row: 1 Layout.rowSpan: 2 - Layout.alignment: Qt.AlignVCenter - width: Nheko.avatarSize + displayName: roomName + enabled: false height: Nheko.avatarSize - url: avatarUrl.replace("mxc://", "image://MxcImage/") roomid: roomId + url: avatarUrl.replace("mxc://", "image://MxcImage/") userid: isDirect ? directChatOtherUserId : "" - displayName: roomName - enabled: false + width: Nheko.avatarSize } - Label { - Layout.fillWidth: true Layout.column: 2 + Layout.fillWidth: true Layout.row: 1 color: palette.text - font.pointSize: fontMetrics.font.pointSize * 1.1 + elide: Text.ElideRight font.bold: true - text: roomName + font.pointSize: fontMetrics.font.pointSize * 1.1 maximumLineCount: 1 - elide: Text.ElideRight + text: roomName textFormat: Text.RichText } - MatrixText { id: roomTopicC - Layout.fillWidth: true + Layout.column: 2 - Layout.row: 2 + Layout.fillWidth: true Layout.maximumHeight: fontMetrics.lineSpacing * 2 // show 2 lines - selectByMouse: false - enabled: false + Layout.row: 2 clip: true + enabled: false + selectByMouse: false text: roomTopic } - ImageButton { id: pinButton property bool pinsShown: !Settings.hiddenPins.includes(roomId) - visible: !!room && room.pinnedMessages.length > 0 - Layout.column: 3 - Layout.row: 1 - Layout.rowSpan: 2 Layout.alignment: Qt.AlignVCenter + Layout.column: 3 Layout.preferredHeight: Nheko.avatarSize - Nheko.paddingMedium Layout.preferredWidth: Nheko.avatarSize - Nheko.paddingMedium - image: pinsShown ? ":/icons/icons/ui/pin.svg" : ":/icons/icons/ui/pin-off.svg" - ToolTip.visible: hovered + Layout.row: 1 + Layout.rowSpan: 2 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) { @@ -226,242 +156,280 @@ Pane { } Settings.hiddenPins = ps; } - } - AbstractButton { Layout.column: 4 - Layout.row: 1 - Layout.rowSpan: 2 Layout.preferredHeight: Nheko.avatarSize - Nheko.paddingMedium Layout.preferredWidth: Nheko.avatarSize - Nheko.paddingMedium + Layout.row: 1 + Layout.rowSpan: 2 + background: null contentItem: EncryptionIndicator { - encrypted: isEncrypted - trust: trustlevel - enabled: false - unencryptedIcon: ":/icons/icons/ui/people.svg" - unencryptedColor: palette.buttonText - unencryptedHoverColor: palette.highlight - hovered: parent.hovered - ToolTip.delay: Nheko.tooltipDelay ToolTip.text: { if (!isEncrypted) - return qsTr("Show room members."); - + return qsTr("Show room members."); switch (trustlevel) { - case Crypto.Verified: + case Crypto.Verified: return qsTr("This room contains only verified devices."); - case Crypto.TOFU: + case Crypto.TOFU: return qsTr("This room contains verified devices and devices which have never changed their master key."); - default: + default: return qsTr("This room contains unverified devices!"); } } + enabled: false + encrypted: isEncrypted + hovered: parent.hovered + trust: trustlevel + unencryptedColor: palette.buttonText + unencryptedHoverColor: palette.highlight + unencryptedIcon: ":/icons/icons/ui/people.svg" } - background: null onClicked: TimelineManager.openRoomMembers(room) } - ImageButton { id: searchButton property bool searchActive: false - visible: !!room - Layout.column: 5 - Layout.row: 1 - Layout.rowSpan: 2 Layout.alignment: Qt.AlignVCenter + Layout.column: 5 Layout.preferredHeight: Nheko.avatarSize - Nheko.paddingMedium Layout.preferredWidth: Nheko.avatarSize - Nheko.paddingMedium - image: ":/icons/icons/ui/search.svg" - ToolTip.visible: hovered + Layout.row: 1 + Layout.rowSpan: 2 ToolTip.text: qsTr("Search this room") - onClicked: searchActive = !searchActive + ToolTip.visible: hovered + image: ":/icons/icons/ui/search.svg" + visible: !!room + onClicked: searchActive = !searchActive onSearchActiveChanged: { if (searchActive) { searchField.forceActiveFocus(); - } - else { + } else { searchField.clear(); topBar.searchString = ""; } } } - ImageButton { id: roomOptionsButton - visible: !!room - Layout.column: 6 - Layout.row: 1 - Layout.rowSpan: 2 Layout.alignment: Qt.AlignVCenter + Layout.column: 6 Layout.preferredHeight: Nheko.avatarSize - Nheko.paddingMedium Layout.preferredWidth: Nheko.avatarSize - Nheko.paddingMedium - image: ":/icons/icons/ui/options.svg" - ToolTip.visible: hovered + Layout.row: 1 + Layout.rowSpan: 2 ToolTip.text: qsTr("Room options") + ToolTip.visible: hovered + image: ":/icons/icons/ui/options.svg" + visible: !!room + onClicked: roomOptionsMenu.open(roomOptionsButton) Platform.Menu { id: roomOptionsMenu Platform.MenuItem { - visible: room ? room.permissions.canInvite() : false text: qsTr("Invite users") + visible: room ? room.permissions.canInvite() : false + onTriggered: TimelineManager.openInviteUsers(roomId) } - Platform.MenuItem { text: qsTr("Members") + onTriggered: TimelineManager.openRoomMembers(room) } - Platform.MenuItem { text: qsTr("Leave room") + onTriggered: TimelineManager.openLeaveRoomDialog(roomId) } - Platform.MenuItem { text: qsTr("Settings") + onTriggered: TimelineManager.openRoomSettings(roomId) } - } - } - ScrollView { id: pinnedMessages - Layout.row: 3 Layout.column: 2 Layout.columnSpan: 4 - Layout.fillWidth: true Layout.preferredHeight: Math.min(contentHeight, Nheko.avatarSize * 4) - - visible: !!room && room.pinnedMessages.length > 0 && !Settings.hiddenPins.includes(roomId) - clip: true - + Layout.row: 3 ScrollBar.horizontal.visible: false + clip: true + visible: !!room && room.pinnedMessages.length > 0 && !Settings.hiddenPins.includes(roomId) ListView { - - spacing: Nheko.paddingSmall model: room ? room.pinnedMessages : undefined + spacing: Nheko.paddingSmall + delegate: RowLayout { required property string modelData - width: ListView.view.width height: implicitHeight + width: ListView.view.width Reply { id: reply + property var e: room ? room.getDump(modelData, "pins") : {} - Connections { - function onPinnedMessagesChanged() { reply.e = room.getDump(modelData, "pins") } - target: room - } + Layout.fillWidth: true Layout.preferredHeight: height - - userColor: TimelineManager.userColor(e.userId, palette.window) blurhash: e.blurhash ?? "" body: e.body ?? "" - formattedBody: e.formattedBody ?? "" + encryptionError: e.encryptionError ?? 0 eventId: e.eventId ?? "" filename: e.filename ?? "" filesize: e.filesize ?? "" + formattedBody: e.formattedBody ?? "" + isOnlyEmoji: e.isOnlyEmoji ?? false + keepFullText: true + originalWidth: e.originalWidth ?? 0 proportionalHeight: e.proportionalHeight ?? 1 type: e.type ?? MtxEvent.UnknownMessage typeString: e.typeString ?? "" url: e.url ?? "" - originalWidth: e.originalWidth ?? 0 - isOnlyEmoji: e.isOnlyEmoji ?? false + userColor: TimelineManager.userColor(e.userId, palette.window) userId: e.userId ?? "" userName: e.userName ?? "" - encryptionError: e.encryptionError ?? 0 - keepFullText: true - } + Connections { + function onPinnedMessagesChanged() { + reply.e = room.getDump(modelData, "pins"); + } + + target: room + } + } ImageButton { id: deletePinButton + Layout.alignment: Qt.AlignTop | Qt.AlignLeft Layout.preferredHeight: 16 Layout.preferredWidth: 16 - Layout.alignment: Qt.AlignTop | Qt.AlignLeft - visible: room.permissions.canChange(MtxEvent.PinnedEvents) - + ToolTip.text: qsTr("Unpin") + ToolTip.visible: hovered hoverEnabled: true image: ":/icons/icons/ui/dismiss.svg" - ToolTip.visible: hovered - ToolTip.text: qsTr("Unpin") + visible: room.permissions.canChange(MtxEvent.PinnedEvents) onClicked: room.unpin(modelData) } } - - } } - ScrollView { id: widgets - Layout.row: 4 Layout.column: 2 Layout.columnSpan: 4 - Layout.fillWidth: true Layout.preferredHeight: Math.min(contentHeight, Nheko.avatarSize * 1.5) - - visible: !!room && room.widgetLinks.length > 0 && !Settings.hiddenWidgets.includes(roomId) - clip: true - + Layout.row: 4 ScrollBar.horizontal.visible: false + clip: true + visible: !!room && room.widgetLinks.length > 0 && !Settings.hiddenWidgets.includes(roomId) ListView { - - spacing: Nheko.paddingSmall model: room ? room.widgetLinks : undefined + spacing: Nheko.paddingSmall + delegate: MatrixText { required property var modelData color: palette.text text: modelData } - - } } - MatrixTextField { id: searchField - visible: searchButton.searchActive - enabled: visible - hasClear: true - Layout.row: 5 Layout.column: 2 Layout.columnSpan: 4 - Layout.fillWidth: true - + Layout.row: 5 + enabled: visible + hasClear: true placeholderText: qsTr("Enter search query") + visible: searchButton.searchActive + onAccepted: topBar.searchString = text } } - CursorShape { - anchors.fill: parent anchors.bottomMargin: (pinnedMessages.visible ? pinnedMessages.height : 0) + (widgets.visible ? widgets.height : 0) + anchors.fill: parent cursorShape: Qt.PointingHandCursor } } + + 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 + } } |