diff --git a/resources/qml/delegates/MessageDelegate.qml b/resources/qml/delegates/MessageDelegate.qml
index 3725be05..c2d49e91 100644
--- a/resources/qml/delegates/MessageDelegate.qml
+++ b/resources/qml/delegates/MessageDelegate.qml
@@ -62,6 +62,33 @@ Item {
}
DelegateChoice {
+ roleValue: MtxEvent.Tombstone
+
+
+ ColumnLayout {
+ width: parent.width
+
+ NoticeMessage {
+ body: formatted
+ isOnlyEmoji: false
+ isReply: d.isReply
+ keepFullText: d.keepFullText
+ isStateEvent: d.isStateEvent
+ Layout.fillWidth: true
+ formatted: qsTr("This room was replaced for the following reason: %1").arg(d.body)
+ }
+
+ Button {
+ palette: Nheko.colors
+ Layout.alignment: Qt.AlignHCenter
+ text: qsTr("Go to replacement room")
+ onClicked: room.joinReplacementRoom(eventId)
+ }
+
+ }
+ }
+
+ DelegateChoice {
roleValue: MtxEvent.TextMessage
TextMessage {
@@ -579,6 +606,7 @@ Item {
Button {
visible: d.relatedEventCacheBuster, room.showAcceptKnockButton(d.eventId)
palette: Nheko.colors
+ Layout.alignment: Qt.AlignHCenter
text: qsTr("Allow them in")
onClicked: room.acceptKnock(eventId)
}
diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp
index fe8a78ef..62dbdae6 100644
--- a/src/timeline/TimelineModel.cpp
+++ b/src/timeline/TimelineModel.cpp
@@ -1489,7 +1489,6 @@ TimelineModel::sendEncryptedMessage(mtx::events::RoomEvent<T> msg, mtx::events::
const auto room_id = room_id_.toStdString();
using namespace mtx::events;
- using namespace mtx::identifiers;
nlohmann::json doc = {{"type", mtx::events::to_string(eventType)},
{"content", nlohmann::json(msg.content)},
@@ -2658,6 +2657,32 @@ TimelineModel::showAcceptKnockButton(const QString &id)
return event->content.membership == Membership::Knock;
}
+void
+TimelineModel::joinReplacementRoom(const QString &id)
+{
+ mtx::events::collections::TimelineEvents *e = events.get(id.toStdString(), "");
+ if (!e)
+ return;
+
+ auto event = std::get_if<mtx::events::StateEvent<mtx::events::state::Tombstone>>(e);
+ if (!event)
+ return;
+
+ auto joined_rooms = cache::joinedRooms();
+ for (const auto &roomid : joined_rooms) {
+ if (roomid == event->content.replacement_room) {
+ manager_->rooms()->setCurrentRoom(
+ QString::fromStdString(event->content.replacement_room));
+ return;
+ }
+ }
+
+ ChatPage::instance()->joinRoomVia(
+ event->content.replacement_room,
+ {mtx::identifiers::parse<mtx::identifiers::User>(event->sender).hostname()},
+ true);
+}
+
QString
TimelineModel::formatMemberEvent(const QString &id)
{
diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h
index 2352be1f..01d80797 100644
--- a/src/timeline/TimelineModel.h
+++ b/src/timeline/TimelineModel.h
@@ -287,6 +287,7 @@ public:
Q_INVOKABLE QString formatTypingUsers(const std::vector<QString> &users, const QColor &bg);
Q_INVOKABLE bool showAcceptKnockButton(const QString &id);
Q_INVOKABLE void acceptKnock(const QString &id);
+ Q_INVOKABLE void joinReplacementRoom(const QString &id);
Q_INVOKABLE QString formatMemberEvent(const QString &id);
Q_INVOKABLE QString formatJoinRuleEvent(const QString &id);
Q_INVOKABLE QString formatHistoryVisibilityEvent(const QString &id);
|