mmeoise callbacks for right panel attachments

pull/1783/head
Audric Ackermann 4 years ago
parent 511adcf388
commit 5c8bb358c6
No known key found for this signature in database
GPG Key ID: 999F434D76324AD4

@ -1,7 +1,7 @@
/** /**
* @prettier * @prettier
*/ */
import React, { useEffect, useState } from 'react'; import React, { useCallback, useEffect, useState } from 'react';
import * as MIME from '../types/MIME'; import * as MIME from '../types/MIME';
import { Lightbox } from './Lightbox'; import { Lightbox } from './Lightbox';
@ -31,7 +31,7 @@ type Props = {
export const LightboxGallery = (props: Props) => { export const LightboxGallery = (props: Props) => {
const { media, onSave } = props; const { media, onSave } = props;
const [currentIndex, setCurrentIndex] = useState(0); const [currentIndex, setCurrentIndex] = useState(-1);
const dispatch = useDispatch(); const dispatch = useDispatch();
@ -43,33 +43,26 @@ export const LightboxGallery = (props: Props) => {
const selectedMedia = media[currentIndex]; const selectedMedia = media[currentIndex];
const firstIndex = 0; const firstIndex = 0;
const lastIndex = media.length - 1; const lastIndex = media.length - 1;
const onPrevious =
currentIndex > firstIndex const hasPrevious = currentIndex > firstIndex;
? () => { const hasNext = currentIndex < lastIndex;
setCurrentIndex(Math.max(currentIndex - 1, 0));
} const onPrevious = useCallback(() => {
: undefined; setCurrentIndex(Math.max(currentIndex - 1, 0));
const onNext = }, [currentIndex]);
currentIndex < lastIndex
? () => { const onNext = useCallback(() => {
setCurrentIndex(Math.min(currentIndex + 1, lastIndex)); setCurrentIndex(Math.min(currentIndex + 1, lastIndex));
} }, [currentIndex, lastIndex]);
: undefined;
const handleSave = useCallback(() => {
const handleSave = () => {
if (!onSave) { if (!onSave) {
return; return;
} }
const mediaItem = media[currentIndex]; const mediaItem = media[currentIndex];
onSave(mediaItem); onSave(mediaItem);
}; }, [currentIndex, media]);
const objectURL = selectedMedia?.objectURL || 'images/alert-outline.svg';
const { attachment } = selectedMedia;
const saveCallback = onSave ? handleSave : undefined;
const captionCallback = attachment ? attachment.caption : undefined;
useKey( useKey(
'ArrowRight', 'ArrowRight',
@ -88,17 +81,31 @@ export const LightboxGallery = (props: Props) => {
[currentIndex] [currentIndex]
); );
useKey('Escape', () => { useKey(
dispatch(showLightBox(undefined)); '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 ( return (
// tslint:disable: use-simple-attributes
<Lightbox <Lightbox
onPrevious={onPrevious} onPrevious={hasPrevious ? onPrevious : undefined}
onNext={onNext} onNext={hasNext ? onNext : undefined}
onSave={saveCallback} onSave={saveCallback}
objectURL={objectURL} objectURL={objectURL}
caption={captionCallback} caption={caption}
contentType={selectedMedia.contentType} contentType={selectedMedia.contentType}
/> />
); );

@ -14,7 +14,6 @@ type Props = {
const Items = (props: Props): JSX.Element => { const Items = (props: Props): JSX.Element => {
const { mediaItems, type } = props; const { mediaItems, type } = props;
const selectedConversationKey = useSelector(getSelectedConversationKey);
return ( return (
<> <>
@ -40,7 +39,6 @@ const Items = (props: Props): JSX.Element => {
shouldShowSeparator={shouldShowSeparator} shouldShowSeparator={shouldShowSeparator}
timestamp={messageTimestamp} timestamp={messageTimestamp}
mediaItem={mediaItem} mediaItem={mediaItem}
conversationId={selectedConversationKey as string}
/> />
); );
default: default:

@ -1,4 +1,4 @@
import React from 'react'; import React, { useCallback } from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import moment from 'moment'; import moment from 'moment';
@ -8,6 +8,8 @@ import { getDecryptedMediaUrl } from '../../../session/crypto/DecryptedAttachmen
import { sendDataExtractionNotification } from '../../../session/messages/outgoing/controlMessage/DataExtractionNotificationMessage'; import { sendDataExtractionNotification } from '../../../session/messages/outgoing/controlMessage/DataExtractionNotificationMessage';
import { AttachmentTypeWithPath, save } from '../../../types/Attachment'; import { AttachmentTypeWithPath, save } from '../../../types/Attachment';
import { MediaItemType } from '../../LightboxGallery'; import { MediaItemType } from '../../LightboxGallery';
import { useSelector } from 'react-redux';
import { getSelectedConversationKey } from '../../../state/selectors/conversations';
type Props = { type Props = {
// Required // Required
@ -18,7 +20,6 @@ type Props = {
fileSize?: number | null; fileSize?: number | null;
shouldShowSeparator?: boolean; shouldShowSeparator?: boolean;
mediaItem: MediaItemType; mediaItem: MediaItemType;
conversationId: string;
}; };
const saveAttachment = async ({ const saveAttachment = async ({
@ -32,21 +33,35 @@ const saveAttachment = async ({
messageSender: string; messageSender: string;
conversationId: string; conversationId: string;
}) => { }) => {
const timestamp = messageTimestamp;
attachment.url = await getDecryptedMediaUrl(attachment.url, attachment.contentType); attachment.url = await getDecryptedMediaUrl(attachment.url, attachment.contentType);
save({ save({
attachment, attachment,
document, document,
getAbsolutePath: window.Signal.Migrations.getAbsoluteAttachmentPath, getAbsolutePath: window.Signal.Migrations.getAbsoluteAttachmentPath,
timestamp, timestamp: messageTimestamp,
}); });
await sendDataExtractionNotification(conversationId, messageSender, timestamp); await sendDataExtractionNotification(conversationId, messageSender, messageTimestamp);
}; };
export const DocumentListItem = (props: Props) => { export const DocumentListItem = (props: Props) => {
const { shouldShowSeparator, fileName, fileSize, timestamp } = props; const { shouldShowSeparator, fileName, fileSize, timestamp } = props;
const defaultShowSeparator = shouldShowSeparator === undefined ? true : shouldShowSeparator; 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 ( return (
<div <div
@ -58,14 +73,7 @@ export const DocumentListItem = (props: Props) => {
<div <div
className="module-document-list-item__content" className="module-document-list-item__content"
role="button" role="button"
onClick={() => { onClick={saveAttachmentCallback}
void saveAttachment({
messageSender: props.mediaItem.messageSender,
messageTimestamp: props.mediaItem.messageTimestamp,
attachment: props.mediaItem.attachment,
conversationId: props.conversationId,
});
}}
> >
<div className="module-document-list-item__icon" /> <div className="module-document-list-item__icon" />
<div className="module-document-list-item__metadata"> <div className="module-document-list-item__metadata">

@ -1,9 +1,8 @@
import React, { useState } from 'react'; import React, { useCallback, useState } from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import { AttachmentSection } from './AttachmentSection'; import { AttachmentSection } from './AttachmentSection';
import { EmptyState } from './EmptyState'; import { EmptyState } from './EmptyState';
import { missingCaseError } from '../../../util/missingCaseError';
import { MediaItemType } from '../../LightboxGallery'; import { MediaItemType } from '../../LightboxGallery';
type Props = { type Props = {
@ -17,12 +16,10 @@ const Tab = ({
isSelected, isSelected,
label, label,
onSelect, onSelect,
type,
}: { }: {
isSelected: boolean; isSelected: boolean;
label: string; label: string;
onSelect: () => void; onSelect: () => void;
type: TabType;
}) => { }) => {
return ( return (
<div <div
@ -45,18 +42,8 @@ const Sections = (props: Props & { selectedTab: TabType }) => {
const type = selectedTab; const type = selectedTab;
if (!mediaItems || mediaItems.length === 0) { if (!mediaItems || mediaItems.length === 0) {
const label = (() => { const label =
switch (type) { type === 'media' ? window.i18n('mediaEmptyState') : window.i18n('documentsEmptyState');
case 'media':
return window.i18n('mediaEmptyState');
case 'documents':
return window.i18n('documentsEmptyState');
default:
throw missingCaseError(type);
}
})();
return <EmptyState data-test="EmptyState" label={label} />; return <EmptyState data-test="EmptyState" label={label} />;
} }
@ -74,24 +61,22 @@ export const MediaGallery = (props: Props) => {
const isDocumentSelected = selectedTab === 'documents'; const isDocumentSelected = selectedTab === 'documents';
const isMediaSelected = selectedTab === 'media'; const isMediaSelected = selectedTab === 'media';
const setMediaTab = useCallback(() => {
setSelectedTab('media');
}, []);
const setDocumentsTab = useCallback(() => {
setSelectedTab('documents');
}, []);
return ( return (
<div className="module-media-gallery"> <div className="module-media-gallery">
<div className="module-media-gallery__tab-container"> <div className="module-media-gallery__tab-container">
<Tab <Tab label={window.i18n('media')} isSelected={isMediaSelected} onSelect={setMediaTab} />
label={window.i18n('media')}
type="media"
isSelected={isMediaSelected}
onSelect={() => {
setSelectedTab('media');
}}
/>
<Tab <Tab
label={window.i18n('documents')} label={window.i18n('documents')}
type="documents"
isSelected={isDocumentSelected} isSelected={isDocumentSelected}
onSelect={() => { onSelect={setDocumentsTab}
setSelectedTab('documents');
}}
/> />
</div> </div>
<div className="module-media-gallery__content"> <div className="module-media-gallery__content">

Loading…
Cancel
Save