Skip to content
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

usage on expo as there is no android_asset folder #19

Closed
tshiamor-adft opened this issue Jun 24, 2019 · 5 comments
Closed

usage on expo as there is no android_asset folder #19

tshiamor-adft opened this issue Jun 24, 2019 · 5 comments
Assignees
Labels
bug Something isn't working

Comments

@tshiamor-adft
Copy link

tshiamor-adft commented Jun 24, 2019

Thanks for such a wrapper, however I am unclear on how to use this with expo, as there is no separate android + ios folder when using expo-cli. already tried adding a new android_asset/index.html to the assets folder, however that didn't work. Would appreciate a bit of explanation for beginners, since the readme illustrates useage in a react-native structure and none is shown for expo project structure, thanks a lot.

@tomLadder
Copy link
Owner

I will have a look at it and i will write a step by step tutorial for expo.

@tshiamor-adft
Copy link
Author

tshiamor-adft commented Jul 3, 2019

finally got it working in expo by making a sort of dirty workaround.
had to modify the index.js in the node_modules/react-native-echarts-wrapper/src/, and reference the index.html in the same folder.

Hope there is a better approach or solution for expo on android, as this is just a temporary approach, rebuilding the project would probably replace with the original file as this is within the node_modules.

import React, { Component } from 'react';
import { View, Platform } from 'react-native';
import PropTypes from 'prop-types';
/* eslint-enable */

import * as jsBuilder from './jsBuilder';

import {WebView} from 'react-native';
let WebViewExternalPackage  = WebView;

class ECharts extends Component {
  static propTypes = {
    onData: PropTypes.func,
    baseUrl: PropTypes.string,
    legacyMode: PropTypes.bool,
    canvas: PropTypes.bool,
    onLoadEnd: PropTypes.func
  };

  static defaultProps = {
    baseUrl: "",
    onData: () => {},
    legacyMode: false,
    canvas: false,
    onLoadEnd: () => {}
  };

  constructor(props) {
    super(props);
    this.onGetHeight = null;
    this.callbacks = {};
    const { baseUrl } = props;

    this.html = `
      <!DOCTYPE html>
      <html lang="de">

      <head>
          <meta http-equiv="content-type" content="text/html; charset=utf-8">
          <meta name="viewport" content="initial-scale=1, maximum-scale=3, minimum-scale=1, user-scalable=no">
          <style type="text/css">
            html,body {
              height: 100%;
              width: 100%;
              margin: 0;
              padding: 0;
              background-color:rgba(0, 0, 0, 0);
            }
            #main {
              height: 100%;
              background-color:rgba(0, 0, 0, 0);
            }
            </style>
            <script src="${baseUrl}/echarts.min.js"></script>
          </head>

      <body>
          <div id="main"></div>
      </body>

      </html>`;
  }

  onMessage = e => {
    try {
      if (!e) return null;

      const { onData } = this.props;

      const data = JSON.parse(e.nativeEvent.data);

      if (data.types === "DATA") {
        onData(data.payload);
      } else if (data.types === "CALLBACK") {
        /* eslint-disable no-case-declarations */
        const { uuid } = data;
        /* eslint-enable no-case-declarations */
        this.callbacks[uuid](data.payload);
      }
    } catch (error) {
      console.log(error);
    }
  };

  postMessage = data => {
    this.webview.postMessage(jsBuilder.convertToPostMessageString(data));
  };

  ID = () =>
    `_${Math.random()
      .toString(36)
      .substr(2, 9)}`;

  getOption = (callback, properties = undefined) => {
    const uuid = this.ID();
    this.callbacks[uuid] = callback;
    const data = {
      types: "GET_OPTION",
      uuid,
      properties
    };
    this.postMessage(data);
  };

  setOption = (option, notMerge, lazyUpdate) => {
    const data = {
      types: "SET_OPTION",
      payload: {
        option,
        notMerge: notMerge || false,
        lazyUpdate: lazyUpdate || false
      }
    };
    this.postMessage(data);
  };

  clear = () => {
    const data = {
      types: "CLEAR"
    };
    this.postMessage(data);
  };

  getWebViewRef = ref => {
    this.webview = ref;
  };

  render() {
    let source;
    const { baseUrl, legacyMode } = this.props;
    const localUri = Expo.Asset.fromModule(require('./index.html')).uri;


    if (baseUrl) {
      source = {
        html: this.html,
        baseUrl
      };
    } else {
      /* eslint-disable global-require */
      source =
        Platform.OS === "ios"
          ? require("./index.html")
          : {'uri': localUri };
          console.log(JSON.stringify(source));
      /* eslint-enable global-require */
    }



    let isExpo = false;

    if (typeof Expo !== "undefined" && Expo.Constants) {
      isExpo = Expo.Constants.appOwnership === "expo";
    }

    return (
      <View style={{ flex: 1 }}>
        {legacyMode ? (
          <WebView
            ref={this.getWebViewRef}
            useWebKit={isExpo}
            originWhitelist={["*"]}
            scrollEnabled={false}
            source={source}
            injectedJavaScript={jsBuilder.getJavascriptSource(this.props)}
            onMessage={this.onMessage}
            allowFileAccess
            allowUniversalAccessFromFileURLs
            mixedContentMode="always"
            onLoadEnd={this.props.onLoadEnd}
          />
        ) : (
          <WebViewExternalPackage
            ref={this.getWebViewRef}
            useWebKit={isExpo}
            originWhitelist={["*"]}
            scrollEnabled={false}
            source={source}
            injectedJavaScript={jsBuilder.getJavascriptSource(this.props)}
            onMessage={this.onMessage}
            allowFileAccess
            allowUniversalAccessFromFileURLs
            mixedContentMode="always"
            onLoadEnd={this.props.onLoadEnd}
          />
        )}
      </View>
    );
  }
}

export { ECharts };


@tomLadder
Copy link
Owner

ok solution. Not dirty at all if its works. Can you verify if it's correctly loaded on Android if you create a release version of your expo app? If everything is ok, i will implement the changes and release it in the upcoming version.

@tomLadder tomLadder added the bug Something isn't working label Jul 3, 2019
@tshiamor-adft
Copy link
Author

alright, sure. it can be produced with a minimal build though. seems alright on android expo.Should probably mention I tested on expo 32, and ran the example with legacyMode enabled,
using this package.json.

{
  "main": "node_modules/expo/AppEntry.js",
  "scripts": {
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "web": "expo start --web",
    "eject": "expo eject"
  },
  "dependencies": {
    "expo": "^32.0.0",
    "react": "16.5.0",
    "react-native": "https://github.com/expo/react-native/archive/sdk-32.0.0.tar.gz",
    "react-native-echarts-wrapper": "^1.4.1",
    "react-native-web": "^0.11.4",
    "react-native-webview": "^5.12.0"
  },
  "devDependencies": {
    "babel-preset-expo": "^5.1.1"
  },
  "private": true
}

@vyppN
Copy link

vyppN commented Sep 4, 2019

I tried @tshiamor-adft approach. It shows plain HTML instead. This occurred on both legacyMode and no-legacyMode

@tomLadder tomLadder self-assigned this Sep 4, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants