Skip to content

Commit

Permalink
[Mobile] MediaUploadProgress - Cancel failed or in progress uploads i…
Browse files Browse the repository at this point in the history
…f the media block is removed (#61251)

* React Native Bridge - Update mediaUploadUpdate and mediaUpdate to have optional params for state and progress. Needed to be able to update the thumbnails only.

* Media & Text - Update updateMediaProgress to update the thumbnail as soon as it is available

* Media & Text - Pass new callback onMediaThumbnailUpdate to set the updated thumbnail for images

* Cover block - Update onUpdateMediaProgress to set the thumbnail as soon as it is ready

* Media Upload Progress - Request cancelling an image upload on unmount if there's a pending or failed upload. It also updates the code to be able to update the media thumbnail when there's no state update passed as a param.

* Adds requestImageUploadCancel mock
  • Loading branch information
Gerardo Pacheco authored May 16, 2024
1 parent c9a27c9 commit 11897ee
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ import { View } from 'react-native';
import { Component } from '@wordpress/element';
import { Spinner } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { subscribeMediaUpload } from '@wordpress/react-native-bridge';
import {
subscribeMediaUpload,
requestImageUploadCancel,
} from '@wordpress/react-native-bridge';

/**
* Internal dependencies
Expand Down Expand Up @@ -44,12 +47,17 @@ export class MediaUploadProgress extends Component {
}

componentWillUnmount() {
const { isUploadInProgress, isUploadFailed } = this.state;
const { mediaId } = this.props;

if ( isUploadInProgress || isUploadFailed ) {
requestImageUploadCancel( mediaId );
}
this.removeMediaUploadListener();
}

mediaUpload( payload ) {
const { mediaId } = this.props;

if (
payload.mediaId !== mediaId ||
( payload.state === this.state.uploadState &&
Expand All @@ -58,6 +66,11 @@ export class MediaUploadProgress extends Component {
return;
}

if ( payload?.mediaUrl && ! payload.state ) {
this.updateMediaThumbnail( payload );
return;
}

switch ( payload.state ) {
case MEDIA_UPLOAD_STATE_UPLOADING:
this.updateMediaProgress( payload );
Expand Down Expand Up @@ -89,6 +102,13 @@ export class MediaUploadProgress extends Component {
}
}

updateMediaThumbnail( payload ) {
const { onUpdateMediaProgress } = this.props;
if ( onUpdateMediaProgress ) {
onUpdateMediaProgress( payload );
}
}

finishMediaUploadWithSuccess( payload ) {
this.setState( {
uploadState: payload.state,
Expand Down
19 changes: 16 additions & 3 deletions packages/block-library/src/cover/edit.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,21 @@ const Cover = ( {
} );
};

const onUpdateMediaProgress = useCallback(
( payload ) => {
const { mediaUrl, state } = payload;

setIsUploadInProgress( true );

if ( isUploadInProgress && isImage && mediaUrl && ! state ) {
setAttributes( {
url: mediaUrl,
} );
}
},
[ isImage, isUploadInProgress, setAttributes ]
);

const onMediaPressed = () => {
if ( isUploadInProgress ) {
requestImageUploadCancelDialog( id );
Expand Down Expand Up @@ -447,9 +462,7 @@ const Cover = ( {
toolbarControls( openMediaOptionsRef.current ) }
<MediaUploadProgress
mediaId={ id }
onUpdateMediaProgress={ () => {
setIsUploadInProgress( true );
} }
onUpdateMediaProgress={ onUpdateMediaProgress }
onFinishMediaUploadWithSuccess={ ( {
mediaServerId,
mediaUrl,
Expand Down
10 changes: 10 additions & 0 deletions packages/block-library/src/media-text/edit.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class MediaTextEdit extends Component {

this.onSelectMedia = this.onSelectMedia.bind( this );
this.onMediaUpdate = this.onMediaUpdate.bind( this );
this.onMediaThumbnailUpdate = this.onMediaThumbnailUpdate.bind( this );
this.onWidthChange = this.onWidthChange.bind( this );
this.commitWidthChange = this.commitWidthChange.bind( this );
this.onLayoutChange = this.onLayoutChange.bind( this );
Expand Down Expand Up @@ -121,6 +122,14 @@ class MediaTextEdit extends Component {
} );
}

onMediaThumbnailUpdate( mediaUrl ) {
const { setAttributes } = this.props;

setAttributes( {
mediaUrl,
} );
}

onWidthChange( width ) {
this.setState( {
mediaWidth: applyWidthConstraints( width ),
Expand Down Expand Up @@ -221,6 +230,7 @@ class MediaTextEdit extends Component {
onFocus={ this.props.onFocus }
onMediaSelected={ this.onMediaSelected }
onMediaUpdate={ this.onMediaUpdate }
onMediaThumbnailUpdate={ this.onMediaThumbnailUpdate }
onSelectMedia={ this.onSelectMedia }
onSetOpenPickerRef={ this.onSetOpenPickerRef }
onWidthChange={ this.onWidthChange }
Expand Down
17 changes: 15 additions & 2 deletions packages/block-library/src/media-text/media-container.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,23 @@ class MediaContainer extends Component {
return <Icon icon={ icon } { ...iconStyle } />;
}

updateMediaProgress() {
if ( ! this.state.isUploadInProgress ) {
updateMediaProgress( payload ) {
const { isUploadInProgress } = this.state;
const { mediaUrl, state } = payload;
const { mediaType, onMediaThumbnailUpdate } = this.props;

if ( ! isUploadInProgress ) {
this.setState( { isUploadInProgress: true } );
}

if (
isUploadInProgress &&
mediaType === MEDIA_TYPE_IMAGE &&
mediaUrl &&
! state
) {
onMediaThumbnailUpdate( mediaUrl );
}
}

finishMediaUploadWithSuccess( payload ) {
Expand Down
13 changes: 10 additions & 3 deletions packages/react-native-bridge/ios/Gutenberg.swift
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ public class Gutenberg: UIResponder {
bridgeModule.sendEvent(withName: event.rawValue, body: body)
}

public func mediaUploadUpdate(id: Int32, state: MediaUploadState, progress: Float, url: URL?, serverID: Int32?, metadata: [String: Any] = [:]) {
public func mediaUploadUpdate(id: Int32, state: MediaUploadState? = nil, progress: Float? = nil, url: URL?, serverID: Int32? = nil, metadata: [String: Any] = [:]) {
mediaUpdate(event: .mediaUpload, id: id, state: state, progress: progress, url: url, serverID: serverID, metadata: metadata)
}

Expand All @@ -169,8 +169,15 @@ public class Gutenberg: UIResponder {
])
}

private func mediaUpdate<State: MediaState>(event: RNReactNativeGutenbergBridge.EventName, id: Int32, state: State, progress: Float, url: URL?, serverID: Int32?, metadata: [String: Any] = [:]) {
var data: [String: Any] = ["mediaId": id, "state": state.rawValue, "progress": progress, "metadata": metadata ];
private func mediaUpdate<State: MediaState>(event: RNReactNativeGutenbergBridge.EventName, id: Int32, state: State?, progress: Float?, url: URL?, serverID: Int32?, metadata: [String: Any] = [:]) {
var data: [String: Any] = ["mediaId": id, "metadata": metadata ];

if let state = state {
data["state"] = state.rawValue
}
if let progress = progress {
data["progress"] = progress
}
if let url = url {
data["mediaUrl"] = url.absoluteString
}
Expand Down
1 change: 1 addition & 0 deletions test/native/setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ jest.mock( '@wordpress/react-native-bridge', () => {
provideToNative_Html: jest.fn(),
requestImageFailedRetryDialog: jest.fn(),
requestImageUploadCancelDialog: jest.fn(),
requestImageUploadCancel: jest.fn(),
requestMediaEditor: jest.fn(),
requestMediaPicker: jest.fn(),
requestMediaImport: jest.fn(),
Expand Down

0 comments on commit 11897ee

Please sign in to comment.