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

Media Files Collection (part4: error handling) #26008

Merged
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
12483fa
added mobile StoryUpdateProgress component and bridge code to send/re…
mzorz Sep 21, 2020
2c17055
updated WPAndroid bridge DeferredEventEmitter to handle Story save ev…
mzorz Sep 24, 2020
78455a8
changed all Save event interface methods to use String ids instead of…
mzorz Sep 24, 2020
da1a900
redefined upload/save state constants
mzorz Sep 25, 2020
9613c56
added onStorySaveResult handling to bridge, and renamed STORY_SAVE_ST…
mzorz Sep 25, 2020
b305a9d
checking for matches of mediaId in mediaFiles while saving to send s…
mzorz Sep 28, 2020
407b2d1
added mediaModelCreated() method to the bridge, so a new ID can be as…
mzorz Sep 28, 2020
269cc91
mediaId should always be a string in mediaFiles so, converting to avo…
mzorz Sep 29, 2020
5ce5e5c
removed commented code
mzorz Sep 29, 2020
e83c8c8
updated documentation
mzorz Sep 30, 2020
42288a5
added missing implementation of method storySaveSync() in demo app
mzorz Oct 1, 2020
0213a1f
Merge branch 'try/jetpack-stories-block-mobile' into try/jetpack-stor…
mzorz Oct 1, 2020
5d385b5
fixed prettier warning
mzorz Oct 1, 2020
1934b2d
Merge branch 'try/jetpack-stories-block-mobile' into try/jetpack-stor…
mzorz Oct 9, 2020
6cc55f4
renames for generic media files collection block and BlockMediaUpdate…
mzorz Oct 10, 2020
61877c2
referencing the right props method in finishMediaSaveWithFailure
mzorz Oct 10, 2020
1ab42cf
mistaken renames of parameters in bridge methods
mzorz Oct 10, 2020
4182bdd
renamed more abstract/generic method names requestMediaFilesEditorLoad
mzorz Oct 10, 2020
4fbc17d
removed extra whtie space
mzorz Oct 11, 2020
3592ff0
renamed argument type
mzorz Oct 11, 2020
f1e4782
renamed event paramter name to easier to understand 'success' boolean…
mzorz Oct 11, 2020
ee45b07
added cancel and retry bridge methods specific for mediaFiles collect…
mzorz Oct 12, 2020
053a168
added requestMediaFilesSaveCancelDialog bridge method
mzorz Oct 12, 2020
7a18e56
renamed bridge method mediaModelCreatedForFile for more general purpo…
mzorz Oct 13, 2020
d72efb8
fixed merge conflicts
mzorz Oct 16, 2020
1ac5a80
Add missing iOS bridge declarations
etoledom Oct 20, 2020
bc2f577
added jsdoc like description for methods
mzorz Oct 20, 2020
0817df1
removed unneeded return statement in some bridge methods
mzorz Oct 20, 2020
f2ef699
Update packages/react-native-bridge/index.js
mzorz Oct 21, 2020
2f7d802
Update packages/react-native-bridge/index.js
mzorz Oct 21, 2020
a17fe89
Update packages/react-native-bridge/index.js
mzorz Oct 21, 2020
8e01d8b
fixed typo, added punctuation
mzorz Oct 21, 2020
0e00c7a
fixed merge conflict
mzorz Oct 21, 2020
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
Expand Up @@ -40,7 +40,7 @@ function BlockUpdatingProgress( { url, id } ) {

### mediaFiles

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

- Type: `Array`
- Required: Yes
Expand Down Expand Up @@ -97,7 +97,7 @@ The argument of the callback is an object containing the following properties:

### onMediaUploadStateReset

Callback called when the media upload is reset.
Callback called when the media upload is reset

- Type: `Function`
- Required: No
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export const MEDIA_SAVE_STATE_SUCCEEDED = 6;
export const MEDIA_SAVE_STATE_FAILED = 7;
export const MEDIA_SAVE_STATE_RESET = 8;
export const MEDIA_SAVE_FINAL_STATE_RESULT = 9;
export const MEDIA_SAVE_MEDIAMODEL_CREATED = 10;
export const MEDIA_SAVE_MEDIAID_CHANGED = 10;

export class BlockMediaUpdateProgress extends React.Component {
constructor( props ) {
Expand Down Expand Up @@ -118,8 +118,8 @@ export class BlockMediaUpdateProgress extends React.Component {
case MEDIA_SAVE_FINAL_STATE_RESULT:
this.finalSaveResult( payload );
break;
case MEDIA_SAVE_MEDIAMODEL_CREATED:
this.mediaModelCreated( payload );
case MEDIA_SAVE_MEDIAID_CHANGED:
this.mediaIdChanged( payload );
break;
}
}
Expand Down Expand Up @@ -172,15 +172,15 @@ export class BlockMediaUpdateProgress extends React.Component {
}
}

mediaModelCreated( payload ) {
mediaIdChanged( payload ) {
this.setState( {
isUploadInProgress: false,
isUploadFailed: false,
isSaveInProgress: false,
isSaveFailed: false,
} );
if ( this.props.onMediaModelCreated ) {
this.props.onMediaModelCreated( payload );
if ( this.props.onMediaIdChanged ) {
this.props.onMediaIdChanged( payload );
}
}

Expand Down Expand Up @@ -265,9 +265,17 @@ export class BlockMediaUpdateProgress extends React.Component {
this.state.isUploadInProgress || this.state.isSaveInProgress;
const progress = this.state.progress * 100;
// eslint-disable-next-line @wordpress/i18n-no-collapsible-whitespace
const retryMessage = __(
const retryMessageSave = __(
'Failed to save files.\nPlease tap for options.'
);
// eslint-disable-next-line @wordpress/i18n-no-collapsible-whitespace
const retryMessageUpload = __(
'Failed to upload files.\nPlease tap for options.'
);
let retryMessage = retryMessageSave;
if ( isUploadFailed ) {
retryMessage = retryMessageUpload;
}

return (
<View style={ styles.mediaUploadProgress } pointerEvents="box-none">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ interface MediaSaveEventEmitter {
void onMediaFileSaveSucceeded(String mediaId, String mediaUrl);
void onMediaFileSaveFailed(String mediaId);
void onMediaCollectionSaveResult(String firstMediaIdInCollection, boolean success);
void onMediaModelCreatedForFile(final String oldId, final String newId, final String oldUrl);
void onMediaIdChanged(final String oldId, final String newId, final String oldUrl);
}

interface ReplaceUnsupportedBlockCallback {
Expand Down Expand Up @@ -175,4 +175,10 @@ void requestMediaFilesEditorLoad(ReplaceMediaFilesEditedBlockCallback replaceMed
ReadableArray mediaFiles,
String blockId
);

void requestMediaFilesFailedRetryDialog(ReadableArray mediaFiles);

void requestMediaFilesUploadCancelDialog(ReadableArray mediaFiles);

void requestMediaFilesSaveCancelDialog(ReadableArray mediaFiles);
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,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_MEDIA_FINAL_SAVE_RESULT = "mediaFinalSaveResult";
public static final String MAP_KEY_MEDIA_FINAL_SAVE_RESULT_SUCCESS_VALUE = "success";

private static final String MAP_KEY_IS_PREFERRED_COLOR_SCHEME_DARK = "isPreferredColorSchemeDark";

Expand Down Expand Up @@ -242,6 +242,21 @@ public void requestMediaFilesEditorLoad(ReadableArray mediaFiles, String blockId
replaceBlock(savedMediaFiles, savedBlockId), mediaFiles, blockId);
}

@ReactMethod
public void requestMediaFilesFailedRetryDialog(ReadableArray mediaFiles) {
mGutenbergBridgeJS2Parent.requestMediaFilesFailedRetryDialog(mediaFiles);
}

@ReactMethod
public void requestMediaFilesUploadCancelDialog(ReadableArray mediaFiles) {
mGutenbergBridgeJS2Parent.requestMediaFilesUploadCancelDialog(mediaFiles);
}

@ReactMethod
public void requestMediaFilesSaveCancelDialog(ReadableArray mediaFiles) {
mGutenbergBridgeJS2Parent.requestMediaFilesSaveCancelDialog(mediaFiles);
}

@ReactMethod
public void editorDidEmitLog(String message, int logLevel) {
mGutenbergBridgeJS2Parent.editorDidEmitLog(message, GutenbergBridgeJS2Parent.LogLevel.valueOf(logLevel));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
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_MEDIA_FINAL_SAVE_RESULT;
import static org.wordpress.mobile.ReactNativeGutenbergBridge.RNReactNativeGutenbergBridgeModule.MAP_KEY_MEDIA_FINAL_SAVE_RESULT_SUCCESS_VALUE;

public class DeferredEventEmitter implements MediaUploadEventEmitter, MediaSaveEventEmitter {
public interface JSEventEmitter {
Expand All @@ -34,7 +34,7 @@ public interface JSEventEmitter {
private static final int MEDIA_SAVE_STATE_FAILED = 7;
private static final int MEDIA_SAVE_STATE_RESET = 8;
private static final int MEDIA_SAVE_FINAL_STATE_RESULT = 9;
private static final int MEDIA_SAVE_MEDIAMODEL_CREATED = 10;
private static final int MEDIA_SAVE_MEDIAID_CHANGED = 10;

private static final String EVENT_NAME_MEDIA_UPLOAD = "mediaUpload";
private static final String EVENT_NAME_MEDIA_SAVE = "mediaSave";
Expand Down Expand Up @@ -128,7 +128,7 @@ private void setMediaSaveResultDataInJS(int state, String mediaId, boolean succe
WritableMap writableMap = new WritableNativeMap();
writableMap.putInt(MAP_KEY_MEDIA_FILE_STATE, state);
writableMap.putString(MAP_KEY_MEDIA_FILE_UPLOAD_MEDIA_ID, mediaId);
writableMap.putBoolean(MAP_KEY_MEDIA_FINAL_SAVE_RESULT, success);
writableMap.putBoolean(MAP_KEY_MEDIA_FINAL_SAVE_RESULT_SUCCESS_VALUE, success);
writableMap.putDouble(MAP_KEY_MEDIA_FILE_MEDIA_ACTION_PROGRESS, progress);
if (isCriticalMessage(state)) {
queueActionToJS(EVENT_NAME_MEDIA_SAVE, writableMap);
Expand All @@ -140,7 +140,7 @@ private void setMediaSaveResultDataInJS(int state, String mediaId, boolean succe
private boolean isCriticalMessage(int state) {
return state == MEDIA_UPLOAD_STATE_SUCCEEDED || state == MEDIA_UPLOAD_STATE_FAILED
|| state == MEDIA_SAVE_STATE_SUCCEEDED || state == MEDIA_SAVE_STATE_FAILED
|| state == MEDIA_SAVE_MEDIAMODEL_CREATED;
|| state == MEDIA_SAVE_MEDIAID_CHANGED;
}

@Override
Expand Down Expand Up @@ -189,13 +189,13 @@ public void onMediaCollectionSaveResult(String firstMediaIdInCollection, boolean
setMediaSaveResultDataInJS(MEDIA_SAVE_FINAL_STATE_RESULT, firstMediaIdInCollection, success, success ? 1 : 0);
}

@Override public void onMediaModelCreatedForFile(String oldId, String newId, String oldUrl) {
@Override public void onMediaIdChanged(String oldId, String newId, String oldUrl) {
WritableMap writableMap = new WritableNativeMap();
writableMap.putInt(MAP_KEY_MEDIA_FILE_STATE, MEDIA_SAVE_MEDIAMODEL_CREATED);
writableMap.putInt(MAP_KEY_MEDIA_FILE_STATE, MEDIA_SAVE_MEDIAID_CHANGED);
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);
if (isCriticalMessage(MEDIA_SAVE_MEDIAMODEL_CREATED)) {
if (isCriticalMessage(MEDIA_SAVE_MEDIAID_CHANGED)) {
queueActionToJS(EVENT_NAME_MEDIA_SAVE, writableMap);
} else {
emitOrDrop(EVENT_NAME_MEDIA_SAVE, writableMap);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ public class WPAndroidGlueCode {
private OnGutenbergDidSendButtonPressedActionListener mOnGutenbergDidSendButtonPressedActionListener;
private ReplaceUnsupportedBlockCallback mReplaceUnsupportedBlockCallback;
private OnStarterPageTemplatesTooltipShownEventListener mOnStarterPageTemplatesTooltipShownListener;
private OnMediaFilesEditorLoadRequestListener mOnMediaFilesEditorLoadRequestListener;
private OnMediaFilesCollectionBasedBlockEditorListener mOnMediaFilesCollectionBasedBlockEditorListener;
private ReplaceMediaFilesEditedBlockCallback mReplaceMediaFilesEditedBlockCallback;
private boolean mIsEditorMounted;

Expand Down Expand Up @@ -150,8 +150,11 @@ public interface OnMediaLibraryButtonListener {
void onOtherMediaButtonClicked(String mediaSource, boolean allowMultipleSelection);
}

public interface OnMediaFilesEditorLoadRequestListener {
public interface OnMediaFilesCollectionBasedBlockEditorListener {
jd-alexander marked this conversation as resolved.
Show resolved Hide resolved
void onRequestMediaFilesEditorLoad(ArrayList<Object> mediaFiles, String blockId);
void onCancelUploadForMediaCollection(ArrayList<Object> mediaFiles);
void onRetryUploadForMediaCollection(ArrayList<Object> mediaFiles);
void onCancelSaveForMediaCollection(ArrayList<Object> mediaFiles);
}

public interface OnImageFullscreenPreviewListener {
Expand Down Expand Up @@ -424,7 +427,29 @@ public void requestMediaFilesEditorLoad(
String blockId
) {
mReplaceMediaFilesEditedBlockCallback = replaceMediaFilesEditedBlockCallback;
mOnMediaFilesEditorLoadRequestListener.onRequestMediaFilesEditorLoad(mediaFiles.toArrayList(), blockId);
mOnMediaFilesCollectionBasedBlockEditorListener
.onRequestMediaFilesEditorLoad(mediaFiles.toArrayList(), blockId);
}

@Override
public void requestMediaFilesFailedRetryDialog(ReadableArray mediaFiles) {
mOnMediaFilesCollectionBasedBlockEditorListener.onRetryUploadForMediaCollection(
mediaFiles.toArrayList()
);
}

@Override
public void requestMediaFilesUploadCancelDialog(ReadableArray mediaFiles) {
mOnMediaFilesCollectionBasedBlockEditorListener.onCancelUploadForMediaCollection(
mediaFiles.toArrayList()
);
}

@Override
public void requestMediaFilesSaveCancelDialog(ReadableArray mediaFiles) {
mOnMediaFilesCollectionBasedBlockEditorListener.onCancelSaveForMediaCollection(
mediaFiles.toArrayList()
);
}
}, mIsDarkMode);

Expand Down Expand Up @@ -502,7 +527,7 @@ public void attachToContainer(ViewGroup viewGroup,
OnGutenbergDidSendButtonPressedActionListener onGutenbergDidSendButtonPressedActionListener,
AddMentionUtil addMentionUtil,
OnStarterPageTemplatesTooltipShownEventListener onStarterPageTemplatesTooltipListener,
OnMediaFilesEditorLoadRequestListener onMediaFilesEditorLoadRequestListener,
OnMediaFilesCollectionBasedBlockEditorListener onMediaFilesCollectionBasedBlockEditorListener,
boolean isDarkMode) {
MutableContextWrapper contextWrapper = (MutableContextWrapper) mReactRootView.getContext();
contextWrapper.setBaseContext(viewGroup.getContext());
Expand All @@ -520,7 +545,7 @@ public void attachToContainer(ViewGroup viewGroup,
mOnGutenbergDidSendButtonPressedActionListener = onGutenbergDidSendButtonPressedActionListener;
mAddMentionUtil = addMentionUtil;
mOnStarterPageTemplatesTooltipShownListener = onStarterPageTemplatesTooltipListener;
mOnMediaFilesEditorLoadRequestListener = onMediaFilesEditorLoadRequestListener;
mOnMediaFilesCollectionBasedBlockEditorListener = onMediaFilesCollectionBasedBlockEditorListener;

sAddCookiesInterceptor.setOnAuthHeaderRequestedListener(onAuthHeaderRequestedListener);

Expand Down Expand Up @@ -908,8 +933,8 @@ public void mediaCollectionFinalSaveResult(final String blockFirstMediaId, final
mDeferredEventEmitter.onMediaCollectionSaveResult(blockFirstMediaId, success);
}

public void mediaModelCreatedForFile(final String oldId, final String newId, final String oldUrl) {
mDeferredEventEmitter.onMediaModelCreatedForFile(oldId, newId, oldUrl);
public void mediaIdChanged(final String oldId, final String newId, final String oldUrl) {
mDeferredEventEmitter.onMediaIdChanged(oldId, newId, oldUrl);
}

public void replaceUnsupportedBlock(String content, String blockId) {
Expand Down
18 changes: 18 additions & 0 deletions packages/react-native-bridge/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -259,4 +259,22 @@ export function requestMediaFilesEditorLoad( mediaFiles, blockClientId ) {
);
}

export function requestMediaFilesFailedRetryDialog( mediaFiles ) {
return RNReactNativeGutenbergBridge.requestMediaFilesFailedRetryDialog(
mediaFiles
);
}
etoledom marked this conversation as resolved.
Show resolved Hide resolved

export function requestMediaFilesUploadCancelDialog( mediaFiles ) {
return RNReactNativeGutenbergBridge.requestMediaFilesUploadCancelDialog(
mediaFiles
);
}

export function requestMediaFilesSaveCancelDialog( mediaFiles ) {
return RNReactNativeGutenbergBridge.requestMediaFilesSaveCancelDialog(
mediaFiles
);
}

export default RNReactNativeGutenbergBridge;
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ @interface RCT_EXTERN_MODULE(RNReactNativeGutenbergBridge, NSObject)
RCT_EXTERN_METHOD(requestStarterPageTemplatesTooltipShown:(RCTResponseSenderBlock)callback)
RCT_EXTERN_METHOD(setStarterPageTemplatesTooltipShown:(BOOL)tooltipShown)
RCT_EXTERN_METHOD(requestMediaFilesEditorLoad:(NSArray *)mediaFiles blockId:(NSString *)blockId)
RCT_EXTERN_METHOD(requestMediaFilesFailedRetryDialog:(NSArray *)mediaFiles)
RCT_EXTERN_METHOD(onCancelUploadForMediaCollection:(NSArray *)mediaFiles)
RCT_EXTERN_METHOD(actionButtonPressed:(NSString *)buttonType)

@end
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,33 @@ public class RNReactNativeGutenbergBridge: RCTEventEmitter {
// }
}

@objc
func requestMediaFilesFailedRetryDialog(_ mediaFilesArray: [AnyObject]) {
// TODO actually implement the delegate call on iOS
let mediaFiles = mediaFilesArray.compactMap { $0 as? String }
// DispatchQueue.main.async {
// self.delegate?.gutenbergDidRequestMediaFilesFailedRetryDialog(mediaFiles: mediaFiles, blockId: blockId)
// }
}

@objc
func requestMediaFilesUploadCancelDialog(_ mediaFilesArray: [AnyObject]) {
// TODO actually implement the delegate call on iOS
let mediaFiles = mediaFilesArray.compactMap { $0 as? String }
// DispatchQueue.main.async {
// self.delegate?.gutenbergDidRequestMediaFilesUploadCancelDialog(mediaFiles: mediaFiles, blockId: blockId)
// }
}

@objc
func requestMediaFilesSaveCancelDialog(_ mediaFilesArray: [AnyObject]) {
// TODO actually implement the delegate call on iOS
let mediaFiles = mediaFilesArray.compactMap { $0 as? String }
// DispatchQueue.main.async {
// self.delegate?.gutenbergDidRequestMediaFilesSaveCancelDialog(mediaFiles: mediaFiles, blockId: blockId)
// }
}

@objc
func actionButtonPressed(_ buttonType: String) {
guard let button = Gutenberg.ActionButtonType(rawValue: buttonType) else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,21 @@ public void requestMediaFilesEditorLoad(
Toast.makeText(MainApplication.this, "requestMediaFilesEditorLoad called", Toast.LENGTH_SHORT).show();
}

@Override
public void requestMediaFilesFailedRetryDialog(ReadableArray mediaFiles) {
Toast.makeText(MainApplication.this, "requestMediaFilesFailedRetryDialog called", Toast.LENGTH_SHORT).show();
}

@Override
public void requestMediaFilesUploadCancelDialog(ReadableArray mediaFiles) {
Toast.makeText(MainApplication.this, "requestMediaFilesUploadCancelDialog called", Toast.LENGTH_SHORT).show();
}

@Override
public void requestMediaFilesSaveCancelDialog(ReadableArray mediaFiles) {
Toast.makeText(MainApplication.this, "requestMediaFilesSaveCancelDialog called", Toast.LENGTH_SHORT).show();
}

@Override
public void gutenbergDidSendButtonPressedAction(String buttonType) {

Expand Down