From 952827d629bbb7571f290dad63ae5dad69646472 Mon Sep 17 00:00:00 2001
From: Nicolas Werner <nicolas.werner@hotmail.de>
Date: Tue, 13 Dec 2022 05:08:05 +0100
Subject: [PATCH] Add a button to room the upgraded room in the timeline

---
 resources/qml/delegates/MessageDelegate.qml | 28 +++++++++++++++++++++
 src/timeline/TimelineModel.cpp              | 27 +++++++++++++++++++-
 src/timeline/TimelineModel.h                |  1 +
 3 files changed, 55 insertions(+), 1 deletion(-)

diff --git a/resources/qml/delegates/MessageDelegate.qml b/resources/qml/delegates/MessageDelegate.qml
index 3725be051..c2d49e915 100644
--- a/resources/qml/delegates/MessageDelegate.qml
+++ b/resources/qml/delegates/MessageDelegate.qml
@@ -61,6 +61,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
 
@@ -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 fe8a78ef8..62dbdae6d 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 2352be1f3..01d807976 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);
-- 
GitLab