From ba98c592bb7efbcef602f3d6971381bfaed8849d Mon Sep 17 00:00:00 2001 From: DCloud_LXH <283700113@qq.com> Date: Fri, 27 Aug 2021 17:49:49 +0800 Subject: [PATCH] =?UTF-8?q?feat(App-nvue):=20createLivePusherContext?= =?UTF-8?q?=E3=80=81createVideoContext=E3=80=81createMapContext?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../uni-api/src/protocols/context/context.ts | 10 ++ .../api/context/createLivePusherContext.ts | 98 ++++++++++++++ .../src/service/api/context/operateMap.ts | 64 +++++++++ .../service/api/context/operateVideoPlayer.ts | 47 +++++++ .../uni-app-plus/src/service/api/index.ts | 1 + packages/uni-app-plus/src/service/api/util.ts | 127 ++++++++++++++++++ .../src/view/components/video/index.tsx | 3 + 7 files changed, 350 insertions(+) create mode 100644 packages/uni-app-plus/src/service/api/context/createLivePusherContext.ts create mode 100644 packages/uni-app-plus/src/service/api/util.ts diff --git a/packages/uni-api/src/protocols/context/context.ts b/packages/uni-api/src/protocols/context/context.ts index 750217c98..d011fb7f7 100644 --- a/packages/uni-api/src/protocols/context/context.ts +++ b/packages/uni-api/src/protocols/context/context.ts @@ -34,3 +34,13 @@ export const CreateCanvasContextProtocol: ProtocolOptions[] = [ export const API_CREATE_INNER_AUDIO_CONTEXT = 'createInnerAudioContext' export type API_TYPE_CREATEE_INNER_AUDIO_CONTEXT = typeof uni.createInnerAudioContext + +export const API_CREATE_LIVE_PUSHER_CONTEXT = 'createLivePusherContext' +export type API_TYPE_CREATE_LIVE_PUSHER_CONTEXT = ( + id: string, + componentInstance: any +) => ReturnType | void +export const CreateLivePusherContextProtocol = validator.concat({ + name: 'componentInstance', + type: Object, +}) diff --git a/packages/uni-app-plus/src/service/api/context/createLivePusherContext.ts b/packages/uni-app-plus/src/service/api/context/createLivePusherContext.ts new file mode 100644 index 000000000..373cdb3a0 --- /dev/null +++ b/packages/uni-app-plus/src/service/api/context/createLivePusherContext.ts @@ -0,0 +1,98 @@ +import { + API_CREATE_LIVE_PUSHER_CONTEXT, + API_TYPE_CREATE_LIVE_PUSHER_CONTEXT, + CreateLivePusherContextProtocol, + defineSyncApi, +} from '@dcloudio/uni-api' +import { + findElmById, + invokeVmMethod, + invokeVmMethodWithoutArgs, + CallBacks as cb, +} from '../util' +type CallBacks = Partial +class LivePusherContext implements UniApp.LivePusherContext { + id: string + ctx: any + + constructor(id: string, ctx: any) { + this.id = id + this.ctx = ctx + } + + start(option?: CallBacks) { + return invokeVmMethodWithoutArgs(this.ctx, 'start', option) + } + + stop(option?: CallBacks) { + return invokeVmMethodWithoutArgs(this.ctx, 'stop', option) + } + + pause(option?: CallBacks) { + return invokeVmMethodWithoutArgs(this.ctx, 'pause', option) + } + + resume(option?: CallBacks) { + return invokeVmMethodWithoutArgs(this.ctx, 'resume', option) + } + + switchCamera(option?: CallBacks) { + return invokeVmMethodWithoutArgs(this.ctx, 'switchCamera', option) + } + + snapshot(option?: CallBacks) { + return invokeVmMethodWithoutArgs(this.ctx, 'snapshot', option) + } + + toggleTorch(option?: CallBacks) { + return invokeVmMethodWithoutArgs(this.ctx, 'toggleTorch', option) + } + + playBGM(option?: CallBacks) { + return invokeVmMethod(this.ctx, 'playBGM', option) + } + + stopBGM(option?: CallBacks) { + return invokeVmMethodWithoutArgs(this.ctx, 'stopBGM', option) + } + + pauseBGM(option?: CallBacks) { + return invokeVmMethodWithoutArgs(this.ctx, 'pauseBGM', option) + } + + resumeBGM(option?: CallBacks) { + return invokeVmMethodWithoutArgs(this.ctx, 'resumeBGM', option) + } + + setBGMVolume(option?: CallBacks) { + return invokeVmMethod(this.ctx, 'setBGMVolume', option) + } + + startPreview(option?: CallBacks) { + return invokeVmMethodWithoutArgs(this.ctx, 'startPreview', option) + } + + stopPreview(args?: CallBacks) { + return invokeVmMethodWithoutArgs(this.ctx, 'stopPreview', args) + } + + 'setMICVolume': () => {} +} + +export const createLivePusherContext = + defineSyncApi( + API_CREATE_LIVE_PUSHER_CONTEXT, + (id, vm) => { + if (!vm) { + return console.warn( + 'uni.createLivePusherContext: 2 arguments required, but only 1 present' + ) + } + const elm = findElmById(id, vm) + if (!elm) { + return console.warn('Can not find `' + id + '`') + } + return new LivePusherContext(id, elm) + }, + CreateLivePusherContextProtocol + ) diff --git a/packages/uni-app-plus/src/service/api/context/operateMap.ts b/packages/uni-app-plus/src/service/api/context/operateMap.ts index bd8fc168c..05601820d 100644 --- a/packages/uni-app-plus/src/service/api/context/operateMap.ts +++ b/packages/uni-app-plus/src/service/api/context/operateMap.ts @@ -1,3 +1,59 @@ +import { ComponentPublicInstance } from 'vue' +import { findElmById, invokeVmMethod, invokeVmMethodWithoutArgs } from '../util' + +type Methords = Record void> + +const METHODS: Methords = { + getCenterLocation(ctx, cbs) { + return invokeVmMethodWithoutArgs(ctx, 'getCenterLocation', cbs) + }, + moveToLocation(ctx, args) { + return invokeVmMethod(ctx, 'moveToLocation', args) + }, + translateMarker(ctx, args) { + return invokeVmMethod(ctx, 'translateMarker', args, ['animationEnd']) + }, + includePoints(ctx, args) { + return invokeVmMethod(ctx, 'includePoints', args) + }, + getRegion(ctx, cbs) { + return invokeVmMethodWithoutArgs(ctx, 'getRegion', cbs) + }, + getScale(ctx, cbs) { + return invokeVmMethodWithoutArgs(ctx, 'getScale', cbs) + }, + addCustomLayer(ctx, args) { + return invokeVmMethod(ctx, 'addCustomLayer', args) + }, + removeCustomLayer(ctx, args) { + return invokeVmMethod(ctx, 'removeCustomLayer', args) + }, + addGroundOverlay(ctx, args) { + return invokeVmMethod(ctx, 'addGroundOverlay', args) + }, + removeGroundOverlay(ctx, args) { + return invokeVmMethod(ctx, 'removeGroundOverlay', args) + }, + updateGroundOverlay(ctx, args) { + return invokeVmMethod(ctx, 'updateGroundOverlay', args) + }, + initMarkerCluster(ctx, args) { + return invokeVmMethod(ctx, 'initMarkerCluster', args) + }, + addMarkers(ctx, args) { + return invokeVmMethod(ctx, 'addMarkers', args) + }, + removeMarkers(ctx, args) { + return invokeVmMethod(ctx, 'removeMarkers', args) + }, + moveAlong(ctx, args) { + return invokeVmMethod(ctx, 'moveAlong', args) + }, + openMapApp(ctx, args) { + return invokeVmMethod(ctx, 'openMapApp', args) + }, +} + export function operateMap( id: string, pageId: number, @@ -5,6 +61,14 @@ export function operateMap( data?: unknown, operateMapCallback?: (res: any) => void ) { + const page = getCurrentPages().find((page) => page.$page.id === pageId) + if (page?.$page.meta.isNVue) { + const pageVm = (page as any).$vm as ComponentPublicInstance + return METHODS[type as keyof typeof METHODS]( + findElmById(id, pageVm), + data as any + ) + } UniServiceJSBridge.invokeViewMethod( 'map.' + id, { diff --git a/packages/uni-app-plus/src/service/api/context/operateVideoPlayer.ts b/packages/uni-app-plus/src/service/api/context/operateVideoPlayer.ts index dac17b663..b0aeae4ce 100644 --- a/packages/uni-app-plus/src/service/api/context/operateVideoPlayer.ts +++ b/packages/uni-app-plus/src/service/api/context/operateVideoPlayer.ts @@ -1,9 +1,56 @@ +import { ComponentPublicInstance } from 'vue' +import { findElmById, invokeVmMethod, invokeVmMethodWithoutArgs } from '../util' + +const METHODS = { + play(ctx: any) { + return invokeVmMethodWithoutArgs(ctx, 'play') + }, + pause(ctx: any) { + return invokeVmMethodWithoutArgs(ctx, 'pause') + }, + seek(ctx: any, args: { position: number }) { + return invokeVmMethod(ctx, 'seek', args.position) + }, + stop(ctx: any) { + return invokeVmMethodWithoutArgs(ctx, 'stop') + }, + sendDanmu(ctx: any, args: WechatMiniprogram.Danmu) { + return invokeVmMethod(ctx, 'sendDanmu', args) + }, + playbackRate(ctx: any, args: { rate: number }) { + return invokeVmMethod(ctx, 'playbackRate', args.rate) + }, + requestFullScreen( + ctx: any, + args: WechatMiniprogram.VideoContextRequestFullScreenOption = {} + ) { + return invokeVmMethod(ctx, 'requestFullScreen', args) + }, + exitFullScreen(ctx: any) { + return invokeVmMethodWithoutArgs(ctx, 'exitFullScreen') + }, + showStatusBar(ctx: any) { + return invokeVmMethodWithoutArgs(ctx, 'showStatusBar') + }, + hideStatusBar(ctx: any) { + return invokeVmMethodWithoutArgs(ctx, 'hideStatusBar') + }, +} + export function operateVideoPlayer( videoId: string, pageId: number, type: string, data?: unknown ) { + const page = getCurrentPages().find((page) => page.$page.id === pageId) + if (page?.$page.meta.isNVue) { + const pageVm = (page as any).$vm as ComponentPublicInstance + return METHODS[type as keyof typeof METHODS]( + findElmById(videoId, pageVm), + data as any + ) + } UniServiceJSBridge.invokeViewMethod( 'video.' + videoId, { diff --git a/packages/uni-app-plus/src/service/api/index.ts b/packages/uni-app-plus/src/service/api/index.ts index 89d088fec..9afc5ef83 100644 --- a/packages/uni-app-plus/src/service/api/index.ts +++ b/packages/uni-app-plus/src/service/api/index.ts @@ -38,6 +38,7 @@ export * from './network/uploadFile' export * from './context/createInnerAudioContext' export * from './context/getBackgroundAudioManager' +export * from './context/createLivePusherContext' export * from './location/getLocation' export * from './location/chooseLocation' diff --git a/packages/uni-app-plus/src/service/api/util.ts b/packages/uni-app-plus/src/service/api/util.ts new file mode 100644 index 000000000..41fdec495 --- /dev/null +++ b/packages/uni-app-plus/src/service/api/util.ts @@ -0,0 +1,127 @@ +import { isFunction } from '@vue/shared' +import { ComponentPublicInstance } from 'vue' + +const SUCCESS = 'success' +const FAIL = 'fail' +const COMPLETE = 'complete' +const CALLBACKS: CallBackName[] = [SUCCESS, FAIL, COMPLETE] + +type CallBackName = typeof SUCCESS | typeof FAIL | typeof COMPLETE +export type CallBacks = Record + +/** + * 调用无参数,或仅一个参数且为 callback 的 API + * @param {Object} vm + * @param {Object} method + * @param {Object} args + * @param {Object} extras + */ +export function invokeVmMethodWithoutArgs( + vm: any, + method: string, + args?: any, + extras?: [any] +) { + if (!vm) { + return + } + if (typeof args === 'undefined') { + return vm[method]() + } + const [, callbacks] = normalizeArgs(args, extras) + if (!Object.keys(callbacks).length) { + return vm[method]() + } + return vm[method](normalizeCallback(method, callbacks)) +} +/** + * 调用两个参数(第一个入参为普通参数,第二个入参为 callback) API + * @param {Object} vm + * @param {Object} method + * @param {Object} args + * @param {Object} extras + */ +export function invokeVmMethod( + vm: any, + method: string, + args: any, + extras?: [any] +) { + if (!vm) { + return + } + const [pureArgs, callbacks] = normalizeArgs(args, extras) + if (!Object.keys(callbacks).length) { + return vm[method](pureArgs) + } + return vm[method](pureArgs, normalizeCallback(method, callbacks)) +} + +export function findElmById(id: string, vm: ComponentPublicInstance) { + const elm = findRefByElm(id, vm.$el) + if (!elm) { + return console.error('Can not find `' + id + '`') + } + return elm +} + +function findRefByElm(id: string, elm: any): any { + if (!id || !elm) { + return + } + if (elm.attr && elm.attr.id === id) { + return elm + } + const children = elm.children + if (!children) { + return + } + for (let i = 0, len = children.length; i < len; i++) { + const elm = findRefByElm(id, children[i]) + if (elm) { + return elm + } + } +} + +function normalizeArgs(args: any = {}, extras?: [any]) { + const callbacks = Object.create(null) + + const iterator = function iterator(name: string) { + const callback = args[name] + if (isFunction(callback)) { + callbacks[name] = callback + delete args[name] + } + } + + CALLBACKS.forEach(iterator) + + extras && extras.forEach(iterator) + + return [args, callbacks] +} + +function normalizeCallback(method: string, callbacks: CallBacks) { + return function weexCallback(ret: any) { + const type = ret.type as CallBackName + delete ret.type + const callback = callbacks[type] + + if (type === SUCCESS) { + ret.errMsg = `${method}:ok` + } else if (type === FAIL) { + ret.errMsg = method + ':fail ' + (ret.msg ? ' ' + ret.msg : '') + } + + delete ret.code + delete ret.msg + + isFunction(callback) && callback(ret) + + if (type === SUCCESS || type === FAIL) { + const complete = callbacks.complete + isFunction(complete) && complete(ret) + } + } +} diff --git a/packages/uni-app-plus/src/view/components/video/index.tsx b/packages/uni-app-plus/src/view/components/video/index.tsx index 23dd46f8c..afe4c3b20 100644 --- a/packages/uni-app-plus/src/view/components/video/index.tsx +++ b/packages/uni-app-plus/src/view/components/video/index.tsx @@ -233,6 +233,9 @@ export default /*#__PURE__*/ defineBuiltInComponent({ case 'playbackRate': options = data.rate break + case 'requestFullScreen': + options = data.direction + break } if (video) { video[type as Method](options) -- GitLab