signal-desktop/ts/components/LightboxGallery.tsx

113 lines
2.7 KiB
TypeScript
Raw Normal View History

2020-10-30 20:34:04 +00:00
// Copyright 2018-2020 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import * as MIME from '../types/MIME';
import { Lightbox } from './Lightbox';
2018-04-26 20:48:08 +00:00
import { Message } from './conversation/media-gallery/types/Message';
2019-01-14 21:49:58 +00:00
import { AttachmentType } from '../types/Attachment';
import { LocalizerType } from '../types/Util';
export type MediaItemType = {
2018-04-26 20:48:08 +00:00
objectURL?: string;
thumbnailObjectUrl?: string;
contentType?: MIME.MIMEType;
index: number;
attachment: AttachmentType;
message: Message;
};
export type Props = {
close: () => void;
2019-01-14 21:49:58 +00:00
i18n: LocalizerType;
media: Array<MediaItemType>;
2020-01-08 17:44:54 +00:00
onSave?: (options: {
attachment: AttachmentType;
message: Message;
index: number;
}) => void;
selectedIndex: number;
};
type State = {
selectedIndex: number;
};
export class LightboxGallery extends React.Component<Props, State> {
public static defaultProps: Partial<Props> = {
selectedIndex: 0,
};
constructor(props: Props) {
super(props);
this.state = {
2020-09-12 00:46:52 +00:00
selectedIndex: props.selectedIndex,
};
}
2020-09-12 00:46:52 +00:00
public render(): JSX.Element {
const { close, media, onSave, i18n } = this.props;
const { selectedIndex } = this.state;
const selectedMedia = media[selectedIndex];
const firstIndex = 0;
const lastIndex = media.length - 1;
const onPrevious =
selectedIndex > firstIndex ? this.handlePrevious : undefined;
const onNext = selectedIndex < lastIndex ? this.handleNext : undefined;
2020-08-21 22:06:33 +00:00
const objectURL =
selectedMedia.objectURL || 'images/full-screen-flow/alert-outline.svg';
const { attachment } = selectedMedia;
2018-04-26 20:48:08 +00:00
2019-01-14 21:49:58 +00:00
const saveCallback = onSave ? this.handleSave : undefined;
const captionCallback = attachment ? attachment.caption : undefined;
return (
<Lightbox
2019-01-14 21:49:58 +00:00
caption={captionCallback}
2019-10-03 19:03:46 +00:00
close={close}
contentType={selectedMedia.contentType}
i18n={i18n}
2019-10-03 19:03:46 +00:00
isViewOnce={false}
objectURL={objectURL}
onNext={onNext}
onPrevious={onPrevious}
onSave={saveCallback}
/>
);
}
2019-01-14 21:49:58 +00:00
private readonly handlePrevious = () => {
this.setState(prevState => ({
selectedIndex: Math.max(prevState.selectedIndex - 1, 0),
}));
};
2019-01-14 21:49:58 +00:00
private readonly handleNext = () => {
this.setState((prevState, props) => ({
selectedIndex: Math.min(
prevState.selectedIndex + 1,
props.media.length - 1
),
}));
};
2018-04-26 20:48:08 +00:00
2019-01-14 21:49:58 +00:00
private readonly handleSave = () => {
const { media, onSave } = this.props;
2018-04-26 20:48:08 +00:00
if (!onSave) {
return;
}
const { selectedIndex } = this.state;
const mediaItem = media[selectedIndex];
const { attachment, message, index } = mediaItem;
onSave({ attachment, message, index });
2018-04-26 20:48:08 +00:00
};
}