@wordpress/block-library
Version:
Block library for the WordPress editor.
331 lines (301 loc) • 9.28 kB
JavaScript
import _extends from "@babel/runtime/helpers/esm/extends";
import { createElement, Fragment } from "@wordpress/element";
/**
* External dependencies
*/
import { View, Text, TouchableWithoutFeedback } from 'react-native';
/**
* WordPress dependencies
*/
import { mediaUploadSync, requestImageFailedRetryDialog, requestImageUploadCancelDialog, requestImageFullscreenPreview } from '@wordpress/react-native-bridge';
import { Icon, Image, IMAGE_DEFAULT_FOCAL_POINT } from '@wordpress/components';
import { MEDIA_TYPE_IMAGE, MEDIA_TYPE_VIDEO, MediaPlaceholder, MediaUpload, MediaUploadProgress, VIDEO_ASPECT_RATIO, VideoPlayer } from '@wordpress/block-editor';
import { Component } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { isURL, getProtocol } from '@wordpress/url';
import { compose, withPreferredColorScheme } from '@wordpress/compose';
/**
* Internal dependencies
*/
import styles from './style.scss';
import icon from './media-container-icon';
import SvgIconRetry from './icon-retry';
/**
* Constants
*/
const ALLOWED_MEDIA_TYPES = [MEDIA_TYPE_IMAGE, MEDIA_TYPE_VIDEO];
const ICON_TYPE = {
PLACEHOLDER: 'placeholder',
RETRY: 'retry'
};
export { imageFillStyles } from './media-container.js';
class MediaContainer extends Component {
constructor() {
super(...arguments);
this.updateMediaProgress = this.updateMediaProgress.bind(this);
this.finishMediaUploadWithSuccess = this.finishMediaUploadWithSuccess.bind(this);
this.finishMediaUploadWithFailure = this.finishMediaUploadWithFailure.bind(this);
this.mediaUploadStateReset = this.mediaUploadStateReset.bind(this);
this.onSelectMediaUploadOption = this.onSelectMediaUploadOption.bind(this);
this.onMediaPressed = this.onMediaPressed.bind(this);
this.state = {
isUploadInProgress: false
};
}
componentDidMount() {
const {
mediaId,
mediaUrl
} = this.props; // Make sure we mark any temporary images as failed if they failed while
// the editor wasn't open.
if (mediaId && mediaUrl && getProtocol(mediaUrl) === 'file:') {
mediaUploadSync();
}
}
onSelectMediaUploadOption(params) {
const {
id,
url,
type
} = params;
const {
onSelectMedia
} = this.props;
onSelectMedia({
media_type: type,
id,
url
});
}
onMediaPressed() {
const {
isUploadInProgress
} = this.state;
const {
mediaId,
mediaUrl,
mediaType,
isMediaSelected,
onMediaSelected
} = this.props;
if (isUploadInProgress) {
requestImageUploadCancelDialog(mediaId);
} else if (mediaId && getProtocol(mediaUrl) === 'file:') {
requestImageFailedRetryDialog(mediaId);
} else if (mediaType === MEDIA_TYPE_IMAGE && isMediaSelected) {
requestImageFullscreenPreview(mediaUrl);
} else if (mediaType === MEDIA_TYPE_IMAGE) {
onMediaSelected();
}
}
getIcon(iconType) {
const {
mediaType,
getStylesFromColorScheme
} = this.props;
let iconStyle;
switch (iconType) {
case ICON_TYPE.RETRY:
iconStyle = mediaType === MEDIA_TYPE_IMAGE ? styles.iconRetry : getStylesFromColorScheme(styles.iconRetryVideo, styles.iconRetryVideoDark);
return createElement(Icon, _extends({
icon: SvgIconRetry
}, iconStyle));
case ICON_TYPE.PLACEHOLDER:
iconStyle = getStylesFromColorScheme(styles.iconPlaceholder, styles.iconPlaceholderDark);
break;
}
return createElement(Icon, _extends({
icon: icon
}, iconStyle));
}
updateMediaProgress() {
if (!this.state.isUploadInProgress) {
this.setState({
isUploadInProgress: true
});
}
}
finishMediaUploadWithSuccess(payload) {
const {
onMediaUpdate
} = this.props;
onMediaUpdate({
id: payload.mediaServerId,
url: payload.mediaUrl
});
this.setState({
isUploadInProgress: false
});
}
finishMediaUploadWithFailure() {
this.setState({
isUploadInProgress: false
});
}
mediaUploadStateReset() {
const {
onMediaUpdate
} = this.props;
onMediaUpdate({
id: null,
url: null
});
this.setState({
isUploadInProgress: false
});
}
renderImage(params, openMediaOptions) {
const {
isUploadInProgress
} = this.state;
const {
aligmentStyles,
focalPoint,
imageFill,
isMediaSelected,
isSelected,
mediaAlt,
mediaUrl,
mediaWidth,
shouldStack
} = this.props;
const {
isUploadFailed,
retryMessage
} = params;
const focalPointValues = !focalPoint ? IMAGE_DEFAULT_FOCAL_POINT : focalPoint;
return createElement(View, {
style: [imageFill && styles.imageWithFocalPoint, imageFill && shouldStack && {
height: styles.imageFill.height
}]
}, createElement(TouchableWithoutFeedback, {
accessible: !isSelected,
onPress: this.onMediaPressed,
disabled: !isSelected
}, createElement(View, {
style: [imageFill && styles.imageCropped, styles.mediaImageContainer, !isUploadInProgress && aligmentStyles]
}, createElement(Image, {
align: "center",
alt: mediaAlt,
focalPoint: imageFill && focalPointValues,
isSelected: isMediaSelected,
isUploadFailed: isUploadFailed,
isUploadInProgress: isUploadInProgress,
onSelectMediaUploadOption: this.onSelectMediaUploadOption,
openMediaOptions: openMediaOptions,
retryMessage: retryMessage,
url: mediaUrl,
width: !isUploadInProgress && mediaWidth
}))));
}
renderVideo(params) {
const {
aligmentStyles,
mediaUrl,
isSelected,
getStylesFromColorScheme
} = this.props;
const {
isUploadInProgress
} = this.state;
const {
isUploadFailed,
retryMessage
} = params;
const showVideo = isURL(mediaUrl) && !isUploadInProgress && !isUploadFailed;
const videoPlaceholderStyles = getStylesFromColorScheme(styles.videoPlaceholder, styles.videoPlaceholderDark);
const retryVideoTextStyles = [styles.uploadFailedText, getStylesFromColorScheme(styles.uploadFailedTextVideo, styles.uploadFailedTextVideoDark)];
return createElement(View, {
style: styles.mediaVideo
}, createElement(TouchableWithoutFeedback, {
accessible: !isSelected,
onPress: this.onMediaPressed,
disabled: !isSelected
}, createElement(View, {
style: [styles.videoContainer, aligmentStyles]
}, createElement(View, {
style: [styles.videoContent, {
aspectRatio: VIDEO_ASPECT_RATIO
}]
}, showVideo && createElement(View, {
style: styles.videoPlayer
}, createElement(VideoPlayer, {
isSelected: isSelected,
style: styles.video,
source: {
uri: mediaUrl
},
paused: true
})), !showVideo && createElement(View, {
style: videoPlaceholderStyles
}, createElement(View, {
style: styles.modalIcon
}, isUploadFailed ? this.getIcon(ICON_TYPE.RETRY) : this.getIcon(ICON_TYPE.PLACEHOLDER)), isUploadFailed && createElement(Text, {
style: retryVideoTextStyles
}, retryMessage))))));
}
renderContent(params, openMediaOptions) {
const {
mediaType
} = this.props;
let mediaElement = null;
switch (mediaType) {
case MEDIA_TYPE_IMAGE:
mediaElement = this.renderImage(params, openMediaOptions);
break;
case MEDIA_TYPE_VIDEO:
mediaElement = this.renderVideo(params);
break;
}
return mediaElement;
}
renderPlaceholder() {
return createElement(MediaPlaceholder, {
icon: this.getIcon(ICON_TYPE.PLACEHOLDER),
labels: {
title: __('Media area')
},
onSelect: this.onSelectMediaUploadOption,
allowedTypes: ALLOWED_MEDIA_TYPES,
onFocus: this.props.onFocus
});
}
render() {
const {
mediaUrl,
mediaId,
mediaType,
onSetOpenPickerRef
} = this.props;
const coverUrl = mediaType === MEDIA_TYPE_IMAGE ? mediaUrl : null;
if (mediaUrl) {
return createElement(MediaUpload, {
isReplacingMedia: true,
onSelect: this.onSelectMediaUploadOption,
allowedTypes: ALLOWED_MEDIA_TYPES,
value: mediaId,
render: _ref => {
let {
open,
getMediaOptions
} = _ref;
onSetOpenPickerRef(open);
return createElement(Fragment, null, getMediaOptions(), createElement(MediaUploadProgress, {
coverUrl: coverUrl,
mediaId: mediaId,
onUpdateMediaProgress: this.updateMediaProgress,
onFinishMediaUploadWithSuccess: this.finishMediaUploadWithSuccess,
onFinishMediaUploadWithFailure: this.finishMediaUploadWithFailure,
onMediaUploadStateReset: this.mediaUploadStateReset,
renderContent: params => {
return this.renderContent(params, open);
}
}));
}
});
}
return this.renderPlaceholder();
}
}
export default compose([withPreferredColorScheme])(MediaContainer);
//# sourceMappingURL=media-container.native.js.map