| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- import React from 'react';
- import PropTypes from 'prop-types';
- import Carousel, { Modal, ModalGateway } from 'react-images';
- import RefsContext from '../util/RefsContext';
- /**
- * 1. when 'fileFormat' is image, render Attachment as an image
- * 2. when 'fileFormat' is not image, render Attachment as an Attachment component
- */
- export default class ExtractedAttachments extends React.PureComponent {
- constructor(props) {
- super(props);
- this.state = {
- showCarousel: false,
- currentIndex: null,
- };
- }
- imageClickedHandler(index) {
- this.setState({
- showCarousel: true,
- currentIndex: index,
- });
- }
- getAttachmentsFilteredByFormat() {
- return this.props.attachments
- .filter(attachment => attachment.fileFormat.startsWith('image/'));
- }
- getClassesAndStylesForNonGrid() {
- const { refsContext } = this.props;
- const { options } = refsContext;
- const {
- width,
- height,
- 'max-width': maxWidth,
- 'max-height': maxHeight,
- display = 'block',
- } = options;
- const containerStyles = {
- width, height, maxWidth, maxHeight, display,
- };
- const imageClasses = [];
- const imageStyles = {
- width, height, maxWidth, maxHeight,
- };
- return {
- containerStyles,
- imageClasses,
- imageStyles,
- };
- }
- getClassesAndStylesForGrid() {
- const { refsContext } = this.props;
- const { options } = refsContext;
- const {
- 'max-width': maxWidth,
- 'max-height': maxHeight,
- } = options;
- const containerStyles = {
- width: refsContext.getOptGridWidth(),
- height: refsContext.getOptGridHeight(),
- maxWidth,
- maxHeight,
- };
- const imageClasses = ['w-100', 'h-100'];
- const imageStyles = {
- objectFit: 'cover',
- maxWidth,
- maxHeight,
- };
- return {
- containerStyles,
- imageClasses,
- imageStyles,
- };
- }
- /**
- * wrapper method for getClassesAndStylesForGrid/getClassesAndStylesForNonGrid
- */
- getClassesAndStyles() {
- const { refsContext } = this.props;
- const { options } = refsContext;
- return (options.grid != null)
- ? this.getClassesAndStylesForGrid()
- : this.getClassesAndStylesForNonGrid();
- }
- renderExtractedImage(attachment, index) {
- const { refsContext } = this.props;
- const { options } = refsContext;
- // determine alt
- let alt = refsContext.isSingle ? options.alt : undefined; // use only when single mode
- alt = alt || attachment.originalName; // use 'originalName' if options.alt is not specified
- // get styles
- const {
- containerStyles, imageClasses, imageStyles,
- } = this.getClassesAndStyles();
- // carousel settings
- let onClick;
- if (options['no-carousel'] == null) {
- // pointer cursor
- Object.assign(containerStyles, { cursor: 'pointer' });
- // set click handler
- onClick = () => {
- this.imageClickedHandler(index);
- };
- }
- return (
- <div key={attachment._id} style={containerStyles} onClick={onClick}>
- <img src={attachment.filePathProxied} alt={alt} className={imageClasses.join(' ')} style={imageStyles} />
- </div>
- );
- }
- renderCarousel() {
- const { options } = this.props.refsContext;
- const withCarousel = options['no-carousel'] == null;
- const { showCarousel, currentIndex } = this.state;
- const images = this.getAttachmentsFilteredByFormat()
- .map((attachment) => {
- return { src: attachment.filePathProxied };
- });
- // overwrite react-images modal styles
- const zIndex = 1030; // > grw-navbar
- const modalStyles = {
- blanket: (styleObj) => {
- return Object.assign(styleObj, { zIndex });
- },
- positioner: (styleObj) => {
- return Object.assign(styleObj, { zIndex });
- },
- };
- return (
- <ModalGateway>
- { withCarousel && showCarousel && (
- <Modal styles={modalStyles} onClose={() => { this.setState({ showCarousel: false }) }}>
- <Carousel views={images} currentIndex={currentIndex} />
- </Modal>
- ) }
- </ModalGateway>
- );
- }
- render() {
- const { refsContext } = this.props;
- const { options } = refsContext;
- const {
- grid,
- 'grid-gap': gridGap,
- } = options;
- const styles = {};
- // Grid mode
- if (grid != null) {
- const gridTemplateColumns = (refsContext.isOptGridColumnEnabled())
- ? `repeat(${refsContext.getOptGridColumnsNum()}, 1fr)`
- : `repeat(auto-fill, ${refsContext.getOptGridWidth()})`;
- Object.assign(styles, {
- display: 'grid',
- gridTemplateColumns,
- gridAutoRows: '1fr',
- gridGap,
- });
- }
- const contents = this.getAttachmentsFilteredByFormat()
- .map((attachment, index) => this.renderExtractedImage(attachment, index));
- return (
- <React.Fragment>
- <div style={styles}>
- {contents}
- </div>
- { this.renderCarousel() }
- </React.Fragment>
- );
- }
- }
- ExtractedAttachments.propTypes = {
- attachments: PropTypes.arrayOf(PropTypes.object).isRequired,
- refsContext: PropTypes.instanceOf(RefsContext).isRequired,
- };
|