UNPKG

coolink-ts

Version:

Coocaa Coolink APP JavaScript library base on Thresh-lib.

309 lines (295 loc) 9.15 kB
/** * MIT License * * Copyright (c) 2020 ManBang Group * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * */ import BridgeManager from '../manager/BridgeManager' import UtilManager from '../manager/UtilManager' import Util from '../shared/Util' import { ChannelParams, BridgeParams } from '../types/type' import threshApp from '../core/ThreshApp' import appContainer from '../core/AppContainer' import { PerformanceInfo } from '../core/PageContainer' declare const methodChannel_js_call_flutter: Function declare const methodChannel_js_call_native: Function /** * JS 向 Flutter 发出消息的类型枚举 */ export enum FlutterMethodChannelType { none = '', // 改消息会被忽略 setBundleDir = 'setBundleDir', devtools = 'devtools', bridgeRequest = 'bridgeRequest', onError = 'onError', // UI mediaQuery = 'mediaQuery', setAppBarHeight = 'setAppBarHeight', pushPage = 'pushPage', pushReplacement = 'pushReplacement', popPage = 'popPage', showModal = 'showModal', showToast = 'showToast', hideToast = 'hideToast', setResourcePath = 'setResourcePath', updateWidget = 'updateWidget', pageNotFound = 'pageNotFound', stopAlwaysRender = 'stopAlwaysRender', onDestroyed = 'onDestroyed', // Utils copy = 'copy', blur = 'blur', // Widget Methods updateTitle = 'updateTitle', scrollTo = 'scrollTo', stopAsyncOperate = 'stopAsyncOperate', openActions = 'openActions', closeActions = 'closeActions', swipeTo = 'swipeTo', setValue = 'setValue', triggerFocus = 'triggerFocus', jumpTo = 'jumpTo', animateTo = 'animateTo', switchTo = 'switchTo', setNestScrollViewStatus = 'setNestScrollViewStatus', dragPositionAnimateTo = 'dragPositionAnimateTo', // video audio play = 'play', pause = 'pause', seekTo = 'seekTo', setVolume = 'setVolume', //audio setSourceUrl = 'setSourceUrl', //file fileRequest = 'fileRequest', // pdf view openFile = 'openFile', setPage = 'setPage', setScale = 'setScale', switchTheme = 'switchTheme', getPageCount = 'getPageCount', getCurrentPage = 'getCurrentPage', chooseLocalFile = 'chooseLocalFile' } /** * JS 向 Native 发出消息的类型枚举 */ export enum NativeMethodChannelType { print = 'print', reload = 'reload', pageDidShow = 'pageDidShow', invokeNativeViewMethod = 'invokeNativeViewMethod', bridgeRequest = 'bridgeRequest', sendData = 'sendData', } /** * JS 接收到的消息类型枚举 */ export enum MethodChannelReceiveType { mediaQuery = 'mediaQuery', ready = 'ready', setupPage = 'setupPage', needPopPage = 'needPopPage', hasPopPage = 'hasPopPage', triggerEvent = 'triggerEvent', lifeCycle = 'lifeCycle', bridgeResponse = 'bridgeResponse', closeWindow = 'closeWindow', pageDidLoad = 'pageDidLoad', onDestroyed = 'onDestroyed', //file fileResponse = 'fileResponse', } /** * 打印method channel方法参数 */ const methodChannelConsole = (channelParams: ChannelParams) => { const { method, params, contextId } = channelParams console.group('[CHANNEL PRINT] method: ' + method) if (params) { if (params.widgetRenderData) { params.widgetRenderData = JSON.parse(params.widgetRenderData) } if (params.widgetUpdateData) { params.widgetUpdateData = JSON.parse(params.widgetUpdateData) } } console.log('contextId: ', contextId) console.log('params: ', params) console.groupEnd() } /** * js与native和flutter通信的方法 * methodChannel_js_call_flutter methodChannel_js_call_native 为 native 注入到当前 js context 中的方法 */ function jsCallNative(channelParams: ChannelParams) { try { channelParams = formatChannelParams(channelParams) if (channelParams.method === FlutterMethodChannelType.none) return methodChannel_js_call_native(channelParams) } catch (e) { } finally { // if (threshApp.debugMode && process.env.NODE_ENV === 'development') { // methodChannelConsole(channelParams) // } } } function jsCallFlutter(channelParams: ChannelParams) { try { channelParams = formatChannelParams(channelParams) if (channelParams.method === FlutterMethodChannelType.none) return methodChannel_js_call_flutter(channelParams) } catch (e) { } finally { // if (threshApp.debugMode && process.env.NODE_ENV === 'development') { // methodChannelConsole(channelParams) // } } } function formatChannelParams(channelParams: ChannelParams, stringifyParams: boolean = false): ChannelParams { let { params } = channelParams if (Util.isNil(params)) params = {} if (!Util.isObject(params)) { UtilManager.error('Channel params must pass in an object!') return { method: FlutterMethodChannelType.none } } // if (!Util.isNil(params.__channelStartTime__)) { // UtilManager.error('Channel params cannot use "__channelStartTime__" as a key!') // return { method: FlutterMethodChannelType.none } // } // params.__channelStartTime__ = Date.now() if (!channelParams.contextId) channelParams.contextId = appContainer.contextId channelParams.params = stringifyParams ? JSON.stringify(params) : params return channelParams } /** * 通信类 * 封装了js调用native和flutter的方法 */ export default class MethodChannel { static MAX_CHUNK_SIZE: number = 1024 * 10 // 调用注入方法 static call({ method, params = {}, contextId, }: { method: FlutterMethodChannelType | NativeMethodChannelType params?: any contextId?: string }) { jsCallFlutter({ contextId, method, params }) } // 页面初次渲染完成时通知 native static pageDidShow(networkTime: number = 0) { const performanceInfo: PerformanceInfo | undefined = appContainer.getPagePerformanceInfo() if (!performanceInfo || performanceInfo.hasReported) return performanceInfo.hasReported = true const pageShowTimestamp = Date.now() const pageName = threshApp.pageName || 'unknown' jsCallNative({ method: NativeMethodChannelType.pageDidShow, params: { flutterVersion: threshApp.flutterVersion, jsVersion: threshApp.jsVersion, pageName, // 网络通信耗时 networkTime, // 页面创建时的时间戳 pageCreateTimestamp: performanceInfo.createTimestamp, // 页面首帧加载完成的时间戳 pageLoadTimestamp: performanceInfo.loadTimestamp, // 页面显示时的时间戳(包含网络通信耗时) pageShowTimestamp, } }) UtilManager.log({ pageName, networkTime, pageLoadTime: performanceInfo.loadTimestamp - performanceInfo.createTimestamp, pageShowTime: pageShowTimestamp - performanceInfo.createTimestamp }) } // 输出到native static print(params: any = {}) { jsCallNative({ method: NativeMethodChannelType.print, params }) } // 重载bundle.js static reload() { jsCallNative({ method: NativeMethodChannelType.reload, params: {} }) } // 触发 NativeView 方法 static invokeNativeViewMethod({ methodName, methodParams = {}, viewType, viewParams = {}, }: { methodName: string, methodParams?: any, viewType: string, viewParams?: any, }) { jsCallNative({ method: NativeMethodChannelType.invokeNativeViewMethod, params: { methodName, methodParams, viewType, viewParams, } }) } // bridge方法 static bridge(methodId: string, params: BridgeParams) { if (!Util.isProd && BridgeManager.isNetworkRequest(params)) { jsCallFlutter({ method: FlutterMethodChannelType.bridgeRequest, params: { methodId, request: Util.toString(params), } }) return } jsCallNative({ method: NativeMethodChannelType.bridgeRequest, params: { methodId, request: params, } }) } // 向Native侧传数据 static sendDataToNative(params: any = {}) { jsCallNative({ method: NativeMethodChannelType.sendData, params }) } }