Path : /home/vishqocm/vjmedia.in/wp-content/plugins/coblocks/src/blocks/gallery-carousel/
File Upload :
Current File : /home/vishqocm/vjmedia.in/wp-content/plugins/coblocks/src/blocks/gallery-carousel/edit.js

/**
 * External dependencies
 */
import classnames from 'classnames';
import filter from 'lodash/filter';
import Flickity from 'react-flickity-component';

/**
 * Internal dependencies
 */
import { title, icon } from './';
import Inspector from './inspector';
import Controls from './controls';
import GalleryImage from '../../components/block-gallery/gallery-image';
import GalleryPlaceholder from '../../components/block-gallery/gallery-placeholder';
import GalleryDropZone from '../../components/block-gallery/gallery-dropzone';
import GalleryUploader from '../../components/block-gallery/gallery-uploader';
import { BackgroundStyles, BackgroundClasses, BackgroundVideo } from '../../components/background';
import { GalleryClasses } from '../../components/block-gallery/shared';

/**
 * WordPress dependencies
 */
const { __, sprintf } = wp.i18n;
const { Component, Fragment } = wp.element;
const { compose } = wp.compose;
const { withNotices, ResizableBox, Spinner } = wp.components;
const { withColors, RichText } = wp.blockEditor;
const { isBlobURL } = wp.blob;

/**
 * Block consts.
 */
const flickityOptions = {
	draggable: false,
	pageDots: true,
	prevNextButtons: true,
	wrapAround: true,
	autoPlay: false,
	arrowShape: {
		x0: 10,
		x1: 60, y1: 50,
		x2: 65, y2: 45,
		x3: 20,
	},
};

class GalleryCarouselEdit extends Component {
	constructor() {
		super( ...arguments );

		this.onSelectImage = this.onSelectImage.bind( this );
		this.onRemoveImage = this.onRemoveImage.bind( this );
		this.setImageAttributes = this.setImageAttributes.bind( this );
		this.onFocusCaption = this.onFocusCaption.bind( this );
		this.onItemClick = this.onItemClick.bind( this );

		this.state = {
			selectedImage: null,
			captionFocused: false,
		};
	}

	componentDidMount() {
		// This block does not support the following attributes.
		this.props.setAttributes( {
			lightbox: undefined,
			lightboxStyle: undefined,
			shadow: undefined,
		} );
	}

	componentDidUpdate( prevProps ) {
		// Deselect images when deselecting the block.
		if ( ! this.props.isSelected && prevProps.isSelected ) {
			this.setState( {
				selectedImage: null,
				captionSelected: false,
				captionFocused: false,
			} );
		}

		if ( ! this.props.isSelected && prevProps.isSelected && this.state.captionFocused ) {
			this.setState( {
				captionFocused: false,
			} );
		}

		if ( this.props.attributes.gutter <= 0 ) {
			this.props.setAttributes( {
				radius: 0,
			} );
		}

		if ( this.props.attributes.gridSize === 'xlrg' && prevProps.attributes.align === undefined ) {
			this.props.setAttributes( {
				gutter: 0,
				gutterMobile: 0,
			} );
		}
	}

	onSelectImage( index ) {
		return () => {
			if ( this.state.selectedImage !== index ) {
				this.setState( {
					selectedImage: index,
					captionFocused: false,
				} );
			}
		};
	}

	onRemoveImage( index ) {
		return () => {
			const images = filter( this.props.attributes.images, ( _img, i ) => index !== i );
			this.setState( { selectedImage: null } );
			this.props.setAttributes( {
				images,
			} );
		};
	}

	setImageAttributes( index, attributes ) {
		const { attributes: { images }, setAttributes } = this.props;
		if ( ! images[ index ] ) {
			return;
		}
		setAttributes( {
			images: [
				...images.slice( 0, index ),
				{
					...images[ index ],
					...attributes,
				},
				...images.slice( index + 1 ),
			],
		} );
	}

	onFocusCaption() {
		if ( ! this.state.captionFocused ) {
			this.setState( {
				captionFocused: true,
			} );
		}
	}

	onItemClick() {
		if ( ! this.props.isSelected ) {
			this.props.onSelect();
		}

		if ( this.state.captionFocused ) {
			this.setState( {
				captionFocused: false,
			} );
		}
	}

