UNPKG

coolink-ts

Version:

Coocaa Coolink APP JavaScript library base on Thresh-lib.

327 lines (314 loc) 10.4 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 MethodChannel from '../channel/MethodChannel' import RenderManager from '../manager/RenderManager' import createElement from './createElement' import Widget from './Widget' import VNode from './VNode' import appContainer from './AppContainer' import { PageRoute, PageInfo, RouteConfig, ThreshProvidersConfig } from '../types/type' import { ToastInfo } from '../types/widget' import threshAppContext from './ThreshAppContext' import Util from '../shared/Util' import bus from '../shared/bus' import eventManager from '../manager/EventManager' import mpWeb from '../coolink/MpWeb' /** * 对外暴露所有接口的threshApp主类 */ export class ThreshApp { // 代码中配置的默认展示页面 private _defaultPageName: string // 代码中配置的404页面 private _notFoundPageName: string // 是否正在关闭 modal // 如果正在关闭中,将阻止新的 modal 创建 private _modalIsHiding: boolean = false // flutter version flutterVersion: string // js version get jsVersion (): string { return '1.3.2' } // 是否调试模式 debugMode: boolean = false // 平台类型 platform: 'Android' | 'iOS' | void // 外部环境是否准备完成 envReady: boolean = false // 三方注入的路由信息 injectRouteInfo: PageRoute // 三方插件 providers: ThreshProvidersConfig = {} // 持有注入的路由信息 injectRoute = injectRoute createElement: Function = createElement Widget = Widget get pageName (): string { const originPageName = appContainer.currentPageName const defaultPageName = (threshApp.injectRouteInfo || { pageName: '' }).pageName if (!originPageName) return defaultPageName return originPageName.split('#').shift() || defaultPageName } get referPageName (): string { const originReferPageName = appContainer.referPageName if (!originReferPageName) return '' return originReferPageName.split('#').shift() || '' } constructor () { if (mpWeb.isBrowser()) { return; } threshAppContext.initGlobal(this) } clear () { appContainer.clear() bus.clear() eventManager.resetAndRegisterBuiltInEvents() } // 上报异常到 flutter onError = (error: any) => {} /** * 判断当前 df 版本是否小于目标版本 * @param flutterVersion 目标 df 版本 */ flutterVersionSmallerThan = Util.flutterVersionSmallerThan /** * 注册页面 * @param {String} pageName * @param {Function} pageBuilder * @param {boolean} isDefault */ registerPage (pageName: string, pageBuilder: Function, config: RouteConfig = { isDefault: false, isNotFound: false }) { appContainer.addRoute(pageName, pageBuilder) if (config.isDefault) this._defaultPageName = pageName if (config.isNotFound) this._notFoundPageName = pageName } /** * @override * 表示相关环境已准备完成执行的回调,如 flutter 环境 * 可以在这个函数中做一些配置 */ ready = () => {} /** * js主动显示页面 * 存在 injectRouteInfo 时显示 injectRouteInfo 对应的页面 * 不存在时显示 _defaultPageName 页面 * 都不存在时不显示 */ runApp () { this.pushPage() } /** * 通知 flutter 进入下一级页面 * @param {String} pageName * @param {Object} params 页面参数 */ pushPage (pageName?: string, params: object = {}, checkSamePage: boolean = true) { let pageInfo = RenderManager.currentPage; if (checkSamePage) { if (pageInfo) { if (pageInfo.pageName == pageName) { return; } } } // const pageCreateTimestamp = Date.now() const pageRes: PageInfo = this._findPage(pageName || '', params) if (pageRes.pageData) { RenderManager.pushPage(pageRes.pageData, pageRes.pageName, pageCreateTimestamp) Util.log('Push page: ' + pageRes.pageName) } } /** * 通知 flutter 进入下一级页面 * @param {String} pageName * @param {Object} params 页面参数 */ pushReplacement (pageName?: string, params: object = {}) { const pageCreateTimestamp = Date.now() const pageRes: PageInfo = this._findPage(pageName || '', params) if (pageRes.pageData) { RenderManager.pushReplacement(pageRes.pageData, pageRes.pageName, pageCreateTimestamp) Util.log('Push page: ' + pageRes.pageName) } } /** * 推出页面或关闭当前窗口 */ async popPage () { if (appContainer.isEmpty) return return await RenderManager.popPage() } /** * 当前页面是否可以pop */ canPop (): boolean { return appContainer.canPop } /** * 显示模态框 * @param {VNode} modal * @param {String} title * @param {boolean} popup */ showModal (modal: VNode, { title, popup }: { title?: string, popup?: boolean } = {}) { if (!this._modalIsHiding) { RenderManager.showModal(modal, appContainer.formatModalName(title), !!popup) } } /** * 隐藏模态框 */ async hideModal () { this._modalIsHiding = true await RenderManager.hideModal() this._modalIsHiding = false } /** * 显示 toast * toast 不具备生命周期 * @param {VNode} toast * @param {ToastInfo} info 该参数字段见下,可选 * @param {String} name 名称,用来控制隐藏,如果不设置将会设置为自动隐藏 * @param {int} stayTime toast 保持时间,默认 2000ms * @param {int} duration toast 动画时长,默认 200ms * @param {boolean} mask 是否需要透明遮罩,默认 false,设置为 true 则背景不可点击 * @param {Object|Array<Object>} position 动画位置信息,可以是一个 Object 也可以是包含两个 Object 的数组(第一个元素是起始位置,第二个是结束位置),Object 有 left right top bottom width height 6个 double 属性,存在 width 时会忽略 left right,不设置默认为 { bottom: 50, right: 50, left: 50 } * @param {double|Array<double>} opacity 动画透明度,可以是一个 double 也可以是包含两个 double 的数组(第一个元素是起始透明度,第二个是结束透明度),不设置默认为 [0.0, 1.0] */ showToast (toast: VNode, info?: ToastInfo) { RenderManager.showToast(toast, info) } /** * 隐藏 toast * @param {String} name */ hideToast (name: string) { RenderManager.hideToast(name) } /** * 设置资源的路径 */ setResourcePath(path: string) { RenderManager.setResourcePath(path) } /** * 在关闭容器之前 * 通过该方法可以停止页面上永久渲染组件的渲染,如 Refresh / gif 等 * 防止关闭容器后因为持续渲染导致 crash * PS: 如果通过 threshApp.popPage() 关闭容器则不需要主动调用该方法,popPage 内部会判断调用时机 */ stopInfinitRender () { RenderManager.stopAlwaysRender() } /** * 上报当前正在显示页面的数据 * @param networkTime 接口耗时 */ pageDidShow (networkTime: number = 0) { MethodChannel.pageDidShow(networkTime) } /** * 加载 providers */ useProviders (providers: ThreshProvidersConfig) { this.providers = providers } /** * native 打印方法 */ print (args: any) { MethodChannel.print(args) } /** * 重载 js 并执行 */ // reload () { // MethodChannel.reload() // } /** * 在已注册的页面找到目标页面 * 页面优先级如下: * 1. 已指定页面则显示指定页面,不存在则显示404页面,未设置404页面则会向flutter发出pageNotFound的通知并执行flutter中的处理方法 * 2. 未指定页面则按如下顺序显示:注入路由页面 > 默认页面 > 404页面 > flutter pageNotFound */ _findPage (pageName: string, params: object = {}): PageInfo { let pageBuilder: Function let pageData: any if (!pageName) { if (this.injectRouteInfo) { pageName = this.injectRouteInfo.pageName params = this.injectRouteInfo.params } else if (this._defaultPageName) { pageName = this._defaultPageName } else if (this._notFoundPageName) { pageName = this._notFoundPageName } } else { if (!appContainer.hasRoute(pageName) && this._notFoundPageName) { pageName = this._notFoundPageName } } if (!appContainer.hasRoute(pageName)) { RenderManager.pageNotFound(pageName) } else { const builder: Function = appContainer.getRoute(pageName) as Function pageBuilder = builder() if (pageBuilder) { pageData = createElement(pageBuilder, params) if (!(pageData instanceof VNode)) throw new Error(`page ${pageName} is not a Widget`) } else { RenderManager.pageNotFound(pageName) } } return { pageData, pageName } } } /** * 第三方注入路由 * 该方法需要暴露在全局下 * 调试是可以使用该方法快速进入某个页面 * @param {String} pageName * @param {Object} params */ export function injectRoute (route: PageRoute) { if (!route.pageName) return threshApp.injectRouteInfo = route } const threshApp: ThreshApp = new ThreshApp() export default threshApp