diff --git a/src/messageattached.cpp b/src/messageattached.cpp index 0bdbc30f6..35775818d 100644 --- a/src/messageattached.cpp +++ b/src/messageattached.cpp @@ -82,6 +82,38 @@ void MessageAttached::setMaxContentWidth(qreal maxContentWidth) Q_EMIT maxContentWidthChanged(); } +QString MessageAttached::selectedText() const +{ + return m_selectedText; +} + +void MessageAttached::setSelectedText(const QString &selectedTest) +{ + m_explicitSelectedText = true; + if (m_selectedText == selectedTest) { + return; + } + m_selectedText = selectedTest; + propagateMessage(this); + Q_EMIT selectedTextChanged(); +} + +QString MessageAttached::hoveredLink() const +{ + return m_hoveredLink; +} + +void MessageAttached::setHoveredLink(const QString &hoveredLink) +{ + m_explicitHoveredLink = true; + if (m_hoveredLink == hoveredLink) { + return; + } + m_hoveredLink = hoveredLink; + propagateMessage(this); + Q_EMIT hoveredLinkChanged(); +} + void MessageAttached::propagateMessage(MessageAttached *message) { if (m_explicitRoom || m_room != message->room()) { @@ -104,6 +136,16 @@ void MessageAttached::propagateMessage(MessageAttached *message) Q_EMIT maxContentWidthChanged(); } + if (m_explicitSelectedText || m_selectedText != message->selectedText()) { + m_selectedText = message->selectedText(); + Q_EMIT selectedTextChanged(); + } + + if (m_explicitHoveredLink || m_hoveredLink != message->hoveredLink()) { + m_hoveredLink = message->hoveredLink(); + Q_EMIT hoveredLinkChanged(); + } + const auto styles = attachedChildren(); for (auto *child : attachedChildren()) { MessageAttached *message = qobject_cast(child); diff --git a/src/messageattached.h b/src/messageattached.h index 1585c79c3..4bb5f231c 100644 --- a/src/messageattached.h +++ b/src/messageattached.h @@ -36,6 +36,16 @@ class MessageAttached : public QQuickAttachedPropertyPropagator */ Q_PROPERTY(qreal maxContentWidth READ maxContentWidth WRITE setMaxContentWidth NOTIFY maxContentWidthChanged FINAL) + /** + * @brief The current selected message text. + */ + Q_PROPERTY(QString selectedText READ selectedText WRITE setSelectedText NOTIFY selectedTextChanged FINAL) + + /** + * @brief The text of a hovered link if any. + */ + Q_PROPERTY(QString hoveredLink READ hoveredLink WRITE setHoveredLink NOTIFY hoveredLinkChanged FINAL) + public: explicit MessageAttached(QObject *parent = nullptr); @@ -53,11 +63,19 @@ public: qreal maxContentWidth() const; void setMaxContentWidth(qreal maxContentWidth); + QString selectedText() const; + void setSelectedText(const QString &selectedTest); + + QString hoveredLink() const; + void setHoveredLink(const QString &hoveredLink); + Q_SIGNALS: void roomChanged(); void timelineChanged(); void indexChanged(); void maxContentWidthChanged(); + void selectedTextChanged(); + void hoveredLinkChanged(); protected: void propagateMessage(MessageAttached *message); @@ -70,9 +88,15 @@ private: QPointer m_timeline; bool m_explicitTimeline = false; - int m_index; + int m_index = -1; bool m_explicitIndex = false; qreal m_maxContentWidth = -1; bool m_explicitMaxContentWidth = false; + + QString m_selectedText = {}; + bool m_explicitSelectedText = false; + + QString m_hoveredLink = {}; + bool m_explicitHoveredLink = false; }; diff --git a/src/timeline/AuthorComponent.qml b/src/timeline/AuthorComponent.qml index c3a12c65f..e8df80f21 100644 --- a/src/timeline/AuthorComponent.qml +++ b/src/timeline/AuthorComponent.qml @@ -12,6 +12,11 @@ import org.kde.neochat RowLayout { id: root + /** + * @brief The matrix ID of the message event. + */ + required property string eventId + /** * @brief The message author. * @@ -68,4 +73,16 @@ RowLayout { id: timeHoverHandler } } + + TapHandler { + acceptedButtons: Qt.LeftButton + acceptedDevices: PointerDevice.TouchScreen + onLongPressed: RoomManager.viewEventMenu(root.eventId, root.Message.room, root.author, root.Message.selectedText, root.Message.hoveredLink); + } + TapHandler { + acceptedButtons: Qt.RightButton + acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad | PointerDevice.Stylus + gesturePolicy: TapHandler.WithinBounds + onTapped: RoomManager.viewEventMenu(root.eventId, root.Message.room, root.author, root.Message.selectedText, root.Message.hoveredLink); + } } diff --git a/src/timeline/BaseMessageComponentChooser.qml b/src/timeline/BaseMessageComponentChooser.qml index 99409daf2..66cab0f76 100644 --- a/src/timeline/BaseMessageComponentChooser.qml +++ b/src/timeline/BaseMessageComponentChooser.qml @@ -25,11 +25,6 @@ DelegateChooser { */ signal hoveredLinkChanged(string hoveredLink) - /** - * @brief Request a context menu be show for the message. - */ - signal showMessageMenu - signal removeLinkPreview(int index) /** @@ -49,7 +44,6 @@ DelegateChooser { delegate: TextComponent { onSelectedTextChanged: root.selectedTextChanged(selectedText) onHoveredLinkChanged: root.hoveredLinkChanged(hoveredLink) - onShowMessageMenu: root.showMessageMenu() } } @@ -69,7 +63,6 @@ DelegateChooser { onSelectedTextChanged: selectedText => { root.selectedTextChanged(selectedText); } - onShowMessageMenu: root.showMessageMenu() } } @@ -79,7 +72,6 @@ DelegateChooser { onSelectedTextChanged: selectedText => { root.selectedTextChanged(selectedText); } - onShowMessageMenu: root.showMessageMenu() } } diff --git a/src/timeline/Bubble.qml b/src/timeline/Bubble.qml index 7d2d6b111..8a008052d 100644 --- a/src/timeline/Bubble.qml +++ b/src/timeline/Bubble.qml @@ -97,7 +97,6 @@ QQC2.Control { onHoveredLinkChanged: hoveredLink => { root.hoveredLinkChanged(hoveredLink); } - onShowMessageMenu: root.showMessageMenu() onRemoveLinkPreview: index => root.contentModel.closeLinkPreview(index) } } diff --git a/src/timeline/CodeComponent.qml b/src/timeline/CodeComponent.qml index eacc238cc..fdcc9a6ac 100644 --- a/src/timeline/CodeComponent.qml +++ b/src/timeline/CodeComponent.qml @@ -13,6 +13,11 @@ import org.kde.neochat QQC2.Control { id: root + /** + * @brief The matrix ID of the message event. + */ + required property string eventId + /** * @brief The message author. * @@ -42,11 +47,6 @@ QQC2.Control { */ signal selectedTextChanged(string selectedText) - /** - * @brief Request a context menu be show for the message. - */ - signal showMessageMenu - Layout.fillWidth: true Layout.fillHeight: true Layout.maximumWidth: Message.maxContentWidth @@ -129,7 +129,7 @@ QQC2.Control { TapHandler { acceptedDevices: PointerDevice.TouchScreen - onLongPressed: root.showMessageMenu() + onLongPressed: RoomManager.viewEventMenu(root.eventId, root.Message.room, root.author, root.Message.selectedText, root.Message.hoveredLink); } background: null diff --git a/src/timeline/MessageComponentChooser.qml b/src/timeline/MessageComponentChooser.qml index d40f6bc3b..3af15f5a1 100644 --- a/src/timeline/MessageComponentChooser.qml +++ b/src/timeline/MessageComponentChooser.qml @@ -14,6 +14,13 @@ BaseMessageComponentChooser { DelegateChoice { roleValue: MessageComponentType.ThreadBody - delegate: ThreadBodyComponent {} + delegate: ThreadBodyComponent { + onSelectedTextChanged: selectedText => { + root.selectedTextChanged(selectedText); + } + onHoveredLinkChanged: hoveredLink => { + root.hoveredLinkChanged(hoveredLink); + } + } } } diff --git a/src/timeline/MessageDelegate.qml b/src/timeline/MessageDelegate.qml index b9b60b8a1..5854ba135 100644 --- a/src/timeline/MessageDelegate.qml +++ b/src/timeline/MessageDelegate.qml @@ -166,16 +166,6 @@ TimelineDelegate { */ property bool isTemporaryHighlighted: false - /** - * @brief The user selected text. - */ - property string selectedText: "" - - /** - * @brief The user hovered link. - */ - property string hoveredLink: "" - onIsTemporaryHighlightedChanged: if (isTemporaryHighlighted) { temporaryHighlightTimer.start(); } @@ -293,12 +283,11 @@ TimelineDelegate { isPending: root.isPending onSelectedTextChanged: selectedText => { - root.selectedText = selectedText; + root.Message.selectedText = selectedText; } onHoveredLinkChanged: hoveredLink => { - root.hoveredLink = hoveredLink; + root.Message.hoveredLink = hoveredLink; } - onShowMessageMenu: _private.showMessageMenu() showBackground: root.cardBackground && !NeoChatConfig.compactLayout } @@ -358,7 +347,7 @@ TimelineDelegate { property bool showUserMessageOnRight: NeoChatConfig.showLocalMessagesOnRight && root.author.isLocalMember && !NeoChatConfig.compactLayout && !root.alwaysFillWidth && !root.isThreaded function showMessageMenu() { - RoomManager.viewEventMenu(root.eventId, root.room, root.author, root.selectedText, root.hoveredLink); + RoomManager.viewEventMenu(root.eventId, root.room, root.author, root.Message.selectedText, root.Message.hoveredLink); } } } diff --git a/src/timeline/QuoteComponent.qml b/src/timeline/QuoteComponent.qml index 237d677c5..562798fda 100644 --- a/src/timeline/QuoteComponent.qml +++ b/src/timeline/QuoteComponent.qml @@ -12,6 +12,20 @@ import org.kde.neochat QQC2.Control { id: root + /** + * @brief The matrix ID of the message event. + */ + required property string eventId + + /** + * @brief The message author. + * + * A Quotient::RoomMember object. + * + * @sa Quotient::RoomMember + */ + required property NeochatRoomMember author + /** * @brief The display text of the message. */ @@ -22,11 +36,6 @@ QQC2.Control { */ signal selectedTextChanged(string selectedText) - /** - * @brief Request a context menu be show for the message. - */ - signal showMessageMenu - Layout.fillWidth: true Layout.fillHeight: true Layout.maximumWidth: Message.maxContentWidth @@ -54,7 +63,7 @@ QQC2.Control { enabled: !quoteText.hoveredLink acceptedDevices: PointerDevice.TouchScreen acceptedButtons: Qt.LeftButton - onLongPressed: root.showMessageMenu() + onLongPressed: RoomManager.viewEventMenu(root.eventId, root.Message.room, root.author, root.Message.selectedText, root.Message.hoveredLink); } } diff --git a/src/timeline/TextComponent.qml b/src/timeline/TextComponent.qml index 2588d88db..475759ab3 100644 --- a/src/timeline/TextComponent.qml +++ b/src/timeline/TextComponent.qml @@ -15,6 +15,20 @@ import org.kde.neochat TextEdit { id: root + /** + * @brief The matrix ID of the message event. + */ + required property string eventId + + /** + * @brief The message author. + * + * A Quotient::RoomMember object. + * + * @sa Quotient::RoomMember + */ + required property NeochatRoomMember author + /** * @brief The display text of the message. */ @@ -35,11 +49,6 @@ TextEdit { */ property bool spoilerRevealed: !hasSpoiler.test(display) - /** - * @brief Request a context menu be show for the message. - */ - signal showMessageMenu - Layout.fillWidth: true Layout.fillHeight: true Layout.maximumWidth: Message.maxContentWidth @@ -119,7 +128,6 @@ a{ HoverHandler { cursorShape: (root.hoveredLink || !spoilerRevealed) ? Qt.PointingHandCursor : Qt.IBeamCursor } - TapHandler { enabled: !root.hoveredLink && !spoilerRevealed onTapped: spoilerRevealed = true @@ -128,6 +136,12 @@ a{ enabled: !root.hoveredLink acceptedButtons: Qt.LeftButton acceptedDevices: PointerDevice.TouchScreen - onLongPressed: root.showMessageMenu() + onLongPressed: RoomManager.viewEventMenu(root.eventId, root.Message.room, root.author, root.Message.selectedText, root.Message.hoveredLink); + } + TapHandler { + acceptedButtons: Qt.RightButton + acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad | PointerDevice.Stylus + gesturePolicy: TapHandler.WithinBounds + onTapped: RoomManager.viewEventMenu(root.eventId, root.Message.room, root.author, root.Message.selectedText, root.Message.hoveredLink); } } diff --git a/src/timeline/ThreadBodyComponent.qml b/src/timeline/ThreadBodyComponent.qml index 921faf726..af1a161ca 100644 --- a/src/timeline/ThreadBodyComponent.qml +++ b/src/timeline/ThreadBodyComponent.qml @@ -31,11 +31,6 @@ ColumnLayout { */ signal hoveredLinkChanged(string hoveredLink) - /** - * @brief Request a context menu be show for the message. - */ - signal showMessageMenu - Layout.fillWidth: true Layout.fillHeight: true Layout.maximumWidth: Message.maxContentWidth @@ -52,7 +47,6 @@ ColumnLayout { onHoveredLinkChanged: hoveredLink => { root.hoveredLinkChanged(hoveredLink); } - onShowMessageMenu: root.showMessageMenu() onRemoveLinkPreview: index => threadRepeater.model.closeLinkPreview(index) onFetchMoreEvents: threadRepeater.model.fetchMoreEvents(5) }