2020-03-26 10:57:31 +01:00
|
|
|
import React, { useRef, useEffect } from 'react';
|
2020-03-26 10:22:09 +01:00
|
|
|
import { useDrag, useDrop } from 'react-dnd';
|
2020-02-14 17:44:54 +01:00
|
|
|
import PropTypes from 'prop-types';
|
2020-03-26 10:57:31 +01:00
|
|
|
import { getEmptyImage } from 'react-dnd-html5-backend';
|
2020-03-26 10:22:09 +01:00
|
|
|
import { formatBytes, getExtension, getType, ItemTypes } from '../../utils';
|
2020-03-18 00:47:16 +01:00
|
|
|
|
|
|
|
import Flex from '../Flex';
|
2020-03-05 14:38:51 +01:00
|
|
|
import Text from '../Text';
|
2020-02-14 17:44:54 +01:00
|
|
|
import CardImgWrapper from '../CardImgWrapper';
|
2020-03-02 00:21:43 +01:00
|
|
|
import CardPreview from '../CardPreview';
|
2020-03-18 00:47:16 +01:00
|
|
|
import Tag from '../Tag';
|
2020-02-14 17:44:54 +01:00
|
|
|
import Wrapper from './Wrapper';
|
|
|
|
import Title from './Title';
|
2020-03-10 11:32:52 +01:00
|
|
|
import ErrorMessage from './ErrorMessage';
|
2020-03-10 00:27:18 +01:00
|
|
|
import Border from './Border';
|
2020-02-14 17:44:54 +01:00
|
|
|
|
2020-03-06 17:19:20 +01:00
|
|
|
const Card = ({
|
2020-03-24 07:35:16 +01:00
|
|
|
id,
|
2020-03-06 17:19:20 +01:00
|
|
|
checked,
|
|
|
|
children,
|
|
|
|
errorMessage,
|
|
|
|
hasError,
|
2020-03-26 10:22:09 +01:00
|
|
|
index,
|
|
|
|
isDraggable,
|
2020-03-06 17:19:20 +01:00
|
|
|
mime,
|
2020-03-26 10:22:09 +01:00
|
|
|
moveAsset,
|
2020-03-06 17:19:20 +01:00
|
|
|
name,
|
2020-03-24 07:35:16 +01:00
|
|
|
onClick,
|
2020-03-06 17:19:20 +01:00
|
|
|
small,
|
|
|
|
size,
|
|
|
|
type,
|
|
|
|
url,
|
2020-03-24 15:45:01 +01:00
|
|
|
withFileCaching,
|
2020-03-06 17:19:20 +01:00
|
|
|
}) => {
|
2020-03-26 10:22:09 +01:00
|
|
|
const ref = useRef(null);
|
|
|
|
const [, drop] = useDrop({
|
|
|
|
accept: ItemTypes.MEDIA_CARD,
|
2020-03-26 10:57:31 +01:00
|
|
|
hover(item) {
|
2020-03-26 10:22:09 +01:00
|
|
|
if (!ref.current) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const dragIndex = item.index;
|
|
|
|
const hoverIndex = index;
|
|
|
|
|
|
|
|
// Don't replace items with themselves
|
|
|
|
if (dragIndex === hoverIndex) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-03-26 10:57:31 +01:00
|
|
|
// Directly move the asset for faster reorder
|
|
|
|
// It doing so makes lot of computations though
|
2020-03-26 10:22:09 +01:00
|
|
|
moveAsset(dragIndex, hoverIndex);
|
|
|
|
// Note: we're mutating the monitor item here!
|
|
|
|
// Generally it's better to avoid mutations,
|
|
|
|
// but it's good here for the sake of performance
|
|
|
|
// to avoid expensive index searches.
|
|
|
|
item.index = hoverIndex;
|
|
|
|
},
|
|
|
|
});
|
2020-03-26 10:57:31 +01:00
|
|
|
|
|
|
|
const fileSize = formatBytes(size, 0);
|
|
|
|
const fileType = mime || type;
|
|
|
|
|
|
|
|
const [{ isDragging }, drag, preview] = useDrag({
|
|
|
|
item: { type: ItemTypes.MEDIA_CARD, id, index, checked, url, fileType },
|
2020-03-26 10:22:09 +01:00
|
|
|
canDrag: () => isDraggable,
|
|
|
|
collect: monitor => ({
|
|
|
|
isDragging: monitor.isDragging(),
|
|
|
|
}),
|
|
|
|
});
|
|
|
|
|
2020-03-26 10:57:31 +01:00
|
|
|
// Remove the default preview when the item is being dragged
|
|
|
|
// The preview is handled by the DragLayer
|
|
|
|
useEffect(() => {
|
|
|
|
preview(getEmptyImage(), { captureDraggingState: true });
|
|
|
|
}, [preview]);
|
|
|
|
|
|
|
|
const opacity = isDragging ? 0.2 : 1;
|
2020-03-18 23:31:02 +01:00
|
|
|
|
2020-03-24 07:35:16 +01:00
|
|
|
const handleClick = () => {
|
|
|
|
onClick(id);
|
|
|
|
};
|
|
|
|
|
2020-03-26 10:57:31 +01:00
|
|
|
drag(drop(ref));
|
|
|
|
|
2020-02-14 17:44:54 +01:00
|
|
|
return (
|
2020-03-26 10:22:09 +01:00
|
|
|
<Wrapper onClick={handleClick} isDraggable={isDraggable} ref={ref} style={{ opacity }}>
|
2020-03-10 16:32:12 +01:00
|
|
|
<CardImgWrapper checked={checked} small={small}>
|
2020-03-24 15:45:01 +01:00
|
|
|
<CardPreview
|
|
|
|
hasError={hasError}
|
|
|
|
url={url}
|
|
|
|
type={fileType}
|
|
|
|
withFileCaching={withFileCaching}
|
|
|
|
/>
|
2020-03-10 16:32:12 +01:00
|
|
|
<Border color={hasError ? 'orange' : 'mediumBlue'} shown={checked || hasError} />
|
2020-03-10 00:37:14 +01:00
|
|
|
{children}
|
|
|
|
</CardImgWrapper>
|
2020-03-18 00:47:16 +01:00
|
|
|
<Flex>
|
|
|
|
<Title>{name}</Title>
|
2020-03-23 22:30:23 +01:00
|
|
|
<Tag label={getType(fileType)} />
|
2020-03-18 00:47:16 +01:00
|
|
|
</Flex>
|
|
|
|
<Text color="grey" fontSize="xs" ellipsis>
|
2020-03-23 22:30:23 +01:00
|
|
|
{`${getExtension(fileType)} - ${fileSize}`}
|
2020-03-18 00:47:16 +01:00
|
|
|
</Text>
|
2020-03-10 16:32:12 +01:00
|
|
|
{hasError && <ErrorMessage>{errorMessage}</ErrorMessage>}
|
2020-02-14 17:44:54 +01:00
|
|
|
</Wrapper>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
Card.defaultProps = {
|
2020-03-05 16:13:44 +01:00
|
|
|
checked: false,
|
2020-03-06 17:19:20 +01:00
|
|
|
children: null,
|
2020-03-10 00:27:18 +01:00
|
|
|
errorMessage: null,
|
2020-03-24 07:35:16 +01:00
|
|
|
id: null,
|
2020-03-26 10:22:09 +01:00
|
|
|
index: 0,
|
|
|
|
isDraggable: false,
|
2020-03-06 17:19:20 +01:00
|
|
|
hasError: false,
|
2020-03-10 00:27:18 +01:00
|
|
|
mime: null,
|
2020-03-26 10:22:09 +01:00
|
|
|
moveAsset: () => {},
|
2020-03-05 16:13:44 +01:00
|
|
|
name: null,
|
2020-03-24 07:35:16 +01:00
|
|
|
onClick: () => {},
|
2020-03-05 16:13:44 +01:00
|
|
|
size: 0,
|
2020-03-05 14:34:05 +01:00
|
|
|
small: false,
|
2020-03-05 16:13:44 +01:00
|
|
|
type: null,
|
|
|
|
url: null,
|
2020-03-24 15:45:01 +01:00
|
|
|
withFileCaching: true,
|
2020-02-14 17:44:54 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
Card.propTypes = {
|
2020-03-24 07:35:16 +01:00
|
|
|
id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
2020-03-05 16:13:44 +01:00
|
|
|
checked: PropTypes.bool,
|
2020-03-06 17:19:20 +01:00
|
|
|
children: PropTypes.node,
|
2020-03-10 00:27:18 +01:00
|
|
|
errorMessage: PropTypes.string,
|
2020-03-06 17:19:20 +01:00
|
|
|
hasError: PropTypes.bool,
|
2020-03-26 10:22:09 +01:00
|
|
|
index: PropTypes.number,
|
|
|
|
isDraggable: PropTypes.bool,
|
2020-03-10 00:27:18 +01:00
|
|
|
mime: PropTypes.string,
|
2020-03-26 10:22:09 +01:00
|
|
|
moveAsset: PropTypes.func,
|
2020-03-05 16:13:44 +01:00
|
|
|
name: PropTypes.string,
|
2020-03-24 07:35:16 +01:00
|
|
|
onClick: PropTypes.func,
|
2020-03-05 16:13:44 +01:00
|
|
|
size: PropTypes.number,
|
2020-03-05 14:34:05 +01:00
|
|
|
small: PropTypes.bool,
|
2020-03-05 16:13:44 +01:00
|
|
|
type: PropTypes.string,
|
|
|
|
url: PropTypes.string,
|
2020-03-24 15:45:01 +01:00
|
|
|
withFileCaching: PropTypes.bool,
|
2020-02-14 17:44:54 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
export default Card;
|