diff --git a/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/GutenbergBridgeJS2Parent.java b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/GutenbergBridgeJS2Parent.java index 7d6d90e005055..adccb29497368 100644 --- a/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/GutenbergBridgeJS2Parent.java +++ b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/GutenbergBridgeJS2Parent.java @@ -41,16 +41,13 @@ interface MediaSaveEventEmitter { void onMediaFileSaveFailed(String mediaId); void onMediaCollectionSaveResult(String firstMediaIdInCollection, boolean success); void onMediaIdChanged(final String oldId, final String newId, final String oldUrl); + void onReplaceMediaFilesEditedBlock(final String mediaFiles, final String blockId); } interface ReplaceUnsupportedBlockCallback { void replaceUnsupportedBlock(String content, String blockId); } - interface ReplaceMediaFilesEditedBlockCallback { - void replaceMediaFilesEditedBlock(String mediaFiles, String blockId); - } - // Ref: https://github.com/facebook/react-native/blob/master/Libraries/polyfills/console.js#L376 enum LogLevel { TRACE(0), @@ -166,14 +163,13 @@ void gutenbergDidRequestUnsupportedBlockFallback(ReplaceUnsupportedBlockCallback void onShowXpostSuggestions(Consumer onResult); - void requestMediaFilesEditorLoad(ReplaceMediaFilesEditedBlockCallback replaceMediaFilesEditedBlockCallback, - ReadableArray mediaFiles, - String blockId - ); + void requestMediaFilesEditorLoad(ReadableArray mediaFiles, String blockId); void requestMediaFilesFailedRetryDialog(ReadableArray mediaFiles); void requestMediaFilesUploadCancelDialog(ReadableArray mediaFiles); void requestMediaFilesSaveCancelDialog(ReadableArray mediaFiles); + + void mediaFilesBlockReplaceSync(ReadableArray mediaFiles, String blockId); } diff --git a/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/RNReactNativeGutenbergBridgeModule.java b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/RNReactNativeGutenbergBridgeModule.java index 27e9ef93f0ff5..eb1732de4616d 100644 --- a/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/RNReactNativeGutenbergBridgeModule.java +++ b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/RNReactNativeGutenbergBridgeModule.java @@ -237,8 +237,7 @@ public void requestMediaEditor(String mediaUrl, final Callback onUploadMediaSele @ReactMethod public void requestMediaFilesEditorLoad(ReadableArray mediaFiles, String blockId) { - mGutenbergBridgeJS2Parent.requestMediaFilesEditorLoad((savedMediaFiles, savedBlockId) -> - replaceBlock(savedMediaFiles, savedBlockId), mediaFiles, blockId); + mGutenbergBridgeJS2Parent.requestMediaFilesEditorLoad(mediaFiles, blockId); } @ReactMethod @@ -256,6 +255,11 @@ public void requestMediaFilesSaveCancelDialog(ReadableArray mediaFiles) { mGutenbergBridgeJS2Parent.requestMediaFilesSaveCancelDialog(mediaFiles); } + @ReactMethod + public void mediaFilesBlockReplaceSync(ReadableArray mediaFiles, String blockId) { + mGutenbergBridgeJS2Parent.mediaFilesBlockReplaceSync(mediaFiles, blockId); + } + @ReactMethod public void editorDidEmitLog(String message, int logLevel) { mGutenbergBridgeJS2Parent.editorDidEmitLog(message, GutenbergBridgeJS2Parent.LogLevel.valueOf(logLevel)); diff --git a/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/DeferredEventEmitter.java b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/DeferredEventEmitter.java index 013a89da92f51..8643d4ca37b0b 100644 --- a/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/DeferredEventEmitter.java +++ b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/DeferredEventEmitter.java @@ -38,12 +38,15 @@ public interface JSEventEmitter { private static final String EVENT_NAME_MEDIA_UPLOAD = "mediaUpload"; private static final String EVENT_NAME_MEDIA_SAVE = "mediaSave"; + private static final String EVENT_NAME_MEDIA_REPLACE_BLOCK = "replaceBlock"; 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"; + private static final String MAP_KEY_REPLACE_BLOCK_HTML = "html"; + private static final String MAP_KEY_REPLACE_BLOCK_BLOCK_ID = "clientId"; /** * Used for storing deferred actions prior to editor mounting @@ -202,6 +205,14 @@ public void onMediaCollectionSaveResult(String firstMediaIdInCollection, boolean } } + @Override public void onReplaceMediaFilesEditedBlock(String mediaFiles, String blockId) { + WritableMap writableMap = new WritableNativeMap(); + writableMap.putString(MAP_KEY_REPLACE_BLOCK_HTML, mediaFiles); + writableMap.putString(MAP_KEY_REPLACE_BLOCK_BLOCK_ID, blockId); + // this is a critical message so, always enqueue + queueActionToJS(EVENT_NAME_MEDIA_REPLACE_BLOCK, writableMap); + } + public void updateCapabilities(GutenbergProps gutenbergProps) { queueActionToJS(MAP_KEY_UPDATE_CAPABILITIES, Arguments.makeNativeMap(gutenbergProps.getUpdatedCapabilitiesProps())); } diff --git a/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/WPAndroidGlueCode.java b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/WPAndroidGlueCode.java index fb3b56d79b49d..87d3129ef5065 100644 --- a/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/WPAndroidGlueCode.java +++ b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/WPAndroidGlueCode.java @@ -49,7 +49,6 @@ import org.wordpress.mobile.ReactNativeGutenbergBridge.GutenbergBridgeJS2Parent; import org.wordpress.mobile.ReactNativeGutenbergBridge.GutenbergBridgeJS2Parent.GutenbergUserEvent; import org.wordpress.mobile.ReactNativeGutenbergBridge.GutenbergBridgeJS2Parent.MediaSelectedCallback; -import org.wordpress.mobile.ReactNativeGutenbergBridge.GutenbergBridgeJS2Parent.ReplaceMediaFilesEditedBlockCallback; import org.wordpress.mobile.ReactNativeGutenbergBridge.GutenbergBridgeJS2Parent.ReplaceUnsupportedBlockCallback; import org.wordpress.mobile.ReactNativeGutenbergBridge.RNMedia; import org.wordpress.mobile.ReactNativeGutenbergBridge.RNReactNativeGutenbergBridgePackage; @@ -94,7 +93,6 @@ public class WPAndroidGlueCode { private OnGutenbergDidSendButtonPressedActionListener mOnGutenbergDidSendButtonPressedActionListener; private ReplaceUnsupportedBlockCallback mReplaceUnsupportedBlockCallback; private OnMediaFilesCollectionBasedBlockEditorListener mOnMediaFilesCollectionBasedBlockEditorListener; - private ReplaceMediaFilesEditedBlockCallback mReplaceMediaFilesEditedBlockCallback; private boolean mIsEditorMounted; private String mContentHtml = ""; @@ -158,6 +156,7 @@ public interface OnMediaFilesCollectionBasedBlockEditorListener { void onCancelUploadForMediaCollection(ArrayList mediaFiles); void onRetryUploadForMediaCollection(ArrayList mediaFiles); void onCancelSaveForMediaCollection(ArrayList mediaFiles); + void onMediaFilesBlockReplaceSync(ArrayList mediaFiles, String blockId); } public interface OnImageFullscreenPreviewListener { @@ -435,12 +434,7 @@ public void onShowUserSuggestions(Consumer onResult) { } @Override - public void requestMediaFilesEditorLoad( - ReplaceMediaFilesEditedBlockCallback replaceMediaFilesEditedBlockCallback, - ReadableArray mediaFiles, - String blockId - ) { - mReplaceMediaFilesEditedBlockCallback = replaceMediaFilesEditedBlockCallback; + public void requestMediaFilesEditorLoad(ReadableArray mediaFiles, String blockId) { mOnMediaFilesCollectionBasedBlockEditorListener .onRequestMediaFilesEditorLoad(mediaFiles.toArrayList(), blockId); } @@ -465,6 +459,14 @@ public void requestMediaFilesSaveCancelDialog(ReadableArray mediaFiles) { mediaFiles.toArrayList() ); } + + @Override + public void mediaFilesBlockReplaceSync(ReadableArray mediaFiles, String blockId) { + mOnMediaFilesCollectionBasedBlockEditorListener.onMediaFilesBlockReplaceSync( + mediaFiles.toArrayList(), blockId + ); + } + }, mIsDarkMode); return Arrays.asList( @@ -956,11 +958,8 @@ public void replaceUnsupportedBlock(String content, String blockId) { } } - public void replaceMediaFilesEditedBlock(String mediaFiles, String blockId) { - if (mReplaceMediaFilesEditedBlockCallback != null) { - mReplaceMediaFilesEditedBlockCallback.replaceMediaFilesEditedBlock(mediaFiles, blockId); - mReplaceMediaFilesEditedBlockCallback = null; - } + public void replaceMediaFilesEditedBlock(final String mediaFiles, final String blockId) { + mDeferredEventEmitter.onReplaceMediaFilesEditedBlock(mediaFiles, blockId); } private boolean isMediaSelectedCallbackRegistered() { diff --git a/packages/react-native-bridge/index.js b/packages/react-native-bridge/index.js index 398e359be69f7..8bf3742ce1634 100644 --- a/packages/react-native-bridge/index.js +++ b/packages/react-native-bridge/index.js @@ -346,4 +346,18 @@ export function requestMediaFilesSaveCancelDialog( mediaFiles ) { ); } +/** + * Request the host app to listen to mediaFiles collection based block replacement signals + * in case such an event was enqueued + * + * @param {Array} mediaFiles the mediaFiles attribute of the block, containing data about each media item. + * @param {string} blockClientId the clientId of the block. + */ +export function mediaFilesBlockReplaceSync( mediaFiles, blockClientId ) { + RNReactNativeGutenbergBridge.mediaFilesBlockReplaceSync( + mediaFiles, + blockClientId + ); +} + export default RNReactNativeGutenbergBridge; diff --git a/packages/react-native-bridge/ios/GutenbergBridgeDelegate.swift b/packages/react-native-bridge/ios/GutenbergBridgeDelegate.swift index b0da1919bf9dd..daf77a2c26edc 100644 --- a/packages/react-native-bridge/ios/GutenbergBridgeDelegate.swift +++ b/packages/react-native-bridge/ios/GutenbergBridgeDelegate.swift @@ -262,4 +262,5 @@ public extension GutenbergBridgeDelegate { func gutenbergDidRequestMediaFilesFailedRetryDialog(_ mediaFiles: [String]) { } func gutenbergDidRequestMediaFilesUploadCancelDialog(_ mediaFiles: [String]) { } func gutenbergDidRequestMediaFilesSaveCancelDialog(_ mediaFiles: [String]) { } + func gutenbergDidRequestMediaFilesBlockReplaceSync() {} } diff --git a/packages/react-native-bridge/ios/RNReactNativeGutenbergBridge.m b/packages/react-native-bridge/ios/RNReactNativeGutenbergBridge.m index 4b8a2e0c83daa..26e9a4fb7689c 100644 --- a/packages/react-native-bridge/ios/RNReactNativeGutenbergBridge.m +++ b/packages/react-native-bridge/ios/RNReactNativeGutenbergBridge.m @@ -29,5 +29,6 @@ @interface RCT_EXTERN_MODULE(RNReactNativeGutenbergBridge, NSObject) RCT_EXTERN_METHOD(onCancelUploadForMediaCollection:(NSArray *)mediaFiles) RCT_EXTERN_METHOD(actionButtonPressed:(NSString *)buttonType) RCT_EXTERN_METHOD(mediaSaveSync) +RCT_EXTERN_METHOD(mediaFilesBlockReplaceSync) @end diff --git a/packages/react-native-bridge/ios/RNReactNativeGutenbergBridge.swift b/packages/react-native-bridge/ios/RNReactNativeGutenbergBridge.swift index c9f5cbcbb7c7f..ecd4f4f0c60a5 100644 --- a/packages/react-native-bridge/ios/RNReactNativeGutenbergBridge.swift +++ b/packages/react-native-bridge/ios/RNReactNativeGutenbergBridge.swift @@ -327,6 +327,15 @@ public class RNReactNativeGutenbergBridge: RCTEventEmitter { } } + @objc + func mediaFilesBlockReplaceSync() { + DispatchQueue.main.async { + if self.hasObservers { + self.delegate?.gutenbergDidRequestMediaFilesBlockReplaceSync() + } + } + } + @objc func actionButtonPressed(_ buttonType: String) { guard let button = Gutenberg.ActionButtonType(rawValue: buttonType) else { diff --git a/packages/react-native-editor/android/app/src/main/java/com/gutenberg/MainApplication.java b/packages/react-native-editor/android/app/src/main/java/com/gutenberg/MainApplication.java index dd9519b4ba2cd..5e3cbf873eef0 100644 --- a/packages/react-native-editor/android/app/src/main/java/com/gutenberg/MainApplication.java +++ b/packages/react-native-editor/android/app/src/main/java/com/gutenberg/MainApplication.java @@ -195,7 +195,6 @@ public void onShowXpostSuggestions(Consumer onResult) { @Override public void requestMediaFilesEditorLoad( - ReplaceMediaFilesEditedBlockCallback replaceMediaFilesEditedBlockCallback, ReadableArray mediaFiles, String blockId ) { @@ -217,6 +216,14 @@ public void requestMediaFilesSaveCancelDialog(ReadableArray mediaFiles) { Toast.makeText(MainApplication.this, "requestMediaFilesSaveCancelDialog called", Toast.LENGTH_SHORT).show(); } + @Override + public void mediaFilesBlockReplaceSync( + ReadableArray mediaFiles, + String blockId + ) { + Toast.makeText(MainApplication.this, "mediaFilesBlockReplaceSync called", Toast.LENGTH_SHORT).show(); + } + @Override public void gutenbergDidSendButtonPressedAction(String buttonType) { diff --git a/packages/react-native-editor/ios/GutenbergDemo/GutenbergViewController.swift b/packages/react-native-editor/ios/GutenbergDemo/GutenbergViewController.swift index 1e1d7841a1d49..175ad6dbebe63 100644 --- a/packages/react-native-editor/ios/GutenbergDemo/GutenbergViewController.swift +++ b/packages/react-native-editor/ios/GutenbergDemo/GutenbergViewController.swift @@ -233,6 +233,10 @@ extension GutenbergViewController: GutenbergBridgeDelegate { print(#function) } + func gutenbergDidRequestMediaFilesBlockReplaceSync() { + print(#function) + } + func gutenbergDidRequestMediaFilesEditorLoad(_ mediaFiles: [String], blockId: String) { print(#function) }