2018-04-11 11:57:31 -04:00
|
|
|
import React from 'react';
|
2018-07-17 17:15:34 -07:00
|
|
|
import classNames from 'classnames';
|
2018-04-11 11:57:31 -04:00
|
|
|
|
2018-04-12 20:56:05 -04:00
|
|
|
import moment from 'moment';
|
|
|
|
|
2018-04-14 21:11:40 -04:00
|
|
|
import { AttachmentSection } from './AttachmentSection';
|
2018-04-26 19:06:48 -04:00
|
|
|
import { EmptyState } from './EmptyState';
|
2018-11-14 10:47:19 -08:00
|
|
|
import { groupMediaItemsByDate } from './groupMediaItemsByDate';
|
2018-04-25 16:42:08 -04:00
|
|
|
import { ItemClickEvent } from './types/ItemClickEvent';
|
2018-04-26 19:06:48 -04:00
|
|
|
import { missingCaseError } from '../../../util/missingCaseError';
|
2019-01-14 13:49:58 -08:00
|
|
|
import { LocalizerType } from '../../../types/Util';
|
2018-04-12 16:23:26 -04:00
|
|
|
|
2018-11-14 10:47:19 -08:00
|
|
|
import { MediaItemType } from '../../LightboxGallery';
|
|
|
|
|
2018-04-11 11:57:31 -04:00
|
|
|
interface Props {
|
2018-11-14 10:47:19 -08:00
|
|
|
documents: Array<MediaItemType>;
|
2019-01-14 13:49:58 -08:00
|
|
|
i18n: LocalizerType;
|
2018-11-14 10:47:19 -08:00
|
|
|
media: Array<MediaItemType>;
|
2018-04-15 02:16:39 -04:00
|
|
|
onItemClick?: (event: ItemClickEvent) => void;
|
2018-04-12 16:23:26 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
interface State {
|
2018-11-14 10:47:19 -08:00
|
|
|
selectedTab: 'media' | 'documents';
|
2018-04-11 11:57:31 -04:00
|
|
|
}
|
|
|
|
|
2018-04-12 20:56:05 -04:00
|
|
|
const MONTH_FORMAT = 'MMMM YYYY';
|
2018-04-12 16:23:26 -04:00
|
|
|
|
|
|
|
interface TabSelectEvent {
|
2018-11-14 10:47:19 -08:00
|
|
|
type: 'media' | 'documents';
|
2018-04-12 16:23:26 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
const Tab = ({
|
|
|
|
isSelected,
|
|
|
|
label,
|
|
|
|
onSelect,
|
|
|
|
type,
|
|
|
|
}: {
|
2018-04-13 16:25:52 -04:00
|
|
|
isSelected: boolean;
|
|
|
|
label: string;
|
|
|
|
onSelect?: (event: TabSelectEvent) => void;
|
2018-11-14 10:47:19 -08:00
|
|
|
type: 'media' | 'documents';
|
2018-04-12 16:23:26 -04:00
|
|
|
}) => {
|
2018-05-22 12:31:43 -07:00
|
|
|
const handleClick = onSelect
|
|
|
|
? () => {
|
|
|
|
onSelect({ type });
|
|
|
|
}
|
|
|
|
: undefined;
|
2018-04-12 16:23:26 -04:00
|
|
|
|
|
|
|
return (
|
|
|
|
<div
|
2018-07-17 17:15:34 -07:00
|
|
|
className={classNames(
|
|
|
|
'module-media-gallery__tab',
|
|
|
|
isSelected ? 'module-media-gallery__tab--active' : null
|
|
|
|
)}
|
2018-04-12 16:23:26 -04:00
|
|
|
onClick={handleClick}
|
2018-05-22 12:31:43 -07:00
|
|
|
role="tab"
|
2018-04-12 16:23:26 -04:00
|
|
|
>
|
|
|
|
{label}
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
export class MediaGallery extends React.Component<Props, State> {
|
|
|
|
public state: State = {
|
|
|
|
selectedTab: 'media',
|
|
|
|
};
|
|
|
|
|
2018-04-11 11:57:31 -04:00
|
|
|
public render() {
|
2018-04-12 16:23:26 -04:00
|
|
|
const { selectedTab } = this.state;
|
|
|
|
|
2018-04-11 11:57:31 -04:00
|
|
|
return (
|
2018-07-17 17:15:34 -07:00
|
|
|
<div className="module-media-gallery">
|
|
|
|
<div className="module-media-gallery__tab-container">
|
2018-04-12 16:23:26 -04:00
|
|
|
<Tab
|
|
|
|
label="Media"
|
|
|
|
type="media"
|
|
|
|
isSelected={selectedTab === 'media'}
|
|
|
|
onSelect={this.handleTabSelect}
|
|
|
|
/>
|
|
|
|
<Tab
|
|
|
|
label="Documents"
|
|
|
|
type="documents"
|
|
|
|
isSelected={selectedTab === 'documents'}
|
|
|
|
onSelect={this.handleTabSelect}
|
|
|
|
/>
|
|
|
|
</div>
|
2018-07-17 17:15:34 -07:00
|
|
|
<div className="module-media-gallery__content">
|
|
|
|
{this.renderSections()}
|
|
|
|
</div>
|
2018-04-12 16:23:26 -04:00
|
|
|
</div>
|
2018-04-11 11:57:31 -04:00
|
|
|
);
|
|
|
|
}
|
2018-04-12 16:23:26 -04:00
|
|
|
|
2019-01-14 13:49:58 -08:00
|
|
|
private readonly handleTabSelect = (event: TabSelectEvent): void => {
|
2018-04-13 16:25:52 -04:00
|
|
|
this.setState({ selectedTab: event.type });
|
|
|
|
};
|
2018-04-13 10:55:34 -04:00
|
|
|
|
2018-04-12 20:56:05 -04:00
|
|
|
private renderSections() {
|
2018-04-15 02:16:39 -04:00
|
|
|
const { i18n, media, documents, onItemClick } = this.props;
|
2018-04-12 20:56:05 -04:00
|
|
|
const { selectedTab } = this.state;
|
|
|
|
|
2018-11-14 10:47:19 -08:00
|
|
|
const mediaItems = selectedTab === 'media' ? media : documents;
|
2018-04-12 20:56:05 -04:00
|
|
|
const type = selectedTab;
|
|
|
|
|
2018-11-14 10:47:19 -08:00
|
|
|
if (!mediaItems || mediaItems.length === 0) {
|
2018-04-26 19:06:48 -04:00
|
|
|
const label = (() => {
|
|
|
|
switch (type) {
|
|
|
|
case 'media':
|
|
|
|
return i18n('mediaEmptyState');
|
|
|
|
|
|
|
|
case 'documents':
|
|
|
|
return i18n('documentsEmptyState');
|
|
|
|
|
|
|
|
default:
|
|
|
|
throw missingCaseError(type);
|
|
|
|
}
|
|
|
|
})();
|
2018-05-22 12:31:43 -07:00
|
|
|
|
2018-04-26 19:06:48 -04:00
|
|
|
return <EmptyState data-test="EmptyState" label={label} />;
|
2018-04-12 20:56:05 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
const now = Date.now();
|
2018-11-14 10:47:19 -08:00
|
|
|
const sections = groupMediaItemsByDate(now, mediaItems).map(section => {
|
|
|
|
const first = section.mediaItems[0];
|
|
|
|
const { message } = first;
|
|
|
|
const date = moment(message.received_at);
|
2018-04-13 16:27:06 -04:00
|
|
|
const header =
|
|
|
|
section.type === 'yearMonth'
|
|
|
|
? date.format(MONTH_FORMAT)
|
|
|
|
: i18n(section.type);
|
2018-05-22 12:31:43 -07:00
|
|
|
|
2018-04-12 20:56:05 -04:00
|
|
|
return (
|
2018-04-14 21:11:40 -04:00
|
|
|
<AttachmentSection
|
2018-04-12 20:56:05 -04:00
|
|
|
key={header}
|
|
|
|
header={header}
|
|
|
|
i18n={i18n}
|
|
|
|
type={type}
|
2018-11-14 10:47:19 -08:00
|
|
|
mediaItems={section.mediaItems}
|
2018-04-15 02:16:39 -04:00
|
|
|
onItemClick={onItemClick}
|
2018-04-12 20:56:05 -04:00
|
|
|
/>
|
|
|
|
);
|
|
|
|
});
|
2018-04-26 19:06:13 -04:00
|
|
|
|
2018-07-17 17:15:34 -07:00
|
|
|
return <div className="module-media-gallery__sections">{sections}</div>;
|
2018-04-12 16:23:26 -04:00
|
|
|
}
|
2018-04-11 11:57:31 -04:00
|
|
|
}
|