Skip to content

Commit

Permalink
Revert "Revert "Media: Replace usages of flux add and addExternal med…
Browse files Browse the repository at this point in the history
…ia with thunks"" (#44009)

* Revert "Revert "Media: Replace usages of flux add and addExternal media with thunks (#43884)" (#44007)"

This reverts commit c2fc4a3.

* Media: Correctly handle FileList created by the add button

* External Media: Pass arguments in correct order
  • Loading branch information
sarayourfriend authored Jul 13, 2020
1 parent ac79d2b commit c7e1b7a
Show file tree
Hide file tree
Showing 27 changed files with 457 additions and 675 deletions.
5 changes: 3 additions & 2 deletions client/blocks/image-selector/dropzone.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,11 @@ class ImageSelectorDropZone extends Component {
return false;
}

const uploadedMedia = await this.props.addMedia( this.props.site, {
const file = {
fileContents: droppedImage,
fileName: droppedImage.name,
} );
};
const uploadedMedia = await this.props.addMedia( file, this.props.site );

this.props.onDroppedImage( uploadedMedia );
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import React, { Component } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { connect } from 'react-redux';
import { head, find, noop, trim, uniqueId } from 'lodash';
import { head, noop, trim, uniqueId } from 'lodash';
import Gridicon from 'components/gridicon';
import { localize } from 'i18n-calypso';

Expand All @@ -18,9 +18,8 @@ import { errorNotice as errorNoticeAction } from 'state/notices/actions';
import DropZone from 'components/drop-zone';
import FilePicker from 'components/file-picker';
import getMediaErrors from 'state/selectors/get-media-errors';
import MediaActions from 'lib/media/actions';
import { filterItemsByMimePrefix, isItemBeingUploaded } from 'lib/media/utils';
import MediaStore from 'lib/media/store';
import { filterItemsByMimePrefix } from 'lib/media/utils';
import { addWoocommerceProductImage } from 'state/media/thunks';

class ProductImageUploader extends Component {
static propTypes = {
Expand All @@ -34,6 +33,7 @@ class ProductImageUploader extends Component {
onUpload: PropTypes.func,
onError: PropTypes.func,
onFinish: PropTypes.func,
addWoocommerceProductImage: PropTypes.func,
};

static defaultProps = {
Expand All @@ -43,6 +43,7 @@ class ProductImageUploader extends Component {
onUpload: noop,
onError: noop,
onFinish: noop,
addWoocommerceProductImage: noop,
};

UNSAFE_componentWillMount() {
Expand All @@ -52,7 +53,8 @@ class ProductImageUploader extends Component {
this._isMounted = false;
}

showError = ( media, transientId ) => {
showError = ( media ) => {
const { ID: transientId } = media;
const { mediaValidationErrors, onError, errorNotice, translate } = this.props;

onError( {
Expand Down Expand Up @@ -139,51 +141,13 @@ class ProductImageUploader extends Component {

onSelect( filesToUpload );

const transientIds = filesToUpload.map( ( file ) => {
return file.ID;
} );

const uploadedIds = [];
const handleUpload = () => {
const transientId = head( transientIds );
const media = MediaStore.get( site.ID, transientId );
const isUploadInProgress = media && isItemBeingUploaded( media );

// File has finished uploading or failed.
if ( ! isUploadInProgress ) {
// Stop uploading and don't push events if they navigated away
if ( ! this._isMounted ) {
MediaStore.off( 'change', handleUpload );
return;
}

if ( media ) {
const file = find( filesToUpload, ( f ) => f.ID === transientId );
if ( media.URL ) {
onUpload( {
ID: media.ID,
transientId,
URL: media.URL,
placeholder: file.preview,
} );
uploadedIds.push( transientId );
} else {
this.showError( media, transientId );
}
} else {
this.showError( media, transientId );
}

transientIds.shift();
if ( transientIds.length === 0 ) {
MediaStore.off( 'change', handleUpload );
onFinish( uploadedIds );
}
}
};

MediaStore.on( 'change', handleUpload );
MediaActions.add( site, filesToUpload );
this.props.addWoocommerceProductImage(
filesToUpload,
site,
onUpload,
this.showError,
onFinish
);
};

renderCompactUploader() {
Expand Down Expand Up @@ -270,6 +234,7 @@ function mapStateToProps( state ) {
};
}

export default connect( mapStateToProps, { errorNotice: errorNoticeAction } )(
localize( ProductImageUploader )
);
export default connect( mapStateToProps, {
errorNotice: errorNoticeAction,
addWoocommerceProductImage,
} )( localize( ProductImageUploader ) );
103 changes: 1 addition & 102 deletions client/lib/media/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,13 @@ const debug = debugFactory( 'calypso:media' );
*/
import Dispatcher from 'dispatcher';
import wpcom from 'lib/wp';
import { reduxDispatch, reduxGetState } from 'lib/redux-bridge';
import { createTransientMedia, getFileUploader } from './utils';
import getMediaItemErrors from 'state/selectors/get-media-item-errors';
import { reduxDispatch } from 'lib/redux-bridge';
import MediaStore from './store';
import MediaListStore from './list-store';
import {
changeMediaSource,
createMediaItem,
failMediaItemRequest,
failMediaRequest,
receiveMedia,
successMediaItemRequest,
successMediaRequest,
} from 'state/media/actions';

Expand All @@ -40,11 +35,6 @@ const MediaActions = {
_fetching: {},
};

/**
* Constants
*/
const ONE_YEAR_IN_MILLISECONDS = 31540000000;

MediaActions.setQuery = function ( siteId, query ) {
Dispatcher.handleViewAction( {
type: 'SET_MEDIA_QUERY',
Expand Down Expand Up @@ -90,97 +80,6 @@ MediaActions.fetchNextPage = function ( siteId ) {
}
};

const getExternalUploader = ( service ) => ( file, siteId ) => {
return wpcom.undocumented().site( siteId ).uploadExternalMedia( service, [ file.guid ] );
};

function uploadFiles( uploader, files, site ) {
// We offset the current time when generating a fake date for the transient
// media so that the first uploaded media doesn't suddenly become newest in
// the set once it finishes uploading. This duration is pretty arbitrary,
// but one would hope that it would never take this long to upload an item.
const baseTime = Date.now() + ONE_YEAR_IN_MILLISECONDS;
const siteId = site.ID;

return files.reduce( ( lastUpload, file, i ) => {
// Assign a date such that the first item will be the oldest at the
// time of upload, as this is expected order when uploads finish
const date = new Date( baseTime - ( files.length - i ) ).toISOString();

// Generate a fake transient item that can be used immediately, even
// before the media has persisted to the server
const transientMedia = { date, ...createTransientMedia( file ) };
if ( file.ID ) {
transientMedia.ID = file.ID;
}

Dispatcher.handleViewAction( {
type: 'CREATE_MEDIA_ITEM',
siteId: siteId,
data: transientMedia,
site,
} );

// Abort upload if file fails to pass validation.
if ( getMediaItemErrors( reduxGetState(), siteId, transientMedia.ID ).length ) {
return Promise.resolve();
}

// If there are no errors, dispatch the create media item action
reduxDispatch( createMediaItem( site, transientMedia ) );

return lastUpload.then( () => {
// Achieve series upload by waiting for the previous promise to
// resolve before starting this item's upload
const action = { type: 'RECEIVE_MEDIA_ITEM', id: transientMedia.ID, siteId };

return uploader( file, siteId )
.then( ( data ) => {
Dispatcher.handleServerAction(
Object.assign( action, {
data: data.media[ 0 ],
} )
);

reduxDispatch( successMediaItemRequest( siteId, transientMedia.ID ) );
reduxDispatch(
receiveMedia(
siteId,
{ ...data.media[ 0 ], transientId: transientMedia.ID },
data.found
)
);

// also refetch media limits
Dispatcher.handleServerAction( {
type: 'FETCH_MEDIA_LIMITS',
siteId: siteId,
} );
} )
.catch( ( error ) => {
Dispatcher.handleServerAction( Object.assign( action, { error } ) );
reduxDispatch( failMediaItemRequest( siteId, transientMedia.ID, error ) );
} );
} );
}, Promise.resolve() );
}

MediaActions.addExternal = function ( site, files, service ) {
return uploadFiles( getExternalUploader( service ), files, site );
};

MediaActions.add = function ( site, files ) {
if ( files instanceof window.FileList ) {
files = [ ...files ];
}

if ( ! Array.isArray( files ) ) {
files = [ files ];
}

return uploadFiles( getFileUploader(), files, site );
};

MediaActions.edit = function ( siteId, item ) {
const newItem = assign( {}, MediaStore.get( siteId, item.ID ), item );

Expand Down
Loading

0 comments on commit c7e1b7a

Please sign in to comment.