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 #include #include +#include #include #include +#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{"" + body + ""}; + + 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 += ""; + 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 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"; if (with_sender) { @@ -485,7 +484,7 @@ TimelineItem::TimelineItem(const mtx::events::RoomEvent 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 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 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,