From 460997bca3392f799f306f2b5684d95fac65abe3 Mon Sep 17 00:00:00 2001 From: James Graham Date: Fri, 11 Nov 2022 17:05:14 +0000 Subject: [PATCH] Refactor Timeline Container Update the base item in the timeline container to be a column layout. This means that all the items can be laid out automatically without the need to set lots of manual settings and anchoring. The overall height calculation for the delegate is vastly simplified (in fact it is removed) which deals with the fact that there were still instances where the manual calculation didn't work e.g. a delegate with a reaction followed by another message from the same user didn't give the correct bottom margin (see below) before: ![timelineContainer_height_bug](/uploads/5b14568294698198dee8412f6cd19be0/timelineContainer_height_bug.png) after: ![timelineContainer_height_bug_fix](/uploads/c5828f1b793817fd0ed523c3580a2ecc/timelineContainer_height_bug_fix.png) This also improves upon the recently changed hover highlight behaviour. The previous patched moved it to cover the avatar as well as the bubble however it also covered the section and reaction when present which didn't look good. The highlight now only covers the avatar and bubble before: ![highlight_bug](/uploads/0d08dc769ff737e0fb4981243d02d5f3/highlight_bug.png) after: ![highlight_bug_fixed](/uploads/536ed672d0f1bb6cbe6c45777fed4b53/highlight_bug_fixed.png) This also cleans up some of the margins in both bubble and compact to ensure consistency. --- src/qml/Component/Timeline/AudioDelegate.qml | 4 +- src/qml/Component/Timeline/FileDelegate.qml | 3 - src/qml/Component/Timeline/ImageDelegate.qml | 3 - .../Component/Timeline/MessageDelegate.qml | 4 - .../Component/Timeline/ReactionDelegate.qml | 4 +- .../Component/Timeline/TimelineContainer.qml | 443 +++++++++--------- src/qml/Component/Timeline/VideoDelegate.qml | 3 - src/qml/Page/RoomPage.qml | 3 +- 8 files changed, 221 insertions(+), 246 deletions(-) diff --git a/src/qml/Component/Timeline/AudioDelegate.qml b/src/qml/Component/Timeline/AudioDelegate.qml index 89dfca9a4..bbbc05e64 100644 --- a/src/qml/Component/Timeline/AudioDelegate.qml +++ b/src/qml/Component/Timeline/AudioDelegate.qml @@ -13,15 +13,13 @@ import org.kde.neochat 1.0 TimelineContainer { id: audioDelegate - onReplyClicked: ListView.view.goToEvent(eventID) - onOpenContextMenu: openFileContext(model, audioDelegate) readonly property bool downloaded: model.progressInfo && model.progressInfo.completed onDownloadedChanged: audio.play() - hoverComponent: hoverActions innerObject: ColumnLayout { + Layout.fillWidth: true Layout.maximumWidth: audioDelegate.contentMaxWidth Audio { diff --git a/src/qml/Component/Timeline/FileDelegate.qml b/src/qml/Component/Timeline/FileDelegate.qml index 76452103c..b62f1022d 100644 --- a/src/qml/Component/Timeline/FileDelegate.qml +++ b/src/qml/Component/Timeline/FileDelegate.qml @@ -13,9 +13,6 @@ import org.kde.neochat 1.0 TimelineContainer { id: fileDelegate - onReplyClicked: ListView.view.goToEvent(eventID) - hoverComponent: hoverActions - onOpenContextMenu: openFileContext(model, fileDelegate) readonly property bool downloaded: progressInfo && progressInfo.completed diff --git a/src/qml/Component/Timeline/ImageDelegate.qml b/src/qml/Component/Timeline/ImageDelegate.qml index 3b3850bcd..ecd186f30 100644 --- a/src/qml/Component/Timeline/ImageDelegate.qml +++ b/src/qml/Component/Timeline/ImageDelegate.qml @@ -13,9 +13,6 @@ import org.kde.neochat 1.0 TimelineContainer { id: imageDelegate - onReplyClicked: ListView.view.goToEvent(eventID) - hoverComponent: hoverActions - onOpenContextMenu: openFileContext(model, imageDelegate) property var content: model.content diff --git a/src/qml/Component/Timeline/MessageDelegate.qml b/src/qml/Component/Timeline/MessageDelegate.qml index 555eb9a99..9e2e7e986 100644 --- a/src/qml/Component/Timeline/MessageDelegate.qml +++ b/src/qml/Component/Timeline/MessageDelegate.qml @@ -16,9 +16,6 @@ TimelineContainer { property bool isEmote: false onOpenContextMenu: openMessageContext(model, label.selectedText, Controller.plainText(label.textDocument)) - onReplyClicked: ListView.view.goToEvent(eventID) - hoverComponent: hoverActions - innerObject: ColumnLayout { Layout.maximumWidth: messageDelegate.contentMaxWidth RichLabel { @@ -29,7 +26,6 @@ TimelineContainer { Loader { id: linkPreviewLoader Layout.fillWidth: true - height: active ? item.implicitHeight : 0 active: !currentRoom.usesEncryption && model.display && model.display.includes("http") visible: Config.showLinkPreview && active sourceComponent: LinkPreviewDelegate { diff --git a/src/qml/Component/Timeline/ReactionDelegate.qml b/src/qml/Component/Timeline/ReactionDelegate.qml index ffcf92b49..92ac37c84 100644 --- a/src/qml/Component/Timeline/ReactionDelegate.qml +++ b/src/qml/Component/Timeline/ReactionDelegate.qml @@ -9,7 +9,8 @@ import QtQuick.Layouts 1.15 import org.kde.kirigami 2.15 as Kirigami Flow { - spacing: Kirigami.Units.largeSpacing + spacing: Kirigami.Units.smallSpacing + Repeater { model: reaction ?? null @@ -32,7 +33,6 @@ Flow { border.width: 1 } - checkable: true checked: modelData.hasLocalUser diff --git a/src/qml/Component/Timeline/TimelineContainer.qml b/src/qml/Component/Timeline/TimelineContainer.qml index 93d013494..799b5e765 100644 --- a/src/qml/Component/Timeline/TimelineContainer.qml +++ b/src/qml/Component/Timeline/TimelineContainer.qml @@ -9,15 +9,21 @@ import org.kde.kirigami 2.15 as Kirigami import org.kde.neochat 1.0 -QQC2.ItemDelegate { - id: timelineContainer +ColumnLayout { + id: root + + signal openContextMenu + signal openExternally() + signal replyClicked(string eventID) + + onReplyClicked: ListView.view.goToEvent(eventID) + default property alias innerObject : column.children - // readonly property bool failed: marks == EventStatus.SendingFailed - - readonly property bool sectionVisible: model.showSection + property Item hoverComponent: hoverActions property bool isEmote: false property bool cardBackground: true + property bool showUserMessageOnRight: Config.showLocalMessagesOnRight && model.author.isLocalUser && !Config.compactLayout property bool isHighlighted: model.isHighlighted || isTemporaryHighlighted property bool isTemporaryHighlighted: false @@ -30,58 +36,15 @@ QQC2.ItemDelegate { onTriggered: isTemporaryHighlighted = false } - signal openContextMenu - // The bubble and delegate widths are allowed to grow once the ListView gets beyond a certain size // extraWidth defines this as the excess after a certain ListView width, capped to a max value readonly property int extraWidth: messageListView.width >= Kirigami.Units.gridUnit * 46 ? Math.min((messageListView.width - Kirigami.Units.gridUnit * 46), Kirigami.Units.gridUnit * 20) : 0 readonly property int bubbleMaxWidth: Kirigami.Units.gridUnit * 20 + extraWidth * 0.5 - readonly property int delegateMaxWidth: Config.compactLayout ? messageListView.width : Math.min(messageListView.width, Kirigami.Units.gridUnit * 40 + extraWidth) + readonly property int delegateWidth: Config.compactLayout ? messageListView.width : Math.min(messageListView.width, Kirigami.Units.gridUnit * 40 + extraWidth) readonly property int contentMaxWidth: Config.compactLayout ? width - (Config.showAvatarInTimeline ? Kirigami.Units.gridUnit * 2 : 0) - Kirigami.Units.largeSpacing * 4 : Math.min(width - Kirigami.Units.gridUnit * 2 - Kirigami.Units.largeSpacing * 6, bubbleMaxWidth) - property bool showUserMessageOnRight: Config.showLocalMessagesOnRight && - model.author.isLocalUser && !Config.compactLayout - - signal openExternally() - signal replyClicked(string eventID) - - Component.onCompleted: { - if (model.isReply && model.reply === undefined) { - messageEventModel.loadReply(sortedMessageEventModel.mapToSource(sortedMessageEventModel.index(model.index, 0))) - } - } - - topPadding: 0 - bottomPadding: 0 - topInset: showAuthor ? Kirigami.Units.largeSpacing : (Config.compactLayout ? 1 : Kirigami.Units.smallSpacing) - leftInset: Kirigami.Units.smallSpacing - rightInset: Kirigami.Units.smallSpacing - width: delegateMaxWidth - height: sectionDelegate.height + Math.max(model.showAuthor ? avatar.height : 0, bubble.implicitHeight) + loader.height + loader.anchors.topMargin + avatar.anchors.topMargin - background: Rectangle { - visible: timelineContainer.hovered - color: Kirigami.ColorUtils.tintWithAlpha(Kirigami.Theme.backgroundColor, Kirigami.Theme.highlightColor, 0.15) - radius: Kirigami.Units.smallSpacing - } - - property Item hoverComponent - - // show hover actions - onHoveredChanged: { - if (hovered && !Kirigami.Settings.isMobile) { - updateHoverComponent(); - } - } - - // updates the global hover component to point to this delegate, and update its position - function updateHoverComponent() { - if (hoverComponent) { - hoverComponent.delegate = timelineContainer - hoverComponent.bubble = bubble - hoverComponent.updateFunction = updateHoverComponent; - hoverComponent.event = model - } - } + width: delegateWidth + spacing: Kirigami.Units.smallSpacing state: Config.compactLayout ? "alignLeft" : "alignCenter" // Align left when in compact mode and center when using bubbles @@ -89,7 +52,7 @@ QQC2.ItemDelegate { State { name: "alignLeft" AnchorChanges { - target: timelineContainer + target: root anchors.horizontalCenter: undefined anchors.left: parent ? parent.left : undefined } @@ -97,7 +60,7 @@ QQC2.ItemDelegate { State { name: "alignCenter" AnchorChanges { - target: timelineContainer + target: root anchors.horizontalCenter: parent ? parent.horizontalCenter : undefined anchors.left: undefined } @@ -112,216 +75,244 @@ QQC2.ItemDelegate { SectionDelegate { id: sectionDelegate - anchors.left: timelineContainer.left - anchors.right: timelineContainer.right - visible: sectionVisible - height: visible ? implicitHeight : 0 + + Layout.fillWidth: true + visible: model.showSection labelText: model.showSection ? section : "" } - Kirigami.Avatar { - id: avatar - width: visible || Config.showAvatarInTimeline ? Kirigami.Units.gridUnit * 2 + Kirigami.Units.smallSpacing * 2 : 0 - height: width - padding: Kirigami.Units.smallSpacing - topInset: Kirigami.Units.smallSpacing - bottomInset: Kirigami.Units.smallSpacing - leftInset: Kirigami.Units.smallSpacing - rightInset: Kirigami.Units.smallSpacing - sourceSize.width: width - sourceSize.height: width - anchors { - top: sectionDelegate.bottom - topMargin: model.showAuthor ? Kirigami.Units.largeSpacing : (Config.compactLayout ? 1 : Kirigami.Units.smallSpacing) - left: parent.left - leftMargin: Kirigami.Units.smallSpacing - } + QQC2.ItemDelegate { + id: mainContainer - visible: model.showAuthor && - Config.showAvatarInTimeline && - (Config.compactLayout || !showUserMessageOnRight) - name: model.displayNameForInitials - source: visible && model.author.avatarMediaId ? ("image://mxc/" + model.author.avatarMediaId) : "" - color: model.author.color + Layout.fillWidth: true + Layout.topMargin: showAuthor ? Kirigami.Units.largeSpacing : (Config.compactLayout ? 1 : Kirigami.Units.smallSpacing) + Layout.leftMargin: Kirigami.Units.smallSpacing - MouseArea { - anchors.fill: parent - onClicked: { - userDetailDialog.createObject(QQC2.ApplicationWindow.overlay, { - room: currentRoom, - user: author.object, - displayName: author.displayName, - avatarMediaId: author.avatarMediaId, - avatarUrl: author.avatarUrl - }).open(); + implicitHeight: Math.max(model.showAuthor ? avatar.implicitHeight : 0, bubble.height) + + Component.onCompleted: { + if (model.isReply && model.reply === undefined) { + messageEventModel.loadReply(sortedMessageEventModel.mapToSource(sortedMessageEventModel.index(model.index, 0))) } - cursorShape: Qt.PointingHandCursor } - } - QQC2.Control { - id: bubble - topPadding: Config.compactLayout ? Kirigami.Units.smallSpacing / 2 : Kirigami.Units.largeSpacing - bottomPadding: Config.compactLayout ? Kirigami.Units.mediumSpacing / 2 : Kirigami.Units.largeSpacing - leftPadding: Kirigami.Units.largeSpacing + Kirigami.Units.smallSpacing - rightPadding: Kirigami.Units.largeSpacing + Kirigami.Units.smallSpacing - hoverEnabled: true - - anchors { - top: avatar.top - leftMargin: Kirigami.Units.smallSpacing - rightMargin: showUserMessageOnRight ? Kirigami.Units.smallSpacing : Kirigami.Units.largeSpacing + // show hover actions + onHoveredChanged: { + if (hovered && !Kirigami.Settings.isMobile) { + updateHoverComponent(); + } } - // HACK: anchoring didn't reset anchors.right when switching from parent.right to undefined reliably - width: Config.compactLayout ? timelineContainer.width - (Config.showAvatarInTimeline ? Kirigami.Units.gridUnit * 2 : 0) + Kirigami.Units.largeSpacing * 2 : implicitWidth - state: showUserMessageOnRight ? "userMessageOnRight" : "userMessageOnLeft" - // states for anchor animations on window resize - // as setting anchors to undefined did not work reliably - states: [ - State { - name: "userMessageOnRight" - AnchorChanges { - target: bubble - anchors.left: undefined - anchors.right: parent.right + + // Show hover actions by updating the global hover component to this delegate + function updateHoverComponent() { + if (hovered && !Kirigami.Settings.isMobile) { + hoverComponent.delegate = root + hoverComponent.bubble = bubble + hoverComponent.event = model + hoverComponent.updateFunction = updateHoverComponent; + } + } + + Kirigami.Avatar { + id: avatar + width: visible || Config.showAvatarInTimeline ? Kirigami.Units.gridUnit * 2 + Kirigami.Units.smallSpacing * 2 : 0 + height: width + padding: Kirigami.Units.smallSpacing + topInset: Kirigami.Units.smallSpacing + bottomInset: Kirigami.Units.smallSpacing + leftInset: Kirigami.Units.smallSpacing + rightInset: Kirigami.Units.smallSpacing + anchors { + left: parent.left + leftMargin: Kirigami.Units.smallSpacing + } + + visible: model.showAuthor && + Config.showAvatarInTimeline && + (Config.compactLayout || !showUserMessageOnRight) + name: model.author.name ?? model.author.displayName + source: visible && model.author.avatarMediaId ? ("image://mxc/" + model.author.avatarMediaId) : "" + color: model.author.color + + MouseArea { + anchors.fill: parent + onClicked: { + userDetailDialog.createObject(QQC2.ApplicationWindow.overlay, { + room: currentRoom, + user: author.object, + displayName: author.displayName, + avatarMediaId: author.avatarMediaId, + avatarUrl: author.avatarUrl + }).open(); } - }, - State { - name: "userMessageOnLeft" - AnchorChanges { - target: bubble - anchors.left: avatar.right - anchors.right: undefined + cursorShape: Qt.PointingHandCursor + } + } + + QQC2.Control { + id: bubble + topPadding: Config.compactLayout ? Kirigami.Units.smallSpacing / 2 : Kirigami.Units.largeSpacing + bottomPadding: Config.compactLayout ? Kirigami.Units.mediumSpacing / 2 : Kirigami.Units.largeSpacing + leftPadding: Config.compactLayout ? 0 : Kirigami.Units.largeSpacing + Kirigami.Units.smallSpacing + rightPadding: Kirigami.Units.largeSpacing + Kirigami.Units.smallSpacing + hoverEnabled: true + + anchors { + leftMargin: Kirigami.Units.smallSpacing + rightMargin: Kirigami.Units.largeSpacing + } + // HACK: anchoring didn't reset anchors.right when switching from parent.right to undefined reliably + width: Config.compactLayout ? mainContainer.width - (Config.showAvatarInTimeline ? Kirigami.Units.gridUnit * 2 : 0) + Kirigami.Units.largeSpacing * 2 : implicitWidth + + state: showUserMessageOnRight ? "userMessageOnRight" : "userMessageOnLeft" + // states for anchor animations on window resize + // as setting anchors to undefined did not work reliably + states: [ + State { + name: "userMessageOnRight" + AnchorChanges { + target: bubble + anchors.left: undefined + anchors.right: parent.right + } + }, + State { + name: "userMessageOnLeft" + AnchorChanges { + target: bubble + anchors.left: avatar.right + anchors.right: undefined + } } - } - ] + ] - transitions: [ - Transition { - AnchorAnimation{duration: Kirigami.Units.longDuration; easing.type: Easing.OutCubic} - } - ] - - contentItem: ColumnLayout { - id: column - spacing: Kirigami.Units.smallSpacing - RowLayout { - id: rowLayout + transitions: [ + Transition { + AnchorAnimation{duration: Kirigami.Units.longDuration; easing.type: Easing.OutCubic} + } + ] + contentItem: ColumnLayout { + id: column spacing: Kirigami.Units.smallSpacing - visible: model.showAuthor && !isEmote + RowLayout { + id: rowLayout - QQC2.Label { - id: nameLabel + spacing: Kirigami.Units.smallSpacing + visible: model.showAuthor && !isEmote - Layout.maximumWidth: contentMaxWidth - timeLabel.implicitWidth - rowLayout.spacing + QQC2.Label { + id: nameLabel - text: visible ? author.displayName : "" - textFormat: Text.PlainText - font.weight: Font.Bold - color: author.color - elide: Text.ElideRight - MouseArea { - anchors.fill: parent - cursorShape: Qt.PointingHandCursor - onClicked: { - userDetailDialog.createObject(QQC2.ApplicationWindow.overlay, { - room: currentRoom, - user: author.object, - displayName: author.displayName, - avatarMediaId: author.avatarMediaId, - avatarUrl: author.avatarUrl - }).open(); + Layout.maximumWidth: contentMaxWidth - timeLabel.implicitWidth - rowLayout.spacing + + text: visible ? author.displayName : "" + textFormat: Text.PlainText + font.weight: Font.Bold + color: author.color + elide: Text.ElideRight + MouseArea { + anchors.fill: parent + cursorShape: Qt.PointingHandCursor + onClicked: { + userDetailDialog.createObject(QQC2.ApplicationWindow.overlay, { + room: currentRoom, + user: author.object, + displayName: author.displayName, + avatarMediaId: author.avatarMediaId, + avatarUrl: author.avatarUrl + }).open(); + } + } + } + QQC2.Label { + id: timeLabel + + text: visible ? time.toLocaleTimeString(Qt.locale(), Locale.ShortFormat) : "" + color: Kirigami.Theme.disabledTextColor + QQC2.ToolTip.visible: hoverHandler.hovered + QQC2.ToolTip.text: time.toLocaleString(Qt.locale(), Locale.LongFormat) + QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay + + HoverHandler { + id: hoverHandler } } } - QQC2.Label { - id: timeLabel + Loader { + id: replyLoader - text: visible ? time.toLocaleTimeString(Qt.locale(), Locale.ShortFormat) : "" - color: Kirigami.Theme.disabledTextColor - QQC2.ToolTip.visible: hoverHandler.hovered - QQC2.ToolTip.text: time.toLocaleString(Qt.locale(), Locale.LongFormat) - QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay + Layout.maximumWidth: contentMaxWidth - HoverHandler { - id: hoverHandler + active: model.reply !== undefined + visible: active + + sourceComponent: ReplyComponent { + name: currentRoom.htmlSafeMemberName(reply.author.id) + avatar: reply.author.avatarMediaId ? ("image://mxc/" + reply.author.avatarMediaId) : "" + color: reply.author.color + } + + Connections { + target: replyLoader.item + function onReplyClicked() { + replyClicked(reply.eventId) + } } } } - Loader { - id: replyLoader - Layout.maximumWidth: contentMaxWidth + background: Item { + Kirigami.ShadowedRectangle { + id: bubbleBackground + visible: cardBackground && !Config.compactLayout + anchors.fill: parent + color: { + if (model.author.isLocalUser) { + return Kirigami.ColorUtils.tintWithAlpha(Kirigami.Theme.backgroundColor, Kirigami.Theme.highlightColor, 0.15) + } else if (root.isHighlighted) { + return Kirigami.Theme.positiveBackgroundColor + } else { + return Kirigami.Theme.backgroundColor + } + } + radius: Kirigami.Units.smallSpacing + shadow.size: Kirigami.Units.smallSpacing + shadow.color: root.isHighlighted ? Qt.rgba(0.0, 0.0, 0.0, 0.10) : Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.10) + border.color: Kirigami.ColorUtils.tintWithAlpha(color, Kirigami.Theme.textColor, 0.15) + border.width: 1 - active: model.reply !== undefined - visible: active - - sourceComponent: ReplyComponent { - name: currentRoom.htmlSafeMemberName(reply.author.id) - avatar: reply.author.avatarMediaId ? ("image://mxc/" + reply.author.avatarMediaId) : "" - color: reply.author.color - } - - Connections { - target: replyLoader.item - function onReplyClicked() { - replyClicked(reply.eventId) + Behavior on color { + ColorAnimation {target: bubbleBackground; duration: Kirigami.Units.veryLongDuration; easing.type: Easing.InOutCubic} } } } } - background: Item { - Kirigami.ShadowedRectangle { - id: bubbleBackground - visible: cardBackground && !Config.compactLayout - anchors.fill: parent - color: { - if (model.author.isLocalUser) { - return Kirigami.ColorUtils.tintWithAlpha(Kirigami.Theme.backgroundColor, Kirigami.Theme.highlightColor, 0.15) - } else if (timelineContainer.isHighlighted) { - return Kirigami.Theme.positiveBackgroundColor - } else { - return Kirigami.Theme.backgroundColor - } - } - radius: Kirigami.Units.smallSpacing - shadow.size: Kirigami.Units.smallSpacing - shadow.color: timelineContainer.isHighlighted ? Qt.rgba(0.0, 0.0, 0.0, 0.10) : Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.10) - border.color: Kirigami.ColorUtils.tintWithAlpha(color, Kirigami.Theme.textColor, 0.15) - border.width: 1 + background: Rectangle { + visible: mainContainer.hovered + color: Kirigami.ColorUtils.tintWithAlpha(Kirigami.Theme.backgroundColor, Kirigami.Theme.highlightColor, 0.15) + radius: Kirigami.Units.smallSpacing + } - Behavior on color { - ColorAnimation {target: bubbleBackground; duration: Kirigami.Units.veryLongDuration; easing.type: Easing.InOutCubic} - } - } + TapHandler { + acceptedButtons: Qt.RightButton + onTapped: root.openContextMenu() + } + + TapHandler { + acceptedButtons: Qt.LeftButton + onLongPressed: root.openContextMenu() } } - Loader { - id: loader - anchors { - left: bubble.left - right: parent.right - top: bubble.bottom - topMargin: active ? Kirigami.Units.smallSpacing : 0 - } - height: active ? item.implicitHeight : 0 - active: eventType !== MessageEventModel.State && eventType !== MessageEventModel.Notice && reaction != undefined && reaction.length > 0 - visible: active - sourceComponent: ReactionDelegate { } - } + ReactionDelegate { + Layout.maximumWidth: delegateWidth - Kirigami.Units.largeSpacing * 2 + Layout.alignment: showUserMessageOnRight ? Qt.AlignRight : Qt.AlignLeft + Layout.leftMargin: showUserMessageOnRight ? 0 : bubble.x + bubble.anchors.leftMargin + Layout.rightMargin: showUserMessageOnRight ? Kirigami.Units.largeSpacing : 0 - TapHandler { - acceptedButtons: Qt.RightButton - acceptedDevices: PointerDevice.Mouse - onTapped: timelineContainer.openContextMenu() - } - - TapHandler { - acceptedButtons: Qt.LeftButton - onLongPressed: timelineContainer.openContextMenu() + visible: eventType !== MessageEventModel.State && eventType !== MessageEventModel.Notice && reaction != undefined && reaction.length > 0 } } diff --git a/src/qml/Component/Timeline/VideoDelegate.qml b/src/qml/Component/Timeline/VideoDelegate.qml index 2e14965e3..855398d8c 100644 --- a/src/qml/Component/Timeline/VideoDelegate.qml +++ b/src/qml/Component/Timeline/VideoDelegate.qml @@ -14,9 +14,6 @@ import org.kde.neochat 1.0 TimelineContainer { id: videoDelegate - onReplyClicked: ListView.view.goToEvent(eventID) - hoverComponent: hoverActions - property bool playOnFinished: false readonly property bool downloaded: progressInfo && progressInfo.completed diff --git a/src/qml/Page/RoomPage.qml b/src/qml/Page/RoomPage.qml index edaa83f13..979da3d42 100644 --- a/src/qml/Page/RoomPage.qml +++ b/src/qml/Page/RoomPage.qml @@ -463,6 +463,7 @@ Kirigami.ScrollablePage { property var bubble: null property var hovered: bubble && bubble.hovered property var visibleDelayed: (hovered || hoverHandler.hovered) && !Kirigami.Settings.isMobile + property var updateFunction onVisibleDelayedChanged: if (visibleDelayed) { visible = true; } else { @@ -482,8 +483,6 @@ Kirigami.ScrollablePage { visible: false - property var updateFunction - property alias childWidth: hoverActionsRow.width property alias childHeight: hoverActionsRow.height