Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mobile Stories block (part3: refactor / rename) #26005

Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
StoryUpdateProgress
BlockMediaUpdateProgress
===================

`StoryUpdateProgress` shows a progress bar while the media files associated with a Story block are being saved and uploaded
`BlockMediaUpdateProgress` shows a progress bar while the media files associated with a media-containing block are being saved first and uploaded later

## Usage

Expand All @@ -10,12 +10,12 @@ Usage example
```jsx
import { ImageBackground, Text, View } from 'react-native';
import {
StoryUpdateProgress,
BlockMediaUpdateProgress,
} from '@wordpress/block-editor';

function StoryProgress( { url, id } ) {
function BlockUpdatingProgress( { url, id } ) {
return (
<StoryUpdateProgress
<BlockMediaUpdateProgress
mediaId={ id }
renderContent={ ( { isSaveFailed, retryMessage } ) => {
return (
Expand All @@ -40,7 +40,7 @@ function StoryProgress( { url, id } ) {

### mediaFiles

A collection of media ID that identifies the current story upload.
A collection of media ID that identifies the current colleciton of files represented in this media container block.

- Type: `Array`
- Required: Yes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,21 @@ import {
*/
import styles from './styles.scss';

export const STORY_UPLOAD_STATE_UPLOADING = 1;
export const STORY_UPLOAD_STATE_SUCCEEDED = 2;
export const STORY_UPLOAD_STATE_FAILED = 3;
export const STORY_UPLOAD_STATE_RESET = 4;
export const MEDIA_UPLOAD_STATE_UPLOADING = 1;
export const MEDIA_UPLOAD_STATE_SUCCEEDED = 2;
export const MEDIA_UPLOAD_STATE_FAILED = 3;
export const MEDIA_UPLOAD_STATE_RESET = 4;

export const MEDIA_SAVE_STATE_SAVING = 5;
export const MEDIA_SAVE_STATE_SUCCEEDED = 6;
export const MEDIA_SAVE_STATE_FAILED = 7;
export const MEDIA_SAVE_STATE_RESET = 8;
export const STORY_SAVE_STATE_RESULT = 9;
export const MEDIA_SAVE_FINAL_STATE_RESULT = 9;
export const MEDIA_SAVE_MEDIAMODEL_CREATED = 10;

export class StoryUpdateProgress extends React.Component {
export class BlockMediaUpdateProgress extends React.Component {
constructor( props ) {
super( props );
super( props );

this.state = {
progress: 0,
Expand Down Expand Up @@ -79,16 +79,16 @@ export class StoryUpdateProgress extends React.Component {
}

switch ( payload.state ) {
case STORY_UPLOAD_STATE_UPLOADING:
case MEDIA_UPLOAD_STATE_UPLOADING:
this.updateMediaUploadProgress( payload );
break;
case STORY_UPLOAD_STATE_SUCCEEDED:
case MEDIA_UPLOAD_STATE_SUCCEEDED:
this.finishMediaUploadWithSuccess( payload );
break;
case STORY_UPLOAD_STATE_FAILED:
case MEDIA_UPLOAD_STATE_FAILED:
this.finishMediaUploadWithFailure( payload );
break;
case STORY_UPLOAD_STATE_RESET:
case MEDIA_UPLOAD_STATE_RESET:
this.mediaUploadStateReset( payload );
break;
}
Expand Down Expand Up @@ -117,16 +117,16 @@ export class StoryUpdateProgress extends React.Component {
case MEDIA_SAVE_STATE_RESET:
this.mediaSaveStateReset( payload );
break;
case STORY_SAVE_STATE_RESULT:
this.storySaveResult( payload );
case MEDIA_SAVE_FINAL_STATE_RESULT:
this.finalSaveResult( payload );
break;
case MEDIA_SAVE_MEDIAMODEL_CREATED:
this.mediaModelCreated( payload );
break;
}
}

// ---- Story (media) save actions
// ---- Block media save actions
updateMediaSaveProgress( payload ) {
this.setState( {
progress: payload.progress,
Expand All @@ -149,8 +149,8 @@ export class StoryUpdateProgress extends React.Component {

finishMediaSaveWithFailure( payload ) {
this.setState( { isSaveInProgress: false, isSaveFailed: true } );
if ( this.props.onFinishMediaUploadWithFailure ) {
this.props.onFinishMediaUploadWithFailure( payload );
if ( this.props.onFinishMediaSaveWithFailure ) {
this.props.onFinishMediaSaveWithFailure( payload );
}
}

Expand All @@ -161,16 +161,16 @@ export class StoryUpdateProgress extends React.Component {
}
}

storySaveResult( payload ) {
finalSaveResult( payload ) {
this.setState( {
progress: payload.progress,
isUploadInProgress: false,
isUploadFailed: false,
isSaveInProgress: false,
isSaveFailed: ! payload.success,
} );
if ( this.props.onStorySaveResult ) {
this.props.onStorySaveResult( payload );
if ( this.props.onFinalSaveResult ) {
this.props.onFinalSaveResult( payload );
}
}

Expand All @@ -186,7 +186,7 @@ export class StoryUpdateProgress extends React.Component {
}
}

// ---- Story upload actions
// ---- Block media upload actions
updateMediaUploadProgress( payload ) {
this.setState( {
progress: payload.progress,
Expand Down Expand Up @@ -268,7 +268,7 @@ export class StoryUpdateProgress extends React.Component {
const progress = this.state.progress * 100;
// eslint-disable-next-line @wordpress/i18n-no-collapsible-whitespace
const retryMessage = __(
'Failed to save Story.\nPlease tap for options.'
'Failed to save files.\nPlease tap for options.'
);

return (
Expand All @@ -290,4 +290,4 @@ export class StoryUpdateProgress extends React.Component {
}
}

export default StoryUpdateProgress;
export default BlockMediaUpdateProgress;
2 changes: 1 addition & 1 deletion packages/block-editor/src/components/index.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export {
MEDIA_TYPE_VIDEO,
} from './media-upload';
export { default as MediaUploadProgress } from './media-upload-progress';
export { default as StoryUpdateProgress } from './story-update-progress';
export { default as BlockMediaUpdateProgress } from './block-media-update-progress';
export { default as URLInput } from './url-input';
export { default as BlockInvalidWarning } from './block-list/block-invalid-warning';
export { default as BlockCaption } from './block-caption';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,21 @@ interface MediaUploadEventEmitter {
void onMediaFileUploadFailed(int mediaId);
}

interface StorySaveEventEmitter {
interface MediaSaveEventEmitter {
void onSaveMediaFileClear(String mediaId);
void onMediaFileSaveProgress(String mediaId, float progress);
void onMediaFileSaveSucceeded(String mediaId, String mediaUrl);
void onMediaFileSaveFailed(String mediaId);
void onStorySaveResult(String storyFirstMediaId, boolean success);
void onMediaCollectionSaveResult(String firstMediaIdInCollection, boolean success);
void onMediaModelCreatedForFile(final String oldId, final String newId, final String oldUrl);
}

interface ReplaceUnsupportedBlockCallback {
void replaceUnsupportedBlock(String content, String blockId);
}

interface ReplaceStoryEditedBlockCallback {
void replaceStoryBlock(String mediaFiles, String blockId);
interface ReplaceMediaFilesEditedBlockCallback {
void replaceMediaFilesEditedBlock(String mediaFiles, String blockId);
}

interface StarterPageTemplatesTooltipShownCallback {
Expand Down Expand Up @@ -135,7 +135,7 @@ public static GutenbergUserEvent getEnum(String eventName) {

void mediaUploadSync(MediaSelectedCallback mediaSelectedCallback);

void storySaveSync(MediaSelectedCallback mediaSelectedCallback);
void mediaSaveSync(MediaSelectedCallback mediaSelectedCallback);

void requestImageFailedRetryDialog(int mediaId);

Expand Down Expand Up @@ -171,7 +171,7 @@ void gutenbergDidRequestUnsupportedBlockFallback(ReplaceUnsupportedBlockCallback

void requestStarterPageTemplatesTooltipShown(StarterPageTemplatesTooltipShownCallback starterPageTemplatesTooltipShownCallback);

void requestStoryCreatorLoad(ReplaceStoryEditedBlockCallback replaceStoryEditedBlockCallback,
void requestMediaFilesEditorLoad(ReplaceMediaFilesEditedBlockCallback replaceMediaFilesEditedBlockCallback,
ReadableArray mediaFiles,
String blockId
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public class RNReactNativeGutenbergBridgeModule extends ReactContextBaseJavaModu
public static final String MAP_KEY_MEDIA_FILE_UPLOAD_MEDIA_TYPE = "mediaType";
private static final String MAP_KEY_THEME_UPDATE_COLORS = "colors";
private static final String MAP_KEY_THEME_UPDATE_GRADIENTS = "gradients";
public static final String MAP_KEY_STORY_SAVE_RESULT = "storySaveResult";
public static final String MAP_KEY_MEDIA_FINAL_SAVE_RESULT = "mediaFinalSaveResult";

private static final String MAP_KEY_IS_PREFERRED_COLOR_SCHEME_DARK = "isPreferredColorSchemeDark";

Expand Down Expand Up @@ -198,8 +198,8 @@ public void mediaUploadSync() {
}

@ReactMethod
public void storySaveSync() {
mGutenbergBridgeJS2Parent.storySaveSync(getNewMediaSelectedCallback(true,null));
public void mediaSaveSync() {
mGutenbergBridgeJS2Parent.mediaSaveSync(getNewMediaSelectedCallback(true,null));
}

@ReactMethod
Expand Down Expand Up @@ -228,8 +228,8 @@ public void requestMediaEditor(String mediaUrl, final Callback onUploadMediaSele
}

@ReactMethod
public void requestStoryCreatorLoad(ReadableArray mediaFiles, String blockId) {
mGutenbergBridgeJS2Parent.requestStoryCreatorLoad((savedMediaFiles, savedBlockId) ->
public void requestMediaFilesEditorLoad(ReadableArray mediaFiles, String blockId) {
Copy link
Contributor Author

@mzorz mzorz Oct 10, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternative to use sendActionButtonPressed

It was discussed previously that we could probably use sendActionButtonPressed in place of the dedicated requestMediaFilesEditorLoad (previously named requestStoryCreatorLoad) but I understand the sendActionButtonPressed exists to signal the host app about something, and then changing state and then being able to actually trigger the fallback (as for example requestUnsupportedBlockFallback in the following piece of code), and I believe this is because we had a bottom sheet appearing for the unsupported block case.

				onModalHide={ () => {
					if ( this.state.sendFallbackMessage ) {
						// On iOS, onModalHide is called when the controller is still part of the hierarchy.
						// A small delay will ensure that the controller has already been removed.
						this.timeout = setTimeout( () => {
							// for the Classic block, the content is kept in the `content` attribute
							const content =
								blockName === 'core/freeform'
									? attributes.content
									: attributes.originalContent;
							requestUnsupportedBlockFallback(
								content,
								clientId,
								blockName,
								blockTitle
							);
						}, 100 );
						this.setState( { sendFallbackMessage: false } );
					} else if ( this.state.sendButtonPressMessage ) {
						this.timeout = setTimeout( () => {
							sendActionButtonPressedAction(
								actionButtons.missingBlockAlertActionButton
							);
						}, 100 );
						this.setState( { sendButtonPressMessage: false } );
					}
				} }

Given we don't have a bottom sheet but rather have a direct signal to trigger the media files editor (in particular, the story block editor), I think just making the previously named requestStoryCreatorLoad bridge method more generic is enough (as it is now).

I have saved my work though in these following branches, in case there's a compelling reason to go with the 2-phased signaling of 1) sendActionButtonPressedAction and then 2) a similarly named to requestUnsupportedBlockFallback method, because otherwise we would need to add all these optionals to sendActionButtonPressedAction: blockId, mediaFiles, and the ReplaceMediaFilesEditedBlockCallback callback function as well. I don't think it's necessary, but interested in knowing what your thoughts on this are @etoledom 🙇

The WIP branches showing this exploration are all the same name on all 4 repos: (WPAndroid, gutenberg-mobile, jetpack, and gutenberg):
base branch: try/jetpack-stories-block-mobile-on-done-refactor
exercise branch: try/jetpack-stories-try-send-action

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could add an optional block ID and callback block but I agree that the need of mediaFiles as an argument makes it specific enough to have its own method 👍

mGutenbergBridgeJS2Parent.requestMediaFilesEditorLoad((savedMediaFiles, savedBlockId) ->
replaceBlock(savedMediaFiles, savedBlockId), mediaFiles, blockId);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,17 @@
import com.facebook.react.bridge.WritableNativeMap;

import org.wordpress.mobile.ReactNativeGutenbergBridge.GutenbergBridgeJS2Parent.MediaUploadEventEmitter;
import org.wordpress.mobile.ReactNativeGutenbergBridge.GutenbergBridgeJS2Parent.StorySaveEventEmitter;
import org.wordpress.mobile.ReactNativeGutenbergBridge.GutenbergBridgeJS2Parent.MediaSaveEventEmitter;

import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

import static org.wordpress.mobile.ReactNativeGutenbergBridge.RNReactNativeGutenbergBridgeModule.MAP_KEY_MEDIA_FILE_UPLOAD_MEDIA_ID;
import static org.wordpress.mobile.ReactNativeGutenbergBridge.RNReactNativeGutenbergBridgeModule.MAP_KEY_MEDIA_FILE_UPLOAD_MEDIA_NEW_ID;
import static org.wordpress.mobile.ReactNativeGutenbergBridge.RNReactNativeGutenbergBridgeModule.MAP_KEY_MEDIA_FILE_UPLOAD_MEDIA_URL;
import static org.wordpress.mobile.ReactNativeGutenbergBridge.RNReactNativeGutenbergBridgeModule.MAP_KEY_STORY_SAVE_RESULT;
import static org.wordpress.mobile.ReactNativeGutenbergBridge.RNReactNativeGutenbergBridgeModule.MAP_KEY_MEDIA_FINAL_SAVE_RESULT;

public class DeferredEventEmitter implements MediaUploadEventEmitter, StorySaveEventEmitter {
public class DeferredEventEmitter implements MediaUploadEventEmitter, MediaSaveEventEmitter {
public interface JSEventEmitter {
void emitToJS(String eventName, @Nullable WritableMap data);
}
Expand All @@ -33,15 +33,15 @@ public interface JSEventEmitter {
private static final int MEDIA_SAVE_STATE_SUCCEEDED = 6;
private static final int MEDIA_SAVE_STATE_FAILED = 7;
private static final int MEDIA_SAVE_STATE_RESET = 8;
private static final int STORY_SAVE_STATE_RESULT = 9;
private static final int MEDIA_SAVE_FINAL_STATE_RESULT = 9;
private static final int MEDIA_SAVE_MEDIAMODEL_CREATED = 10;

private static final String EVENT_NAME_MEDIA_UPLOAD = "mediaUpload";
private static final String EVENT_NAME_MEDIA_SAVE = "mediaSave";

private static final String MAP_KEY_MEDIA_FILE_UPLOAD_STATE = "state";
private static final String MAP_KEY_MEDIA_FILE_UPLOAD_MEDIA_PROGRESS = "progress";
private static final String MAP_KEY_MEDIA_FILE_UPLOAD_MEDIA_SERVER_ID = "mediaServerId";
private static final String MAP_KEY_MEDIA_FILE_STATE = "state";
private static final String MAP_KEY_MEDIA_FILE_MEDIA_ACTION_PROGRESS = "progress";
private static final String MAP_KEY_MEDIA_FILE_MEDIA_SERVER_ID = "mediaServerId";
private static final String MAP_KEY_UPDATE_CAPABILITIES = "updateCapabilities";


Expand Down Expand Up @@ -97,12 +97,12 @@ private void setMediaFileUploadDataInJS(int state, int mediaId, String mediaUrl,

private void setMediaFileUploadDataInJS(int state, int mediaId, String mediaUrl, float progress, int mediaServerId) {
WritableMap writableMap = new WritableNativeMap();
writableMap.putInt(MAP_KEY_MEDIA_FILE_UPLOAD_STATE, state);
writableMap.putInt(MAP_KEY_MEDIA_FILE_STATE, state);
writableMap.putInt(MAP_KEY_MEDIA_FILE_UPLOAD_MEDIA_ID, mediaId);
writableMap.putString(MAP_KEY_MEDIA_FILE_UPLOAD_MEDIA_URL, mediaUrl);
writableMap.putDouble(MAP_KEY_MEDIA_FILE_UPLOAD_MEDIA_PROGRESS, progress);
writableMap.putDouble(MAP_KEY_MEDIA_FILE_MEDIA_ACTION_PROGRESS, progress);
if (mediaServerId != MEDIA_SERVER_ID_UNKNOWN) {
writableMap.putInt(MAP_KEY_MEDIA_FILE_UPLOAD_MEDIA_SERVER_ID, mediaServerId);
writableMap.putInt(MAP_KEY_MEDIA_FILE_MEDIA_SERVER_ID, mediaServerId);
}
if (isCriticalMessage(state)) {
queueActionToJS(EVENT_NAME_MEDIA_UPLOAD, writableMap);
Expand All @@ -111,25 +111,25 @@ private void setMediaFileUploadDataInJS(int state, int mediaId, String mediaUrl,
}
}

private void setStorySaveDataInJS(int state, String mediaId, String mediaUrl, float progress) {
private void setMediaSaveResultDataInJS(int state, String mediaId, String mediaUrl, float progress) {
WritableMap writableMap = new WritableNativeMap();
writableMap.putInt(MAP_KEY_MEDIA_FILE_UPLOAD_STATE, state);
writableMap.putInt(MAP_KEY_MEDIA_FILE_STATE, state);
writableMap.putString(MAP_KEY_MEDIA_FILE_UPLOAD_MEDIA_ID, mediaId);
writableMap.putString(MAP_KEY_MEDIA_FILE_UPLOAD_MEDIA_URL, mediaUrl);
writableMap.putDouble(MAP_KEY_MEDIA_FILE_UPLOAD_MEDIA_PROGRESS, progress);
writableMap.putDouble(MAP_KEY_MEDIA_FILE_MEDIA_ACTION_PROGRESS, progress);
if (isCriticalMessage(state)) {
queueActionToJS(EVENT_NAME_MEDIA_SAVE, writableMap);
} else {
emitOrDrop(EVENT_NAME_MEDIA_SAVE, writableMap);
}
}

private void setStorySaveDataInJS(int state, String mediaId, boolean success, float progress) {
private void setMediaSaveResultDataInJS(int state, String mediaId, boolean success, float progress) {
WritableMap writableMap = new WritableNativeMap();
writableMap.putInt(MAP_KEY_MEDIA_FILE_UPLOAD_STATE, state);
writableMap.putInt(MAP_KEY_MEDIA_FILE_STATE, state);
writableMap.putString(MAP_KEY_MEDIA_FILE_UPLOAD_MEDIA_ID, mediaId);
writableMap.putBoolean(MAP_KEY_STORY_SAVE_RESULT, success);
writableMap.putDouble(MAP_KEY_MEDIA_FILE_UPLOAD_MEDIA_PROGRESS, progress);
writableMap.putBoolean(MAP_KEY_MEDIA_FINAL_SAVE_RESULT, success);
writableMap.putDouble(MAP_KEY_MEDIA_FILE_MEDIA_ACTION_PROGRESS, progress);
if (isCriticalMessage(state)) {
queueActionToJS(EVENT_NAME_MEDIA_SAVE, writableMap);
} else {
Expand Down Expand Up @@ -163,35 +163,35 @@ public void onMediaFileUploadFailed(int mediaId) {
setMediaFileUploadDataInJS(MEDIA_UPLOAD_STATE_FAILED, mediaId, null, 0);
}

// Story save events emitter
// Media file save events emitter
@Override
public void onSaveMediaFileClear(String mediaId) {
setStorySaveDataInJS(MEDIA_SAVE_STATE_RESET, mediaId, null, 0);
setMediaSaveResultDataInJS(MEDIA_SAVE_STATE_RESET, mediaId, null, 0);
}

@Override
public void onMediaFileSaveProgress(String mediaId, float progress) {
setStorySaveDataInJS(MEDIA_SAVE_STATE_SAVING, mediaId, null, progress);
setMediaSaveResultDataInJS(MEDIA_SAVE_STATE_SAVING, mediaId, null, progress);
}

@Override
public void onMediaFileSaveSucceeded(String mediaId, String mediaUrl) {
setStorySaveDataInJS(MEDIA_SAVE_STATE_SUCCEEDED, mediaId, mediaUrl, 1);
setMediaSaveResultDataInJS(MEDIA_SAVE_STATE_SUCCEEDED, mediaId, mediaUrl, 1);
}

@Override
public void onMediaFileSaveFailed(String mediaId) {
setStorySaveDataInJS(MEDIA_SAVE_STATE_FAILED, mediaId, null, 0);
setMediaSaveResultDataInJS(MEDIA_SAVE_STATE_FAILED, mediaId, null, 0);
}

@Override
public void onStorySaveResult(String storyFirstMediaId, boolean success) {
setStorySaveDataInJS(STORY_SAVE_STATE_RESULT, storyFirstMediaId, success, success ? 1 : 0);
public void onMediaCollectionSaveResult(String firstMediaIdInCollection, boolean success) {
setMediaSaveResultDataInJS(MEDIA_SAVE_FINAL_STATE_RESULT, firstMediaIdInCollection, success, success ? 1 : 0);
}

@Override public void onMediaModelCreatedForFile(String oldId, String newId, String oldUrl) {
WritableMap writableMap = new WritableNativeMap();
writableMap.putInt(MAP_KEY_MEDIA_FILE_UPLOAD_STATE, MEDIA_SAVE_MEDIAMODEL_CREATED);
writableMap.putInt(MAP_KEY_MEDIA_FILE_STATE, MEDIA_SAVE_MEDIAMODEL_CREATED);
writableMap.putString(MAP_KEY_MEDIA_FILE_UPLOAD_MEDIA_ID, oldId);
writableMap.putString(MAP_KEY_MEDIA_FILE_UPLOAD_MEDIA_NEW_ID, newId);
writableMap.putString(MAP_KEY_MEDIA_FILE_UPLOAD_MEDIA_URL, oldUrl);
Expand Down
Loading