diff --git a/src/components/AddImages/AddImages.js b/src/components/AddImages/AddImages.js
index 65096843..c5cc445e 100644
--- a/src/components/AddImages/AddImages.js
+++ b/src/components/AddImages/AddImages.js
@@ -8,6 +8,7 @@
*
*/
import React, { PropTypes } from 'react';
+import { SortableContainer, SortableElement } from 'react-sortable-hoc';
import { Promised } from '../../components';
import css from './AddImages.css';
@@ -24,47 +25,54 @@ const readImage = file => new Promise((resolve, reject) => {
reader.readAsDataURL(file);
});
-const AddImages = props => {
+// Create sortable elments out of given thumbnail file
+const SortableImage = SortableElement(props => {
+ const { file, id, imageId } = props;
+ // While image is uploading we show overlay on top of thumbnail
+ const uploadingOverlay = !imageId ?
Uploading
: null;
+ return (
+ {
+ return (
+
+
+ {uploadingOverlay}
+
+ );
+ }}
+ renderRejected={() => Could not read file}
+ />
+ );
+});
+
+// Create container where there are sortable images and passed children like "Add image" input etc.
+const SortableImages = SortableContainer(props => {
const { children, images } = props;
return (
-
- {images.map(i => {
- // While image is uploading we show overlay on top of thumbnail
- const uploadingOverlay = !i.imageId
- ?
Uploading
- : null;
- return (
-
{
- return (
-
-

- {uploadingOverlay}
-
- );
- }}
- renderRejected={() => Could not read file
}
- />
- );
- })}
+
+ {images.map((image, index) => )}
{children}
-
+
);
+});
+
+// Configure sortable container see. https://github.com/clauderic/react-sortable-hoc
+// Items can be sorted horizontally, vertically or in a grid.
+// axis="xy" means grid like sorting
+const AddImages = props => {
+ return ;
};
AddImages.defaultProps = { images: [] };
-const { array, node } = PropTypes;
+const { array, func, node } = PropTypes;
AddImages.propTypes = {
images: array,
children: node.isRequired,
+ onSortEnd: func.isRequired,
};
export default AddImages;
diff --git a/src/containers/EditListingForm/EditListingForm.js b/src/containers/EditListingForm/EditListingForm.js
index 40047841..5dfef8a5 100644
--- a/src/containers/EditListingForm/EditListingForm.js
+++ b/src/containers/EditListingForm/EditListingForm.js
@@ -2,6 +2,7 @@ import React, { Component, PropTypes } from 'react';
import { Field, reduxForm, propTypes as formPropTypes } from 'redux-form';
import { intlShape, injectIntl } from 'react-intl';
import { isEqual } from 'lodash';
+import { arrayMove } from 'react-sortable-hoc';
import { noEmptyArray, maxLength, required } from '../../util/validators';
import { AddImages } from '../../components';
import css from './EditListingForm.css';
@@ -70,6 +71,7 @@ class EditListingForm extends Component {
super(props);
this.handleInitialize = this.handleInitialize.bind(this);
this.onImageUploadHandler = this.onImageUploadHandler.bind(this);
+ this.onSortEnd = this.onSortEnd.bind(this);
}
componentDidMount() {
@@ -89,6 +91,11 @@ class EditListingForm extends Component {
}
}
+ onSortEnd({ oldIndex, newIndex }) {
+ const images = arrayMove(this.props.images, oldIndex, newIndex);
+ this.props.onUpdateImageOrder(images.map(i => i.id));
+ }
+
handleInitialize() {
const { initData = {}, initialize } = this.props;
initialize(initData);
@@ -122,7 +129,7 @@ class EditListingForm extends Component {
/>
Images
-
+
({
+ type: UPDATE_IMAGE_ORDER,
+ payload: { imageOrder },
+});
+
// All the action creators that don't have the {Success, Error} suffix
// take the params object that the corresponding SDK endpoint method
// expects.
diff --git a/src/containers/EditListingPage/EditListingPage.js b/src/containers/EditListingPage/EditListingPage.js
index 845bcc0e..5ce65cdd 100644
--- a/src/containers/EditListingPage/EditListingPage.js
+++ b/src/containers/EditListingPage/EditListingPage.js
@@ -10,6 +10,7 @@ import {
requestCreateListing,
requestShowListing,
requestImageUpload,
+ updateImageOrder,
} from './EditListingPage.duck';
const formatRequestData = values => {
@@ -39,7 +40,16 @@ export class EditListingPageComponent extends Component {
}
render() {
- const { data, intl, onCreateListing, onImageUpload, page, params, type } = this.props;
+ const {
+ data,
+ intl,
+ onCreateListing,
+ onImageUpload,
+ onUpdateImageOrder,
+ page,
+ params,
+ type,
+ } = this.props;
const isNew = type === 'new';
const id = page.submittedListingId || (params && new types.UUID(params.id));
const listingsById = getListingsById(data, [id]);
@@ -77,6 +87,7 @@ export class EditListingPageComponent extends Component {
initData={initData}
onImageUpload={onImageUpload}
onSubmit={onSubmit(onCreateListing)}
+ onUpdateImageOrder={onUpdateImageOrder}
saveActionMsg={saveActionMsg}
/>
@@ -103,9 +114,10 @@ const { func, object, shape, string } = PropTypes;
EditListingPageComponent.propTypes = {
data: object.isRequired,
intl: intlShape.isRequired,
- onImageUpload: func.isRequired,
- onLoadListing: func.isRequired,
onCreateListing: func.isRequired,
+ onLoadListing: func.isRequired,
+ onImageUpload: func.isRequired,
+ onUpdateImageOrder: func.isRequired,
page: object.isRequired,
params: shape({
id: string,
@@ -124,6 +136,7 @@ const mapDispatchToProps = dispatch => {
onLoadListing: id => dispatch(requestShowListing({ id, include: ['author', 'images'] })),
onCreateListing: values => dispatch(requestCreateListing(formatRequestData(values))),
onImageUpload: data => dispatch(requestImageUpload(data)),
+ onUpdateImageOrder: imageOrder => dispatch(updateImageOrder(imageOrder)),
};
};
diff --git a/src/containers/EditListingPage/EditListingPage.test.js b/src/containers/EditListingPage/EditListingPage.test.js
index ba72ed3d..cd6c2ff7 100644
--- a/src/containers/EditListingPage/EditListingPage.test.js
+++ b/src/containers/EditListingPage/EditListingPage.test.js
@@ -12,6 +12,7 @@ describe('EditListingPageComponent', () => {
onCreateListing={v => v}
onLoadListing={v => v}
onImageUpload={v => v}
+ onUpdateImageOrder={v => v}
page={{ imageOrder: [], images: {} }}
type="new"
/>,
diff --git a/src/containers/EditListingPage/__snapshots__/EditListingPage.test.js.snap b/src/containers/EditListingPage/__snapshots__/EditListingPage.test.js.snap
index b04b050c..a302296e 100644
--- a/src/containers/EditListingPage/__snapshots__/EditListingPage.test.js.snap
+++ b/src/containers/EditListingPage/__snapshots__/EditListingPage.test.js.snap
@@ -6,6 +6,7 @@ exports[`EditListingPageComponent matches snapshot 1`] = `
initData={Object {}}
onImageUpload={[Function]}
onSubmit={[Function]}
+ onUpdateImageOrder={[Function]}
saveActionMsg="Create listing" />
`;