From cae4d464923e3435058fefd3791c5785d5ddfffe Mon Sep 17 00:00:00 2001
From: Audric Ackermann <audric@loki.network>
Date: Mon, 11 Apr 2022 16:31:21 +1000
Subject: [PATCH] allow to save attachments even if there is multiple of them

This is a bit dirty for now

Relates #2229
---
 ts/components/conversation/Image.tsx              |  3 +++
 ts/components/conversation/ImageGrid.tsx          | 15 +++++++++++++++
 .../message-content/MessageContextMenu.tsx        | 15 ++++++++++++---
 3 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/ts/components/conversation/Image.tsx b/ts/components/conversation/Image.tsx
index f2aed75a2..b1a81c417 100644
--- a/ts/components/conversation/Image.tsx
+++ b/ts/components/conversation/Image.tsx
@@ -23,6 +23,7 @@ type Props = {
   playIconOverlay?: boolean;
   softCorners?: boolean;
   forceSquare?: boolean;
+  attachmentIndex?: number;
 
   onClick?: (attachment: AttachmentTypeWithPath | AttachmentType) => void;
   onClickClose?: (attachment: AttachmentTypeWithPath | AttachmentType) => void;
@@ -45,6 +46,7 @@ export const Image = (props: Props) => {
     playIconOverlay,
     softCorners,
     forceSquare,
+    attachmentIndex,
     url,
     width,
   } = props;
@@ -87,6 +89,7 @@ export const Image = (props: Props) => {
         maxHeight: `${height}px`,
         maxWidth: `${width}px`,
       }}
