import RemoteMessenger from '@joplin/lib/utils/ipc/RemoteMessenger'; import { SerializableData } from '@joplin/lib/utils/ipc/types'; import { WebViewMessageEvent } from 'react-native-webview'; import { WebViewControl } from '../../components/ExtendedWebView'; import { RefObject } from 'react'; export default class RNToWebViewMessenger extends RemoteMessenger { public constructor(channelId: string, private webviewControl: WebViewControl|RefObject, localApi: LocalInterface) { super(channelId, localApi); } protected override postMessage(message: SerializableData): void { const webviewControl = (this.webviewControl as RefObject).current ?? (this.webviewControl as WebViewControl); // This can happen just after the WebView unloads. if (!webviewControl) return; // This is the case in testing environments where no WebView is available. if (!webviewControl.injectJS) return; webviewControl.injectJS(` window.dispatchEvent( new MessageEvent( 'message', { data: ${JSON.stringify(message)}, origin: 'react-native' }, ), ); `); } public onWebViewMessage = (event: WebViewMessageEvent) => { if (!this.hasBeenClosed()) { void this.onMessage(JSON.parse(event.nativeEvent.data)); } }; public onWebViewLoaded = () => { // Send onReadyToReceive again (if needed). // // This is necessary because any events sent before the webview finished loading // may not have been delivered (though they may have). this.onReadyToReceive(); }; protected override onClose(): void { } }