diff --git a/packages/block-library/src/image/edit.native.js b/packages/block-library/src/image/edit.native.js
index 5b4132e19a2b2..476dea2981b15 100644
--- a/packages/block-library/src/image/edit.native.js
+++ b/packages/block-library/src/image/edit.native.js
@@ -9,67 +9,104 @@ import RNReactNativeGutenbergBridge from 'react-native-gutenberg-bridge';
*/
import { MediaPlaceholder, RichText, BlockControls } from '@wordpress/editor';
import { Toolbar, ToolbarButton } from '@wordpress/components';
+import { Component } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
+import ImageSize from './image-size';
-export default function ImageEdit( props ) {
- const { attributes, isSelected, setAttributes } = props;
- const { url, caption } = attributes;
+class ImageEdit extends Component {
+ constructor() {
+ super( ...arguments );
+ this.onMediaLibraryPress = this.onMediaLibraryPress.bind( this );
+ }
- const onUploadPress = () => {
+ onUploadPress() {
// This method should present an image picker from
// the device.
//TODO: Implement upload image method.
- };
+ }
- const onMediaLibraryPress = () => {
+ onMediaLibraryPress() {
RNReactNativeGutenbergBridge.onMediaLibraryPress( ( mediaUrl ) => {
if ( mediaUrl ) {
- setAttributes( { url: mediaUrl } );
+ this.props.setAttributes( { url: mediaUrl } );
}
} );
- };
+ }
- if ( ! url ) {
+ toolbarEditButton() {
return (
-
+
+
+
);
}
- const toolbarEditButton = (
-
-
-
- );
+ render() {
+ const { attributes, isSelected, setAttributes } = this.props;
+ const { url, caption, height, width } = attributes;
+
+ if ( ! url ) {
+ return (
+
+ );
+ }
+
+ return (
+
+
+ { this.toolbarEditButton() }
+
+
+ { ( sizes ) => {
+ const {
+ imageWidthWithinContainer,
+ imageHeightWithinContainer,
+ } = sizes;
- return (
-
-
- { toolbarEditButton }
-
-
- { ( ! RichText.isEmpty( caption ) > 0 || isSelected ) && (
-
- setAttributes( { caption: newCaption } ) }
- />
-
- ) }
-
- );
+ let finalHeight = imageHeightWithinContainer;
+ if ( height > 0 && height < imageHeightWithinContainer ) {
+ finalHeight = height;
+ }
+
+ let finalWidth = imageWidthWithinContainer;
+ if ( width > 0 && width < imageWidthWithinContainer ) {
+ finalWidth = width;
+ }
+
+ return (
+
+
+
+ );
+ } }
+
+ { ( ! RichText.isEmpty( caption ) > 0 || isSelected ) && (
+
+ setAttributes( { caption: newCaption } ) }
+ />
+
+ ) }
+
+ );
+ }
}
+
+export default ImageEdit;
diff --git a/packages/block-library/src/image/image-size.js b/packages/block-library/src/image/image-size.js
index 0a1b88aed12d7..bc7ebaeaa59b4 100644
--- a/packages/block-library/src/image/image-size.js
+++ b/packages/block-library/src/image/image-size.js
@@ -9,6 +9,11 @@ import { noop } from 'lodash';
import { withGlobalEvents } from '@wordpress/compose';
import { Component } from '@wordpress/element';
+/**
+ * Internal dependencies
+ */
+import { calculatePreferedImageSize } from './utils';
+
class ImageSize extends Component {
constructor() {
super( ...arguments );
@@ -55,11 +60,7 @@ class ImageSize extends Component {
}
calculateSize() {
- const maxWidth = this.container.clientWidth;
- const exceedMaxWidth = this.image.width > maxWidth;
- const ratio = this.image.height / this.image.width;
- const width = exceedMaxWidth ? maxWidth : this.image.width;
- const height = exceedMaxWidth ? maxWidth * ratio : this.image.height;
+ const { width, height } = calculatePreferedImageSize( this.image, this.container );
this.setState( { width, height } );
}
diff --git a/packages/block-library/src/image/image-size.native.js b/packages/block-library/src/image/image-size.native.js
new file mode 100644
index 0000000000000..8b29b9607e81e
--- /dev/null
+++ b/packages/block-library/src/image/image-size.native.js
@@ -0,0 +1,87 @@
+/**
+ * WordPress dependencies
+ */
+import { Component } from '@wordpress/element';
+
+/**
+* External dependencies
+*/
+import { View, Image } from 'react-native';
+
+/**
+ * Internal dependencies
+ */
+import { calculatePreferedImageSize } from './utils';
+
+class ImageSize extends Component {
+ constructor() {
+ super( ...arguments );
+ this.state = {
+ width: undefined,
+ height: undefined,
+ };
+ this.onLayout = this.onLayout.bind( this );
+ }
+
+ componentDidUpdate( prevProps ) {
+ if ( this.props.src !== prevProps.src ) {
+ this.image = {};
+
+ this.setState( {
+ width: undefined,
+ height: undefined,
+ } );
+ this.fetchImageSize();
+ }
+
+ if ( this.props.dirtynessTrigger !== prevProps.dirtynessTrigger ) {
+ this.calculateSize();
+ }
+ }
+
+ componentDidMount() {
+ this.fetchImageSize();
+ }
+
+ fetchImageSize() {
+ Image.getSize( this.props.src, ( width, height ) => {
+ this.image = { width, height };
+ this.calculateSize();
+ } );
+ }
+
+ calculateSize() {
+ if ( this.image === undefined || this.container === undefined ) {
+ return;
+ }
+ const { width, height } = calculatePreferedImageSize( this.image, this.container );
+ this.setState( { width, height } );
+ }
+
+ onLayout( event ) {
+ const { width, height } = event.nativeEvent.layout;
+ this.container = {
+ clientWidth: width,
+ clientHeight: height,
+ };
+ this.calculateSize();
+ }
+
+ render() {
+ const sizes = {
+ imageWidth: this.image && this.image.width,
+ imageHeight: this.image && this.image.height,
+ containerWidth: this.container && this.container.width,
+ containerHeight: this.container && this.container.height,
+ imageWidthWithinContainer: this.state.width,
+ imageHeightWithinContainer: this.state.height,
+ };
+ return (
+
+ { this.props.children( sizes ) }
+
+ );
+ }
+}
+
+export default ImageSize;
diff --git a/packages/block-library/src/image/utils.js b/packages/block-library/src/image/utils.js
new file mode 100644
index 0000000000000..32bdb9d71564c
--- /dev/null
+++ b/packages/block-library/src/image/utils.js
@@ -0,0 +1,9 @@
+
+export function calculatePreferedImageSize( image, container ) {
+ const maxWidth = container.clientWidth;
+ const exceedMaxWidth = image.width > maxWidth;
+ const ratio = image.height / image.width;
+ const width = exceedMaxWidth ? maxWidth : image.width;
+ const height = exceedMaxWidth ? maxWidth * ratio : image.height;
+ return { width, height };
+}