English | [简体中文](./README-zh_CN.md)

# @ray-js/webview-invoke

> WebviewInvoke is a middleware that communicates with Webview across multiple platforms. You can communicate with Webview on the ray platform, the mini program platform, and the ReactNative platform.

## Installation

```sh
$ npm install @ray-js/webview-invoke
// or
$ yarn add @ray-js/webview-invoke
```

## Usage

<!--START_SECTION:txp-usage-->

Mini program view layer
</br>

```xml
<web-view src="{{src}}" id="{{ webviewId }}" bind:message="onMessage" bind:load="onLoadEnd" bind:error="onError"></web-view>
```

Mini program logic layer
```js
const componentOptions = {
   properties: {
    src: { type: String },
    webviewId: { type: String },
  },
  data: {},
  observers: {},
  lifetimes: {
    ready() {
      this.bindWebViewInvoke();
      this.defineCallbacks();
      this.bindFunctions();
    },
  },
  methods: {
    onLoadEnd() {
      // This simulates sending data to WebView
      setTimeout(() => {
        this.postBundleBinaryWEB({
          key: 'file',
          id: 'file',
          bundle: 'bundle',
          index: 1,
          total: 10,
        });
      }, 3000);
    },
    /**
     * Create a webviewContext object and bind it to invoke
     */
    bindWebViewInvoke() {
      if (ty.createWebviewContext) {
        this.webviewContext = ty.createWebviewContext(this.data.webviewId);
        /**
         * Inject platform attribute into webviewContext
         */
        Object.defineProperty(this.webviewContext, 'platform', {
          value: 'mini',
          writable: false,
        });
        this.invoke = createInvoke(() => this.webviewContext);
      }
    },
    /**
     * Create a defined callback function that can throw data out of WebView
     */
    defineCallbacks() {
      if (this.invoke) {
        this.invoke.define('onLoggerInfo', this.onLoggerInfo);
      }
    },
    /**
     * Define the logical layer to throw data into the specified method in WebView
     */
    bindFunctions() {
      if (this.invoke) {
        this.postBundleBinaryWEB = this.invoke.bind('postBundleBinary');
      }
    },
    // Here accept messages from WebView
    onMessage(evt) {
      if (this.invoke) {
        this.invoke.listener(evt);
      }
    },
    // WebView failed to load
    onError() {},
    /**
     * The following methods are all used to bind the communication between the native components of the mini program and the ray components.
     * @param {*} data
     */
    onLoggerInfo(data) {
      this.triggerEvent('onLoggerInfo'.toLowerCase(), data);
    },
  }
};
Component(componentOptions);
```


Mixed development using small program components in Ray components

```tsx
import React, { useState, useEffect, useCallback, useRef } from 'react';
// This is your mini program component
import WebView from '../webview';

interface IProps {}
const MapView: React.FC<IProps> = props => {
  const webviewId: any = useRef(`webviewId_${new Date().getTime()}`).current;

  const onLoggerInfo = (data: any) => {
    console.log('Received data callback from WebView',data);
  };

  const onEvent = useCallback((evt: { type: string; detail: any}) => {
    const { detail } = evt;
    switch (evt.type) {
      case 'onLoggerInfo'.toLowerCase():
        onLoggerInfo(detail);
        break;
    }
  }, []);

  return (
    <View>
      <WebView
        // Here is your service address, you can also change it to a local file
        src="http://172.20.10.3:3000?mode=debugger"
        webviewId={webviewId}
        // Different ray versions here may have slightly different writing methods.
        bindonloggerinfo={onEvent}
        />
    </View>
  )
} 

```
<!--END_SECTION:txp-usage-->