mirror of
https://github.com/plankanban/planka.git
synced 2025-12-19 01:12:02 +03:00
130 lines
3.7 KiB
React
130 lines
3.7 KiB
React
|
|
/*!
|
||
|
|
* Copyright (c) 2024 PLANKA Software GmbH
|
||
|
|
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||
|
|
*/
|
||
|
|
|
||
|
|
import React, { useMemo } from 'react';
|
||
|
|
import PropTypes from 'prop-types';
|
||
|
|
import classNames from 'classnames';
|
||
|
|
import { useSelector } from 'react-redux';
|
||
|
|
import { useTranslation } from 'react-i18next';
|
||
|
|
import { Item as GalleryItem } from 'react-photoswipe-gallery';
|
||
|
|
|
||
|
|
import selectors from '../../../selectors';
|
||
|
|
import Encodings from '../../../constants/Encodings';
|
||
|
|
import { AttachmentTypes } from '../../../constants/Enums';
|
||
|
|
import ItemContent from './ItemContent';
|
||
|
|
import ContentViewer from './ContentViewer';
|
||
|
|
|
||
|
|
import styles from './Item.module.scss';
|
||
|
|
|
||
|
|
const Item = React.memo(({ id, isVisible }) => {
|
||
|
|
const selectAttachmentById = useMemo(() => selectors.makeSelectAttachmentById(), []);
|
||
|
|
|
||
|
|
const attachment = useSelector((state) => selectAttachmentById(state, id));
|
||
|
|
|
||
|
|
const [t] = useTranslation();
|
||
|
|
|
||
|
|
if (!attachment.isPersisted) {
|
||
|
|
return <ItemContent id={id} />;
|
||
|
|
}
|
||
|
|
|
||
|
|
let galleryItemProps;
|
||
|
|
if (attachment.type === AttachmentTypes.FILE) {
|
||
|
|
if (attachment.data.image) {
|
||
|
|
galleryItemProps = attachment.data.image;
|
||
|
|
} else {
|
||
|
|
let content;
|
||
|
|
switch (attachment.data.mimeType) {
|
||
|
|
case 'application/pdf':
|
||
|
|
content = (
|
||
|
|
// eslint-disable-next-line jsx-a11y/alt-text
|
||
|
|
<object
|
||
|
|
data={attachment.data.url}
|
||
|
|
type={attachment.data.mimeType}
|
||
|
|
className={classNames(styles.content, styles.contentViewer)}
|
||
|
|
/>
|
||
|
|
);
|
||
|
|
|
||
|
|
break;
|
||
|
|
case 'audio/mpeg':
|
||
|
|
case 'audio/wav':
|
||
|
|
case 'audio/ogg':
|
||
|
|
case 'audio/opus':
|
||
|
|
case 'audio/mp4':
|
||
|
|
case 'audio/x-aac':
|
||
|
|
content = (
|
||
|
|
// eslint-disable-next-line jsx-a11y/media-has-caption
|
||
|
|
<audio controls src={attachment.data.url} className={styles.content} />
|
||
|
|
);
|
||
|
|
|
||
|
|
break;
|
||
|
|
case 'video/mp4':
|
||
|
|
case 'video/ogg':
|
||
|
|
case 'video/webm':
|
||
|
|
content = (
|
||
|
|
// eslint-disable-next-line jsx-a11y/media-has-caption
|
||
|
|
<video controls src={attachment.data.url} className={styles.content} />
|
||
|
|
);
|
||
|
|
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
if (attachment.data.encoding === Encodings.UTF8) {
|
||
|
|
content = (
|
||
|
|
<ContentViewer
|
||
|
|
src={attachment.data.url}
|
||
|
|
filename={attachment.data.filename}
|
||
|
|
className={classNames(styles.content, styles.contentViewer)}
|
||
|
|
/>
|
||
|
|
);
|
||
|
|
} else {
|
||
|
|
content = (
|
||
|
|
<span className={classNames(styles.content, styles.contentError)}>
|
||
|
|
{t('common.thereIsNoPreviewAvailableForThisAttachment')}
|
||
|
|
</span>
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
galleryItemProps = {
|
||
|
|
content,
|
||
|
|
};
|
||
|
|
}
|
||
|
|
} else if (attachment.type === AttachmentTypes.LINK) {
|
||
|
|
galleryItemProps = {
|
||
|
|
content: (
|
||
|
|
<span className={classNames(styles.content, styles.contentError)}>
|
||
|
|
{t('common.thereIsNoPreviewAvailableForThisAttachment')}
|
||
|
|
</span>
|
||
|
|
),
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
return (
|
||
|
|
<GalleryItem
|
||
|
|
{...galleryItemProps} // eslint-disable-line react/jsx-props-no-spreading
|
||
|
|
original={attachment.data.url}
|
||
|
|
caption={attachment.name}
|
||
|
|
>
|
||
|
|
{({ ref, open }) =>
|
||
|
|
isVisible ? (
|
||
|
|
<ItemContent
|
||
|
|
ref={ref}
|
||
|
|
id={id}
|
||
|
|
onOpen={attachment.type === AttachmentTypes.FILE ? open : undefined}
|
||
|
|
/>
|
||
|
|
) : (
|
||
|
|
<span ref={ref} />
|
||
|
|
)
|
||
|
|
}
|
||
|
|
</GalleryItem>
|
||
|
|
);
|
||
|
|
});
|
||
|
|
|
||
|
|
Item.propTypes = {
|
||
|
|
id: PropTypes.string.isRequired,
|
||
|
|
isVisible: PropTypes.bool.isRequired,
|
||
|
|
};
|
||
|
|
|
||
|
|
export default Item;
|