-
Notifications
You must be signed in to change notification settings - Fork 2
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
Send message to browser on React Native button click #42
Comments
Do you show the button with React Native or browser? LePont supposes all UIs are rendered in browser (WebView) as HTML/DOM. LePont doesn't support the case where the button is rendered as React Native component. |
The button is shown in React Native. After reading the Lepont source code and thinking for a while I found a solution, but maybe it could be improved. I will share the solution I have found soon. If after that you have suggestions for improvement it would be great to hear. |
I'm curious about your usage of LePont. Do you show UIs both in React Native and browser(WebView)? What part do you use RN and what part browser? |
We will have bidirectional communication between Native and WebView, so both can initiate or receive messages. Currently we have buttons on native end that starts the event, but later this event would be initiated automatically on Native end. Events could also be initiated on WebView. |
In our code we are sending a stream of data from the WebView to React Native, so we first start an operation, then send the data trough multiple messages and at the end close the operation. Here's the code structure: React Native import React, {useEffect} from 'react';
import {WebView} from 'react-native-webview';
import {useBridge, BridgeImpl} from 'lepont';
const MyComponent = () => {
const [webViewRef, onMessage, {registry}] = useBridge();
const register = (f: BridgeImpl<unknown>) => registry.register(f.name, f);
const sendMessage = registry.sendMessage.bind(registry);
const doSomething: BridgeImpl<any> = async (payload, bridge) => {
// Start doing something if it was not initiated by WebView.
if (!payload) {
sendMessage({
type: 'do-something',
payload: '',
});
return;
}
// Operation finished
const endOp = () => {};
// Operation started
const newOp = async () => {};
// Does something
const doIt = () => {};
switch (payload.action) {
case 'new-op':
await newOp();
return 'started';
case 'do-it':
doIt();
return 'did-something';
case 'end-op':
endOp();
return 'ended-op';
default:
throw 'Unknown operation!';
}
};
const doSomethingElse: BridgeImpl<any> = async (payload, bridge) => {
// Start doing something if it was not initiated by WebView.
if (!payload) {
sendMessage({
type: 'do-something-else',
payload: '',
});
return;
}
// ...
};
useEffect(() => {
register(doSomething);
register(doSomethingElse);
}, []);
const handleNavigationStateChange = (state: WebViewNavigation) => {};
return (
<View style={styles.container}>
<WebView
source={{uri: "index.html"}}
originWhitelist={['*']}
allowFileAccessFromFileURLs={true}
allowUniversalAccessFromFileURLs={true}
allowFileAccess={true}
onNavigationStateChange={handleNavigationStateChange}
onMessage={onMessage}
ref={webViewRef}
/>
<Button
title="Do something"
onPress={() => registry.registry.doSomething()}
/>
<Button
title="Do something else"
onPress={() => registry.registry.doSomethingElse()}
/>
</View>
);
} WebView import {sendMessage, on} from 'lepont/browser';
import {encode} from 'base64-arraybuffer';
on('do-something', async payload => {
/** Type of message received on Native end. */
const msgType = 'doSomething';
/** Payload to send to Native end. */
const nativePayload = {
action: '',
data: '',
} as const;
// Create a new operation
await sendMessage({
type: msgType,
payload: {...nativePayload, action: 'new-op'},
});
// Send data chunks
await getStream(async (arrayBuffer) => {
const answer = await sendMessage({
type: msgType,
payload: {
...nativePayload,
action: 'do-it',
data: encode(arrayBuffer),
},
});
});
// End operation
await sendMessage({
type: msgType,
payload: {...nativePayload, action: 'end-op'},
});
});
on('do-something-else', async payload => {
// ...
} There's 2 functions defined on React Native It's important to register the functions inside a |
It's not clear to me how one would send a message to the browser using Lepont when a user clicks for example in a button on the React Native side.
From what I can see one needs to call
bridge.sendMessage
butbridge
is inside all this:Am I supposed to do something like this?
The text was updated successfully, but these errors were encountered: