From 64967bf17f1eab81fe7fd0e126526177357b185d Mon Sep 17 00:00:00 2001
From: Florian Duros <florian.duros@ormaz.fr>
Date: Fri, 6 Sep 2024 17:04:39 +0200
Subject: [PATCH] Hide pinned message link in timeline when the last pinned
 message is unpinned

---
 src/TextForEvent.tsx        | 32 +++++++++++++++++++++++++++++++-
 src/i18n/strings/en_EN.json |  2 ++
 test/TextForEvent-test.ts   |  2 +-
 3 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/src/TextForEvent.tsx b/src/TextForEvent.tsx
index d85b7519ae..06af7b4a97 100644
--- a/src/TextForEvent.tsx
+++ b/src/TextForEvent.tsx
@@ -615,10 +615,37 @@ function textForPinnedEvent(event: MatrixEvent, client: MatrixClient, allowJSX:
     }
 
     if (newlyUnpinned.length === 1 && newlyPinned.length === 0) {
+        const emptyPinned = pinned.length === 0;
+
         // A single message was unpinned, include a link to that message.
         if (allowJSX) {
             const messageId = newlyUnpinned.pop()!;
 
+            // If there are no remaining pinned messages, don't show the link to all the pinned messages
+            if (emptyPinned) {
+                return () => (
+                    <span>
+                        {_t(
+                            "timeline|m.room.pinned_events|unpinned_last_link",
+                            { senderName },
+                            {
+                                a: (sub) => (
+                                    <AccessibleButton
+                                        kind="link_inline"
+                                        onClick={() => {
+                                            PosthogTrackers.trackInteraction("PinnedMessageStateEventClick");
+                                            highlightEvent(roomId, messageId);
+                                        }}
+                                    >
+                                        {sub}
+                                    </AccessibleButton>
+                                ),
+                            },
+                        )}
+                    </span>
+                );
+            }
+
             return () => (
                 <span>
                     {_t(
@@ -647,7 +674,10 @@ function textForPinnedEvent(event: MatrixEvent, client: MatrixClient, allowJSX:
             );
         }
 
-        return () => _t("timeline|m.room.pinned_events|unpinned", { senderName });
+        return () =>
+            emptyPinned
+                ? _t("timeline|m.room.pinned_events|unpinned_last", { senderName })
+                : _t("timeline|m.room.pinned_events|unpinned", { senderName });
     }
 
     if (allowJSX) {
diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json
index e1e44efc61..101e969b3b 100644
--- a/src/i18n/strings/en_EN.json
+++ b/src/i18n/strings/en_EN.json
@@ -3479,6 +3479,8 @@
             "pinned": "%(senderName)s pinned a message to this room. See all pinned messages.",
             "pinned_link": "%(senderName)s pinned <a>a message</a> to this room. See all <b>pinned messages</b>.",
             "unpinned": "%(senderName)s unpinned a message from this room. See all pinned messages.",
+            "unpinned_last": "%(senderName)s unpinned a message from this room.",
+            "unpinned_last_link": "%(senderName)s unpinned <a>a message</a> from this room.",
             "unpinned_link": "%(senderName)s unpinned <a>a message</a> from this room. See all <b>pinned messages</b>."
         },
         "m.room.power_levels": {
diff --git a/test/TextForEvent-test.ts b/test/TextForEvent-test.ts
index ce5c4a97f6..9272349b2c 100644
--- a/test/TextForEvent-test.ts
+++ b/test/TextForEvent-test.ts
@@ -103,7 +103,7 @@ describe("TextForEvent", () => {
             const plainText = textForEvent(event, mockClient);
             const component = render(textForEvent(event, mockClient, true) as ReactElement);
 
-            const expectedText = "@foo:example.com unpinned a message from this room. See all pinned messages.";
+            const expectedText = "@foo:example.com unpinned a message from this room.";
             expect(plainText).toBe(expectedText);
             expect(component.container).toHaveTextContent(expectedText);
         });
-- 
GitLab