@wordpress/block-editor
Version:
294 lines (289 loc) • 10.1 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.MediaUpload = void 0;
var _reactNative = require("react-native");
var _element = require("@wordpress/element");
var _i18n = require("@wordpress/i18n");
var _components = require("@wordpress/components");
var _reactNativeBridge = require("@wordpress/react-native-bridge");
var _icons = require("@wordpress/icons");
var _blockEditor = require("@wordpress/block-editor");
var _compose = require("@wordpress/compose");
var _data = require("@wordpress/data");
var _constants = require("./constants");
var _style = _interopRequireDefault(require("./style.scss"));
var _jsxRuntime = require("react/jsx-runtime");
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const URL_MEDIA_SOURCE = 'URL';
const PICKER_OPENING_DELAY = 200;
class MediaUpload extends _element.Component {
pickerTimeout;
constructor(props) {
super(props);
this.onPickerPresent = this.onPickerPresent.bind(this);
this.onPickerSelect = this.onPickerSelect.bind(this);
this.getAllSources = this.getAllSources.bind(this);
this.state = {
url: '',
showURLInput: false,
otherMediaOptions: []
};
}
componentDidMount() {
const {
allowedTypes = [],
autoOpen
} = this.props;
(0, _reactNativeBridge.getOtherMediaOptions)(allowedTypes, otherMediaOptions => {
const otherMediaOptionsWithIcons = otherMediaOptions.map(option => {
return {
...option,
requiresModal: true,
types: allowedTypes,
id: option.value
};
});
this.setState({
otherMediaOptions: otherMediaOptionsWithIcons
});
});
if (autoOpen) {
this.onPickerPresent();
}
}
componentWillUnmount() {
clearTimeout(this.pickerTimeout);
}
getAllSources() {
const {
onSelectURL
} = this.props;
const cameraImageSource = {
id: _reactNativeBridge.mediaSources.deviceCamera,
// ID is the value sent to native.
value: _reactNativeBridge.mediaSources.deviceCamera + '-IMAGE',
// This is needed to diferenciate image-camera from video-camera sources.
label: _constants.OPTION_TAKE_PHOTO,
requiresModal: true,
types: [_constants.MEDIA_TYPE_IMAGE],
icon: _icons.capturePhoto
};
const cameraVideoSource = {
id: _reactNativeBridge.mediaSources.deviceCamera,
value: _reactNativeBridge.mediaSources.deviceCamera,
label: _constants.OPTION_TAKE_VIDEO,
requiresModal: true,
types: [_constants.MEDIA_TYPE_VIDEO],
icon: _icons.captureVideo
};
const deviceLibrarySource = {
id: _reactNativeBridge.mediaSources.deviceLibrary,
value: _reactNativeBridge.mediaSources.deviceLibrary,
label: (0, _i18n.__)('Choose from device'),
requiresModal: true,
types: [_constants.MEDIA_TYPE_IMAGE, _constants.MEDIA_TYPE_VIDEO],
icon: _icons.image
};
const siteLibrarySource = {
id: _reactNativeBridge.mediaSources.siteMediaLibrary,
value: _reactNativeBridge.mediaSources.siteMediaLibrary,
label: _constants.OPTION_WORDPRESS_MEDIA_LIBRARY,
requiresModal: true,
types: [_constants.MEDIA_TYPE_IMAGE, _constants.MEDIA_TYPE_VIDEO, _constants.MEDIA_TYPE_AUDIO, _constants.MEDIA_TYPE_ANY],
icon: _icons.wordpress,
mediaLibrary: true
};
const urlSource = {
id: URL_MEDIA_SOURCE,
value: URL_MEDIA_SOURCE,
label: _constants.OPTION_INSERT_FROM_URL,
types: [_constants.MEDIA_TYPE_AUDIO, _constants.MEDIA_TYPE_IMAGE, _constants.MEDIA_TYPE_VIDEO],
icon: _icons.globe
};
// Only include `urlSource` option if `onSelectURL` prop is present, in order to match the web behavior.
const internalSources = [deviceLibrarySource, cameraImageSource, cameraVideoSource, siteLibrarySource, ...(onSelectURL ? [urlSource] : [])];
return internalSources.concat(this.state.otherMediaOptions);
}
getMediaOptionsItems() {
const {
allowedTypes = [],
__experimentalOnlyMediaLibrary,
isAudioBlockMediaUploadEnabled
} = this.props;
return this.getAllSources().filter(source => {
if (__experimentalOnlyMediaLibrary) {
return source.mediaLibrary;
} else if (allowedTypes.every(allowedType => allowedType === _constants.MEDIA_TYPE_AUDIO && source.types.includes(allowedType)) && source.id !== URL_MEDIA_SOURCE) {
return isAudioBlockMediaUploadEnabled === true;
}
return allowedTypes.some(allowedType => source.types.includes(allowedType));
}).map(source => {
return {
...source,
icon: source.icon || this.getChooseFromDeviceIcon()
};
});
}
getChooseFromDeviceIcon() {
return _icons.mobile;
}
onPickerPresent() {
const {
autoOpen
} = this.props;
const isIOS = _reactNative.Platform.OS === 'ios';
if (this.picker) {
// the delay below is required because on iOS this action sheet gets dismissed by the close event of the Inserter
// so this delay allows the Inserter to be closed fully before presenting action sheet.
if (autoOpen && isIOS) {
this.pickerTimeout = setTimeout(() => this.picker.presentPicker(), PICKER_OPENING_DELAY);
} else {
this.picker.presentPicker();
}
}
}
onPickerSelect(value) {
const {
allowedTypes = [],
onSelect,
multiple = false
} = this.props;
if (value === URL_MEDIA_SOURCE) {
this.setState({
showURLInput: true
});
return;
}
const mediaSource = this.getAllSources().filter(source => source.value === value).shift();
const types = allowedTypes.filter(type => mediaSource.types.includes(type));
(0, _reactNativeBridge.requestMediaPicker)(mediaSource.id, types, multiple, media => {
if (multiple && media || media && media.id) {
onSelect(media);
}
});
}
render() {
const {
allowedTypes = [],
isReplacingMedia,
multiple
} = this.props;
const isOneType = allowedTypes.length === 1;
const isImage = isOneType && allowedTypes.includes(_constants.MEDIA_TYPE_IMAGE);
const isVideo = isOneType && allowedTypes.includes(_constants.MEDIA_TYPE_VIDEO);
const isAudio = isOneType && allowedTypes.includes(_constants.MEDIA_TYPE_AUDIO);
const isAnyType = isOneType && allowedTypes.includes(_constants.MEDIA_TYPE_ANY);
const isImageOrVideo = allowedTypes.length === 2 && allowedTypes.includes(_constants.MEDIA_TYPE_IMAGE) && allowedTypes.includes(_constants.MEDIA_TYPE_VIDEO);
let pickerTitle;
if (isImage) {
if (isReplacingMedia) {
pickerTitle = (0, _i18n.__)('Replace image');
} else {
pickerTitle = multiple ? (0, _i18n.__)('Choose images') : (0, _i18n.__)('Choose image');
}
} else if (isVideo) {
if (isReplacingMedia) {
pickerTitle = (0, _i18n.__)('Replace video');
} else {
pickerTitle = (0, _i18n.__)('Choose video');
}
} else if (isImageOrVideo) {
if (isReplacingMedia) {
pickerTitle = (0, _i18n.__)('Replace image or video');
} else {
pickerTitle = (0, _i18n.__)('Choose image or video');
}
} else if (isAudio) {
if (isReplacingMedia) {
pickerTitle = (0, _i18n.__)('Replace audio');
} else {
pickerTitle = (0, _i18n.__)('Choose audio');
}
} else if (isAnyType) {
pickerTitle = (0, _i18n.__)('Choose file');
if (isReplacingMedia) {
pickerTitle = (0, _i18n.__)('Replace file');
} else {
pickerTitle = (0, _i18n.__)('Choose file');
}
}
const getMediaOptions = () => /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Picker, {
title: pickerTitle,
hideCancelButton: true,
ref: instance => this.picker = instance,
options: this.getMediaOptionsItems(),
onChange: this.onPickerSelect,
testID: "media-options-picker"
});
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(URLInput, {
isVisible: this.state.showURLInput,
onClose: () => {
if (this.state.url !== '') {
this.props.onSelectURL(this.state.url);
}
this.setState({
showURLInput: false,
url: ''
});
},
onChange: url => {
this.setState({
url
});
},
value: this.state.url
}), this.props.render({
open: this.onPickerPresent,
getMediaOptions
})]
});
}
}
exports.MediaUpload = MediaUpload;
function URLInput(props) {
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.BottomSheet, {
hideHeader: true,
isVisible: props.isVisible,
onClose: props.onClose,
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.PanelBody, {
style: _style.default['media-upload__link-input'],
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.TextControl
// TODO: Switch to `true` (40px size) if possible
, {
__next40pxDefaultSize: false
// eslint-disable-next-line jsx-a11y/no-autofocus
,
autoFocus: true,
autoCapitalize: "none",
autoCorrect: false,
autoComplete: _reactNative.Platform.isIOS ? 'url' : 'off',
keyboardType: "url",
label: _constants.OPTION_INSERT_FROM_URL,
onChange: props.onChange,
placeholder: (0, _i18n.__)('Type a URL'),
value: props.value
})
})
});
}
var _default = exports.default = (0, _compose.compose)([(0, _data.withSelect)(select => {
const {
capabilities
} = select(_blockEditor.store).getSettings();
return {
isAudioBlockMediaUploadEnabled: capabilities?.isAudioBlockMediaUploadEnabled === true
};
})])(MediaUpload);
//# sourceMappingURL=index.native.js.map