From 9786752a4f70fce6cb92eeb28c2cf31f7a1aa833 Mon Sep 17 00:00:00 2001
From: Lim Chee Aun <cheeaun@gmail.com>
Date: Sun, 15 Oct 2023 18:28:04 +0800
Subject: [PATCH] Group similar captions

Some folks really just copy/paste same desc for multiple media's
---
 src/components/status.css | 17 ++++++--
 src/components/status.jsx | 81 ++++++++++++++++++++++++++++-----------
 2 files changed, 71 insertions(+), 27 deletions(-)

diff --git a/src/components/status.css b/src/components/status.css
index 2a563421..515858a5 100644
--- a/src/components/status.css
+++ b/src/components/status.css
@@ -1015,32 +1015,41 @@ body:has(#modal-container .carousel) .status .media img:hover {
       white-space: nowrap;
       overflow: hidden;
       text-overflow: ellipsis;
+      display: inline-flex;
+      gap: 4px;
 
       &:hover {
         color: var(--text-color);
         cursor: pointer;
       }
+
+      &:only-child {
+        white-space: pre-line;
+        overflow: auto;
+        text-overflow: unset;
+      }
     }
 
     sup {
       opacity: 0.75;
       font-variant-numeric: tabular-nums;
+      flex-shrink: 0;
     }
   }
 
   /* Only 4, for now. Would be better if this is a for loop */
   &:has(.media[data-has-alt]:nth-child(1):is(:hover, :focus))
     figcaption
-    > div[data-caption-index='1'],
+    > div[data-caption-index~='1'],
   &:has(.media[data-has-alt]:nth-child(2):is(:hover, :focus))
     figcaption
-    > div[data-caption-index='2'],
+    > div[data-caption-index~='2'],
   &:has(.media[data-has-alt]:nth-child(3):is(:hover, :focus))
     figcaption
-    > div[data-caption-index='3'],
+    > div[data-caption-index~='3'],
   &:has(.media[data-has-alt]:nth-child(4):is(:hover, :focus))
     figcaption
-    > div[data-caption-index='4'] {
+    > div[data-caption-index~='4'] {
     color: var(--text-color);
   }
 }
diff --git a/src/components/status.jsx b/src/components/status.jsx
index a2f57adf..9eb846e9 100644
--- a/src/components/status.jsx
+++ b/src/components/status.jsx
@@ -877,6 +877,62 @@ function Status({
     displayedMediaAttachments.some(
       (media) => !!media.description && !isMediaCaptionLong(media.description),
     );
+  const captionChildren = useMemo(() => {
+    if (!showMultipleMediaCaptions) return null;
+    const attachments = [];
+    displayedMediaAttachments.forEach((media, i) => {
+      if (!media.description) return;
+      const index = attachments.findIndex(
+        (attachment) => attachment.media.description === media.description,
+      );
+      if (index === -1) {
+        attachments.push({
+          media,
+          indices: [i],
+        });
+      } else {
+        attachments[index].indices.push(i);
+      }
+    });
+    return attachments.map(({ media, indices }) => (
+      <div
+        key={media.id}
+        data-caption-index={indices.map((i) => i + 1).join(' ')}
+        onClick={(e) => {
+          e.preventDefault();
+          e.stopPropagation();
+          states.showMediaAlt = {
+            alt: media.description,
+            lang: language,
+          };
+        }}
+        title={media.description}
+      >
+        <sup>{indices.map((i) => i + 1).join(' ')}</sup> {media.description}
+      </div>
+    ));
+
+    // return displayedMediaAttachments.map(
+    //   (media, i) =>
+    //     !!media.description && (
+    //       <div
+    //         key={media.id}
+    //         data-caption-index={i + 1}
+    //         onClick={(e) => {
+    //           e.preventDefault();
+    //           e.stopPropagation();
+    //           states.showMediaAlt = {
+    //             alt: media.description,
+    //             lang: language,
+    //           };
+    //         }}
+    //         title={media.description}
+    //       >
+    //         <sup>{i + 1}</sup> {media.description}
+    //       </div>
+    //     ),
+    // );
+  }, [showMultipleMediaCaptions, displayedMediaAttachments, language]);
 
   return (
     <article
@@ -1277,28 +1333,7 @@ function Status({
             <MultipleMediaFigure
               lang={language}
               enabled={showMultipleMediaCaptions}
-              captionChildren={() => {
-                return displayedMediaAttachments.map(
-                  (media, i) =>
-                    !!media.description && (
-                      <div
-                        key={media.id}
-                        data-caption-index={i + 1}
-                        onClick={(e) => {
-                          e.preventDefault();
-                          e.stopPropagation();
-                          states.showMediaAlt = {
-                            alt: media.description,
-                            lang: language,
-                          };
-                        }}
-                        title={media.description}
-                      >
-                        <sup>{i + 1}</sup> {media.description}
-                      </div>
-                    ),
-                );
-              }}
+              captionChildren={captionChildren}
             >
               <div
                 ref={mediaContainerRef}
@@ -1533,7 +1568,7 @@ function MultipleMediaFigure(props) {
     <figure class="media-figure-multiple">
       {children}
       <figcaption lang={lang} dir="auto">
-        {captionChildren?.()}
+        {captionChildren}
       </figcaption>
     </figure>
   );