JavaScript Bridge - lazaronixon/react-native-turbolinks GitHub Wiki

Problem

At some point you will want to read the html content, whether to get the title, subtitle, read some meta attribute or better... parse html attributes and generate a native mobile menu. The code below was extracted from one of my app's and show how you can do this.

App.js

import React, { Component } from 'react'
import Turbolinks from 'react-native-turbolinks'
import javaScriptBridge from './helpers/JavaScriptBridge'

export default class App extends Component {

  componentDidMount() {
    Turbolinks.addEventListener('turbolinksVisitCompleted', this.handleVisitCompleted)
    Turbolinks.addEventListener('turbolinksMessage', this.handleMessage)

    Turbolinks.addEventListener('turbolinksVisit', this.handleVisit)
    Turbolinks.addEventListener('turbolinksError', this.handleError)
    Turbolinks.startSingleScreenApp({url: 'http://MYIP:9292'}, {injectedJavaScript: javaScriptBridge, messageHandler: 'sigWebMobile'})
  }

  handleMessage = (message) => {
    const { name, data } = JSON.parse(message)
    if (name == 'handleVisitCompleted') {
      this.hasCalendar = data.hasCalendar
      this.startDate   = data.startDate
      this.endDate     = data.endDate
      this.actions     = this.parseActions(data.actions)
      Turbolinks.renderTitle(data.title, data.subtitle)
      Turbolinks.renderActions(this.actions)
    }
  }

  handleVisitCompleted = (data) => {
    Turbolinks.injectJavaScript('bridge.handleVisitCompleted()')
  }

  parseActions = (actions) => {
    return actions.map((a) => { return {...this.availableActions[a.id], href: a.href} })
  }

  handleVisit = (data) => {
    Turbolinks.visit({url: data.url, action: data.action})
  }

  handleError = (data) => {
    alert(data.description)
  }

  get availableActions() {
    return {
      1: { id: 1, title: 'Informação',   icon: this.infoIcon,    action: 'advance' },
      2: { id: 2, title: 'Atualizar',    icon: this.refreshIcon, action: 'replace' },
      3: { id: 3, title: 'Compartilhar', icon: this.shareIcon                      }
    }
  }

  render() { return null }
}

JavaScriptBridge.js

const content = `
(function() {

  function Bridge(messageHandler) {
    this.messageHandler = messageHandler;
  }

  Bridge.prototype = {
    handleVisitCompleted: function() {
      this.postMessage("handleVisitCompleted", {
         title: App.bridgeGetMeta("current-page-title"),
         subtitle: App.bridgeGetMeta("current-page-subtitle"),
         hasCalendar: App.bridgeGetMeta("has-calendar"),
         startDate: App.bridgeGetMeta("current-from-date"),
         endDate: App.bridgeGetMeta("current-to-date"),
         actions: App.bridgeGetMenu()
      });
    },

    //Private

    postMessage: function(name, data) {
      var json = JSON.stringify({ name: name, data: data || {} });
      this.messageHandler.postMessage(json);
    },

  }

  if (window.sigWebMobile) { this.bridge = new Bridge(sigWebMobile); };
  if (window.webkit) { this.bridge = new Bridge(webkit.messageHandlers.sigWebMobile); };

})()`

export default content;

References