Skip to content

Commit

Permalink
[RNMobile] Add bridge method to send events to host app (#35272)
Browse files Browse the repository at this point in the history
* Add bridge method to send events to host app

The addition of `sendEventToHost` enables sending arbitrary events to
the native host app, allowing the host to implement the appropriate
mechanism for a given event.

* Fix typo in comment

* Add Android sendEventToHost bridge methods

Mirror the bridge method added for iOS.

* Convert ReadableMap to HashMap

Conversion avoids "leaking" the React Native-specific ReadableMap type
to the host app.

* Improve conversion of properties to hashmap

* Fix comment typo

Co-authored-by: jhnstn <[email protected]>
Co-authored-by: Matt Chowning <[email protected]>
  • Loading branch information
3 people authored Oct 27, 2021
1 parent b48045f commit b4e9811
Show file tree
Hide file tree
Showing 9 changed files with 53 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -174,4 +174,6 @@ void gutenbergDidRequestUnsupportedBlockFallback(ReplaceUnsupportedBlockCallback
void requestContactCustomerSupport();

void requestGotoCustomerSupportOptions();

void sendEventToHost(String eventName, ReadableMap properties);
}
Original file line number Diff line number Diff line change
Expand Up @@ -433,4 +433,9 @@ public void requestContactCustomerSupport() {
public void requestGotoCustomerSupportOptions() {
mGutenbergBridgeJS2Parent.requestGotoCustomerSupportOptions();
}

@ReactMethod
public void sendEventToHost(final String eventName, final ReadableMap properties) {
mGutenbergBridgeJS2Parent.sendEventToHost(eventName, properties);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ public class WPAndroidGlueCode {
private OnGutenbergDidRequestPreviewListener mOnGutenbergDidRequestPreviewListener;
private OnBlockTypeImpressionsEventListener mOnBlockTypeImpressionsEventListener;
private OnCustomerSupportOptionsListener mOnCustomerSupportOptionsListener;
private OnSendEventToHostListener mOnSendEventToHostListener;
private boolean mIsEditorMounted;

private String mContentHtml = "";
Expand Down Expand Up @@ -233,6 +234,10 @@ public interface OnCustomerSupportOptionsListener {
void onGotoCustomerSupportOptions();
}

public interface OnSendEventToHostListener {
void onSendEventToHost(String eventName, Map<String, Object> properties);
}

public void mediaSelectionCancelled() {
mAppendsMultipleSelectedToSiblingBlocks = false;
}
Expand Down Expand Up @@ -543,6 +548,11 @@ public void requestContactCustomerSupport() {
public void requestGotoCustomerSupportOptions() {
mOnCustomerSupportOptionsListener.onGotoCustomerSupportOptions();
}

@Override
public void sendEventToHost(String eventName, ReadableMap properties) {
mOnSendEventToHostListener.onSendEventToHost(eventName, properties.toHashMap());
}
}, mIsDarkMode);

return Arrays.asList(
Expand Down Expand Up @@ -624,6 +634,7 @@ public void attachToContainer(ViewGroup viewGroup,
OnGutenbergDidRequestPreviewListener onGutenbergDidRequestPreviewListener,
OnBlockTypeImpressionsEventListener onBlockTypeImpressionsEventListener,
OnCustomerSupportOptionsListener onCustomerSupportOptionsListener,
OnSendEventToHostListener onSendEventToHostListener,
boolean isDarkMode) {
MutableContextWrapper contextWrapper = (MutableContextWrapper) mReactRootView.getContext();
contextWrapper.setBaseContext(viewGroup.getContext());
Expand All @@ -645,6 +656,7 @@ public void attachToContainer(ViewGroup viewGroup,
mOnGutenbergDidRequestPreviewListener = onGutenbergDidRequestPreviewListener;
mOnBlockTypeImpressionsEventListener = onBlockTypeImpressionsEventListener;
mOnCustomerSupportOptionsListener = onCustomerSupportOptionsListener;
mOnSendEventToHostListener = onSendEventToHostListener;

sAddCookiesInterceptor.setOnAuthHeaderRequestedListener(onAuthHeaderRequestedListener);

Expand Down
14 changes: 14 additions & 0 deletions packages/react-native-bridge/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -422,4 +422,18 @@ export function requestGotoCustomerSupportOptions() {
RNReactNativeGutenbergBridge.requestGotoCustomerSupportOptions();
}

/**
* Request the host app receive an event with properties.
*
* @param {string} eventName Name representing to the event.
* @param {Object} properties Key-value pairs of event properties.
* @return {void}
*/
export function sendEventToHost( eventName, properties ) {
return RNReactNativeGutenbergBridge.sendEventToHost(
eventName,
properties
);
}

export default RNReactNativeGutenbergBridge;
Original file line number Diff line number Diff line change
Expand Up @@ -246,14 +246,17 @@ public protocol GutenbergBridgeDelegate: class {
/// Tells the delegate that the editor requested the block type impression counts
func gutenbergDidRequestBlockTypeImpressions() -> [String: Int]

/// Tells the delegate the the editor requested setting the impression counts
/// Tells the delegate that the editor requested setting the impression counts
func gutenbergDidRequestSetBlockTypeImpressions(_ impressions: [String: Int])

/// Tells the delegate that the editor requested to show the "Contact Support" support view.
func gutenbergDidRequestContactCustomerSupport()

/// Tells the delegate that the editor requested to show the "My Tickets" support view.
func gutenbergDidRequestGotoCustomerSupportOptions()

/// Tells the delegate the editor requested sending an event
func gutenbergDidRequestSendEventToHost(_ eventName: String, properties: [AnyHashable: Any])
}

// MARK: - Optional GutenbergBridgeDelegate methods
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,6 @@ @interface RCT_EXTERN_MODULE(RNReactNativeGutenbergBridge, NSObject)
RCT_EXTERN_METHOD(setBlockTypeImpressions:(NSDictionary *)impressions)
RCT_EXTERN_METHOD(requestContactCustomerSupport)
RCT_EXTERN_METHOD(requestGotoCustomerSupportOptions)
RCT_EXTERN_METHOD(sendEventToHost:(NSString)eventName properties:(NSDictionary *)properties)

@end
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ public class RNReactNativeGutenbergBridge: RCTEventEmitter {
self.delegate?.gutenbergDidSendButtonPressedAction(button)
}
}

@objc
func requestPreview() {
DispatchQueue.main.async {
Expand Down Expand Up @@ -387,6 +387,11 @@ public class RNReactNativeGutenbergBridge: RCTEventEmitter {
self.delegate?.gutenbergDidRequestGotoCustomerSupportOptions()
}
}

@objc
func sendEventToHost(_ eventName: String, properties: [AnyHashable: Any]) {
self.delegate?.gutenbergDidRequestSendEventToHost(eventName, properties: properties)
}
}

// MARK: - RCTBridgeModule delegate
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,11 @@ public void requestContactCustomerSupport() {
public void requestGotoCustomerSupportOptions() {
Toast.makeText(MainApplication.this, "requestGotoCustomerSupportOptions called", Toast.LENGTH_SHORT).show();
}

@Override
public void sendEventToHost(final String eventName, final ReadableMap properties) {
Log.d("SendEventToHost", String.format("Gutenberg requested sending '%s' event to host with properties: %s", eventName, properties));
}
}, isDarkMode());

return new ReactNativeHost(this) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,10 @@ extension GutenbergViewController: GutenbergBridgeDelegate {
func gutenbergDidRequestGotoCustomerSupportOptions() {
print(#function)
}

func gutenbergDidRequestSendEventToHost(_ eventName: String, properties: [AnyHashable: Any]) -> Void {
print("Gutenberg requested sending '\(eventName)' event to host with propreties: \(properties).")
}
}

extension GutenbergViewController: GutenbergWebDelegate {
Expand Down

0 comments on commit b4e9811

Please sign in to comment.