From 5c8bb358c67e78a78886c7b172b2dbe27c436957 Mon Sep 17 00:00:00 2001 From: Audric Ackermann Date: Wed, 14 Jul 2021 14:39:19 +1000 Subject: [PATCH] mmeoise callbacks for right panel attachments --- ts/components/LightboxGallery.tsx | 65 ++++++++++--------- .../media-gallery/AttachmentSection.tsx | 2 - .../media-gallery/DocumentListItem.tsx | 34 ++++++---- .../media-gallery/MediaGallery.tsx | 41 ++++-------- 4 files changed, 70 insertions(+), 72 deletions(-) diff --git a/ts/components/LightboxGallery.tsx b/ts/components/LightboxGallery.tsx index 81c16bb7a..83f4a03bc 100644 --- a/ts/components/LightboxGallery.tsx +++ b/ts/components/LightboxGallery.tsx @@ -1,7 +1,7 @@ /** * @prettier */ -import React, { useEffect, useState } from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; import * as MIME from '../types/MIME'; import { Lightbox } from './Lightbox'; @@ -31,7 +31,7 @@ type Props = { export const LightboxGallery = (props: Props) => { const { media, onSave } = props; - const [currentIndex, setCurrentIndex] = useState(0); + const [currentIndex, setCurrentIndex] = useState(-1); const dispatch = useDispatch(); @@ -43,33 +43,26 @@ export const LightboxGallery = (props: Props) => { const selectedMedia = media[currentIndex]; const firstIndex = 0; const lastIndex = media.length - 1; - const onPrevious = - currentIndex > firstIndex - ? () => { - setCurrentIndex(Math.max(currentIndex - 1, 0)); - } - : undefined; - const onNext = - currentIndex < lastIndex - ? () => { - setCurrentIndex(Math.min(currentIndex + 1, lastIndex)); - } - : undefined; - - const handleSave = () => { + + const hasPrevious = currentIndex > firstIndex; + const hasNext = currentIndex < lastIndex; + + const onPrevious = useCallback(() => { + setCurrentIndex(Math.max(currentIndex - 1, 0)); + }, [currentIndex]); + + const onNext = useCallback(() => { + setCurrentIndex(Math.min(currentIndex + 1, lastIndex)); + }, [currentIndex, lastIndex]); + + const handleSave = useCallback(() => { if (!onSave) { return; } const mediaItem = media[currentIndex]; onSave(mediaItem); - }; - - const objectURL = selectedMedia?.objectURL || 'images/alert-outline.svg'; - const { attachment } = selectedMedia; - - const saveCallback = onSave ? handleSave : undefined; - const captionCallback = attachment ? attachment.caption : undefined; + }, [currentIndex, media]); useKey( 'ArrowRight', @@ -88,17 +81,31 @@ export const LightboxGallery = (props: Props) => { [currentIndex] ); - useKey('Escape', () => { - dispatch(showLightBox(undefined)); - }); + useKey( + 'Escape', + () => { + dispatch(showLightBox(undefined)); + }, + undefined, + [currentIndex] + ); + // just to avoid to render the first element during the first render when the user selected another item + if (currentIndex === -1) { + return null; + } + const objectURL = selectedMedia?.objectURL || 'images/alert-outline.svg'; + const { attachment } = selectedMedia; + const saveCallback = onSave ? handleSave : undefined; + const caption = attachment?.caption; return ( + // tslint:disable: use-simple-attributes ); diff --git a/ts/components/conversation/media-gallery/AttachmentSection.tsx b/ts/components/conversation/media-gallery/AttachmentSection.tsx index 834dfe8af..4f2787933 100644 --- a/ts/components/conversation/media-gallery/AttachmentSection.tsx +++ b/ts/components/conversation/media-gallery/AttachmentSection.tsx @@ -14,7 +14,6 @@ type Props = { const Items = (props: Props): JSX.Element => { const { mediaItems, type } = props; - const selectedConversationKey = useSelector(getSelectedConversationKey); return ( <> @@ -40,7 +39,6 @@ const Items = (props: Props): JSX.Element => { shouldShowSeparator={shouldShowSeparator} timestamp={messageTimestamp} mediaItem={mediaItem} - conversationId={selectedConversationKey as string} /> ); default: diff --git a/ts/components/conversation/media-gallery/DocumentListItem.tsx b/ts/components/conversation/media-gallery/DocumentListItem.tsx index 123073c37..36795c5f1 100644 --- a/ts/components/conversation/media-gallery/DocumentListItem.tsx +++ b/ts/components/conversation/media-gallery/DocumentListItem.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useCallback } from 'react'; import classNames from 'classnames'; import moment from 'moment'; @@ -8,6 +8,8 @@ import { getDecryptedMediaUrl } from '../../../session/crypto/DecryptedAttachmen import { sendDataExtractionNotification } from '../../../session/messages/outgoing/controlMessage/DataExtractionNotificationMessage'; import { AttachmentTypeWithPath, save } from '../../../types/Attachment'; import { MediaItemType } from '../../LightboxGallery'; +import { useSelector } from 'react-redux'; +import { getSelectedConversationKey } from '../../../state/selectors/conversations'; type Props = { // Required @@ -18,7 +20,6 @@ type Props = { fileSize?: number | null; shouldShowSeparator?: boolean; mediaItem: MediaItemType; - conversationId: string; }; const saveAttachment = async ({ @@ -32,21 +33,35 @@ const saveAttachment = async ({ messageSender: string; conversationId: string; }) => { - const timestamp = messageTimestamp; attachment.url = await getDecryptedMediaUrl(attachment.url, attachment.contentType); save({ attachment, document, getAbsolutePath: window.Signal.Migrations.getAbsoluteAttachmentPath, - timestamp, + timestamp: messageTimestamp, }); - await sendDataExtractionNotification(conversationId, messageSender, timestamp); + await sendDataExtractionNotification(conversationId, messageSender, messageTimestamp); }; export const DocumentListItem = (props: Props) => { const { shouldShowSeparator, fileName, fileSize, timestamp } = props; const defaultShowSeparator = shouldShowSeparator === undefined ? true : shouldShowSeparator; + const selectedConversationKey = useSelector(getSelectedConversationKey) as string; + + const saveAttachmentCallback = useCallback(() => { + void saveAttachment({ + messageSender: props.mediaItem.messageSender, + messageTimestamp: props.mediaItem.messageTimestamp, + attachment: props.mediaItem.attachment, + conversationId: selectedConversationKey, + }); + }, [ + selectedConversationKey, + props.mediaItem.messageSender, + props.mediaItem.messageTimestamp, + props.mediaItem.attachment, + ]); return (
{
{ - void saveAttachment({ - messageSender: props.mediaItem.messageSender, - messageTimestamp: props.mediaItem.messageTimestamp, - attachment: props.mediaItem.attachment, - conversationId: props.conversationId, - }); - }} + onClick={saveAttachmentCallback} >
diff --git a/ts/components/conversation/media-gallery/MediaGallery.tsx b/ts/components/conversation/media-gallery/MediaGallery.tsx index 847cd2558..efffb3caa 100644 --- a/ts/components/conversation/media-gallery/MediaGallery.tsx +++ b/ts/components/conversation/media-gallery/MediaGallery.tsx @@ -1,9 +1,8 @@ -import React, { useState } from 'react'; +import React, { useCallback, useState } from 'react'; import classNames from 'classnames'; import { AttachmentSection } from './AttachmentSection'; import { EmptyState } from './EmptyState'; -import { missingCaseError } from '../../../util/missingCaseError'; import { MediaItemType } from '../../LightboxGallery'; type Props = { @@ -17,12 +16,10 @@ const Tab = ({ isSelected, label, onSelect, - type, }: { isSelected: boolean; label: string; onSelect: () => void; - type: TabType; }) => { return (
{ const type = selectedTab; if (!mediaItems || mediaItems.length === 0) { - const label = (() => { - switch (type) { - case 'media': - return window.i18n('mediaEmptyState'); - - case 'documents': - return window.i18n('documentsEmptyState'); - - default: - throw missingCaseError(type); - } - })(); + const label = + type === 'media' ? window.i18n('mediaEmptyState') : window.i18n('documentsEmptyState'); return ; } @@ -74,24 +61,22 @@ export const MediaGallery = (props: Props) => { const isDocumentSelected = selectedTab === 'documents'; const isMediaSelected = selectedTab === 'media'; + const setMediaTab = useCallback(() => { + setSelectedTab('media'); + }, []); + + const setDocumentsTab = useCallback(() => { + setSelectedTab('documents'); + }, []); + return (
- { - setSelectedTab('media'); - }} - /> + { - setSelectedTab('documents'); - }} + onSelect={setDocumentsTab} />