	render() {
		const {
			attributes,
			backgroundColor,
			className,
			isSelected,
			noticeUI,
			setAttributes,
			toggleSelection,
			captionColor,
		} = this.props;

		const {
			align,
			gridSize,
			gutter,
			gutterMobile,
			height,
			images,
			pageDots,
			prevNextButtons,
			primaryCaption,
			backgroundImg,
		} = attributes;

		const hasImages = !! images.length;

		// An additional dropzone to wrap the entire gallery in.
		const dropZone = (
			<GalleryDropZone
				{ ...this.props }
			/>
		);

		const innerClasses = classnames(
			'is-cropped',
			...GalleryClasses( attributes ),
			...BackgroundClasses( attributes ), {
				[ `align${ align }` ]: align,
				'has-horizontal-gutter': gutter > 0,
				'has-no-dots': ! pageDots,
				'has-no-arrows': ! prevNextButtons,
				'is-selected': isSelected,

			}
		);

		const innerStyles = {
			...BackgroundStyles( attributes ),
			backgroundColor: backgroundColor.color,
		};

		const captionStyles = {
			color: captionColor.color,
		};

		const flickityClasses = classnames(
			'has-carousel',
			`has-carousel-${ gridSize }`, {}
		);

		if ( ! hasImages ) {
			return (
				<GalleryPlaceholder
					{ ...this.props }
					label={ title }
					icon={ icon }
				/>
			);
		}

		return (
			<Fragment>
				{ isSelected &&
					<Controls
						{ ...this.props }
					/>
				}
				{ isSelected &&
					<Inspector
						{ ...this.props }
					/>
				}
				{ noticeUI }
				<ResizableBox
					size={ {
						height: height,
						width: '100%',
					} }
					className={ classnames(
						{ 'is-selected': isSelected }
					) }
					minHeight="200"
					enable={ {
						bottom: true,
						bottomLeft: false,
						bottomRight: false,
						left: false,
						right: false,
						top: false,
						topLeft: false,
						topRight: false,
					} }
					onResizeStop={ ( _event, _direction, _elt, delta ) => {
						setAttributes( {
							height: parseInt( height + delta.height, 10 ),
						} );
						toggleSelection( true );
					} }
					onResizeStart={ () => {
						toggleSelection( false );
					} }
				>
					{ dropZone }
					{ isBlobURL( backgroundImg ) && <Spinner /> }
					{ BackgroundVideo( attributes ) }
					<div className={ className }>
						<div
							className={ innerClasses }
							style={ innerStyles }
						>
							<Flickity
								className={ flickityClasses }
								disableImagesLoaded={ false }
								flickityRef={ c => this.flkty = c }
								options={ flickityOptions }
								reloadOnUpdate={ true }
								updateOnEachImageLoad={ true }
							>
								{ images.map( ( img, index ) => {
									// translators: %1$d is the order number of the image, %2$d is the total number of images
									const ariaLabel = sprintf( __( 'image %1$d of %2$d in gallery' ), ( index + 1 ), images.length );

									return (
										<div className="coblocks-gallery--item" key={ img.id || img.url } onClick={ this.onItemClick }>
											<GalleryImage
												url={ img.url }
												alt={ img.alt }
												id={ img.id }
												gutter={ gutter }
												gutterMobile={ gutterMobile }
												marginRight={ true }
												marginLeft={ true }
												isSelected={ isSelected && this.state.selectedImage === index }
												onRemove={ this.onRemoveImage( index ) }
												onSelect={ this.onSelectImage( index ) }
												setAttributes={ ( attrs ) => this.setImageAttributes( index, attrs ) }
												caption={ img.caption }
												aria-label={ ariaLabel }
												supportsCaption={ false }
												supportsMoving={ false }
											/>
										</div>
									);
								} ) }
								{ isSelected && (
									<div className="coblocks-gallery--item">
										<GalleryUploader { ...this.props }
											gutter={ gutter }
											gutterMobile={ gutterMobile }
											marginRight={ true }
											marginLeft={ true }
										/>
									</div>
								) }
							</Flickity>
						</div>
					</div>
				</ResizableBox>
				{ ( ! RichText.isEmpty( primaryCaption ) || isSelected ) && (
					<RichText
						tagName="figcaption"
						placeholder={ __( 'Write caption…' ) }
						value={ primaryCaption }
						className="coblocks-gallery--caption coblocks-gallery--primary-caption"
						style={ captionStyles }
						unstableOnFocus={ this.onFocusCaption }
						onChange={ ( value ) => setAttributes( { primaryCaption: value } ) }
						isSelected={ this.state.captionFocused }
						keepPlaceholderOnFocus
						inlineToolbar
					/>
				) }
			</Fragment>
		);
	}
}

export default compose( [
	withColors( { backgroundColor: 'background-color', captionColor: 'color' } ),
	withNotices,
] )( GalleryCarouselEdit );