diff --git a/imports/NeoChat/Page/RoomListPage.qml b/imports/NeoChat/Page/RoomListPage.qml
index fd896e7a5..4e7d513f2 100644
--- a/imports/NeoChat/Page/RoomListPage.qml
+++ b/imports/NeoChat/Page/RoomListPage.qml
@@ -237,13 +237,8 @@ Kirigami.ScrollablePage {
bold: unreadCount > 0
label: name ?? ""
labelItem.textFormat: Text.PlainText
- subtitle: {
- const txt = (lastEvent.length === 0 ? topic : lastEvent).replace(/(\r\n\t|\n|\r\t)/gm, " ")
- if (txt.length) {
- return txt
- }
- return " "
- }
+ subtitle: subtitleText
+ subtitleItem.textFormat: Text.PlainText
onPressAndHold: {
const menu = roomListContextMenu.createObject(page, {"room": currentRoom})
configButton.visible = true
diff --git a/src/neochatroom.cpp b/src/neochatroom.cpp
index 5711a5e42..b8dc184e4 100644
--- a/src/neochatroom.cpp
+++ b/src/neochatroom.cpp
@@ -252,6 +252,35 @@ QDateTime NeoChatRoom::lastActiveTime()
return messageEvents().rbegin()->get()->originTimestamp();
}
+QString NeoChatRoom::subtitleText()
+{
+ QString subtitle = this->lastEventToString().size() == 0 ? this->topic() : this->lastEventToString();
+
+ subtitle
+ // replace blockquote, i.e. '> text'
+ .replace(QRegularExpression("(\r\n\t|\n|\r\t|)> "), " ")
+ // replace headings, i.e. "# text"
+ .replace(QRegularExpression("(\r\n\t|\n|\r\t|)\\#{1,6} "), " ")
+ // replace newlines
+ .replace(QRegularExpression("(\r\n\t|\n|\r\t)"), " ")
+ // replace '**text**' and '__text__'
+ .replace(QRegularExpression("(\\*\\*|__)(?=\\S)([^\\r]*\\S)\\1"), "\\2")
+ // replace '*text*' and '_text_'
+ .replace(QRegularExpression("(\\*|_)(?=\\S)([^\\r]*\\S)\\1"), "\\2")
+ // replace '~~text~~'
+ .replace(QRegularExpression("~~(.*)~~"), "\\1")
+ // replace '~text~'
+ .replace(QRegularExpression("~(.*)~"), "\\1")
+ // replace 'text'
+ .replace(QRegularExpression("(.*)"), "\\1")
+ // replace '```code```'
+ .replace(QRegularExpression("```([^```]+)```"), "\\1")
+ // replace '`code`'
+ .replace(QRegularExpression("`([^`]+)`"), "\\1");
+
+ return subtitle.size() > 0 ? subtitle : QStringLiteral(" ");
+}
+
int NeoChatRoom::savedTopVisibleIndex() const
{
return firstDisplayedMarker() == historyEdge() ? 0 : int(firstDisplayedMarker() - messageEvents().rbegin());
diff --git a/src/neochatroom.h b/src/neochatroom.h
index 1cd052615..d5bbe357e 100644
--- a/src/neochatroom.h
+++ b/src/neochatroom.h
@@ -66,6 +66,12 @@ public:
/// \see lastEvent
[[nodiscard]] QDateTime lastActiveTime();
+ /// Get subtitle text for room
+ ///
+ /// Fetches last event and removes markdown formatting
+ /// \see lastEventToString
+ [[nodiscard]] QString subtitleText();
+
bool isEventHighlighted(const Quotient::RoomEvent *e) const;
[[nodiscard]] QString joinRule() const;
diff --git a/src/roomlistmodel.cpp b/src/roomlistmodel.cpp
index 8089bdd26..760925ee4 100644
--- a/src/roomlistmodel.cpp
+++ b/src/roomlistmodel.cpp
@@ -171,7 +171,7 @@ void RoomListModel::connectRoomSignals(NeoChatRoom *room)
refresh(room);
});
connect(room, &Room::addedMessages, this, [this, room] {
- refresh(room, {LastEventRole});
+ refresh(room, {LastEventRole, SubtitleTextRole});
});
connect(room, &Room::notificationCountChanged, this, &RoomListModel::handleNotifications);
connect(room, &Room::highlightCountChanged, this, [this, room] {
@@ -396,6 +396,9 @@ QVariant RoomListModel::data(const QModelIndex &index, int role) const
if (role == CategoryVisibleRole) {
return m_categoryVisibility.value(data(index, CategoryRole).toInt(), true);
}
+ if (role == SubtitleTextRole) {
+ return room->subtitleText();
+ }
return QVariant();
}
@@ -426,6 +429,7 @@ QHash RoomListModel::roleNames() const
roles[JoinStateRole] = "joinState";
roles[CurrentRoomRole] = "currentRoom";
roles[CategoryVisibleRole] = "categoryVisible";
+ roles[SubtitleTextRole] = "subtitleText";
return roles;
}
diff --git a/src/roomlistmodel.h b/src/roomlistmodel.h
index 65d931cb0..7890ebc8f 100644
--- a/src/roomlistmodel.h
+++ b/src/roomlistmodel.h
@@ -49,6 +49,7 @@ public:
JoinStateRole,
CurrentRoomRole,
CategoryVisibleRole,
+ SubtitleTextRole,
};
Q_ENUM(EventRoles)