+      data-attachmentindex={attachmentIndex}
     >
       {pending || loading ? (
         <div
diff --git a/ts/components/conversation/ImageGrid.tsx b/ts/components/conversation/ImageGrid.tsx
index 7c08ad9a2..152c192de 100644
--- a/ts/components/conversation/ImageGrid.tsx
+++ b/ts/components/conversation/ImageGrid.tsx
@@ -47,6 +47,7 @@ export const ImageGrid = (props: Props) => {
           url={isMessageVisible ? getThumbnailUrl(attachments[0]) : undefined}
           onClick={onClickAttachment}
           onError={onError}
+          attachmentIndex={0}
         />
       </div>
     );
@@ -65,6 +66,7 @@ export const ImageGrid = (props: Props) => {
           url={isMessageVisible ? getThumbnailUrl(attachments[0]) : undefined}
           onClick={onClickAttachment}
           onError={onError}
+          attachmentIndex={0}
         />
         <Image
           alt={getAlt(attachments[1])}
@@ -76,6 +78,7 @@ export const ImageGrid = (props: Props) => {
           url={isMessageVisible ? getThumbnailUrl(attachments[1]) : undefined}
           onClick={onClickAttachment}
           onError={onError}
+          attachmentIndex={1}
         />
       </div>
     );
@@ -94,6 +97,7 @@ export const ImageGrid = (props: Props) => {
           url={isMessageVisible ? getThumbnailUrl(attachments[0]) : undefined}
           onClick={onClickAttachment}
           onError={onError}
+          attachmentIndex={0}
         />
         <div className="module-image-grid__column">
           <Image
@@ -105,6 +109,7 @@ export const ImageGrid = (props: Props) => {
             url={isMessageVisible ? getThumbnailUrl(attachments[1]) : undefined}
             onClick={onClickAttachment}
             onError={onError}
+            attachmentIndex={1}
           />
           <Image
             alt={getAlt(attachments[2])}
@@ -116,6 +121,7 @@ export const ImageGrid = (props: Props) => {
             url={isMessageVisible ? getThumbnailUrl(attachments[2]) : undefined}
             onClick={onClickAttachment}
             onError={onError}
+            attachmentIndex={2}
           />
         </div>
       </div>
@@ -136,6 +142,7 @@ export const ImageGrid = (props: Props) => {
               url={isMessageVisible ? getThumbnailUrl(attachments[0]) : undefined}
               onClick={onClickAttachment}
               onError={onError}
+              attachmentIndex={0}
             />
             <Image
               alt={getAlt(attachments[1])}
@@ -146,6 +153,7 @@ export const ImageGrid = (props: Props) => {
               url={isMessageVisible ? getThumbnailUrl(attachments[1]) : undefined}
               onClick={onClickAttachment}
               onError={onError}
+              attachmentIndex={1}
             />
           </div>
           <div className="module-image-grid__row">
@@ -159,6 +167,7 @@ export const ImageGrid = (props: Props) => {
               url={isMessageVisible ? getThumbnailUrl(attachments[2]) : undefined}
               onClick={onClickAttachment}
               onError={onError}
+              attachmentIndex={2}
             />
             <Image
               alt={getAlt(attachments[3])}
@@ -170,6 +179,7 @@ export const ImageGrid = (props: Props) => {
               url={isMessageVisible ? getThumbnailUrl(attachments[3]) : undefined}
               onClick={onClickAttachment}
               onError={onError}
+              attachmentIndex={3}
             />
           </div>
         </div>
@@ -193,6 +203,7 @@ export const ImageGrid = (props: Props) => {
             url={isMessageVisible ? getThumbnailUrl(attachments[0]) : undefined}
             onClick={onClickAttachment}
             onError={onError}
+            attachmentIndex={0}
           />
           <Image
             alt={getAlt(attachments[1])}
@@ -203,6 +214,7 @@ export const ImageGrid = (props: Props) => {
             url={isMessageVisible ? getThumbnailUrl(attachments[1]) : undefined}
             onClick={onClickAttachment}
             onError={onError}
+            attachmentIndex={1}
           />
         </div>
         <div className="module-image-grid__row">
@@ -216,6 +228,7 @@ export const ImageGrid = (props: Props) => {
             url={isMessageVisible ? getThumbnailUrl(attachments[2]) : undefined}
             onClick={onClickAttachment}
             onError={onError}
+            attachmentIndex={2}
           />
           <Image
             alt={getAlt(attachments[3])}
@@ -227,6 +240,7 @@ export const ImageGrid = (props: Props) => {
             url={isMessageVisible ? getThumbnailUrl(attachments[3]) : undefined}
             onClick={onClickAttachment}
             onError={onError}
+            attachmentIndex={3}
           />
           <Image
             alt={getAlt(attachments[4])}
@@ -240,6 +254,7 @@ export const ImageGrid = (props: Props) => {
             url={isMessageVisible ? getThumbnailUrl(attachments[4]) : undefined}
             onClick={onClickAttachment}
             onError={onError}
+            attachmentIndex={4}
           />
         </div>
       </div>
diff --git a/ts/components/conversation/message/message-content/MessageContextMenu.tsx b/ts/components/conversation/message/message-content/MessageContextMenu.tsx
index 68cdb7265..80e91a2e7 100644
--- a/ts/components/conversation/message/message-content/MessageContextMenu.tsx
+++ b/ts/components/conversation/message/message-content/MessageContextMenu.tsx
@@ -73,7 +73,6 @@ export const MessageContextMenu = (props: Props) => {
   const isOutgoing = direction === 'outgoing';
   const showRetry = status === 'error' && isOutgoing;
   const isSent = status === 'sent' || status === 'read'; // a read message should be replyable
-  const multipleAttachments = attachments && attachments.length > 1;
 
   const onContextMenuShown = useCallback(() => {
     window.contextMenuShown = true;
@@ -120,13 +119,23 @@ export const MessageContextMenu = (props: Props) => {
 
   const saveAttachment = useCallback(
     (e: any) => {
+      // this is quite dirty but considering that we want the context menu of the message to show on click on the attachment
+      // and the context menu save attachment item to save the right attachment I did not find a better way for now.
+      let targetAttachmentIndex = e.triggerEvent.path[1].getAttribute('data-attachmentindex');
       e.event.stopPropagation();
       if (!attachments?.length) {
         return;
       }
+
+      if (!targetAttachmentIndex) {
+        targetAttachmentIndex = 0;
+      }
+      if (targetAttachmentIndex > attachments.length) {
+        return;
+      }
       const messageTimestamp = timestamp || serverTimestamp || 0;
       void saveAttachmentToDisk({
-        attachment: attachments[0],
+        attachment: attachments[targetAttachmentIndex],
         messageTimestamp,
         messageSender: sender,
         conversationId: convoId,
@@ -173,7 +182,7 @@ export const MessageContextMenu = (props: Props) => {
       onHidden={onContextMenuHidden}
       animation={animation.fade}
     >
-      {!multipleAttachments && attachments && attachments[0] ? (
+      {attachments?.length ? (
         <Item onClick={saveAttachment}>{window.i18n('downloadAttachment')}</Item>
       ) : null}