@craftercms/studio-ui
Version:
Services, components, models & utils to build CrafterCMS authoring extensions.
211 lines (209 loc) • 6.8 kB
JavaScript
/*
* Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3 as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import React from 'react';
import Card from '@mui/material/Card';
import CardHeader, { cardHeaderClasses } from '@mui/material/CardHeader';
import CardMedia, { cardMediaClasses } from '@mui/material/CardMedia';
import CardActionArea from '@mui/material/CardActionArea';
import { makeStyles } from 'tss-react/mui';
import FormGroup from '@mui/material/FormGroup';
import Checkbox from '@mui/material/Checkbox';
import cardTitleStyles, { cardSubtitleStyles } from '../../styles/card';
import palette from '../../styles/palette';
import SystemIcon from '../SystemIcon';
import Box from '@mui/material/Box';
const useStyles = makeStyles()(() => ({
card: {
position: 'relative'
},
cardTitle: {
...cardTitleStyles
},
cardSubtitle: {
...cardSubtitleStyles,
WebkitLineClamp: 1
},
cardHeader: { alignSelf: 'center' },
media: {
height: 0,
paddingTop: '56.25%'
},
mediaIcon: {
paddingTop: '56.25%',
position: 'relative',
overflow: 'hidden',
'& .media-icon': {
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
color: palette.gray.medium4,
fontSize: '50px'
},
'&.list': {
height: '80px',
width: '80px',
paddingTop: '0',
order: -1
}
},
videoThumbnail: {
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
width: '100%'
}
}));
function MediaCard(props) {
const { classes, cx } = useStyles();
// region const { ... } = props
const {
onSelect,
selected,
item,
previewAppBaseUri,
showPath = true,
onClick,
onPreview = onClick,
action,
avatar,
onDragStart,
onDragEnd,
viewMode = 'card'
} = props;
// endregion
let { name, path, type } = item;
if (item.mimeType.includes('audio/')) {
type = 'Audio';
}
let iconMap = {
Page: '@mui/icons-material/InsertDriveFileOutlined',
Video: '@mui/icons-material/VideocamOutlined',
Template: '@mui/icons-material/CodeRounded',
Taxonomy: '@mui/icons-material/LocalOfferOutlined',
Component: '@mui/icons-material/ExtensionOutlined',
Groovy: '@mui/icons-material/CodeRounded',
JavaScript: '@mui/icons-material/CodeRounded',
CSS: '@mui/icons-material/CodeRounded',
Audio: '@mui/icons-material/AudiotrackOutlined'
};
let icon = { id: iconMap[type] ?? '@mui/icons-material/InsertDriveFileOutlined' };
const systemIcon = React.createElement(SystemIcon, { icon: icon, svgIconProps: { className: 'media-icon' } });
const CardActionAreaOrFragment = onPreview ? CardActionArea : React.Fragment;
const cardActionAreaOrFragmentProps = onPreview
? {
className: props.classes?.cardActionArea,
disableRipple: Boolean(onDragStart || onDragEnd),
onClick(e) {
e.preventDefault();
e.stopPropagation();
onPreview(e);
}
}
: {};
return React.createElement(
Card,
{
className: cx(classes.card, props.classes?.root),
draggable: Boolean(onDragStart || onDragEnd),
onDragStart: onDragStart,
onDragEnd: onDragEnd,
onClick: onClick,
sx: [
viewMode === 'row' && {
display: 'flex',
width: '100%',
[`& .${cardHeaderClasses.root}`]: { flexGrow: 1 },
[`& .${cardMediaClasses.root}`]: { paddingTop: '0 !important', height: '80px !important', width: '80px' }
}
]
},
React.createElement(CardHeader, {
classes: { action: classes.cardHeader, root: props.classes?.cardHeader },
avatar: onSelect
? React.createElement(
FormGroup,
{ className: props.classes?.checkbox },
React.createElement(Checkbox, {
checked: selected.includes(path),
onClick: (e) => onSelect(path, e.target.checked),
color: 'primary',
size: 'small'
})
)
: avatar,
title: name,
subheader: showPath ? item.path : null,
action: action,
titleTypographyProps: {
variant: 'subtitle2',
component: 'h2',
className: classes.cardTitle,
title: item.name
},
subheaderTypographyProps: {
variant: 'subtitle2',
component: 'div',
className: classes.cardSubtitle,
color: 'textSecondary',
title: item.path
}
}),
viewMode !== 'compact' &&
React.createElement(
CardActionAreaOrFragment,
{ ...cardActionAreaOrFragmentProps },
type === 'Image'
? React.createElement(CardMedia, {
className: cx(classes.media, props.classes?.media),
image: `${previewAppBaseUri}${path}`,
title: name
})
: React.createElement(
Box,
{
className: cx(classes.mediaIcon, props.classes?.mediaIcon),
sx: [viewMode === 'row' && { paddingTop: '0 !important', height: '80px', width: '80px' }]
},
type === 'Video'
? React.createElement(
'video',
{ className: classes.videoThumbnail },
React.createElement('source', { src: path, type: 'video/mp4' }),
systemIcon
)
: systemIcon
)
)
);
}
export default MediaCard;