diff --git a/src/Utils.cpp b/src/Utils.cpp
index 8f7e9992..40039179 100644
--- a/src/Utils.cpp
+++ b/src/Utils.cpp
@@ -3,10 +3,13 @@
#include <QApplication>
#include <QDesktopWidget>
#include <QSettings>
+#include <QXmlStreamReader>
#include <cmath>
#include <boost/variant.hpp>
+#include "Config.h"
+
using TimelineEvent = mtx::events::collections::TimelineEvents;
QString
@@ -276,3 +279,51 @@ utils::humanReadableFingerprint(const QString &ed25519)
}
return fingerprintList.join(" ");
}
+
+QString
+utils::linkifyMessage(const QString &body)
+{
+ QXmlStreamReader xml{"<html>" + body + "</html>"};
+
+ QString textString;
+ while (!xml.atEnd() && !xml.hasError()) {
+ auto t = xml.readNext();
+
+ switch (t) {
+ case QXmlStreamReader::Characters: {
+ auto text = xml.text().toString();
+ text.replace(conf::strings::url_regex, conf::strings::url_html);
+
+ textString += text;
+ break;
+ }
+ case QXmlStreamReader::StartDocument:
+ case QXmlStreamReader::EndDocument:
+ break;
+ case QXmlStreamReader::StartElement: {
+ if (xml.name() == "html")
+ break;
+
+ textString += "<" + xml.name() + ">";
+ break;
+ }
+ case QXmlStreamReader::EndElement: {
+ if (xml.name() == "html")
+ break;
+
+ textString += "</" + xml.name() + ">";
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ }
+
+ if (xml.hasError()) {
+ // qWarning() << "error while parsing xml";
+ return body;
+ }
+
+ return textString;
+}
diff --git a/src/Utils.h b/src/Utils.h
index 347ece80..62af310b 100644
--- a/src/Utils.h
+++ b/src/Utils.h
@@ -201,7 +201,7 @@ humanReadableFingerprint(const QString &ed25519);
//! If the `format` of the message is not supported we fallback to `body`.
template<typename RoomMessageT>
QString
-get_message_body(const RoomMessageT &event)
+getMessageBody(const RoomMessageT &event)
{
if (event.content.format.empty())
return QString::fromStdString(event.content.body);
@@ -211,4 +211,8 @@ get_message_body(const RoomMessageT &event)
return QString::fromStdString(event.content.formatted_body);
}
+
+//! Replace raw URLs in text with HTML link tags.
+QString
+linkifyMessage(const QString &body);
}
diff --git a/src/timeline/TimelineItem.cpp b/src/timeline/TimelineItem.cpp
index 8ff69bee..267dea15 100644
--- a/src/timeline/TimelineItem.cpp
+++ b/src/timeline/TimelineItem.cpp
@@ -437,7 +437,7 @@ TimelineItem::TimelineItem(const mtx::events::RoomEvent<mtx::events::msg::Notice
const auto sender = QString::fromStdString(event.sender);
const auto timestamp = QDateTime::fromMSecsSinceEpoch(event.origin_server_ts);
- auto formatted_body = utils::get_message_body(event).trimmed();
+ auto formatted_body = utils::linkifyMessage(utils::getMessageBody(event).trimmed());
auto body = QString::fromStdString(event.content.body).trimmed();
descriptionMsg_ = {Cache::displayName(room_id_, sender),
@@ -448,7 +448,6 @@ TimelineItem::TimelineItem(const mtx::events::RoomEvent<mtx::events::msg::Notice
generateTimestamp(timestamp);
- formatted_body.replace(conf::strings::url_regex, conf::strings::url_html);
formatted_body = "<i>" + formatted_body + "</i>";
if (with_sender) {
@@ -485,7 +484,7 @@ TimelineItem::TimelineItem(const mtx::events::RoomEvent<mtx::events::msg::Emote>
event_id_ = QString::fromStdString(event.event_id);
const auto sender = QString::fromStdString(event.sender);
- auto formatted_body = utils::get_message_body(event).trimmed();
+ auto formatted_body = utils::linkifyMessage(utils::getMessageBody(event).trimmed());
auto body = QString::fromStdString(event.content.body).trimmed();
auto timestamp = QDateTime::fromMSecsSinceEpoch(event.origin_server_ts);
@@ -494,8 +493,6 @@ TimelineItem::TimelineItem(const mtx::events::RoomEvent<mtx::events::msg::Emote>
descriptionMsg_ = {"", sender, emoteMsg, utils::descriptiveTime(timestamp), timestamp};
- formatted_body.replace(conf::strings::url_regex, conf::strings::url_html);
-
generateTimestamp(timestamp);
if (with_sender) {
@@ -530,14 +527,12 @@ TimelineItem::TimelineItem(const mtx::events::RoomEvent<mtx::events::msg::Text>
event_id_ = QString::fromStdString(event.event_id);
const auto sender = QString::fromStdString(event.sender);
- auto formatted_body = utils::get_message_body(event).trimmed();
+ auto formatted_body = utils::linkifyMessage(utils::getMessageBody(event).trimmed());
auto body = QString::fromStdString(event.content.body).trimmed();
auto timestamp = QDateTime::fromMSecsSinceEpoch(event.origin_server_ts);
auto displayName = Cache::displayName(room_id_, sender);
- formatted_body.replace(conf::strings::url_regex, conf::strings::url_html);
-
QSettings settings;
descriptionMsg_ = {sender == settings.value("auth/user_id") ? "You" : displayName,
sender,
|