diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d8aac8..5e97fbb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ ## [Unreleased] ### Features - Support for sending & receiving markdown formatted messages. (#283) +- Context menu option to show the raw text message of an event. (#437) +- Clicking on a user pill link will open the user profile. ### Improvements - Update Polish translation (#430) diff --git a/src/timeline/TimelineItem.cpp b/src/timeline/TimelineItem.cpp index 5bec445..1654e45 100644 --- a/src/timeline/TimelineItem.cpp +++ b/src/timeline/TimelineItem.cpp @@ -16,6 +16,7 @@ */ #include +#include #include #include #include @@ -35,6 +36,7 @@ #include "timeline/widgets/VideoItem.h" #include "dialogs/RawMessage.h" +#include "mtx/identifiers.hpp" constexpr int MSG_RIGHT_MARGIN = 7; constexpr int MSG_PADDING = 20; @@ -61,8 +63,47 @@ TextLabel::TextLabel(const QString &text, QWidget *parent) &TextLabel::adjustHeight); document()->setDocumentMargin(0); + setFocusPolicy(Qt::NoFocus); setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); setFixedHeight(0); + + connect(this, &TextLabel::linkActivated, this, [](const QUrl &url) { + auto parts = url.toString().split('/'); + auto defaultHandler = [](const QUrl &url) { QDesktopServices::openUrl(url); }; + + if (url.host() != "matrix.to" || parts.isEmpty()) + return defaultHandler(url); + + try { + using namespace mtx::identifiers; + parse(parts.last().toStdString()); + } catch (const std::exception &) { + return defaultHandler(url); + } + + auto user_id = parts.last(); + auto room_id = ChatPage::instance()->currentRoom(); + + MainWindow::instance()->openUserProfile(user_id, room_id); + }); +} + +void +TextLabel::mousePressEvent(QMouseEvent *e) +{ + link_ = (e->button() & Qt::LeftButton) ? anchorAt(e->pos()) : QString(); + QTextBrowser::mousePressEvent(e); +} + +void +TextLabel::mouseReleaseEvent(QMouseEvent *e) +{ + if (e->button() & Qt::LeftButton && !link_.isEmpty() && anchorAt(e->pos()) == link_) { + emit linkActivated(link_); + return; + } + + QTextBrowser::mouseReleaseEvent(e); } StatusIndicator::StatusIndicator(QWidget *parent) diff --git a/src/timeline/TimelineItem.h b/src/timeline/TimelineItem.h index fb961b6..32d586f 100644 --- a/src/timeline/TimelineItem.h +++ b/src/timeline/TimelineItem.h @@ -105,8 +105,18 @@ public: void wheelEvent(QWheelEvent *event) override { event->ignore(); } +protected: + void mousePressEvent(QMouseEvent *e) override; + void mouseReleaseEvent(QMouseEvent *e) override; + private slots: void adjustHeight(const QSizeF &size) { setFixedHeight(size.height()); } + +signals: + void linkActivated(const QUrl &link); + +private: + QString link_; }; class UserProfileFilter : public QObject