From c67c45eb98645577892bd4a8d4f4634fdf9613c6 Mon Sep 17 00:00:00 2001 From: qiang Date: Thu, 7 Nov 2019 11:44:57 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20scanCode=E3=80=81chooseLocation?= =?UTF-8?q?=E3=80=81openLocation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app-plus/service/api/device/scan-code.js | 259 ++++++------------ .../service/api/location/choose-location.js | 169 ++++++------ .../service/api/location/open-location.js | 52 +--- src/platforms/app-plus/service/api/page.js | 139 ++++++++++ 4 files changed, 310 insertions(+), 309 deletions(-) create mode 100644 src/platforms/app-plus/service/api/page.js diff --git a/src/platforms/app-plus/service/api/device/scan-code.js b/src/platforms/app-plus/service/api/device/scan-code.js index 8b5682d22..820468a30 100644 --- a/src/platforms/app-plus/service/api/device/scan-code.js +++ b/src/platforms/app-plus/service/api/device/scan-code.js @@ -1,181 +1,84 @@ -import { - getStatusBarStyle -} from '../util' - -import { - invoke -} from '../../bridge' - -import { - ANI_SHOW, - ANI_DURATION -} from '../../constants' - -import { - registerPlusMessage, - consumePlusMessage -} from '../../framework/plus-message' - -export const SCAN_ID = '__UNIAPP_SCAN' -export const SCAN_PATH = '_www/__uniappscan.html' - -const MESSAGE_TYPE = 'scanCode' - -export function scanCode ({ - onlyFromCamera = false, - scanType -}, callbackId) { - const barcode = plus.barcode - const SCAN_TYPES = { - 'qrCode': [ - barcode.QR, - barcode.AZTEC, - barcode.MAXICODE - ], - 'barCode': [ - barcode.EAN13, - barcode.EAN8, - barcode.UPCA, - barcode.UPCE, - barcode.CODABAR, - barcode.CODE128, - barcode.CODE39, - barcode.CODE93, - barcode.ITF, - barcode.RSS14, - barcode.RSSEXPANDED - ], - 'datamatrix': [barcode.DATAMATRIX], - 'pdf417': [barcode.PDF417] +import { + invoke +} from '../../bridge' + +import { + showPage +} from '../page.js' + +function getStatusBarStyle() { + let style = plus.navigator.getStatusBarStyle() + if (style === 'UIStatusBarStyleBlackTranslucent' || style === 'UIStatusBarStyleBlackOpaque' || style === 'null') { + style = 'light' + } else if (style === 'UIStatusBarStyleDefault') { + style = 'dark' } - - const SCAN_MAPS = { - [barcode.QR]: 'QR_CODE', - [barcode.EAN13]: 'EAN_13', - [barcode.EAN8]: 'EAN_8', - [barcode.DATAMATRIX]: 'DATA_MATRIX', - [barcode.UPCA]: 'UPC_A', - [barcode.UPCE]: 'UPC_E', - [barcode.CODABAR]: 'CODABAR', - [barcode.CODE39]: 'CODE_39', - [barcode.CODE93]: 'CODE_93', - [barcode.CODE128]: 'CODE_128', - [barcode.ITF]: 'CODE_25', - [barcode.PDF417]: 'PDF_417', - [barcode.AZTEC]: 'AZTEC', - [barcode.RSS14]: 'RSS_14', - [barcode.RSSEXPANDED]: 'RSSEXPANDED' - } - - const statusBarStyle = getStatusBarStyle() - const isDark = statusBarStyle !== 'light' - - let result - - let filters = [] - if (Array.isArray(scanType) && scanType.length) { - scanType.forEach(type => { // 暂不考虑去重 - const types = SCAN_TYPES[type] - if (types) { - filters = filters.concat(types) - } - }) - } - if (!filters.length) { - filters = filters.concat(SCAN_TYPES['qrCode']).concat(SCAN_TYPES['barCode']).concat(SCAN_TYPES['datamatrix']).concat( - SCAN_TYPES['pdf417']) - } - - const buttons = [] - if (!onlyFromCamera) { - buttons.push({ - 'float': 'right', - 'text': '相册', - 'fontSize': '17px', - 'width': '60px', - 'onclick': function () { - plus.gallery.pick(file => { - barcode.scan(file, (type, code) => { - if (isDark) { - plus.navigator.setStatusBarStyle('isDark') - } - result = { - type, - code - } - webview.close('auto') - }, () => { - plus.nativeUI.toast('识别失败') - }, filters) - }, err => { - if (err.code !== 12) { - plus.nativeUI.toast('选择失败') - } - }, { - multiple: false, - system: false - }) - } - }) - } - - const webview = plus.webview.create(SCAN_PATH, SCAN_ID, { - titleNView: { - autoBackButton: true, - type: 'float', - backgroundColor: 'rgba(0,0,0,0)', - titleColor: '#ffffff', - titleText: '扫码', - titleSize: '17px', - buttons - }, - popGesture: 'close', - backButtonAutoControl: 'close' - }, { - __uniapp_type: 'scan', - __uniapp_dark: isDark, - __uniapp_scan_type: filters, - 'uni-app': 'none' - }) - const waiting = plus.nativeUI.showWaiting() - webview.addEventListener('titleUpdate', () => { - webview.show(ANI_SHOW, ANI_DURATION, () => { - waiting.close() - }) - }) - webview.addEventListener('close', () => { - if (result) { - invoke(callbackId, { - result: result.code, - scanType: SCAN_MAPS[result.type] || '', - charSet: 'utf8', - path: '', - errMsg: 'scanCode:ok' - }) - } else { - invoke(callbackId, { + return style +} + +export function scanCode(options, callbackId) { + const statusBarStyle = getStatusBarStyle() + const isDark = statusBarStyle !== 'light' + + let result + const page = showPage({ + url: '__uniappscan', + data: { + scanType: options.scanType + }, + style: { + animationType: options.animationType || 'pop-in', + titleNView: { + autoBackButton: true, + type: 'float', + titleText: options.titleText || "扫码", + titleColor: '#ffffff', + backgroundColor: 'rgba(0,0,0,0)', + buttons: !options.onlyFromCamera ? [{ + text: options.albumText || "相册", + fontSize: "17px", + onclick: () => { + page.sendMessage({ + type: "gallery" + }) + } + }] : [] + }, + popGesture: 'close', + backButtonAutoControl: 'close' + }, + onMessage({ + event, + detail + }) { + result = detail + if (event === 'marked') { + result.errMsg = 'scanCode:ok' + } else { + result.errMsg = 'scanCode:fail ' + detail.message + } + }, + onClose() { + if (isDark) { + plus.navigator.setStatusBarStyle('dark') + } + invoke(callbackId, result || { errMsg: 'scanCode:fail cancel' }) - } - consumePlusMessage(MESSAGE_TYPE) - }) - if (isDark) { // 状态栏前景色 - plus.navigator.setStatusBarStyle('light') - webview.addEventListener('popGesture', ({ - type, - result - }) => { - if (type === 'start') { - plus.navigator.setStatusBarStyle('dark') - } else if (type === 'end' && !result) { - plus.navigator.setStatusBarStyle('light') - } - }) - } - - registerPlusMessage(MESSAGE_TYPE, function (res) { - if (res && 'code' in res) { - result = res - } - }, false) -} + } + }) + + if (isDark) { + plus.navigator.setStatusBarStyle('light') + page.webview.addEventListener('popGesture', ({ + type, + result + }) => { + if (type === 'start') { + plus.navigator.setStatusBarStyle('dark') + } else if (type === 'end' && !result) { + plus.navigator.setStatusBarStyle('light') + } + }) + } +} diff --git a/src/platforms/app-plus/service/api/location/choose-location.js b/src/platforms/app-plus/service/api/location/choose-location.js index b1920803d..5070519ee 100644 --- a/src/platforms/app-plus/service/api/location/choose-location.js +++ b/src/platforms/app-plus/service/api/location/choose-location.js @@ -1,97 +1,90 @@ -import { - MAP_ID -} from '../constants' - -import { - invoke -} from '../../bridge' - -import { - ANI_DURATION -} from '../../constants' - -import { - registerPlusMessage, - consumePlusMessage -} from '../../framework/plus-message' - -const CHOOSE_LOCATION_PATH = '_www/__uniappchooselocation.html' +import { + invoke +} from '../../bridge' -const MESSAGE_TYPE = 'chooseLocation' - -export function chooseLocation (params, callbackId) { - const statusBarStyle = plus.navigator.getStatusBarStyle() - const webview = plus.webview.create( - CHOOSE_LOCATION_PATH, - MAP_ID, { - titleNView: { - autoBackButton: true, - backgroundColor: '#000000', - titleColor: '#ffffff', - titleText: '选择位置', - titleSize: '17px', - buttons: [{ - float: 'right', - text: '完成', - fontSize: '17px', - onclick: function () { - webview.evalJS('__chooseLocationConfirm__()') - } - }] - }, - popGesture: 'close', - scrollIndicator: 'none' - }, { - __uniapp_type: 'map', - __uniapp_statusbar_style: statusBarStyle, - 'uni-app': 'none' - } - ) - if (statusBarStyle === 'dark') { - plus.navigator.setStatusBarStyle('light') - webview.addEventListener('popGesture', ({ - type, - result - }) => { - if (type === 'start') { - plus.navigator.setStatusBarStyle('dark') - } else if (type === 'end' && !result) { - plus.navigator.setStatusBarStyle('light') - } - }) - } - let index = 0 - let onShow = function () { - index++ - if (index === 2) { - webview.evalJS(`__chooseLocation__(${JSON.stringify(params)})`) - } +import { + showPage +} from '../page.js' + +function getStatusBarStyle() { + let style = plus.navigator.getStatusBarStyle() + if (style === 'UIStatusBarStyleBlackTranslucent' || style === 'UIStatusBarStyleBlackOpaque' || style === 'null') { + style = 'light' + } else if (style === 'UIStatusBarStyleDefault') { + style = 'dark' } - webview.addEventListener('loaded', onShow) - webview.show('slide-in-bottom', ANI_DURATION, onShow) + return style +} + +export function chooseLocation(options, callbackId) { + const statusBarStyle = getStatusBarStyle() + const isDark = statusBarStyle !== 'light' let result + const page = showPage({ + url: '__uniappchooselocation', + data: { + keyword: options.keyword + }, + style: { + animationType: options.animationType || 'slide-in-bottom', + titleNView: { + autoBackButton: false, + titleText: options.titleText || "选择位置", + titleColor: '#ffffff', + backgroundColor: 'rgba(0,0,0,1)', + buttons: [{ + // text: options.cancelText || "取消", + // fontSize: "17px", + type: "close", + float: "left", + onclick: () => { + page.close() + } + }, { + text: options.doneText || "完成", + fontSize: "17px", + onclick: () => { + page.sendMessage({ + type: "done" + }) + } + }] + }, + popGesture: 'close', + scrollIndicator: 'none' + }, + onMessage({ + event, + detail + }) { + if (event === 'selected') { + result = detail + result.errMsg = 'chooseLocation:ok' + } + }, + onClose() { + if (isDark) { + plus.navigator.setStatusBarStyle('dark') + } - webview.addEventListener('close', () => { - if (result) { - invoke(callbackId, { - name: result.poiname, - address: result.poiaddress, - latitude: result.latlng.lat, - longitude: result.latlng.lng, - errMsg: 'chooseLocation:ok' - }) - } else { - consumePlusMessage(MESSAGE_TYPE) - invoke(callbackId, { + invoke(callbackId, result || { errMsg: 'chooseLocation:fail cancel' }) } }) - - registerPlusMessage(MESSAGE_TYPE, function (res) { - if (res && 'latlng' in res) { - result = res - } - }, false) -} + + if (isDark) { + plus.navigator.setStatusBarStyle('light') + page.webview.addEventListener('popGesture', ({ + type, + result + }) => { + if (type === 'start') { + plus.navigator.setStatusBarStyle('dark') + } else if (type === 'end' && !result) { + plus.navigator.setStatusBarStyle('light') + } + }) + } +} diff --git a/src/platforms/app-plus/service/api/location/open-location.js b/src/platforms/app-plus/service/api/location/open-location.js index e5cf71c14..6e8f90a76 100644 --- a/src/platforms/app-plus/service/api/location/open-location.js +++ b/src/platforms/app-plus/service/api/location/open-location.js @@ -1,51 +1,17 @@ import { - MAP_ID -} from '../constants' + showPage +} from '../page.js' -import { - ANI_SHOW, - ANI_DURATION -} from '../../constants' - -const OPEN_LOCATION_PATH = '_www/__uniappopenlocation.html' - -export function openLocation (params) { - const statusBarStyle = plus.navigator.getStatusBarStyle() - const webview = plus.webview.create( - OPEN_LOCATION_PATH, - MAP_ID, { +export function openLocation(data) { + showPage({ + url: '__uniappopenlocation', + data, + style: { titleNView: { - autoBackButton: true, - titleColor: '#ffffff', - titleText: '', - titleSize: '17px', - type: 'transparent' - }, - popGesture: 'close', - scrollIndicator: 'none' - }, { - __uniapp_type: 'map', - __uniapp_statusbar_style: statusBarStyle, - 'uni-app': 'none' - } - ) - if (statusBarStyle === 'light') { - plus.navigator.setStatusBarStyle('dark') - webview.addEventListener('popGesture', ({ - type, - result - }) => { - if (type === 'start') { - plus.navigator.setStatusBarStyle('light') - } else if (type === 'end' && !result) { - plus.navigator.setStatusBarStyle('dark') + type: "transparent" } - }) - } - webview.show(ANI_SHOW, ANI_DURATION, () => { - webview.evalJS(`__openLocation__(${JSON.stringify(params)})`) + } }) - return { errMsg: 'openLocation:ok' } diff --git a/src/platforms/app-plus/service/api/page.js b/src/platforms/app-plus/service/api/page.js new file mode 100644 index 000000000..3c4201cdb --- /dev/null +++ b/src/platforms/app-plus/service/api/page.js @@ -0,0 +1,139 @@ +let plus_ +let weex_ +let uni_ + +let runtime + +function getRuntime() { + return runtime || (runtime = typeof window === 'object' && typeof navigator === 'object' && typeof document === + 'object' ? + 'webview' : 'v8') +} + +function setRuntime(value) { + runtime = value +} + +function getPageId() { + return plus_.webview.currentWebview().id +} + +let initedEventListener = false +const callbacks = {} + +function addEventListener(pageId, callback) { + const runtime = getRuntime() + + function onPlusMessage(res) { + const message = res.data && res.data.__message + if (!message || !message.__page) { + return + } + const pageId = message.__page + const callback = callbacks[pageId] + callback && callback(message) + if (!message.keep) { + delete callbacks[pageId] + } + } + if (!initedEventListener) { + if (runtime === 'v8') { + const globalEvent = weex_.requireModule('globalEvent') + globalEvent.addEventListener('plusMessage', onPlusMessage) + } else if (runtime === 'v8-native') { + uni_.$on(getPageId(), onPlusMessage) + } else { + window.__plusMessage = onPlusMessage + } + initedEventListener = true + } + callbacks[pageId] = callback +} + +class Page { + constructor(webview) { + this.webview = webview + } + sendMessage(data) { + const runtime = getRuntime() + const message = { + __message: { + data + } + } + if (runtime === 'v8-native') { + uni_.$emit(this.webview.id, { + data: JSON.parse(JSON.stringify(message)) + }) + } else { + plus_.webview.postMessageToUniNView(message, this.webview.id) + } + } + close() { + this.webview.close() + } +} + +export function showPage({ + context, + runtime, + url, + data = {}, + style = {}, + onMessage, + onClose +}) { + if (context) { + plus_ = context.plus + weex_ = context.weex + uni_ = context.uni + } else { + // eslint-disable-next-line + plus_ = typeof plus === 'object' ? plus : null + // eslint-disable-next-line + weex_ = typeof weex === 'object' ? weex : null + // eslint-disable-next-line + uni_ = typeof uni === 'object' ? uni : null + } + if (runtime) { + setRuntime(runtime) + } else { + runtime = getRuntime() + } + const titleNView = { + autoBackButton: true, + titleSize: '17px' + } + const pageId = `page${Date.now()}` + style = Object.assign({}, style) + if (style.titleNView !== false && style.titleNView !== 'none') { + style.titleNView = Object.assign(titleNView, style.titleNView) + } + const defaultStyle = { + top: 0, + bottom: 0, + usingComponents: {}, + popGesture: 'close', + scrollIndicator: 'none', + animationType: 'pop-in', + animationDuration: 200, + uniNView: { + path: `/${url}.js?from=${getPageId()}&runtime=${runtime}&data=${encodeURIComponent(JSON.stringify(data))}`, + defaultFontSize: plus_.screen.resolutionWidth / 20, + viewport: plus_.screen.resolutionWidth + } + } + style = Object.assign(defaultStyle, style) + const page = plus_.webview.create('', pageId, style) + page.addEventListener('close', onClose) + addEventListener(pageId, message => { + if (typeof onMessage === 'function') { + onMessage(message.data) + } + if (!message.keep) { + page.close('auto') + } + }) + page.show(style.animationType, style.animationDuration) + return new Page(page) +} -- GitLab