Skip to content

Commit

Permalink
webview: Tidy up style and comments for new handshake code.
Browse files Browse the repository at this point in the history
This cleans up a few small things from the parent commit:
 * Pull the detailed handshake logic out of `componentDidMount`
   into its own method.
 * Rename `isWebViewReady` to be a bit more specific, and to
   have the grammar of a fact rather than a question, as in
   `if (isReady)` -> "if the thing is ready".
 * Keep mentions of the MessageInput* types in a consistent order.
 * Make the comments a lot terser.

See the parent commit for detailed explanation of this code.
  • Loading branch information
gnprice committed Oct 30, 2018
1 parent 6e42cb8 commit 6d60999
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 42 deletions.
34 changes: 15 additions & 19 deletions src/webview/MessageListWeb.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import { base64Utf8Encode } from '../utils/encoding';
export default class MessageListWeb extends Component<Props> {
context: Context;
props: Props;
isWebViewReady: boolean;
webview: ?Object;
sendMessagesIsReady: boolean;
unsentMessages: WebviewInputMessage[] = [];

static contextTypes = {
Expand All @@ -25,28 +25,24 @@ export default class MessageListWeb extends Component<Props> {
};

componentDidMount() {
/*
* Initiates a two-way handshake with the WebView. Ensures that both sides are
* ready to communicate before considering to be ready.
*
* This component communicates with webView with the help of `postMessage`.
* It needs to be ensured that this communication channel is established successfully
* on both side, else it will cause issue like #3080.
* Two way hand shake mechanism is used for this purpose.
*
* Send a hello event till a confirmation is reveived from webView.
*/
this.setupSendMessages();
}

handleError = (event: Object) => {
console.error(event); // eslint-disable-line
};

/**
* Initiate round-trip handshakes with the WebView, until one succeeds.
*/
setupSendMessages = (): void => {
const intervalId = setInterval(() => {
if (!this.isWebViewReady) {
if (!this.sendMessagesIsReady) {
this.sendMessages([{ type: 'ready' }]);
} else {
clearInterval(intervalId);
}
}, 30);
}

handleError = (event: Object) => {
console.error(event); // eslint-disable-line
};

sendMessages = (messages: WebviewInputMessage[]): void => {
Expand All @@ -58,7 +54,7 @@ export default class MessageListWeb extends Component<Props> {
handleMessage = (event: { nativeEvent: { data: string } }) => {
const eventData: MessageListEvent = JSON.parse(event.nativeEvent.data);
if (eventData.type === 'ready') {
this.isWebViewReady = true;
this.sendMessagesIsReady = true;
this.sendMessages(this.unsentMessages);
} else {
const handler = `handle${eventData.type.charAt(0).toUpperCase()}${eventData.type.slice(1)}`;
Expand All @@ -69,7 +65,7 @@ export default class MessageListWeb extends Component<Props> {
shouldComponentUpdate = (nextProps: Props) => {
const messages = getInputMessages(this.props, nextProps);

if (this.isWebViewReady) {
if (this.sendMessagesIsReady) {
this.sendMessages(messages);
} else {
this.unsentMessages.push(...messages);
Expand Down
4 changes: 2 additions & 2 deletions src/webview/js/generatedEs3.js
Original file line number Diff line number Diff line change
Expand Up @@ -259,10 +259,10 @@ var handleMessageReady = function handleMessageReady(msg) {
};
var messageHandlers = {
ready: handleMessageReady,
content: handleMessageContent,
fetching: handleMessageFetching,
typing: handleMessageTyping
typing: handleMessageTyping,
ready: handleMessageReady
};
document.addEventListener('message', function (e) {
Expand Down
19 changes: 4 additions & 15 deletions src/webview/js/js.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import type {
WebviewInputMessage,
MessageInputContent,
MessageInputFetching,
MessageInputReady,
MessageInputTyping,
MessageInputReady,
} from '../webViewHandleUpdates';

/**
Expand Down Expand Up @@ -328,29 +328,18 @@ const handleMessageTyping = (msg: MessageInputTyping) => {
}
};

/*
* In response to a `ready` message send back another `ready` message and
* thus complete the handshake process. When it is received by the other
* side both sides are ready.
*
* This webView communicates with react component (app) with the help of
* `postMessage`. It needs to be ensured that this communication channel is
* established successfully on both side, else it will cause issue like
* #3080. Two way hand shake mechanism is used for this purpose.
*
* Send a hello event as soon as hello event is reveived from React
* component to convey that webView is active.
*
/**
* Echo back the handshake message, confirming the channel is ready.
*/
const handleMessageReady = (msg: MessageInputReady) => {
sendMessage({ type: 'ready' });
};

const messageHandlers = {
ready: handleMessageReady,
content: handleMessageContent,
fetching: handleMessageFetching,
typing: handleMessageTyping,
ready: handleMessageReady,
};

document.addEventListener('message', e => {
Expand Down
12 changes: 6 additions & 6 deletions src/webview/webViewHandleUpdates.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,20 @@ export type MessageInputFetching = {
fetchingNewer: boolean,
};

export type MessageInputReady = {
type: 'ready',
};

export type MessageInputTyping = {
type: 'typing',
content: string,
};

export type MessageInputReady = {
type: 'ready',
};

export type WebviewInputMessage =
| MessageInputContent
| MessageInputFetching
| MessageInputReady
| MessageInputTyping;
| MessageInputTyping
| MessageInputReady;

const updateContent = (prevProps: Props, nextProps: Props): MessageInputContent => {
const content = htmlBody(renderMessagesAsHtml(nextProps), nextProps.showMessagePlaceholders);
Expand Down

0 comments on commit 6d60999

Please sign in to comment.