diff options
author | Nicolas Werner <nicolas.werner@hotmail.de> | 2020-10-08 21:11:21 +0200 |
---|---|---|
committer | Nicolas Werner <nicolas.werner@hotmail.de> | 2020-10-08 21:11:21 +0200 |
commit | 1a029112d9e6168b123f6cdf4b49319ce4ea356d (patch) | |
tree | a4797860c06eeff4db1154132a084dccc9a963d9 /resources/qml/TimelineView.qml | |
parent | Merge pull request #270 from Chethan2k1/device-verification (diff) | |
download | nheko-1a029112d9e6168b123f6cdf4b49319ce4ea356d.tar.xz |
Lint qml with qml-format
Diffstat (limited to 'resources/qml/TimelineView.qml')
-rw-r--r-- | resources/qml/TimelineView.qml | 1074 |
1 files changed, 565 insertions, 509 deletions
diff --git a/resources/qml/TimelineView.qml b/resources/qml/TimelineView.qml index 5c9ca348..ab0148e9 100644 --- a/resources/qml/TimelineView.qml +++ b/resources/qml/TimelineView.qml @@ -1,526 +1,582 @@ +import "./delegates" +import "./device-verification" +import "./emoji" +import QtGraphicalEffects 1.0 import QtQuick 2.9 import QtQuick.Controls 2.3 import QtQuick.Layouts 1.2 -import QtGraphicalEffects 1.0 import QtQuick.Window 2.2 - import im.nheko 1.0 import im.nheko.EmojiModel 1.0 -import "./delegates" -import "./emoji" -import "./device-verification" - Page { - id: timelineRoot - - property var colors: currentActivePalette - property var systemInactive: SystemPalette { colorGroup: SystemPalette.Disabled } - property var inactiveColors: currentInactivePalette ? currentInactivePalette : systemInactive - property int avatarSize: 40 - property real highlightHue: colors.highlight.hslHue - property real highlightSat: colors.highlight.hslSaturation - property real highlightLight: colors.highlight.hslLightness - - palette: colors - - FontMetrics { - id: fontMetrics - } - - EmojiPicker { - id: emojiPopup - width: 7 * 52 + 20 - height: 6 * 52 - colors: palette - model: EmojiProxyModel { - category: EmojiCategory.People - sourceModel: EmojiModel {} - } - } - - Menu { - id: messageContextMenu - modal: true - - function show(eventId_, eventType_, isEncrypted_, showAt_, position) { - eventId = eventId_ - eventType = eventType_ - isEncrypted = isEncrypted_ - - if (position) - popup(position, showAt_) - else - popup(showAt_) - } - - property string eventId - property int eventType - property bool isEncrypted - - MenuItem { - text: qsTr("React") - onClicked: emojiPopup.show(messageContextMenu.parent, messageContextMenu.eventId) - } - MenuItem { - text: qsTr("Reply") - onClicked: chat.model.replyAction(messageContextMenu.eventId) - } - MenuItem { - text: qsTr("Read receipts") - onTriggered: chat.model.readReceiptsAction(messageContextMenu.eventId) - } - MenuItem { - text: qsTr("Mark as read") - } - MenuItem { - text: qsTr("View raw message") - onTriggered: chat.model.viewRawMessage(messageContextMenu.eventId) - } - MenuItem { - visible: messageContextMenu.isEncrypted - height: visible ? implicitHeight : 0 - text: qsTr("View decrypted raw message") - onTriggered: chat.model.viewDecryptedRawMessage(messageContextMenu.eventId) - } - MenuItem { - text: qsTr("Redact message") - onTriggered: chat.model.redactEvent(messageContextMenu.eventId) - } - MenuItem { - visible: messageContextMenu.eventType == MtxEvent.ImageMessage || messageContextMenu.eventType == MtxEvent.VideoMessage || messageContextMenu.eventType == MtxEvent.AudioMessage || messageContextMenu.eventType == MtxEvent.FileMessage || messageContextMenu.eventType == MtxEvent.Sticker - height: visible ? implicitHeight : 0 - text: qsTr("Save as") - onTriggered: TimelineManager.timeline.saveMedia(messageContextMenu.eventId) - } - } - - Rectangle { - anchors.fill: parent - color: colors.window - - Component { - id: deviceVerificationDialog - DeviceVerification {} - } - Connections { - target: TimelineManager - function onNewDeviceVerificationRequest(flow,transactionId,userId,deviceId,isRequest) { - var dialog = deviceVerificationDialog.createObject(timelineRoot, {flow: flow}); - dialog.show(); - } - } - Connections { - target: TimelineManager.timeline - function onOpenProfile(profile) { - var userProfile = userProfileComponent.createObject(timelineRoot,{profile: profile}); - userProfile.show(); - } - } - - Label { - visible: !TimelineManager.timeline && !TimelineManager.isInitialSync - anchors.centerIn: parent - text: qsTr("No room open") - font.pointSize: 24 - color: colors.text - } - - BusyIndicator { - visible: running - anchors.centerIn: parent - running: TimelineManager.isInitialSync - height: 200 - width: 200 - z: 3 - } - - ColumnLayout { - anchors.fill: parent - Rectangle { - id: topBar - - Layout.fillWidth: true - implicitHeight: topLayout.height + 16 - z: 3 - - color: colors.base - - MouseArea { - anchors.fill: parent - onClicked: TimelineManager.openRoomSettings(); - } - - GridLayout { - id: topLayout - - anchors.left: parent.left - anchors.right: parent.right - anchors.margins: 8 - anchors.verticalCenter: parent.verticalCenter - - //Layout.margins: 8 - - ImageButton { - id: backToRoomsButton - - Layout.column: 0 - Layout.row: 0 - Layout.rowSpan: 2 - Layout.alignment: Qt.AlignVCenter - - visible: TimelineManager.isNarrowView - - image: ":/icons/icons/ui/angle-pointing-to-left.png" - - ToolTip.visible: hovered - ToolTip.text: qsTr("Back to room list") - - onClicked: TimelineManager.backToRooms() - } - - Avatar { - Layout.column: 1 - Layout.row: 0 - Layout.rowSpan: 2 - Layout.alignment: Qt.AlignVCenter - - width: avatarSize - height: avatarSize - - url: chat.model ? chat.model.roomAvatarUrl.replace("mxc://", "image://MxcImage/") : "" - displayName: chat.model ? chat.model.roomName : qsTr("No room selected") - - MouseArea { - anchors.fill: parent - onClicked: TimelineManager.openRoomSettings(); - } - } - - Label { - Layout.fillWidth: true - Layout.column: 2 - Layout.row: 0 - color: colors.text - - font.pointSize: fontMetrics.font.pointSize * 1.1 - - text: chat.model ? chat.model.roomName : qsTr("No room selected") - - MouseArea { - anchors.fill: parent - onClicked: TimelineManager.openRoomSettings(); - } - } - MatrixText { - Layout.fillWidth: true - Layout.column: 2 - Layout.row: 1 - Layout.maximumHeight: fontMetrics.lineSpacing * 2 // show 2 lines - clip: true - - text: chat.model ? chat.model.roomTopic : "" - } - - ImageButton { - id: roomOptionsButton - - Layout.column: 3 - Layout.row: 0 - Layout.rowSpan: 2 - Layout.alignment: Qt.AlignVCenter - - image: ":/icons/icons/ui/vertical-ellipsis.png" - - ToolTip.visible: hovered - ToolTip.text: qsTr("Room options") - - onClicked: roomOptionsMenu.popup(roomOptionsButton) - - Menu { - id: roomOptionsMenu - MenuItem { - text: qsTr("Invite users") - onTriggered: TimelineManager.openInviteUsersDialog(); - } - MenuItem { - text: qsTr("Members") - onTriggered: TimelineManager.openMemberListDialog(); - } - MenuItem { - text: qsTr("Leave room") - onTriggered: TimelineManager.openLeaveRoomDialog(); - } - MenuItem { - text: qsTr("Settings") - onTriggered: TimelineManager.openRoomSettings(); - } - } - } - } - } - - ListView { - id: chat - - visible: TimelineManager.timeline != null - - cacheBuffer: 400 - - Layout.fillWidth: true - Layout.fillHeight: true - - model: TimelineManager.timeline - - boundsBehavior: Flickable.StopAtBounds - - ScrollHelper { - flickable: parent - anchors.fill: parent - } - - pixelAligned: true - - Shortcut { - sequence: StandardKey.MoveToPreviousPage - onActivated: { chat.contentY = chat.contentY - chat.height / 2; chat.returnToBounds(); } - } - Shortcut { - sequence: StandardKey.MoveToNextPage - onActivated: { chat.contentY = chat.contentY + chat.height / 2; chat.returnToBounds(); } - } - Shortcut { - sequence: StandardKey.Cancel - onActivated: chat.model.reply = undefined - } - Shortcut { - sequence: "Alt+Up" - onActivated: chat.model.reply = chat.model.indexToId(chat.model.reply? chat.model.idToIndex(chat.model.reply) + 1 : 0) - } - Shortcut { - sequence: "Alt+Down" - onActivated: { - var idx = chat.model.reply? chat.model.idToIndex(chat.model.reply) - 1 : -1 - chat.model.reply = idx >= 0 ? chat.model.indexToId(idx) : undefined - } - } - - ScrollBar.vertical: ScrollBar { - id: scrollbar - } - - spacing: 4 - verticalLayoutDirection: ListView.BottomToTop - - onCountChanged: if (atYEnd) model.currentIndex = 0 // Mark last event as read, since we are at the bottom - - property int delegateMaxWidth: (Settings.timelineMaxWidth > 100 && (parent.width - Settings.timelineMaxWidth) > scrollbar.width*2) ? Settings.timelineMaxWidth : (parent.width - scrollbar.width*2) - - delegate: Item { - // This would normally be previousSection, but our model's order is inverted. - property bool sectionBoundary: (ListView.nextSection != "" && ListView.nextSection !== ListView.section) || model.index === chat.count - 1 - - id: wrapper - property Item section - anchors.horizontalCenter: parent ? parent.horizontalCenter : undefined - width: chat.delegateMaxWidth - height: section ? section.height + timelinerow.height : timelinerow.height - - TimelineRow { - id: timelinerow - y: section ? section.y + section.height : 0 - } - - onSectionBoundaryChanged: { - if (sectionBoundary) { - var properties = { - 'modelData': model.dump, - 'section': ListView.section, - 'nextSection': ListView.nextSection - } - section = sectionHeader.createObject(wrapper, properties) - } else { - section.destroy() - section = null - } - } - - Connections { - target: chat - function onMovementEnded() { - if (y + height + 2 * chat.spacing > chat.contentY + chat.height && y < chat.contentY + chat.height) - chat.model.currentIndex = index; - } - } - } - - Component{ - id: userProfileComponent - UserProfile{} - } - - section { - property: "section" - } - Component { - id: sectionHeader - Column { - property var modelData - property string section - property string nextSection - - topPadding: 4 - bottomPadding: 4 - spacing: 8 - - visible: !!modelData - - width: parent.width - height: (section.includes(" ") ? dateBubble.height + 8 + userName.height : userName.height) + 8 - - Label { - id: dateBubble - anchors.horizontalCenter: parent ? parent.horizontalCenter : undefined - visible: section.includes(" ") - text: chat.model.formatDateSeparator(modelData.timestamp) - color: colors.text - - height: fontMetrics.height * 1.4 - width: contentWidth * 1.2 - - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - background: Rectangle { - radius: parent.height / 2 - color: colors.base - } - } - - Row { - height: userName.height - spacing: 8 - - Avatar { - width: avatarSize - height: avatarSize - url: chat.model.avatarUrl(modelData.userId).replace("mxc://", "image://MxcImage/") - displayName: modelData.userName - userid: modelData.userId - - MouseArea { - anchors.fill: parent - onClicked: chat.model.openUserProfile(modelData.userId) - cursorShape: Qt.PointingHandCursor - propagateComposedEvents: true - } - } - - Label { - id: userName - text: TimelineManager.escapeEmoji(modelData.userName) - color: TimelineManager.userColor(modelData.userId, colors.window) - textFormat: Text.RichText - - MouseArea { - anchors.fill: parent - Layout.alignment: Qt.AlignHCenter - onClicked: chat.model.openUserProfile(modelData.userId) - cursorShape: Qt.PointingHandCursor - propagateComposedEvents: true - } - } - } - } - } - - footer: BusyIndicator { - anchors.horizontalCenter: parent.horizontalCenter - running: chat.model && chat.model.paginationInProgress - height: 50 - width: 50 - z: 3 - } - } - - Item { - id: chatFooter - - implicitHeight: Math.max(fontMetrics.height * 1.2, footerContent.height) - Layout.fillWidth: true - z: 3 - - Column { - id: footerContent - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - Rectangle { - id: typingRect + id: timelineRoot + + property var colors: currentActivePalette + property var systemInactive + property var inactiveColors: currentInactivePalette ? currentInactivePalette : systemInactive + property int avatarSize: 40 + property real highlightHue: colors.highlight.hslHue + property real highlightSat: colors.highlight.hslSaturation + property real highlightLight: colors.highlight.hslLightness + + palette: colors + + FontMetrics { + id: fontMetrics + } + + EmojiPicker { + id: emojiPopup + + width: 7 * 52 + 20 + height: 6 * 52 + colors: palette + + model: EmojiProxyModel { + category: EmojiCategory.People + + sourceModel: EmojiModel { + } + + } + + } + + Menu { + id: messageContextMenu + + property string eventId + property int eventType + property bool isEncrypted + + function show(eventId_, eventType_, isEncrypted_, showAt_, position) { + eventId = eventId_; + eventType = eventType_; + isEncrypted = isEncrypted_; + if (position) + popup(position, showAt_); + else + popup(showAt_); + } + + modal: true + + MenuItem { + text: qsTr("React") + onClicked: emojiPopup.show(messageContextMenu.parent, messageContextMenu.eventId) + } + + MenuItem { + text: qsTr("Reply") + onClicked: chat.model.replyAction(messageContextMenu.eventId) + } + + MenuItem { + text: qsTr("Read receipts") + onTriggered: chat.model.readReceiptsAction(messageContextMenu.eventId) + } + + MenuItem { + text: qsTr("Mark as read") + } + + MenuItem { + text: qsTr("View raw message") + onTriggered: chat.model.viewRawMessage(messageContextMenu.eventId) + } + + MenuItem { + visible: messageContextMenu.isEncrypted + height: visible ? implicitHeight : 0 + text: qsTr("View decrypted raw message") + onTriggered: chat.model.viewDecryptedRawMessage(messageContextMenu.eventId) + } + + MenuItem { + text: qsTr("Redact message") + onTriggered: chat.model.redactEvent(messageContextMenu.eventId) + } + + MenuItem { + visible: messageContextMenu.eventType == MtxEvent.ImageMessage || messageContextMenu.eventType == MtxEvent.VideoMessage || messageContextMenu.eventType == MtxEvent.AudioMessage || messageContextMenu.eventType == MtxEvent.FileMessage || messageContextMenu.eventType == MtxEvent.Sticker + height: visible ? implicitHeight : 0 + text: qsTr("Save as") + onTriggered: TimelineManager.timeline.saveMedia(messageContextMenu.eventId) + } + + } + + Rectangle { + anchors.fill: parent + color: colors.window + + Component { + id: deviceVerificationDialog + + DeviceVerification { + } + + } + + Connections { + function onNewDeviceVerificationRequest(flow, transactionId, userId, deviceId, isRequest) { + var dialog = deviceVerificationDialog.createObject(timelineRoot, { + "flow": flow + }); + dialog.show(); + } + + target: TimelineManager + } + + Connections { + function onOpenProfile(profile) { + var userProfile = userProfileComponent.createObject(timelineRoot, { + "profile": profile + }); + userProfile.show(); + } + + target: TimelineManager.timeline + } + + Label { + visible: !TimelineManager.timeline && !TimelineManager.isInitialSync + anchors.centerIn: parent + text: qsTr("No room open") + font.pointSize: 24 + color: colors.text + } + + BusyIndicator { + visible: running + anchors.centerIn: parent + running: TimelineManager.isInitialSync + height: 200 + width: 200 + z: 3 + } + + ColumnLayout { + anchors.fill: parent + + Rectangle { + id: topBar + + Layout.fillWidth: true + implicitHeight: topLayout.height + 16 + z: 3 + color: colors.base + + MouseArea { + anchors.fill: parent + onClicked: TimelineManager.openRoomSettings() + } + + GridLayout { + //Layout.margins: 8 + + id: topLayout + anchors.left: parent.left anchors.right: parent.right - color: (chat.model && chat.model.typingUsers.length > 0) ? colors.window : "transparent" - height: typingDisplay.height + anchors.margins: 8 + anchors.verticalCenter: parent.verticalCenter + + ImageButton { + id: backToRoomsButton + + Layout.column: 0 + Layout.row: 0 + Layout.rowSpan: 2 + Layout.alignment: Qt.AlignVCenter + visible: TimelineManager.isNarrowView + image: ":/icons/icons/ui/angle-pointing-to-left.png" + ToolTip.visible: hovered + ToolTip.text: qsTr("Back to room list") + onClicked: TimelineManager.backToRooms() + } + + Avatar { + Layout.column: 1 + Layout.row: 0 + Layout.rowSpan: 2 + Layout.alignment: Qt.AlignVCenter + width: avatarSize + height: avatarSize + url: chat.model ? chat.model.roomAvatarUrl.replace("mxc://", "image://MxcImage/") : "" + displayName: chat.model ? chat.model.roomName : qsTr("No room selected") + + MouseArea { + anchors.fill: parent + onClicked: TimelineManager.openRoomSettings() + } + + } + Label { - id: typingDisplay + Layout.fillWidth: true + Layout.column: 2 + Layout.row: 0 + color: colors.text + font.pointSize: fontMetrics.font.pointSize * 1.1 + text: chat.model ? chat.model.roomName : qsTr("No room selected") + + MouseArea { + anchors.fill: parent + onClicked: TimelineManager.openRoomSettings() + } + + } + + MatrixText { + Layout.fillWidth: true + Layout.column: 2 + Layout.row: 1 + Layout.maximumHeight: fontMetrics.lineSpacing * 2 // show 2 lines + clip: true + text: chat.model ? chat.model.roomTopic : "" + } + + ImageButton { + id: roomOptionsButton + + Layout.column: 3 + Layout.row: 0 + Layout.rowSpan: 2 + Layout.alignment: Qt.AlignVCenter + image: ":/icons/icons/ui/vertical-ellipsis.png" + ToolTip.visible: hovered + ToolTip.text: qsTr("Room options") + onClicked: roomOptionsMenu.popup(roomOptionsButton) + + Menu { + id: roomOptionsMenu + + MenuItem { + text: qsTr("Invite users") + onTriggered: TimelineManager.openInviteUsersDialog() + } + + MenuItem { + text: qsTr("Members") + onTriggered: TimelineManager.openMemberListDialog() + } + + MenuItem { + text: qsTr("Leave room") + onTriggered: TimelineManager.openLeaveRoomDialog() + } + + MenuItem { + text: qsTr("Settings") + onTriggered: TimelineManager.openRoomSettings() + } + + } + + } + + } + + } + + ListView { + id: chat + + property int delegateMaxWidth: (Settings.timelineMaxWidth > 100 && (parent.width - Settings.timelineMaxWidth) > scrollbar.width * 2) ? Settings.timelineMaxWidth : (parent.width - scrollbar.width * 2) + + visible: TimelineManager.timeline != null + cacheBuffer: 400 + Layout.fillWidth: true + Layout.fillHeight: true + model: TimelineManager.timeline + boundsBehavior: Flickable.StopAtBounds + pixelAligned: true + spacing: 4 + verticalLayoutDirection: ListView.BottomToTop + onCountChanged: { + if (atYEnd) + model.currentIndex = 0; + + } // Mark last event as read, since we are at the bottom + + ScrollHelper { + flickable: parent + anchors.fill: parent + } + + Shortcut { + sequence: StandardKey.MoveToPreviousPage + onActivated: { + chat.contentY = chat.contentY - chat.height / 2; + chat.returnToBounds(); + } + } + + Shortcut { + sequence: StandardKey.MoveToNextPage + onActivated: { + chat.contentY = chat.contentY + chat.height / 2; + chat.returnToBounds(); + } + } + + Shortcut { + sequence: StandardKey.Cancel + onActivated: chat.model.reply = undefined + } + + Shortcut { + sequence: "Alt+Up" + onActivated: chat.model.reply = chat.model.indexToId(chat.model.reply ? chat.model.idToIndex(chat.model.reply) + 1 : 0) + } + + Shortcut { + sequence: "Alt+Down" + onActivated: { + var idx = chat.model.reply ? chat.model.idToIndex(chat.model.reply) - 1 : -1; + chat.model.reply = idx >= 0 ? chat.model.indexToId(idx) : undefined; + } + } + + Component { + id: userProfileComponent + + UserProfile { + } + + } + + section { + property: "section" + } + + Component { + id: sectionHeader + + Column { + property var modelData + property string section + property string nextSection + + topPadding: 4 + bottomPadding: 4 + spacing: 8 + visible: !!modelData + width: parent.width + height: (section.includes(" ") ? dateBubble.height + 8 + userName.height : userName.height) + 8 + + Label { + id: dateBubble + + anchors.horizontalCenter: parent ? parent.horizontalCenter : undefined + visible: section.includes(" ") + text: chat.model.formatDateSeparator(modelData.timestamp) + color: colors.text + height: fontMetrics.height * 1.4 + width: contentWidth * 1.2 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + + background: Rectangle { + radius: parent.height / 2 + color: colors.base + } + + } + + Row { + height: userName.height + spacing: 8 + + Avatar { + width: avatarSize + height: avatarSize + url: chat.model.avatarUrl(modelData.userId).replace("mxc://", "image://MxcImage/") + displayName: modelData.userName + userid: modelData.userId + + MouseArea { + anchors.fill: parent + onClicked: chat.model.openUserProfile(modelData.userId) + cursorShape: Qt.PointingHandCursor + propagateComposedEvents: true + } + + } + + Label { + id: userName + + text: TimelineManager.escapeEmoji(modelData.userName) + color: TimelineManager.userColor(modelData.userId, colors.window) + textFormat: Text.RichText + + MouseArea { + anchors.fill: parent + Layout.alignment: Qt.AlignHCenter + onClicked: chat.model.openUserProfile(modelData.userId) + cursorShape: Qt.PointingHandCursor + propagateComposedEvents: true + } + + } + + } + + } + + } + + ScrollBar.vertical: ScrollBar { + id: scrollbar + } + + delegate: Item { + id: wrapper + + // This would normally be previousSection, but our model's order is inverted. + property bool sectionBoundary: (ListView.nextSection != "" && ListView.nextSection !== ListView.section) || model.index === chat.count - 1 + property Item section + + anchors.horizontalCenter: parent ? parent.horizontalCenter : undefined + width: chat.delegateMaxWidth + height: section ? section.height + timelinerow.height : timelinerow.height + onSectionBoundaryChanged: { + if (sectionBoundary) { + var properties = { + "modelData": model.dump, + "section": ListView.section, + "nextSection": ListView.nextSection + }; + section = sectionHeader.createObject(wrapper, properties); + } else { + section.destroy(); + section = null; + } + } + + TimelineRow { + id: timelinerow + + y: section ? section.y + section.height : 0 + } + + Connections { + function onMovementEnded() { + if (y + height + 2 * chat.spacing > chat.contentY + chat.height && y < chat.contentY + chat.height) + chat.model.currentIndex = index; + + } + + target: chat + } + + } + + footer: BusyIndicator { + anchors.horizontalCenter: parent.horizontalCenter + running: chat.model && chat.model.paginationInProgress + height: 50 + width: 50 + z: 3 + } + + } + + Item { + id: chatFooter + + implicitHeight: Math.max(fontMetrics.height * 1.2, footerContent.height) + Layout.fillWidth: true + z: 3 + + Column { + id: footerContent + + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + + Rectangle { + id: typingRect + anchors.left: parent.left - anchors.leftMargin: 10 anchors.right: parent.right - anchors.rightMargin: 10 - color: colors.text - text: chat.model ? chat.model.formatTypingUsers(chat.model.typingUsers, colors.window) : "" - textFormat: Text.RichText + color: (chat.model && chat.model.typingUsers.length > 0) ? colors.window : "transparent" + height: typingDisplay.height + + Label { + id: typingDisplay + + anchors.left: parent.left + anchors.leftMargin: 10 + anchors.right: parent.right + anchors.rightMargin: 10 + color: colors.text + text: chat.model ? chat.model.formatTypingUsers(chat.model.typingUsers, colors.window) : "" + textFormat: Text.RichText + } + + } + + Rectangle { + id: replyPopup + + anchors.left: parent.left + anchors.right: parent.right + visible: chat.model && chat.model.reply + // Height of child, plus margins, plus border + height: replyPreview.height + 10 + color: colors.base + + Reply { + id: replyPreview + + anchors.left: parent.left + anchors.leftMargin: 10 + anchors.right: closeReplyButton.left + anchors.rightMargin: 20 + anchors.bottom: parent.bottom + modelData: chat.model ? chat.model.getDump(chat.model.reply, chat.model.id) : { + } + userColor: TimelineManager.userColor(modelData.userId, colors.window) + } + + ImageButton { + id: closeReplyButton + + anchors.right: parent.right + anchors.rightMargin: 15 + anchors.top: replyPreview.top + hoverEnabled: true + width: 16 + height: 16 + image: ":/icons/icons/ui/remove-symbol.png" + ToolTip.visible: closeReplyButton.hovered + ToolTip.text: qsTr("Close") + onClicked: chat.model.reply = undefined + } + } + } - Rectangle { - anchors.left: parent.left - anchors.right: parent.right - - id: replyPopup - - visible: chat.model && chat.model.reply - // Height of child, plus margins, plus border - height: replyPreview.height + 10 - color: colors.base - - - Reply { - id: replyPreview - - anchors.left: parent.left - anchors.leftMargin: 10 - anchors.right: closeReplyButton.left - anchors.rightMargin: 20 - anchors.bottom: parent.bottom - - modelData: chat.model ? chat.model.getDump(chat.model.reply, chat.model.id) : {} - userColor: TimelineManager.userColor(modelData.userId, colors.window) - } - - ImageButton { - id: closeReplyButton - - anchors.right: parent.right - anchors.rightMargin: 15 - anchors.top: replyPreview.top - hoverEnabled: true - width: 16 - height: 16 - - image: ":/icons/icons/ui/remove-symbol.png" - ToolTip.visible: closeReplyButton.hovered - ToolTip.text: qsTr("Close") - - onClicked: chat.model.reply = undefined - } - } - } - } - - ActiveCallBar { - Layout.fillWidth: true - z: 3 - } - } - } + } + + ActiveCallBar { + Layout.fillWidth: true + z: 3 + } + + } + + } + + systemInactive: SystemPalette { + colorGroup: SystemPalette.Disabled + } + } |